From 69498e062ae3a89f0754b03bbfa9e6d79d72ffec Mon Sep 17 00:00:00 2001 From: APTX Date: Sun, 22 Jun 2014 11:36:59 +0200 Subject: [PATCH] Add Service and ServiceManager. LML has 3 "services": RequestHandler, RenameHandler and DirectoryWatcher. Now they have a common base class and a manager. --- anioni/anioni.cpp | 9 +- localmylist/directorywatcher.cpp | 37 ++++++- localmylist/directorywatcher.h | 11 +- localmylist/include/LocalMyList/Service | 2 + .../include/LocalMyList/ServiceManager | 2 + localmylist/localmylist.pro | 10 +- localmylist/mylist.cpp | 37 +++---- localmylist/mylist.h | 10 +- localmylist/renamehandler.cpp | 41 +++++-- localmylist/renamehandler.h | 11 +- localmylist/requesthandler.cpp | 40 +++++-- localmylist/requesthandler.h | 9 +- localmylist/service.cpp | 98 +++++++++++++++++ localmylist/service.h | 87 +++++++++++++++ localmylist/servicemanager.cpp | 103 ++++++++++++++++++ localmylist/servicemanager.h | 61 +++++++++++ 16 files changed, 507 insertions(+), 61 deletions(-) create mode 100644 localmylist/include/LocalMyList/Service create mode 100644 localmylist/include/LocalMyList/ServiceManager create mode 100644 localmylist/service.cpp create mode 100644 localmylist/service.h create mode 100644 localmylist/servicemanager.cpp create mode 100644 localmylist/servicemanager.h diff --git a/anioni/anioni.cpp b/anioni/anioni.cpp index 8e403bf..48f345f 100644 --- a/anioni/anioni.cpp +++ b/anioni/anioni.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include #ifndef LOCALMYLIST_NO_ANIDBUDPCLIENT # include @@ -112,8 +114,7 @@ void AniOni::start() connect(AniDBUdpClient::Client::instance(), SIGNAL(connectionError()), this, SLOT(handleUdpClientError())); LocalMyList::instance()->setupRequestHandler(); - LocalMyList::instance()->requestHandler()->handleRequests(); - LocalMyList::instance()->requestHandler()->handleMyListUpdates(); + LocalMyList::instance()->serviceManager()->processRequests("RequestHandler"); #else log(QString("AniOni was configured to run the UDP client, but LocalMyList is not compiled with the UDP client." " Recompile LocalMyList with AniDBUdpClient"), QtServiceBase::Error); @@ -130,12 +131,12 @@ void AniOni::start() if (watchDirectories) { LocalMyList::instance()->setupDirectoryWatcher(); - LocalMyList::instance()->directoryWatcher()->checkWatchedDirectories(); + LocalMyList::instance()->serviceManager()->processRequests("DirectoryWatcher"); } if (!(runUdpClient || runRenameHandler || watchDirectories)) { - log(QString("AniOni was configured to do nothing. Check settings"), QtServiceBase::Error); + log(QString("AniOni was configured to do nothing. Check settings."), QtServiceBase::Error); application()->exit(1); return; } diff --git a/localmylist/directorywatcher.cpp b/localmylist/directorywatcher.cpp index 3418eff..ff07ac7 100644 --- a/localmylist/directorywatcher.cpp +++ b/localmylist/directorywatcher.cpp @@ -14,15 +14,11 @@ namespace LocalMyList { DirectoryWatcher::DirectoryWatcher(Database *db, Settings *settings, QObject *parent) : - QObject(parent) + Service("DirectoryWatcher", parent) { this->db = db; this->settings = settings; - - watcher = new QFileSystemWatcher(); - connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watchedDirectoryChanged(QString)), Qt::QueuedConnection); - - setWatchedDirectories(); + watcher = 0; } DirectoryWatcher::~DirectoryWatcher() @@ -87,4 +83,33 @@ void DirectoryWatcher::checkWatchedDirectories() watchedDirectoryChanged(dir); } +void DirectoryWatcher::doInit() +{ + watcher = new QFileSystemWatcher(); +} + +void DirectoryWatcher::doDeInit() +{ + delete watcher; + watcher = 0; +} + +bool DirectoryWatcher::doStart() +{ + connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watchedDirectoryChanged(QString)), Qt::QueuedConnection); + + setWatchedDirectories(); + return true; +} + +void LocalMyList::DirectoryWatcher::doStop() +{ + disconnect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watchedDirectoryChanged(QString))); +} + +void DirectoryWatcher::doProcessRequests() +{ + checkWatchedDirectories(); +} + } // namespace LocalMyList diff --git a/localmylist/directorywatcher.h b/localmylist/directorywatcher.h index fd2f350..d81f629 100644 --- a/localmylist/directorywatcher.h +++ b/localmylist/directorywatcher.h @@ -2,7 +2,7 @@ #define DIRECTORYWATCHER_H #include "localmylist_global.h" -#include +#include "service.h" #include #include @@ -13,7 +13,7 @@ namespace LocalMyList { class Database; class Settings; -class LOCALMYLISTSHARED_EXPORT DirectoryWatcher : public QObject +class LOCALMYLISTSHARED_EXPORT DirectoryWatcher : public Service { Q_OBJECT public: @@ -29,6 +29,13 @@ public slots: void checkWatchedDirectories(); +protected: + void doInit(); + void doDeInit(); + bool doStart(); + void doStop(); + void doProcessRequests(); + private: Database *db; Settings *settings; diff --git a/localmylist/include/LocalMyList/Service b/localmylist/include/LocalMyList/Service new file mode 100644 index 0000000..c1bedfb --- /dev/null +++ b/localmylist/include/LocalMyList/Service @@ -0,0 +1,2 @@ +#include "../../service.h" + diff --git a/localmylist/include/LocalMyList/ServiceManager b/localmylist/include/LocalMyList/ServiceManager new file mode 100644 index 0000000..54f91e5 --- /dev/null +++ b/localmylist/include/LocalMyList/ServiceManager @@ -0,0 +1,2 @@ +#include "../../servicemanager.h" + diff --git a/localmylist/localmylist.pro b/localmylist/localmylist.pro index 98e4063..0d67082 100644 --- a/localmylist/localmylist.pro +++ b/localmylist/localmylist.pro @@ -34,13 +34,15 @@ SOURCES += \ filelocationchecktask.cpp \ messagehandler.cpp \ asyncquerytask.cpp \ + service.cpp \ + servicemanager.cpp \ dynamicmodel/data.cpp \ dynamicmodel/node.cpp \ dynamicmodel/model.cpp \ dynamicmodel/datatype.cpp \ dynamicmodel/types.cpp \ dynamicmodel/datamodel.cpp \ - dynamicmodel/typerelation.cpp + dynamicmodel/typerelation.cpp HEADERS += \ localmylist_global.h \ @@ -68,6 +70,8 @@ HEADERS += \ asyncquerytask.h \ filelocationchecktask.h \ sqlresultiteratorinterface.h \ + service.h \ + servicemanager.h \ dynamicmodel/data.h \ dynamicmodel/node.h \ dynamicmodel/model.h \ @@ -75,7 +79,7 @@ HEADERS += \ dynamicmodel/dynamicmodel_global.h \ dynamicmodel/types.h \ dynamicmodel/datamodel.h \ - dynamicmodel/typerelation.h + dynamicmodel/typerelation.h CONV_HEADERS += \ include/LocalMyList/AbstractTask \ @@ -89,6 +93,8 @@ CONV_HEADERS += \ include/LocalMyList/MyListExportParseTask \ include/LocalMyList/MyListModel \ include/LocalMyList/MyListNode \ + include/LocalMyList/Service \ + include/LocalMyList/ServiceManager \ include/LocalMyList/Settings \ include/LocalMyList/UnknownFileLookupTask \ include/LocalMyList/UnknownFileLookupTask \ diff --git a/localmylist/mylist.cpp b/localmylist/mylist.cpp index 39cfc70..216314f 100644 --- a/localmylist/mylist.cpp +++ b/localmylist/mylist.cpp @@ -13,6 +13,8 @@ #include "asyncquerytask.h" #include "workthread.h" #include "messagehandler.h" +#include "servicemanager.h" +#include "service.h" #ifndef LOCALMYLIST_NO_ANIDBUDPCLIENT # include "requesthandler.h" # include "renamehandler.h" @@ -27,14 +29,12 @@ MyList::MyList() { init(); - m_requestHandler = 0; - m_renameHandler = 0; - m_directoryWatcher = 0; workThread = 0; m_defaultLocalQSettings = new QSettings(QSettings::IniFormat, QSettings::UserScope, organizationName, libraryName, this); db = new Database(); connect(db, SIGNAL(connected()), this, SLOT(setupHostInfo())); m_settings = new Settings(db, this); + m_serviceManager = new ServiceManager(this); m_udpClientId = 0; } @@ -98,14 +98,9 @@ Settings *MyList::settings() const return m_settings; } -RequestHandler *MyList::requestHandler() const +ServiceManager *MyList::serviceManager() const { - return m_requestHandler; -} - -DirectoryWatcher *MyList::directoryWatcher() const -{ - return m_directoryWatcher; + return m_serviceManager; } // ------- @@ -204,34 +199,38 @@ void MyList::setupUdpClient() void MyList::setupRequestHandler() { #ifndef LOCALMYLIST_NO_ANIDBUDPCLIENT - if (m_requestHandler || !db->isConnected() || !udpClientId()) + if (m_serviceManager->hasService("RequestHandler") || !db->isConnected() || !udpClientId()) return; - m_requestHandler = new RequestHandler(db, this); - connect(db, SIGNAL(newPendingRequest()), m_requestHandler, SLOT(handleRequests())); - connect(db, SIGNAL(newPendingMyListUpdate()), m_requestHandler, SLOT(handleMyListUpdates())); + Service *service = new RequestHandler(db, this); + m_serviceManager->addService(service); + service->start(); #endif } void MyList::setupRenameHandler() { #ifndef LOCALMYLIST_NO_ANIDBUDPCLIENT - if (m_renameHandler || !db->isConnected()) + if (m_serviceManager->hasService("RenameHandler") || !db->isConnected()) return; setupWorkThread(); - m_renameHandler = new RenameHandler(workThread->database(), workThread->settings()); - m_renameHandler->moveToThread(workThread); + Service *service = new RenameHandler(workThread->database(), workThread->settings()); + service->moveToThread(workThread); + m_serviceManager->addService(service); + service->start(); #endif } void MyList::setupDirectoryWatcher() { - if (m_directoryWatcher || !db->isConnected()) + if (m_serviceManager->hasService("DirectoryWatcher") || !db->isConnected()) return; - m_directoryWatcher = new DirectoryWatcher(db, m_settings); + Service *service = new DirectoryWatcher(db, m_settings); + m_serviceManager->addService(service); + service->start(); } void MyList::setupWorkThread() diff --git a/localmylist/mylist.h b/localmylist/mylist.h index b744341..b53fe6f 100644 --- a/localmylist/mylist.h +++ b/localmylist/mylist.h @@ -16,6 +16,7 @@ namespace LocalMyList { class Settings; class AbstractTask; class WorkThread; +class ServiceManager; class RequestHandler; class RenameHandler; class DirectoryWatcher; @@ -25,7 +26,7 @@ class LOCALMYLISTSHARED_EXPORT MyList : public QObject Q_OBJECT Q_PROPERTY(LocalMyList::Database *database READ database) Q_PROPERTY(LocalMyList::Settings *settings READ settings) - Q_PROPERTY(LocalMyList::RequestHandler *requestHandler READ requestHandler) + Q_PROPERTY(LocalMyList::ServiceManager *serviceManager READ serviceManager) Q_PROPERTY(QString hostName READ hostName WRITE setHostName) Q_PROPERTY(int hostId READ hostId) Q_PROPERTY(bool isUdpHost READ isUdpHost) @@ -38,8 +39,7 @@ public: LocalMyList::Database *database() const; LocalMyList::Settings *settings() const; - LocalMyList::RequestHandler *requestHandler() const; - LocalMyList::DirectoryWatcher *directoryWatcher() const; + LocalMyList::ServiceManager *serviceManager() const; QString hostName() const; void setHostName(QString name); @@ -95,9 +95,7 @@ private: DatabaseConnectionSettings dbs; Database *db; WorkThread *workThread; - RequestHandler *m_requestHandler; - RenameHandler *m_renameHandler; - DirectoryWatcher *m_directoryWatcher; + ServiceManager *m_serviceManager; Settings *m_settings; HostInfo hostInfo; diff --git a/localmylist/renamehandler.cpp b/localmylist/renamehandler.cpp index f7bd721..7cca535 100644 --- a/localmylist/renamehandler.cpp +++ b/localmylist/renamehandler.cpp @@ -13,14 +13,10 @@ namespace LocalMyList { RenameHandler::RenameHandler(Database *db, Settings *settings, QObject *parent) : - QObject(parent), renameEngine(0), validScript(false) + Service("RenameHandler", parent), renameEngine(0), validScript(false) { this->db = db; this->settings = settings; - connect(db, SIGNAL(renameDataChanged()), this, SLOT(handleRename()), Qt::QueuedConnection); - connect(this, SIGNAL(renameBatchFinished()), this, SLOT(handleRename()), Qt::QueuedConnection); - connect(settings, SIGNAL(settingsChanged()), this, SLOT(clearSetup())); - connect(db, SIGNAL(reconnected()), this, SLOT(handleRename()), Qt::QueuedConnection); m_setup = false; } @@ -33,12 +29,13 @@ void RenameHandler::handleRename() { RaiiTransaction t(db); - QSqlQuery &q = db->prepare( - "SELECT * " - "FROM rename_data " - "WHERE host_id = :host_id " - "AND renamed IS NULL AND failed_rename = false " - "LIMIT :limit"); + QSqlQuery &q = db->prepare(R"( + SELECT * + FROM rename_data + WHERE host_id = :host_id + AND renamed IS NULL AND failed_rename = false + LIMIT :limit + )"); q.bindValue(":host_id", MyList::instance()->hostId()); q.bindValue(":limit", 1); @@ -271,4 +268,26 @@ void RenameHandler::setupRenameEngine() m_setup = true; } +bool RenameHandler::doStart() +{ + connect(db, SIGNAL(renameDataChanged()), this, SLOT(handleRename()), Qt::QueuedConnection); + connect(this, SIGNAL(renameBatchFinished()), this, SLOT(handleRename()), Qt::QueuedConnection); + connect(settings, SIGNAL(settingsChanged()), this, SLOT(clearSetup())); + connect(db, SIGNAL(reconnected()), this, SLOT(handleRename()), Qt::QueuedConnection); + return true; +} + +void RenameHandler::doStop() +{ + disconnect(db, SIGNAL(renameDataChanged()), this, SLOT(handleRename())); + disconnect(this, SIGNAL(renameBatchFinished()), this, SLOT(handleRename())); + disconnect(settings, SIGNAL(settingsChanged()), this, SLOT(clearSetup())); + disconnect(db, SIGNAL(reconnected()), this, SLOT(handleRename())); +} + +void RenameHandler::doProcessRequests() +{ + handleRename(); +} + } // namespace LocalMyList diff --git a/localmylist/renamehandler.h b/localmylist/renamehandler.h index c2411dd..35d8769 100644 --- a/localmylist/renamehandler.h +++ b/localmylist/renamehandler.h @@ -2,7 +2,7 @@ #define RENAMEHANDLER_H #include "localmylist_global.h" -#include +#include "service.h" namespace RenameParser { class RenameEngine; @@ -13,12 +13,12 @@ namespace LocalMyList { class Database; class Settings; -class RenameHandler : public QObject +class RenameHandler : public Service { Q_OBJECT public: explicit RenameHandler(Database *db, Settings *settings, QObject *parent = 0); - + bool isSetup(); signals: @@ -30,6 +30,11 @@ public slots: void clearSetup(); void setupRenameEngine(); +protected: + bool doStart(); + void doStop(); + void doProcessRequests(); + private: Database *db; Settings *settings; diff --git a/localmylist/requesthandler.cpp b/localmylist/requesthandler.cpp index 1327682..f5d8392 100644 --- a/localmylist/requesthandler.cpp +++ b/localmylist/requesthandler.cpp @@ -16,15 +16,9 @@ namespace LocalMyList { RequestHandler::RequestHandler(Database *db, QObject *parent) : - QObject(parent) + Service("RequestHandler", parent) { this->db = db; - connect(this, SIGNAL(batchFinished()), this, SLOT(handleRequests()), Qt::QueuedConnection); - connect(this, SIGNAL(myListUpdateBatchFinished()), this, SLOT(handleMyListUpdates()), Qt::QueuedConnection); - connect(db, SIGNAL(reconnected()), this, SLOT(handleRequests()), Qt::QueuedConnection); - connect(db, SIGNAL(reconnected()), this, SLOT(handleMyListUpdates()), Qt::QueuedConnection); - - db->failPendingRequestsFromOldClients(); } void RequestHandler::handleRequests() @@ -213,6 +207,38 @@ void RequestHandler::handleMyListUpdates() emit myListUpdateBatchFinished(); } +bool RequestHandler::doStart() +{ + connect(this, SIGNAL(batchFinished()), this, SLOT(handleRequests()), Qt::QueuedConnection); + connect(this, SIGNAL(myListUpdateBatchFinished()), this, SLOT(handleMyListUpdates()), Qt::QueuedConnection); + connect(db, SIGNAL(reconnected()), this, SLOT(handleRequests()), Qt::QueuedConnection); + connect(db, SIGNAL(reconnected()), this, SLOT(handleMyListUpdates()), Qt::QueuedConnection); + + + connect(db, SIGNAL(newPendingRequest()), this, SLOT(handleRequests())); + connect(db, SIGNAL(newPendingMyListUpdate()), this, SLOT(handleMyListUpdates())); + + db->failPendingRequestsFromOldClients(); + return true; +} + +void RequestHandler::doStop() +{ + disconnect(this, SIGNAL(batchFinished()), this, SLOT(handleRequests())); + disconnect(this, SIGNAL(myListUpdateBatchFinished()), this, SLOT(handleMyListUpdates())); + disconnect(db, SIGNAL(reconnected()), this, SLOT(handleRequests())); + disconnect(db, SIGNAL(reconnected()), this, SLOT(handleMyListUpdates())); + + disconnect(db, SIGNAL(newPendingRequest()), this, SLOT(handleRequests())); + disconnect(db, SIGNAL(newPendingMyListUpdate()), this, SLOT(handleMyListUpdates())); +} + +void RequestHandler::doProcessRequests() +{ + handleRequests(); + handleMyListUpdates(); +} + void RequestHandler::animeRequestComplete(bool success) { using namespace ::AniDBUdpClient; diff --git a/localmylist/requesthandler.h b/localmylist/requesthandler.h index adb2e20..dce243c 100644 --- a/localmylist/requesthandler.h +++ b/localmylist/requesthandler.h @@ -2,6 +2,7 @@ #define REQUESTHANDLER_H #include "localmylist_global.h" +#include "service.h" #include #include #include @@ -19,7 +20,7 @@ namespace LocalMyList { class Database; -class LOCALMYLISTSHARED_EXPORT RequestHandler : public QObject +class LOCALMYLISTSHARED_EXPORT RequestHandler : public Service { Q_OBJECT public: @@ -33,6 +34,11 @@ public slots: void handleRequests(); void handleMyListUpdates(); +protected: + bool doStart(); + void doStop(); + void doProcessRequests(); + private slots: void animeRequestComplete(bool success); void episodeRequestComplete(bool success); @@ -41,6 +47,7 @@ private slots: void myListAddReplyComplete(bool success); void myListEditReplyComplete(bool success); void myListUpdateVoteReplyComplete(bool success); + private: Database *db; diff --git a/localmylist/service.cpp b/localmylist/service.cpp new file mode 100644 index 0000000..9934cc4 --- /dev/null +++ b/localmylist/service.cpp @@ -0,0 +1,98 @@ +#include "service.h" + +#include +#include "mylist.h" + +namespace LocalMyList { + +Service::Service(const QString &name, QObject *parent) : + QObject{parent}, m_state{Stopped}, m_name{name} +{ +} + +Service::~Service() +{ + stop(); + deinitialize(); +} + +Service::ServiceState Service::state() const +{ + return m_state; +} + + +QString Service::name() const +{ + return m_name; +} + +void Service::start() +{ + if (m_state == Running) + return; + if (m_state == Uninitialized) + { + initAndStart(); + return; + } + if (m_state != Stopped || m_state != Error) + return; + tryStart(); +} + +void Service::stop() +{ + if (m_state != Running) + return; + + qDebug() << "Stopping service" << name(); + doStop(); + setState(Stopped); +} + +void Service::deinitialize() +{ + if (m_state != Stopped || m_state != Error) + return; + doDeInit(); + setState(Uninitialized); +} + +void Service::processRequests() +{ + if (m_state != Running) + return; + + doProcessRequests(); +} + +void Service::setState(Service::ServiceState state) +{ + if (m_state == state) + return; + m_state = state; + emit stateChanged(state); +} + +void Service::initAndStart() +{ + doInit(); + setState(Stopped); + tryStart(); +} + +void Service::tryStart() +{ + qDebug() << "Starting service" << name(); + if (doStart()) + { + setState(Running); + return; + } + MyList::instance()->database()->log(QString("Service %1 failed to start!").arg(name())); + setState(Error); +} + + +} // namespace LocalMyList diff --git a/localmylist/service.h b/localmylist/service.h new file mode 100644 index 0000000..094968f --- /dev/null +++ b/localmylist/service.h @@ -0,0 +1,87 @@ +#ifndef SERVICE_H +#define SERVICE_H + +#include "localmylist_global.h" +#include + +namespace LocalMyList { + +class LOCALMYLISTSHARED_EXPORT Service : public QObject +{ + Q_OBJECT + Q_ENUMS(ServiceState) + Q_PROPERTY(ServiceState state READ state NOTIFY stateChanged) + Q_PROPERTY(QString name READ name) + +public: + ~Service(); + + enum ServiceState + { + Uninitialized, //name())) + return false; + + m_registeredServices.insert(service->name(), service); + connect(service, SIGNAL(stateChanged(Service::ServiceState)), this, SLOT(serviceStateChanged(Service::ServiceState))); + return true; +} + +bool ServiceManager::hasService(const QString &serviceName) const +{ + return m_registeredServices.contains(serviceName); +} + +void ServiceManager::start(const QString &serviceName) +{ + auto it = m_registeredServices.find(serviceName); + if (it == m_registeredServices.end()) + return; + + callServiceSlot(it.value(), "start"); +} + +void ServiceManager::startAll() +{ + for (Service *s : m_registeredServices) + callServiceSlot(s, "start"); +} + +void ServiceManager::stop(const QString &serviceName) +{ + auto it = m_registeredServices.find(serviceName); + if (it == m_registeredServices.end()) + return; + + callServiceSlot(it.value(), "stop"); +} + +void ServiceManager::stopAll() +{ + for (Service *s : m_registeredServices) + callServiceSlot(s, "stop"); +} + +void ServiceManager::processRequests(const QString &serviceName) +{ + auto it = m_registeredServices.find(serviceName); + if (it == m_registeredServices.end()) + return; + + callServiceSlot(it.value(), "processRequests"); +} + +void ServiceManager::processRequestsAll() +{ + for (Service *s : m_registeredServices) + callServiceSlot(s, "processRequests"); +} + +Service::ServiceState ServiceManager::state(const QString &serviceName) +{ + auto it = m_registeredServices.find(serviceName); + if (it == m_registeredServices.end()) + return Service::Invalid; + return it.value()->state(); +} + +QList ServiceManager::registeredServices() const +{ + return m_registeredServices.keys(); +} + +void ServiceManager::serviceStateChanged(Service::ServiceState state) +{ + Q_ASSERT(qobject_cast(sender())); + emit stateChanged(static_cast(sender())->name(), state); +} + +void ServiceManager::callServiceSlot(Service *s, const char *slot) const +{ + QMetaObject::invokeMethod(s, slot, Qt::AutoConnection); +} + +} // namespace LocalMyList diff --git a/localmylist/servicemanager.h b/localmylist/servicemanager.h new file mode 100644 index 0000000..baafcce --- /dev/null +++ b/localmylist/servicemanager.h @@ -0,0 +1,61 @@ +#ifndef SERVICEMANAGER_H +#define SERVICEMANAGER_H + +#include "localmylist_global.h" +#include +#include +#include + +#include "service.h" + +namespace LocalMyList { + +class LOCALMYLISTSHARED_EXPORT ServiceManager : public QObject +{ + Q_OBJECT + +public: + explicit ServiceManager(QObject *parent = 0); + ~ServiceManager(); + + /*! + * \brief addService Adds service to be managed by the ServiceMAnager. + * Takes ownershit of the passed service. + * + * \param service The service to add + * \return Returns true on success. + */ + bool addService(Service *service); + +signals: + void stateChanged(const QString &serviceName, Service::ServiceState state); + +public slots: + void start(const QString &serviceName); + void startAll(); + void stop(const QString &serviceName); + void stopAll(); + void processRequests(const QString &serviceName); + void processRequestsAll(); + + Service::ServiceState state(const QString &serviceName); + + bool hasService(const QString &serviceName) const; + + /*! + * \brief registeredServices return the names of registered services. + * \return list of names of registered services. + */ + QList registeredServices() const; + +private slots: + void serviceStateChanged(Service::ServiceState state); + +private: + void callServiceSlot(Service *s, const char *slot) const; + QMap m_registeredServices; +}; + +} // namespace LocalMyList + +#endif // SERVICEMANAGER_H -- 2.52.0