Last active
December 10, 2015 14:58
-
-
Save LordJZ/4451246 to your computer and use it in GitHub Desktop.
C++ Service Locator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #ifndef _a553_services_services_h | |
| #define _a553_services_services_h | |
| #include <a553/internals.h> | |
| #include <a553/compiler.h> | |
| #pragma region private details | |
| #define _GET_SERVICE_FUNC(SERVICENAME) GetService_##SERVICENAME | |
| #define _GET_SERVICE_RET(SERVICENAME) SERVICENAME* | |
| #define _DEFINE_SERVICE(DECLSPEC, SERVICENAME, IMPLNAME, ...) \ | |
| a553_services_namespace_begin; \ | |
| DECLSPEC _GET_SERVICE_RET(SERVICENAME) \ | |
| _GET_SERVICE_FUNC(SERVICENAME)() \ | |
| { \ | |
| static IMPLNAME s_service_##IMPLNAME = \ | |
| std::move(IMPLNAME(__VA_ARGS__)); \ | |
| return &s_service_##IMPLNAME; \ | |
| } \ | |
| a553_services_namespace_end | |
| #define _REFERENCE_SERVICE(SERVICENAME) \ | |
| a553_services_namespace_begin; \ | |
| extern _GET_SERVICE_RET(SERVICENAME) \ | |
| _GET_SERVICE_FUNC(SERVICENAME)(); \ | |
| a553_services_namespace_end | |
| #define _SERVICE(SERVICENAME) \ | |
| (a553_services_namespace _GET_SERVICE_FUNC(SERVICENAME)()) | |
| #pragma endregion | |
| // Defines the specified service and exports it. | |
| #define DEFINE_SERVICE_DLL(SERVICENAME, IMPLNAME, ...) \ | |
| _DEFINE_SERVICE(DLLEXPORT, SERVICENAME, IMPLNAME, __VA_ARGS__) | |
| // Defines the specified service. | |
| #define DEFINE_SERVICE(SERVICENAME, IMPLNAME, ...) \ | |
| _DEFINE_SERVICE(, SERVICENAME, IMPLNAME, __VA_ARGS__) | |
| // References the specified service, allowing its usage. | |
| #define REFERENCE_SERVICE(SERVICENAME) _REFERENCE_SERVICE(SERVICENAME) | |
| // Ensures that the specified service is initialized. | |
| #define INIT_SERVICE(SERVICENAME) ((void)(SERVICE(SERVICENAME))) | |
| // Retrieves the specified service. The service must be referenced first. | |
| #define SERVICE(SERVICENAME) _SERVICE(SERVICENAME) | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "../testlib/testservice.h" | |
| REFERENCE_SERVICE(TestService); | |
| REFERENCE_SERVICE(DependentService); | |
| int main() | |
| { | |
| INIT_SERVICE(TestService); | |
| SERVICE(TestService)->DoSomething(); | |
| SERVICE(DependentService)->DoSomethingElse(); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <a553/services/services.h> | |
| class NOVTABLE TestService | |
| { | |
| public: | |
| // This method does something very, very important. | |
| virtual void DoSomething() = 0; | |
| }; | |
| class NOVTABLE DependentService | |
| { | |
| public: | |
| virtual void DoSomethingElse() = 0; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include "testservice_impl.h" | |
| #ifdef BUILDING_DLL | |
| DEFINE_SERVICE_DLL(TestService, TestServiceImpl); | |
| DEFINE_SERVICE_DLL(DependentService, DependentServiceImpl, SERVICE(TestService)); | |
| #else | |
| DEFINE_SERVICE(TestService, TestServiceImpl); | |
| DEFINE_SERVICE(DependentService, DependentServiceImpl, SERVICE(TestService)); | |
| #endif | |
| void TestServiceImpl::DoSomething() | |
| { | |
| std::cout << "void TestServiceImpl::DoSomething()" << std::endl; | |
| } | |
| void DependentServiceImpl::DoSomethingElse() | |
| { | |
| std::cout << "void DependentServiceImpl::DoSomethingElse()" << std::endl; | |
| this->m_testService->DoSomething(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "testservice.h" | |
| class TestServiceImpl : public TestService | |
| { | |
| public: | |
| void DoSomething() override; | |
| }; | |
| class DependentServiceImpl : public DependentService | |
| { | |
| TestService* m_testService; | |
| public: | |
| DependentServiceImpl(TestService* testService) | |
| : m_testService(testService) | |
| { | |
| } | |
| void DoSomethingElse() override; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment