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:
parent
f2d81604a9
commit
eb30d66788
5 changed files with 58 additions and 19 deletions
16
src/common/Service.cpp
Normal file
16
src/common/Service.cpp
Normal 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 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,22 +4,34 @@
|
||||||
#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
|
||||||
|
|
||||||
namespace Sapphire::Common
|
namespace Sapphire::Common
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Service locator, nothing more.
|
* @brief Service locator, nothing more.
|
||||||
*
|
*
|
||||||
* A service locator can be used to do what it promises: locate services.<br/>
|
* A service locator can be used to do what it promises: locate services.<br/>
|
||||||
* Usually service locators are tightly bound to the services they expose and
|
* 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
|
* 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
|
* 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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Add table
Reference in a new issue