1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 16:17:46 +00:00

Service locator workaround for Visual Studio.

This commit is contained in:
collett 2023-02-07 06:39:42 +09:00
parent f2d81604a9
commit eb30d66788
5 changed files with 58 additions and 19 deletions

16
src/common/Service.cpp Normal file
View file

@ -0,0 +1,16 @@
#include <Service.h>
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 );
}
}

View file

@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <cassert> #include <cassert>
#include <unordered_map>
// stolen from: https://github.com/skypjack/entt/blob/master/src/entt/locator/locator.hpp // stolen from: https://github.com/skypjack/entt/blob/master/src/entt/locator/locator.hpp
@ -18,8 +19,19 @@ namespace Sapphire::Common
* based implementation tries to fill the gap and to get rid of the burden of * based implementation tries to fill the gap and to get rid of the burden of
* defining a different specific locator for each application. * defining a different specific locator for each application.
* *
* @tparam SvcType Type of service managed by the locator. * 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 > template< typename SvcType >
struct Service struct Service
{ {
@ -38,6 +50,8 @@ namespace Sapphire::Common
*/ */
static bool empty() noexcept static bool empty() noexcept
{ {
auto id = typeid( SvcType ).hash_code();
auto service = ServiceContainer::pSvcContainer->get( id );
return !static_cast< bool >( service ); return !static_cast< bool >( service );
} }
@ -53,6 +67,8 @@ namespace Sapphire::Common
*/ */
static std::weak_ptr< SvcType > get() noexcept 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; return service;
} }
@ -72,6 +88,8 @@ namespace Sapphire::Common
*/ */
static SvcType& ref() noexcept static SvcType& ref() noexcept
{ {
auto id = typeid( SvcType ).hash_code();
auto service = std::reinterpret_pointer_cast< SvcType >( ServiceContainer::pSvcContainer->get( id ) );
return *service; return *service;
} }
@ -84,7 +102,9 @@ namespace Sapphire::Common
template< typename Impl = SvcType, typename... Args > template< typename Impl = SvcType, typename... Args >
static void set( Args&& ... 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 ) static void set( std::shared_ptr< SvcType > ptr )
{ {
assert( static_cast< bool >( 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() 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;
}; };
} }

View file

@ -1,4 +1,5 @@
#include <Script/NativeScriptApi.h> #include <Script/NativeScriptApi.h>
#include <Service.h>
@ScriptIncludes@ @ScriptIncludes@
@ -8,7 +9,8 @@ const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
nullptr nullptr
}; };
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts() extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts( Sapphire::Common::ServiceContainer* pSc )
{ {
Sapphire::Common::ServiceContainer::pSvcContainer = pSc;
return ptrs; return ptrs;
} }

View file

@ -4,6 +4,7 @@
#include <Config/ConfigMgr.h> #include <Config/ConfigMgr.h>
#include <Util/Util.h> #include <Util/Util.h>
#include "ServerMgr.h" #include "ServerMgr.h"
#include "Service.h"
#include <filesystem> #include <filesystem>
@ -95,7 +96,7 @@ Sapphire::Scripting::ScriptInfo* Sapphire::Scripting::ScriptLoader::loadModule(
Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScripts( ModuleHandle handle ) Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScripts( ModuleHandle handle )
{ {
using getScripts = Sapphire::ScriptAPI::ScriptObject** ( * )(); using getScripts = Sapphire::ScriptAPI::ScriptObject** ( * )( Common::ServiceContainer* );
#ifdef _WIN32 #ifdef _WIN32
getScripts func = reinterpret_cast< getScripts >( GetProcAddress( handle, "getScripts" ) ); getScripts func = reinterpret_cast< getScripts >( GetProcAddress( handle, "getScripts" ) );
@ -105,7 +106,7 @@ Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScript
if( func ) if( func )
{ {
auto ptr = func(); auto ptr = func( Common::ServiceContainer::pSvcContainer );
return ptr; return ptr;
} }

View file

@ -15,6 +15,7 @@ int main( int32_t argc, char* argv[] )
{ {
auto pServer = std::make_shared< ServerMgr >( "world.ini" ); auto pServer = std::make_shared< ServerMgr >( "world.ini" );
Common::ServiceContainer::pSvcContainer = new Common::ServiceContainer();
Common::Service< ServerMgr >::set( pServer ); Common::Service< ServerMgr >::set( pServer );
pServer->run( argc, argv ); pServer->run( argc, argv );