#pragma once #include "delegates.hpp" #include "typedefs.hpp" #include "settings.hpp" #include "io/engine_paths.hpp" #include "io/settings_io.hpp" #include "util/ObjectsKeeper.hpp" #include "PostRunnables.hpp" #include "Time.hpp" #include #include class Window; class Assets; class Level; class Screen; class ContentControl; class EngineController; class Input; struct Project; namespace gui { class GUI; } namespace cmd { class CommandsInterpreter; } namespace network { class Network; } namespace devtools { class Editor; class DebuggingServer; } class initialize_error : public std::runtime_error { public: initialize_error(const std::string& message) : std::runtime_error(message) {} }; struct CoreParameters { bool headless = false; bool testMode = false; std::filesystem::path resFolder = "res"; std::filesystem::path userFolder = "."; std::filesystem::path scriptFile; std::filesystem::path projectFolder; std::string debugServerString; int tps = 20; }; using OnWorldOpen = std::function, int64_t)>; class Engine : public util::ObjectsKeeper { CoreParameters params; EngineSettings settings; EnginePaths paths; std::unique_ptr project; std::unique_ptr settingsHandler; std::unique_ptr assets; std::shared_ptr screen; std::unique_ptr content; std::unique_ptr controller; std::unique_ptr cmd; std::unique_ptr network; std::unique_ptr window; std::unique_ptr input; std::unique_ptr gui; std::unique_ptr editor; std::unique_ptr debuggingServer; PostRunnables postRunnables; Time time; OnWorldOpen levelConsumer; bool quitSignal = false; void loadControls(); void loadSettings(); void saveSettings(); void updateHotkeys(); void loadAssets(); void loadProject(); void initializeClient(); void onContentLoad(); public: Engine(); ~Engine(); static Engine& getInstance(); void initialize(CoreParameters coreParameters); void close(); static void terminate(); /// @brief Start the engine void run(); void postUpdate(); void updateFrontend(); void renderFrame(); void nextFrame(); void startPauseLoop(); /// @brief Set screen (scene). /// nullptr may be used to delete previous screen before creating new one, /// not-null value must be set before next frame /// @param screen nullable screen void setScreen(std::shared_ptr screen); /// @brief Get active assets storage instance Assets* getAssets(); /// @brief Get writeable engine settings structure instance EngineSettings& getSettings(); /// @brief Get engine filesystem paths source EnginePaths& getPaths(); /// @brief Get engine resource paths controller ResPaths& getResPaths(); void onWorldOpen(std::unique_ptr level, int64_t localPlayer); void onWorldClosed(); void quit(); bool isQuitSignal() const; /// @brief Get current screen std::shared_ptr getScreen(); /// @brief Enqueue function call to the end of current frame in draw thread void postRunnable(const runnable& callback) { postRunnables.postRunnable(callback); } void saveScreenshot(); EngineController* getController(); void setLevelConsumer(OnWorldOpen levelConsumer); SettingsHandler& getSettingsHandler(); Time& getTime(); const CoreParameters& getCoreParameters() const; bool isHeadless() const; ContentControl& getContentControl(); gui::GUI& getGUI() { return *gui; } Input& getInput() { return *input; } Window& getWindow() { return *window; } network::Network& getNetwork() { return *network; } cmd::CommandsInterpreter& getCmd() { return *cmd; } devtools::Editor& getEditor() { return *editor; } const Project& getProject() { return *project; } devtools::DebuggingServer* getDebuggingServer() { return debuggingServer.get(); } void detachDebugger(); };