diff --git a/game/src/game.cpp b/game/src/game.cpp index 38c8f32..3107b3a 100644 --- a/game/src/game.cpp +++ b/game/src/game.cpp @@ -4,11 +4,12 @@ class Game : public Inferno::Application { public: - Game() {} + Game() : Application({}) {} ~Game() {} }; -Inferno::Application* Inferno::createApplication() +Inferno::Application& Inferno::createApplication() { - return new Game(); + Game::initialize(); + return Game::the(); } diff --git a/inferno/src/inferno/application.cpp b/inferno/src/inferno/application.cpp index 97daa74..b995005 100644 --- a/inferno/src/inferno/application.cpp +++ b/inferno/src/inferno/application.cpp @@ -21,11 +21,9 @@ namespace Inferno { - Application* Application::s_instance = nullptr; - - Application::Application() + Application::Application(s) { - ASSERT(!s_instance, "Application already exists!"); + // Set singleton instance early s_instance = this; // Initialize diff --git a/inferno/src/inferno/application.h b/inferno/src/inferno/application.h index 7ece88f..25606a4 100644 --- a/inferno/src/inferno/application.h +++ b/inferno/src/inferno/application.h @@ -3,6 +3,8 @@ #include // std::unique_ptr, std::shared_ptr +#include "inferno/singleton.h" + namespace Inferno { class Event; @@ -14,9 +16,9 @@ namespace Inferno { class WindowCloseEvent; class WindowResizeEvent; - class Application { + class Application : public Singleton { public: - Application(); + Application(s); virtual ~Application(); int run(); @@ -31,8 +33,6 @@ namespace Inferno { inline Window& getWindow() const { return *m_window; } - static inline Application& the() { return *s_instance; } - private: int m_status { 0 }; float m_lastFrameTime { 0.0f }; @@ -42,12 +42,11 @@ namespace Inferno { // std::shared_ptr m_font; - - static Application* s_instance; + // }; // To be defined in the game - extern Application* createApplication(); + extern Application& createApplication(); } diff --git a/inferno/src/inferno/entrypoint.h b/inferno/src/inferno/entrypoint.h index d5b42d4..457f34d 100644 --- a/inferno/src/inferno/entrypoint.h +++ b/inferno/src/inferno/entrypoint.h @@ -15,11 +15,11 @@ int main(int argc, char* argv[]) (void)argc; (void)argv; - auto app = Inferno::createApplication(); + auto& app = Inferno::createApplication(); - int status = app->run(); + int status = app.run(); - delete app; + app.destroy(); return status; } diff --git a/inferno/src/inferno/singleton.h b/inferno/src/inferno/singleton.h new file mode 100644 index 0000000..670b2c3 --- /dev/null +++ b/inferno/src/inferno/singleton.h @@ -0,0 +1,55 @@ +#ifndef SINGLETON_H +#define SINGLETON_H + +#include "inferno/assert.h" + +namespace Inferno { + + template + class Singleton { + // Application is allowed to access its Singleton instance for early setting + friend class Application; + + public: + static inline void initialize() + { + ASSERT(!s_instance, "Singleton already exists!"); + s_instance = new T { s {} }; + } + + static inline void destroy() + { + ASSERT(s_instance, "Singleton does not exist!"); + delete s_instance; + s_instance = nullptr; + } + + static inline T& the() + { + ASSERT(s_instance, "Singleton does not exist!"); + return *s_instance; + } + + // Remove copy constructor and copy assignment operator + Singleton(const Singleton&) = delete; + Singleton& operator=(const Singleton&) = delete; + Singleton(Singleton&&) = delete; + Singleton& operator=(Singleton&&) = delete; + + protected: + Singleton() {} + + // Constructor token + struct s {}; + + private: + static T* s_instance; + }; + + template + T* Singleton::s_instance = nullptr; + +} // namespace Inferno + + +#endif // SINGLETON_H