diff --git a/include/Game.h b/include/Game.h new file mode 100644 index 0000000..c1b1aa3 --- /dev/null +++ b/include/Game.h @@ -0,0 +1,18 @@ +#pragma once + +class GameInternal; + +// TODO: add managers here +class Game { +public: + virtual ~Game() {} + + virtual void init() = 0; + virtual void update() = 0; + + GameInternal* gameInternal; //!< \deprecated +}; + + +// game factory include to simplify imports in implementation +#include "GameFactory.h" \ No newline at end of file diff --git a/include/GameFactory.h b/include/GameFactory.h new file mode 100644 index 0000000..24fcfcb --- /dev/null +++ b/include/GameFactory.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "Game.h" + +class GameInternal; + +class GameFactory { +public: + using CreateFunc = std::function; + + static GameFactory& instance() { + static GameFactory factory; + return factory; + } + + void registerClass(CreateFunc createFunc) { + this->creator = createFunc; + } + + Game* get() { + assert(this->gameInstance != nullptr); + return this->gameInstance; + } + + Game* create(GameInternal* gameInternal) { + Game* game = this->gameInstance == nullptr ? this->creator() : this->gameInstance; // TODO: error handling + game->gameInternal = gameInternal; + this->gameInstance = game; + return game; + } + + /* named game instances for future use + void registerClass(const std::string& className, CreateFunc createFunc) { + this->creators[className] = createFunc; + } + + Game* create(const std::string& className) { + auto it = this->creators.find(className); + if (it != creators.end()) { + return it->second(); + } + return nullptr; + } + */ + +private: + CreateFunc creator; + Game* gameInstance = nullptr; //!< \depricated + // std::map creators; +}; + +#define REGISTER_GAME(className) \ + static bool registered_##className = []() { \ + GameFactory::instance().registerClass([]() -> Game* { return new className; }); \ + return true; \ + }(); + +/* +#define REGISTER_GAME(className) \ + static bool registered_##className = []() { \ + GameFactory::instance().registerClass(#className, []() -> Game* { return new className; }); \ + return true; \ + }(); +*/ diff --git a/include/GameInternal.h b/include/GameInternal.h index 6821af9..8cd806c 100644 --- a/include/GameInternal.h +++ b/include/GameInternal.h @@ -17,13 +17,7 @@ class CollisionHandler; class TextureManager; class SoundManager; class Map; - -namespace engine { - extern gamefunction init; - extern gamefunction update; - - extern GameInternal* game; // this is a temporary fix to remove artifacts of chicken_game from the engine while the API is not yet finalized -} +class Game; class GameInternal { @@ -69,6 +63,8 @@ public: private: + Game* gameInstance; + int counter = 0; bool isRunning = false; SDL_Window* window; diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 024d8ad..0491db5 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -14,8 +14,8 @@ #include "TextureManager.h" #include "StatEffectsComponent.h" #include "Constants.h" - -GameInternal* engine::game = nullptr; // will be initialized in constructor +#include "Game.h" +#include "GameFactory.h" GameInternal::GameInternal() : manager(this), @@ -27,9 +27,7 @@ GameInternal::GameInternal() : player1(manager.addEntity()), player2(manager.addEntity()), wall(manager.addEntity()) -{ - engine::game = this; -}; +{}; GameInternal::~GameInternal() = default; @@ -181,7 +179,8 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he player2.addComponent(); player2.addGroup((size_t) Entity::GroupLabel::PLAYERS); - engine::init(); + this->gameInstance = GameFactory::instance().create(this); + this->gameInstance->init(); } void GameInternal::selectCharacters(const char* &playerSprite, const char* &enemySprite) @@ -299,7 +298,7 @@ void GameInternal::update() manager.refresh(); manager.update(); - engine::update(); // TODO: this might have to be split up into two update functions, before and after manager... + this->gameInstance->update(); // TODO: this might have to be split up into two update functions, before and after manager... } void GameInternal::render()