/********************************************************************* * \file SHSystemManager.h * \author Daniel Chua Yee Chen * \brief Declaration for the SHSystemManager class. * SHSystemManager is the interface class where users of the engine create * the systems that gives the components their functionality. This also ensures that the Init and Exit functions are ran at the appropriate time * * \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *********************************************************************/ #ifndef SH_SYSTEM_MANAGER_H #define SH_SYSTEM_MANAGER_H #include #include #include #include #include #include "../System/SHSystem.h" #include "../General/SHFamily.h" namespace SHADE { typedef uint32_t SystemTypeID; typedef uint32_t SystemVersionID; typedef uint64_t SystemID; typedef SHFamilyID SystemFamily; class SHSystemManager { //type definition for the container we use to store our system using SystemContainer = std::unordered_map>; private: static SystemContainer systemContainer; public: /*!************************************************************************* * This class is used as a static class. * No objects of this type should be created ***************************************************************************/ SHSystemManager() = delete; ~SHSystemManager() = delete; /************************************************************************** * \brief * Create a system of type T and map it to a name. * throws an error if a system with the same name already exists. * \param name * name of the system * \return * none ***************************************************************************/ template static std::enable_if_t, void> CreateSystem() { SystemTypeID typeID = SystemFamily::GetID(); SystemVersionID version = 0; SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID; while (systemContainer.find(id) != systemContainer.end()) { ++version; SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID; } systemContainer.emplace(id, std::make_unique()); } /************************************************************************** * \brief * Get a pointer to the System with a specified name. * \param name * Name of the system in the map * \return * Base System pointer. ***************************************************************************/ template static std::enable_if_t, T*> GetSystem(SystemVersionID version = 0) { SystemTypeID typeID = SystemFamily::GetID(); SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID; if (systemContainer.find(id) == systemContainer.end()) { std::cout << "System Manager error: System Version " << version << " does not exit." << std::endl; return nullptr; } return (T*)systemContainer.find(id)->second.get(); } /************************************************************************** * \brief * Call the Init function of all systems. * \return * none ***************************************************************************/ static void Init() noexcept; /************************************************************************** * \brief * Call the Exit function of all systems. * \return ***************************************************************************/ static void Exit() noexcept; protected: }; } #endif