#pragma once #include "CoreDefs.h" #include namespace GpDriverIDs { enum GpDriverID { kAudio, kFileSystem, kDisplay, kLog, kInput, kSystemServices, kFont, kEventQueue, kCount }; } typedef GpDriverIDs::GpDriverID GpDriverID_t; template struct GpDriverIndex { }; #define GP_DEFINE_DRIVER(driverID, type) \ struct type;\ template<>\ struct GpDriverIndex\ {\ typedef type Type_t;\ static const bool kIsMultiDriver = false;\ } #define GP_DEFINE_MULTI_DRIVER(driverID, type) \ struct type;\ template<>\ struct GpDriverIndex\ {\ typedef type Type_t;\ static const bool kIsMultiDriver = true;\ } GP_DEFINE_DRIVER(kAudio, IGpAudioDriver); GP_DEFINE_DRIVER(kFileSystem, IGpFileSystem); GP_DEFINE_DRIVER(kDisplay, IGpDisplayDriver); GP_DEFINE_DRIVER(kLog, IGpLogDriver); GP_DEFINE_MULTI_DRIVER(kInput, IGpInputDriver); GP_DEFINE_DRIVER(kSystemServices, IGpSystemServices); GP_DEFINE_DRIVER(kFont, IGpFontHandler); GP_DEFINE_DRIVER(kEventQueue, IGpVOSEventQueue); struct GpDriverCollection { GpDriverCollection(); template void SetDriver(typename GpDriverIndex::Type_t *driver); template void SetDrivers(typename GpDriverIndex::Type_t *const* drivers, size_t numDrivers); template typename GpDriverIndex::Type_t *GetDriver() const; template typename GpDriverIndex::Type_t *GetDriver(size_t index) const; template size_t GetDriverCount() const; private: struct DriverEntry { void *m_value; size_t m_numDrivers; }; DriverEntry m_drivers[GpDriverIDs::kCount]; }; inline GpDriverCollection::GpDriverCollection() { for (int i = 0; i < GpDriverIDs::kCount; i++) { this->m_drivers[i].m_value = nullptr; this->m_drivers[i].m_numDrivers = 0; } } template void GpDriverCollection::SetDriver(typename GpDriverIndex::Type_t *driver) { GP_STATIC_ASSERT(!GpDriverIndex::kIsMultiDriver); m_drivers[T].m_numDrivers = 1; m_drivers[T].m_value = driver; } template void GpDriverCollection::SetDrivers(typename GpDriverIndex::Type_t *const* drivers, size_t numDrivers) { GP_STATIC_ASSERT(GpDriverIndex::kIsMultiDriver); m_drivers[T].m_numDrivers = numDrivers; m_drivers[T].m_value = const_cast::Type_t **>(drivers); } template inline typename GpDriverIndex::Type_t *GpDriverCollection::GetDriver() const { GP_STATIC_ASSERT(!GpDriverIndex::kIsMultiDriver); return static_cast::Type_t*>(this->m_drivers[T].m_value); } template inline typename GpDriverIndex::Type_t *GpDriverCollection::GetDriver(size_t index) const { GP_STATIC_ASSERT(GpDriverIndex::kIsMultiDriver); return static_cast::Type_t*const*>(this->m_drivers[T].m_value)[index]; } template size_t GpDriverCollection::GetDriverCount() const { GP_STATIC_ASSERT(GpDriverIndex::kIsMultiDriver); return this->m_drivers[T].m_numDrivers; }