diff options
Diffstat (limited to 'Src/replicant/nswasabi/singleton.h')
-rw-r--r-- | Src/replicant/nswasabi/singleton.h | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Src/replicant/nswasabi/singleton.h b/Src/replicant/nswasabi/singleton.h new file mode 100644 index 00000000..b31a68bc --- /dev/null +++ b/Src/replicant/nswasabi/singleton.h @@ -0,0 +1,117 @@ +#pragma once + +#include "service/ifc_servicefactory.h" + +/* +====== Usage ====== +disp_t: your Dispatchable base class +implt_t: your implementation class + +SingletonServiceFactory<disp_t, impl_t> myFactory; +impl_t myImplementation; + +//.... + +//during service registration +myFactory.Register(WASABI2_API_SVC, &myImplementation); + +//during service deregistration +myFactory.Deregister(WASABI2_API_SVC, &myImplementation); + +==== Class requirements ==== +your base or implementation class requires the following three static methods +static FOURCC getServiceType(); // return your type (e.g. WaSvc::UNIQUE)... might already be defined in the dispatchable base class +static const char *getServiceName(); // return your service name +static GUID getServiceGuid(); // return your service GUID +*/ + +class WasabiServiceFactory +{ +public: + virtual ~WasabiServiceFactory() {} + virtual void Register(api_service *serviceManager)=0; + virtual void Deregister(api_service *serviceManager)=0; +}; + + +template <class impl_t, class disp_t> +class SingletonServiceFactory : public ifc_serviceFactory +{ +public: + SingletonServiceFactory() : impl(0) + { + } + + ~SingletonServiceFactory() + { + } + + void Register(api_service *serviceManager, impl_t *new_impl) + { + impl=new_impl; + serviceManager->Register(this); + } + + void Deregister(api_service *serviceManager) + { + if (impl) + { + serviceManager->Unregister(this); + impl=0; + } + } + +private: + GUID WASABICALL ServiceFactory_GetServiceType() { return impl_t::GetServiceType(); } + nx_string_t WASABICALL ServiceFactory_GetServiceName() { return impl_t::GetServiceName(); } + GUID WASABICALL ServiceFactory_GetGUID() { return impl_t::GetServiceGUID(); } // GUID per service factory, can be INVALID_GUID + void *WASABICALL ServiceFactory_GetInterface() { return static_cast<disp_t *>(impl); } + int WASABICALL ServiceFactory_ServiceNotify(int msg, intptr_t param1 = 0, intptr_t param2 = 0) { return 0; } + +private: + impl_t *impl; + +}; + +/* same as above, but this one also constructs the implementation object itself + useful when: + 1) you don't need to ever access the implementation object yourself + 2) the implementation class requires no constructor parameters + + TODO: might want to change this to "new" the object during Register and "delete" during Deregister, + in case destruction during program termination isn't safe. +*/ +template <class impl_t, class disp_t> +class SingletonService : public ifc_serviceFactory, public WasabiServiceFactory +{ +public: + SingletonService() + { + } + + ~SingletonService() + { + } + + void Register(api_service *serviceManager) + { + serviceManager->Register(this); + } + + void Deregister(api_service *serviceManager) + { + serviceManager->Unregister(this); + } + +private: + GUID WASABICALL ServiceFactory_GetServiceType() { return impl_t::GetServiceType(); } + nx_string_t WASABICALL ServiceFactory_GetServiceName() { return impl_t::GetServiceName(); } + GUID WASABICALL ServiceFactory_GetGUID() { return impl_t::GetServiceGUID(); } // GUID per service factory, can be INVALID_GUID + void *WASABICALL ServiceFactory_GetInterface() { return static_cast<disp_t *>(&impl); } + int WASABICALL ServiceFactory_ServiceNotify(int msg, intptr_t param1 = 0, intptr_t param2 = 0) { return 0; } + +private: + impl_t impl; + +}; + |