// Minimal host interfaces for compiling the real component without the game VM. #pragma once #include "http.hpp" #include #include #include #include #include #include #include #include #include #include #include using namespace std::chrono_literals; namespace game { constexpr int SCRIPT_NONE = 0; } namespace plugin { class plugin {}; } class component_interface { public: virtual ~component_interface() = default; virtual void on_startup(plugin::plugin*) {} virtual void on_shutdown(plugin::plugin*) {} }; #define REGISTER_COMPONENT(...) namespace scripting { class array; class script_value; using fields = std::map; class script_value { public: std::variant> data; script_value() = default; script_value(int v) : data(v) {} script_value(bool v) : data(v) {} script_value(double v) : data(v) {} script_value(const char* v) : data(std::string(v)) {} script_value(std::string v) : data(std::move(v)) {} script_value(const array& v); template bool is() const { return std::holds_alternative(data); } template T as() const { return std::get(data); } struct raw { int type; }; raw get_raw() const { return {static_cast(data.index())}; } std::string to_string() const { return as(); } }; class array { public: std::shared_ptr data = std::make_shared(); script_value& operator[](const script_value& key) const { return (*data)[key.as()]; } std::vector get_keys() const { std::vector keys; for (const auto& [key, value] : *data) keys.emplace_back(key); return keys; } }; inline script_value::script_value(const array& v) : data(v.data) {} template <> inline bool script_value::is() const { return std::holds_alternative>(data); } template <> inline array script_value::as() const { array result; result.data = std::get>(data); return result; } using variadic_args = std::vector; class object { inline static unsigned next_id = 1; unsigned id = next_id++; public: unsigned get_entity_id() const { return id; } }; inline std::vector> notifications; inline std::function after_notify; inline void notify(unsigned, const std::string& event, const std::vector& args) { assert(event == "done"); notifications.push_back(args); if (after_notify) after_notify(); } inline void on_shutdown(const std::function&) {} } namespace scheduler { struct pool { std::vector> tasks; void push(std::function f) { tasks.push_back(std::move(f)); } void run() { auto work = std::move(tasks); tasks.clear(); for (auto& task : work) task(); } }; inline pool thread_pool; constexpr int server = 0; inline void loop(const std::function&, int) {} } namespace gsc::function { template void add(const char*, F) {} template void add_multiple(F, Names...) {} } namespace utils::http { inline bool throw_from_transfer = false; inline std::optional next_result = result{}; inline timeouts observed_limits; inline std::optional get_data(const std::string&, const std::string&, const headers&, const std::string&, const timeouts& limits) { observed_limits = limits; if (throw_from_transfer) throw std::runtime_error("simulated worker error"); return next_result; } }