#pragma once #include #include #include #include #include #include #include #include namespace qjs { class Runtime; class Context; class Value; } // namespace qjs namespace frostbite2D { class Actor; struct Vec2; class QuickJSVM { public: using BindingInstaller = std::function; static QuickJSVM& get(); void setScriptDirectory(const std::string& path); void setEntryScript(const std::string& path); void setDebugMode(bool enable); bool init(); void shutdown(); bool run(); bool isInitialized() const { return initialized_; } qjs::Context* getContext() const { return context_.get(); } const std::string& getScriptDirectory() const { return scriptDirectory_; } bool runPendingJobs(); void logException(const char* stage); qjs::Value newObject(); qjs::Value loadModule(const std::string& relativePath); qjs::Value loadModule(const std::string& relativePath, const std::string& cacheTag); qjs::Value construct(const qjs::Value& constructor, const qjs::Value& argument); qjs::Value callMethod(const qjs::Value& object, const char* name); qjs::Value callMethod(const qjs::Value& object, const char* name, const qjs::Value& argument); qjs::Value callMethod(const qjs::Value& object, const char* name, double argument); qjs::Value wrapActor(const Ptr& actor); qjs::Value wrapVec2(const Vec2& value); qjs::Value wrapEvent(const Event& event); std::optional parseEventTypeName(std::string_view typeName) const; void RegisterBindingInstaller(BindingInstaller installer); void RegisterBootstrapScript(const std::string& script); private: QuickJSVM() = default; ~QuickJSVM(); QuickJSVM(const QuickJSVM&) = delete; QuickJSVM& operator=(const QuickJSVM&) = delete; bool registerBindings(); bool installGlobals(); void logScriptException(const char* stage); std::string buildEntryPath() const; bool initialized_ = false; bool debugMode_ = false; std::string scriptDirectory_ = "assets/scripts"; std::string entryScript_ = "main.js"; uint64 nextEvalId_ = 1; std::vector bindingInstallers_; std::vector bootstrapScripts_; std::unique_ptr runtime_; std::unique_ptr context_; }; } // namespace frostbite2D