# # # add_file "src/model/AutomateCommand.cpp" # content [45cc241099f0467ccdaf6269dd86e044e0c6c03c] # # patch "src/model/AutomateCommand.h" # from [745a331bc70e34f7e82c680da0f8f3318f359686] # to [0d7eaf1a4c9d8b9fdda0518c11d43bb0f7f84be7] # ============================================================ --- src/model/AutomateCommand.cpp 45cc241099f0467ccdaf6269dd86e044e0c6c03c +++ src/model/AutomateCommand.cpp 45cc241099f0467ccdaf6269dd86e044e0c6c03c @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "AutomateCommand.h" + +AutomateCommand::AutomateCommand(const QString & db, AutomateCommandHelper * helper) + : dbPath(db) +{ + if (helper == 0) + { + helper = new AutomateCommandHelper(this); + } + cmdHelper = helper; +} + +AutomateCommand::~AutomateCommand() +{ + delete cmdHelper; +} + +void AutomateCommand::enqueueTask(const MonotoneTask & task) +{ + QMutexLocker locker(&lock); + + MonotoneThread * thread = APP->manager()->getThread(dbPath); + int threadNumber = thread->getThreadNumber(); + // we want to avoid multiple thread connections + if (!connectedThreads.contains(threadNumber)) + { + QObject::connect( + thread, SIGNAL(taskAborted(const MonotoneTask &)), + cmdHelper, SLOT(taskAborted(const MonotoneTask &)) + ); + + QObject::connect( + thread, SIGNAL(taskFinished(const MonotoneTask &)), + cmdHelper, SLOT(taskFinished(const MonotoneTask &)) + ); + + connectedThreads.append(threadNumber); + } + queuedCommands[threadNumber].append( + thread->enqueueTask(task) + ); +} + +AutomateCommandHelper::AutomateCommandHelper(AutomateCommand * cmd) + : command(cmd) +{} + +void AutomateCommandHelper::taskAborted(const MonotoneTask & task) +{ + // do sth more reasonable here in a subclass, + // i.e. try to query the data again + C(QString("Task %1 (thread %2) aborted (%3)") + .arg(task.getCommandNumber()) + .arg(task.getThreadNumber()) + .arg(QString::fromUtf8(task.getEncodedInput())) + ); +} + +void AutomateCommandHelper::taskFinished(const MonotoneTask & task) +{ + int threadNumber = task.getThreadNumber(); + int cmdNumber = task.getCommandNumber(); + + if (!command->queuedCommands.contains(threadNumber) || + command->queuedCommands[threadNumber].contains(cmdNumber)) + { + return; + } + command->processTaskResult(task); +} + ============================================================ --- src/model/AutomateCommand.h 745a331bc70e34f7e82c680da0f8f3318f359686 +++ src/model/AutomateCommand.h 0d7eaf1a4c9d8b9fdda0518c11d43bb0f7f84be7 @@ -28,70 +28,45 @@ #include #include -class AutomateCommand : public QObject +class AutomateCommandHelper; + +class AutomateCommand { - Q_OBJECT public: - AutomateCommand(const QString & db) : dbPath(db) {} - virtual ~AutomateCommand() {} + AutomateCommand(const QString &, AutomateCommandHelper * helper = 0); + virtual ~AutomateCommand(); + + friend class AutomateCommandHelper; protected: virtual void processTaskResult(const MonotoneTask &) = 0; -protected slots: - virtual void taskAborted(const MonotoneTask & task) - { - // do sth more reasonable here in a subclass, - // i.e. try to query the data again - C(QString("Task %1 (thread %2) aborted (%3)") - .arg(task.getCommandNumber()) - .arg(task.getThreadNumber()) - .arg(QString::fromUtf8(task.getEncodedInput())) - ); - } - virtual void taskFinished(const MonotoneTask & task) - { - int threadNumber = task.getThreadNumber(); - if (!queuedCommands.contains(threadNumber) || - queuedCommands[threadNumber].contains(task.getCommandNumber())) - { - return; - } - processTaskResult(task); - } - protected: - void enqueueTask(const MonotoneTask & task) - { - QMutexLocker locker(&lock); - - MonotoneThread * thread = APP->manager()->getThread(dbPath); - int threadNumber = thread->getThreadNumber(); - // we want to avoid multiple thread connections - if (!connectedThreads.contains(threadNumber)) - { - connect( - thread, SIGNAL(taskAborted(const MonotoneTask &)), - this, SLOT(taskAborted(const MonotoneTask &)) - ); - - connect( - thread, SIGNAL(taskFinished(const MonotoneTask &)), - this, SLOT(taskFinished(const MonotoneTask &)) - ); - - connectedThreads.append(threadNumber); - } - queuedCommands[threadNumber].append( - thread->enqueueTask(task) - ); - } + void enqueueTask(const MonotoneTask &); private: QString dbPath; QMutex lock; QList connectedThreads; QMap > queuedCommands; + AutomateCommandHelper * cmdHelper; }; +// Qt's class hierarchy doesn't support multiple inheritance, so we need +// a helper object which manages our signal/slot connections +class AutomateCommandHelper : public QObject +{ + Q_OBJECT +public: + AutomateCommandHelper(AutomateCommand *); + +protected slots: + virtual void taskAborted(const MonotoneTask &); + + void taskFinished(const MonotoneTask &); + +private: + AutomateCommand * command; +}; + #endif