diff --git a/src/common/Service.cpp b/src/common/Service.cpp new file mode 100644 index 00000000..1894d5e2 --- /dev/null +++ b/src/common/Service.cpp @@ -0,0 +1,16 @@ +#include + +namespace Sapphire::Common +{ + ServiceContainer* ServiceContainer::pSvcContainer = nullptr; + + std::shared_ptr< void > ServiceContainer::get( size_t id ) + { + return serviceTable[ id ]; + } + + void ServiceContainer::set( size_t id, std::shared_ptr< void > svc ) + { + serviceTable[ id ] = std::move( svc ); + } +} \ No newline at end of file diff --git a/src/common/Service.h b/src/common/Service.h index 8cbb43a1..21913bd1 100644 --- a/src/common/Service.h +++ b/src/common/Service.h @@ -4,22 +4,34 @@ #include #include #include +#include // stolen from: https://github.com/skypjack/entt/blob/master/src/entt/locator/locator.hpp namespace Sapphire::Common { /** - * @brief Service locator, nothing more. - * - * A service locator can be used to do what it promises: locate services.
- * Usually service locators are tightly bound to the services they expose and - * thus it's hard to define a general purpose class to do that. This template - * based implementation tries to fill the gap and to get rid of the burden of - * defining a different specific locator for each application. - * - * @tparam SvcType Type of service managed by the locator. - */ + * @brief Service locator, nothing more. + * + * A service locator can be used to do what it promises: locate services.
+ * Usually service locators are tightly bound to the services they expose and + * thus it's hard to define a general purpose class to do that. This template + * based implementation tries to fill the gap and to get rid of the burden of + * defining a different specific locator for each application. + * + * Implementaion of the Service locator is replaced with a workaround for Visual Studio, api unchanged. + */ + + class ServiceContainer + { + private: + std::unordered_map< size_t, std::shared_ptr< void > > serviceTable; + public: + std::shared_ptr< void > get( size_t id ); + void set( size_t id, std::shared_ptr< void > svc ); + static ServiceContainer* pSvcContainer; + }; + template< typename SvcType > struct Service { @@ -38,6 +50,8 @@ namespace Sapphire::Common */ static bool empty() noexcept { + auto id = typeid( SvcType ).hash_code(); + auto service = ServiceContainer::pSvcContainer->get( id ); return !static_cast< bool >( service ); } @@ -53,6 +67,8 @@ namespace Sapphire::Common */ static std::weak_ptr< SvcType > get() noexcept { + auto id = typeid( SvcType ).hash_code(); + auto service = std::reinterpret_pointer_cast< SvcType >( ServiceContainer::pSvcContainer->get( id ) ); return service; } @@ -72,6 +88,8 @@ namespace Sapphire::Common */ static SvcType& ref() noexcept { + auto id = typeid( SvcType ).hash_code(); + auto service = std::reinterpret_pointer_cast< SvcType >( ServiceContainer::pSvcContainer->get( id ) ); return *service; } @@ -84,7 +102,9 @@ namespace Sapphire::Common template< typename Impl = SvcType, typename... Args > static void set( Args&& ... args ) { - service = std::make_shared< Impl >( std::forward< Args >( args )... ); + auto id = typeid( SvcType ).hash_code(); + std::shared_ptr< SvcType > ptr = std::make_shared< Impl >( std::forward< Args >( args )... ); + ServiceContainer::pSvcContainer->set( id, std::move( ptr ) ); } /** @@ -94,7 +114,8 @@ namespace Sapphire::Common static void set( std::shared_ptr< SvcType > ptr ) { assert( static_cast< bool >( ptr ) ); - service = std::move( ptr ); + auto id = typeid( SvcType ).hash_code(); + ServiceContainer::pSvcContainer->set( id, std::move( ptr ) ); } /** @@ -104,11 +125,9 @@ namespace Sapphire::Common */ static void reset() { - service.reset(); + auto id = typeid( SvcType ).hash_code(); + ServiceContainer::pSvcContainer->set( id, nullptr ); } - - private: - inline static std::shared_ptr< SvcType > service = nullptr; }; } diff --git a/src/scripts/ScriptLoader.cpp.in b/src/scripts/ScriptLoader.cpp.in index c68d5f5d..d23c98f4 100644 --- a/src/scripts/ScriptLoader.cpp.in +++ b/src/scripts/ScriptLoader.cpp.in @@ -1,4 +1,5 @@ #include