/* * Copyright (C) 2018-2022 QuasarApp. * Distributed under the lgplv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ #ifndef QASERVICE_H #define QASERVICE_H #include <utility> namespace QuasarAppUtils { /** * @brief The Service class is a template class for creating a singleton services objects. * This is manual control wrapper. You should be manually initializing your service object and manually deinitializing. * If you don't destroy your service, then service object will be automatically destroyed when application will be closed. * @warning If service was destroyed automatically, then destructor of your base class will be not invoked. Use The deinit method for this. * @todo Remove the template Base class. Instead, it needs to use a general inherit paradigm * * **Examples** * * **Create a service class** * * @code{cpp} * * #include <qaservice.h> * * class MyService: public QuasarAppUtils::Service<MyService> {\ * // some implementation * }; * * @endcode * * **Initialise a service object** * * @code{cpp} * * #include <MyService.h> * * // initialise service * MyService* serviceInstance = MyService::initService(); * * // get service instance. * serviceInstance = MyService::instance(); * * // remove service instance object. * MyService::deinitService(); * * @endcode * * * Or you can use the autoInstance method for initialize instance object if not exists. * @note This method try initialize base instance object use default construct. * * @code{cpp} * * #include <MyService.h> * * // initialise service * MyService* serviceInstance = MyService::autoInstance(); * * @endcode */ template<class Base> class Service { public: Service() {}; /** * @brief initService This method initialize the @a Base object as a service. * @param args This is argumets of a constructo of the @a Base class. * @return instance pointer. If the service alredy initialized then return pointer to current service object. * @see instance * @see deinitService * @see autoInstance */ template<class BaseClass = Base, class... Args> static Base* initService(Args&&... args) { Service<Base>* instanceObj = privateInstance(); if(!instanceObj->_data) { instanceObj->_data = new BaseClass(std::forward<Args>(args)...); } return instanceObj->_data; } /** * @brief instance This method return pointerer to current service object. * @note If object was not initialized, then return false. * @return pointerer to current service object if service initialized else nullptr. * @see initService * @see deinitService * @see autoInstance */ static Base* instance() { return privateInstance()->_data; } /** * @brief autoInstance This method return pointerer to current service object and if it is not inited try to initialize it use default constructor. * @return pointerer to current service object if service initialized else nullptr. * @see instance */ static Base* autoInstance() { if (!privateInstance()->_data) { initService(); } return privateInstance()->_data; } /** * @brief deinitService This is distructor method for the service. * @note do nothink if this object alredy distroyed. * @see instance * @see initService * @see autoInstance */ static void deinitService() { Service<Base>* instanceObj = privateInstance(); if(instanceObj->_data) { delete instanceObj->_data; instanceObj->_data = nullptr; } } private: static Service<Base>* privateInstance() { static Service<Base>* privateObject = new Service<Base>; return privateObject; }; Base* _data = nullptr; }; } #endif // QASERVICE_H