module; #include #include export module rutile.core.engine; import rutile.config; import rutile.core.render_server; import rutile.core.ui.ui_server; import wrappers.sdl; export namespace rutile { class Engine { // Whether this class is currently instantiated (to prevent multiple instances) static bool instantiated_; // If this is set to false, the application will exit bool keep_running_ = true; sdl::Window window_; RenderServer render_server_; UIServer ui_server_; // Private constructor Engine(sdl::Window&& window, sdl::Renderer&& renderer) : window_{std::move(window)}, render_server_{std::move(renderer)}, ui_server_{render_server_.get_renderer(), window_} { instantiated_ = true; } public: Engine() = delete; // No copy or move operations Engine(const Engine&) = delete; Engine& operator=(const Engine&) = delete; Engine(Engine&&) = delete; Engine& operator=(Engine&&) = delete; ~Engine() { instantiated_ = false; } static std::unique_ptr create() { // Prevent the class from being instantiated multiple times assert(!instantiated_); auto [sdl_window, sdl_renderer] = sdl::CreateWindowAndRenderer( config::get_window_title(), config::window_width, config::window_height, 0 ); // NOLINTBEGIN: "Allocated memory is leaked" return std::unique_ptr{ new Engine{ std::move(sdl_window), std::move(sdl_renderer) } }; // NOLINTEND } bool keep_running() const { return keep_running_; } sdl::Window& get_window() { return window_; } RenderServer& get_render_server() { return render_server_; } UIServer& get_ui_server() { return ui_server_; } // Handles an SDL event. Returns true if the event has been handled. bool handle_event(const sdl::Event& event) { if (event.type == sdl::EventTypes::Quit) { // Exit the application keep_running_ = false; return true; } if (ui_server_.handle_event(event)) { return true; } return false; } void update() { } void shutdown() { } }; bool Engine::instantiated_ = false; }