/* * Copyright (C) 2018-2024 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 #include 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 * * class MyService: public QuasarAppUtils::Service {\ * // some implementation * }; * * @endcode * * **Initialise a service object** * * @code{cpp} * * #include * * // 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 * * // initialise service * MyService* serviceInstance = MyService::autoInstance(); * * @endcode */ template 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 */ static inline std::unique_ptr& initService() { auto& val = instancePrivat(); if(!val) { val.reset(new Base()); } return val; } /** * @brief initService This is overrided static method of initialization cross libraryes object. * @note If you want to create your own implementation of the settings object - you need to use this method for initioalisation instant qaservice::initService - template method. * Becouse Some OS has every shared libraryes has itself isolation address space (for example Android). * If you initialize instance of your settings model on one libarary the this instance will be available only on your library or upper. * Bot not on the QuasarApp lib so SettingsListner will not work. * @param obj This is inited settings object. * @return true if the @a obj service was saved as a service object else false. */ static bool initService(std::unique_ptr obj) { auto& val = instancePrivat(); if(!val) { val = std::move(obj); return true; } return false; }; /** * @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 instancePrivat().get(); } /** * @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() { auto& val = instancePrivat(); if (!val) { initService(); } return val.get(); } /** * @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() { auto& val = instancePrivat(); if(val) { val.release(); } } private: static inline std::unique_ptr& instancePrivat() { static std::unique_ptr instance = nullptr; return instance; } }; } #endif // QASERVICE_H