diff --git a/src/app.cppm b/src/app.cppm index fe1ab7f..7b59948 100644 --- a/src/app.cppm +++ b/src/app.cppm @@ -15,8 +15,8 @@ export { class App { - std::unique_ptr engine_ = nullptr; - std::unique_ptr game_ = nullptr; + std::unique_ptr engine_{nullptr}; + std::unique_ptr game_{nullptr}; public: App() = default; @@ -36,10 +36,9 @@ export // Initialize SDL subsystems sdl::Init(sdl::InitFlags::Video | sdl::InitFlags::Events); + // Create engine (includes window and renderer) and game state engine_ = core::Engine::create(); - - game_ = std::make_unique(*engine_); - game_->initialize(); + game_ = game::Game::create(*engine_); } catch (const std::runtime_error& e) { std::cerr << "Unhandled exception during initialization: " << e.what() << '\n'; diff --git a/src/core/engine.cppm b/src/core/engine.cppm index aae33ba..3d50323 100644 --- a/src/core/engine.cppm +++ b/src/core/engine.cppm @@ -59,12 +59,12 @@ export namespace core 0 ); - return std::unique_ptr( + return std::unique_ptr{ new Engine{ std::move(sdl_window), Renderer{std::move(sdl_renderer)} } - ); + }; } bool keep_running() const diff --git a/src/game/game.cppm b/src/game/game.cppm index 4216681..1d68ace 100644 --- a/src/game/game.cppm +++ b/src/game/game.cppm @@ -1,5 +1,6 @@ module; +#include #include #include @@ -15,35 +16,49 @@ export namespace game { class Game { + // Whether this class is currently instantiated (to prevent multiple instances) + static bool instantiated_; + + // Reference to the engine core::Engine& engine_; // Sprite for testing - std::unique_ptr sprite_ = nullptr; + std::unique_ptr sprite_{nullptr}; + + // Private constructor + explicit Game(core::Engine& engine) + : engine_(engine) + { + // TODO: Texture should be a reference/pointer to an object managed by a ResourceManager or similar. + auto texture = sdl_image::LoadTexture( + engine_.get_renderer().get_sdl_renderer(), + "assets/neocat.png" + ); + + sprite_ = std::make_unique(std::move(texture), 100, 100); + } public: Game() = delete; - explicit Game(core::Engine& engine) - : engine_(engine) - {} - // No copy or move operations because we have a reference to the engine Game(const Game&) = delete; Game& operator=(const Game&) = delete; Game(Game&&) = delete; Game& operator=(Game&&) = delete; - ~Game() = default; - - void initialize() + ~Game() { - // TODO: Texture should be a reference/pointer to an object managed by a ResourceManager or similar. - auto texture = sdl_image::LoadTexture( - engine_.get_renderer().get_sdl_renderer(), - "assets/neocat.png" - ); + instantiated_ = false; + } - sprite_ = std::make_unique(std::move(texture), 100, 100); + static std::unique_ptr create(core::Engine& engine) + { + // Prevent the class from being instantiated multiple times + assert(!instantiated_); + return std::unique_ptr{ + new Game(engine) + }; } // Handles an SDL event. Returns true if the event has been handled. @@ -75,4 +90,6 @@ export namespace game { } }; + + bool Game::instantiated_ = false; } diff --git a/src/game/sprite.cppm b/src/game/sprite.cppm index 7221d2a..901ea28 100644 --- a/src/game/sprite.cppm +++ b/src/game/sprite.cppm @@ -29,16 +29,6 @@ export namespace game dest_rect_.h = static_cast(height); } - // Don't allow copy operations - Sprite(const Sprite&) = delete; - Sprite& operator=(const Sprite&) = delete; - - // Default move operations - Sprite(Sprite&& other) = default; - Sprite& operator=(Sprite&& other) = default; - - ~Sprite() = default; - void move(const float x, const float y) { dest_rect_.x = x; diff --git a/src/wrappers/sdl/render.cppm b/src/wrappers/sdl/render.cppm index 1838e1b..e0b28c0 100644 --- a/src/wrappers/sdl/render.cppm +++ b/src/wrappers/sdl/render.cppm @@ -21,10 +21,10 @@ export namespace sdl std::unique_ptr< SDL_Texture, utils::FuncDeleter - > raw_texture_ = nullptr; + > raw_texture_; public: - Texture() = default; + Texture() = delete; explicit Texture(SDL_Texture* raw_texture) : raw_texture_{raw_texture} @@ -45,10 +45,10 @@ export namespace sdl std::unique_ptr< SDL_Renderer, utils::FuncDeleter - > raw_renderer_ = nullptr; + > raw_renderer_; public: - Renderer() = default; + Renderer() = delete; explicit Renderer(SDL_Renderer* raw_renderer) : raw_renderer_{raw_renderer} diff --git a/src/wrappers/sdl/video.cppm b/src/wrappers/sdl/video.cppm index 126033c..f80c93f 100644 --- a/src/wrappers/sdl/video.cppm +++ b/src/wrappers/sdl/video.cppm @@ -18,10 +18,10 @@ export namespace sdl std::unique_ptr< SDL_Window, utils::FuncDeleter - > raw_window_ = nullptr; + > raw_window_; public: - Window() = default; + Window() = delete; explicit Window(SDL_Window* raw_window) : raw_window_{raw_window}