Code: Select all
#include "system.h" // simple base class
using SystemID = std::size_t;
inline SystemID getUniqueSystemTypeID()
{
static SystemID cID = 0;
return cID++;
}
template <typename T>
inline SystemID getSystemTypeID() noexcept
{
static_assert(std::is_base_of<System, T>::value,
"T must must inherit from System");
static SystemID id = getUniqueSystemTypeID();
return id;
}
constexpr static SystemID maxSystems = 32;
using SystemBitSet = std::bitset<maxSystems>;
using SystemArray = std::array<System*, maxSystems>;
class SystemFactory
{
SystemBitSet m_systemBitset;
SystemArray m_systemArray;
std::vector < std::unique_ptr<System> > m_systems;
template <typename SystemType>
bool Has()const
{
return m_systemBitset[getSystemTypeID<SystemType>()];
}
public:
SystemFactory();
~SystemFactory();
template <typename SystemType, typename... SystemArgs>
SystemType& Make(SystemArgs&&... mArgs)
{
assert(!Has < SystemType >());
SystemType* sys(new SystemType(std::forward<SystemArgs>(mArgs)...));
std::unique_ptr<System> uPtr{ sys };
m_systems.emplace_back(std::move(uPtr));
m_systemArray[getSystemTypeID<SystemType>()] = sys;
m_systemBitset[getSystemTypeID<SystemType>()] = true;
return *sys;
}
template<typename SystemType>
SystemType* Get()
{
assert(Has < SystemType >());
return (SystemType*)m_systemArray[getSystemTypeID<SystemType>()];
}
};
Code: Select all
int WINAPI WinMain( HINSTANCE , HINSTANCE, LPSTR, int )
{
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if (SUCCEEDED(CoInitialize(NULL)))
{
m_sysFactory = MakeUnique<SystemFactory>();
// create in this order
m_sysFactory->Make<D2DWindow>(scrnW, scrnH);
Locator::SetGraphics(&m_sysFactory->Make<Renderer>());
Locator::SetSoundManager(&m_sysFactory->Make<SoundManager>());
Locator::SetTextManager(&m_sysFactory->Make<TextManager>());
Locator::SetImageManager(&m_sysFactory->Make<ImageManager>());
m_sysFactory->Make<Game>(*m_sysFactory->Get<D2DWindow>());
SimpleTimer timer;
timer.Reset();
bool ok = true;
while (ok)
{
timer.Update();
if ((ok = m_sysFactory->Get<D2DWindow>()->RunMessageLoop()))
ok = m_sysFactory->Get<Game>()->Play(timer);
}
CoUninitialize();
}
}