QuasarAppLib/qaservice.h

160 lines
4.6 KiB
C
Raw Permalink Normal View History

2022-07-23 21:23:19 +03:00
/*
2024-12-30 22:39:49 +01:00
* Copyright (C) 2018-2025 QuasarApp.
2022-07-23 21:23:19 +03:00
* 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
2023-04-07 13:52:17 +02:00
#include <memory>
#include <utility>
2022-07-23 21:23:19 +03:00
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
2022-07-23 22:28:39 +03:00
*
* **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
2022-07-23 21:23:19 +03:00
*/
template<class Base>
class Service
{
2023-04-06 21:44:47 +02:00
2022-07-23 21:23:19 +03:00
public:
2022-08-21 22:25:59 +03:00
Service() {};
2022-07-23 21:23:19 +03:00
/**
2022-07-23 22:28:39 +03:00
* @brief initService This method initialize the @a Base object as a service.
2022-07-23 21:23:19 +03:00
* @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
2022-07-23 21:23:19 +03:00
*/
2023-08-16 13:34:40 +02:00
static inline std::unique_ptr<Base>& initService() {
2023-04-06 21:44:47 +02:00
auto& val = instancePrivat();
2023-04-07 13:52:17 +02:00
if(!val) {
val.reset(new Base());
2022-07-23 21:23:19 +03:00
}
2023-08-16 13:34:40 +02:00
return val;
2022-07-23 21:23:19 +03:00
}
2023-04-07 13:52:17 +02:00
/**
* @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<Base> obj) {
auto& val = instancePrivat();
if(!val) {
val = std::move(obj);
return true;
}
return false;
};
2022-07-23 21:23:19 +03:00
/**
* @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
2022-07-23 21:23:19 +03:00
*/
static Base* instance() {
2023-04-07 13:52:17 +02:00
return instancePrivat().get();
2022-07-23 21:23:19 +03:00
}
/**
* @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() {
2023-04-06 21:44:47 +02:00
auto& val = instancePrivat();
2023-04-07 13:52:17 +02:00
if (!val) {
initService();
}
2023-04-07 13:52:17 +02:00
return val.get();
}
2022-07-23 21:23:19 +03:00
/**
2022-07-23 22:28:39 +03:00
* @brief deinitService This is distructor method for the service.
2022-07-23 21:23:19 +03:00
* @note do nothink if this object alredy distroyed.
* @see instance
* @see initService
* @see autoInstance
2022-07-23 21:23:19 +03:00
*/
2022-07-23 22:28:39 +03:00
static void deinitService() {
2023-04-06 21:44:47 +02:00
auto& val = instancePrivat();
2023-04-07 13:52:17 +02:00
if(val) {
val.release();
2022-07-23 21:23:19 +03:00
}
}
private:
2023-04-07 13:52:17 +02:00
static inline std::unique_ptr<Base>& instancePrivat() {
static std::unique_ptr<Base> instance = nullptr;
2023-04-06 21:44:47 +02:00
return instance;
}
2022-07-23 21:23:19 +03:00
};
}
#endif // QASERVICE_H