mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-30 08:07: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 <utility>
|
||||
#include <cassert>
|
||||
#include <unordered_map>
|
||||
|
||||
// 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.<br/>
|
||||
* 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.<br/>
|
||||
* 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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <Script/NativeScriptApi.h>
|
||||
#include <Service.h>
|
||||
|
||||
@ScriptIncludes@
|
||||
|
||||
|
@ -8,7 +9,8 @@ const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <Config/ConfigMgr.h>
|
||||
#include <Util/Util.h>
|
||||
#include "ServerMgr.h"
|
||||
#include "Service.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
|
@ -95,7 +96,7 @@ Sapphire::Scripting::ScriptInfo* Sapphire::Scripting::ScriptLoader::loadModule(
|
|||
|
||||
Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScripts( ModuleHandle handle )
|
||||
{
|
||||
using getScripts = Sapphire::ScriptAPI::ScriptObject** ( * )();
|
||||
using getScripts = Sapphire::ScriptAPI::ScriptObject** ( * )( Common::ServiceContainer* );
|
||||
|
||||
#ifdef _WIN32
|
||||
getScripts func = reinterpret_cast< getScripts >( GetProcAddress( handle, "getScripts" ) );
|
||||
|
@ -105,7 +106,7 @@ Sapphire::ScriptAPI::ScriptObject** Sapphire::Scripting::ScriptLoader::getScript
|
|||
|
||||
if( func )
|
||||
{
|
||||
auto ptr = func();
|
||||
auto ptr = func( Common::ServiceContainer::pSvcContainer );
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ int main( int32_t argc, char* argv[] )
|
|||
{
|
||||
auto pServer = std::make_shared< ServerMgr >( "world.ini" );
|
||||
|
||||
Common::ServiceContainer::pSvcContainer = new Common::ServiceContainer();
|
||||
Common::Service< ServerMgr >::set( pServer );
|
||||
|
||||
pServer->run( argc, argv );
|
||||
|
|
Loading…
Add table
Reference in a new issue