From 630f45719a527f8ee739b03bc62f886badea6df3 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 13 Dec 2016 16:24:31 +0100 Subject: Revamp of composercontroller to use actions more. Instead of setting all properties individually we directly assign all properties to a context that we assign to the actions. This way actions can automatically update themselves as new data becomes available, and we avoid the setter/getter boilerplate, at the cost of a less explicit interface (But that could be improved by allowing to define the required properties of a context in c++). By relying on prehandler/posthandler to execute certain actions we simplify the control flow and enable the future extension with handlers that i.e. do encryption etc. --- framework/actions/action.cpp | 20 +++++++++++++++++++- framework/actions/action.h | 3 +++ framework/actions/actionbroker.cpp | 16 +++++++++++++--- framework/actions/actionbroker.h | 2 +- framework/actions/actionhandler.cpp | 17 ++++++++++++++++- framework/actions/actionhandler.h | 2 ++ framework/actions/context.cpp | 16 ++++++++++++++++ framework/actions/context.h | 2 ++ 8 files changed, 72 insertions(+), 6 deletions(-) (limited to 'framework/actions') diff --git a/framework/actions/action.cpp b/framework/actions/action.cpp index f41feb66..1344d112 100644 --- a/framework/actions/action.cpp +++ b/framework/actions/action.cpp @@ -42,7 +42,11 @@ Action::Action(const QByteArray &actionId, Context &context, QObject *parent) mContext(&context), mActionId(actionId) { + setContext(&context); +} +Action::~Action() +{ } void Action::setContext(Context *context) @@ -61,6 +65,16 @@ void Action::setContext(Context *context) emit readyChanged(); } +bool Action::eventFilter(QObject *obj, QEvent *e) +{ + if (obj == mContext) { + if (e->type() == QEvent::DynamicPropertyChange) { + contextChanged(); + } + } + return QObject::eventFilter(obj, e); +} + void Action::contextChanged() { emit readyChanged(); @@ -84,7 +98,7 @@ QByteArray Action::actionId() const bool Action::ready() const { - return ActionBroker::instance().isActionReady(mActionId, mContext); + return ActionBroker::instance().isActionReady(mActionId, mContext, mPreHandler); } void Action::execute() @@ -99,11 +113,15 @@ ActionResult Action::executeWithResult() void Action::addPreHandler(ActionHandler *handler) { + //For cleanup + handler->setParent(this); mPreHandler << handler; } void Action::addPostHandler(ActionHandler *handler) { + //For cleanup + handler->setParent(this); mPostHandler << handler; } diff --git a/framework/actions/action.h b/framework/actions/action.h index 47e41138..dda8c987 100644 --- a/framework/actions/action.h +++ b/framework/actions/action.h @@ -37,6 +37,7 @@ class Action : public QObject public: Action(QObject *parent = 0); Action(const QByteArray &actionId, Context &context, QObject *parent = 0); + ~Action(); void setContext(Context *); Context *context() const; @@ -52,6 +53,8 @@ public: void addPreHandler(ActionHandler *handler); void addPostHandler(ActionHandler *handler); + bool eventFilter(QObject *obj, QEvent *e) Q_DECL_OVERRIDE; + Q_SIGNALS: void readyChanged(); diff --git a/framework/actions/actionbroker.cpp b/framework/actions/actionbroker.cpp index 24ef0b2c..17145440 100644 --- a/framework/actions/actionbroker.cpp +++ b/framework/actions/actionbroker.cpp @@ -21,11 +21,14 @@ #include "context.h" #include "actionhandler.h" +#include #include using namespace Kube; +SINK_DEBUG_AREA("actionbroker") + ActionBroker::ActionBroker(QObject *parent) : QObject(parent) { @@ -38,15 +41,20 @@ ActionBroker &ActionBroker::instance() return instance; } -bool ActionBroker::isActionReady(const QByteArray &actionId, Context *context) +bool ActionBroker::isActionReady(const QByteArray &actionId, Context *context, const QList> &preHandler) { if (!context) { return false; } + for (const auto handler : preHandler) { + if (!handler->isActionReady(context)) { + return false; + } + } for (const auto handler : mHandler.values(actionId)) { if (handler) { - if (handler-> isActionReady(context)) { + if (handler->isActionReady(context)) { return true; } } @@ -59,6 +67,8 @@ ActionResult ActionBroker::executeAction(const QByteArray &actionId, Context *co { ActionResult result; if (context) { + SinkLog() << "Executing action " << actionId; + SinkLog() << *context; for (const auto handler : preHandler) { handler->execute(context); } @@ -73,7 +83,7 @@ ActionResult ActionBroker::executeAction(const QByteArray &actionId, Context *co handler->execute(context); } } else { - qWarning() << "Can't execute without context"; + SinkWarning() << "Can't execute without context"; result.setDone(); result.setError(1); } diff --git a/framework/actions/actionbroker.h b/framework/actions/actionbroker.h index d2787c79..84678c16 100644 --- a/framework/actions/actionbroker.h +++ b/framework/actions/actionbroker.h @@ -32,7 +32,7 @@ class ActionBroker : public QObject public: static ActionBroker &instance(); - bool isActionReady(const QByteArray &actionId, Context *context); + bool isActionReady(const QByteArray &actionId, Context *context, const QList> &preHandler); ActionResult executeAction(const QByteArray &actionId, Context *context, const QList> &preHandler, const QList> &postHandler); void registerHandler(const QByteArray &actionId, ActionHandler *handler); diff --git a/framework/actions/actionhandler.cpp b/framework/actions/actionhandler.cpp index 9d58f464..dc9edeca 100644 --- a/framework/actions/actionhandler.cpp +++ b/framework/actions/actionhandler.cpp @@ -77,6 +77,18 @@ QByteArray ActionHandler::actionId() const } +ActionHandlerHelper::ActionHandlerHelper(const Handler &handler) + : ActionHandler(nullptr), + handlerFunction(handler) +{ +} + +ActionHandlerHelper::ActionHandlerHelper(const IsReadyFunction &isReady, const Handler &handler) + : ActionHandler(nullptr), + isReadyFunction(isReady), + handlerFunction(handler) +{ +} ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &isReady, const Handler &handler) : ActionHandler(nullptr), @@ -96,7 +108,10 @@ ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const IsRea bool ActionHandlerHelper::isActionReady(Context *context) { - return isReadyFunction(context); + if (isReadyFunction) { + return isReadyFunction(context); + } + return true; } ActionResult ActionHandlerHelper::execute(Context *context) diff --git a/framework/actions/actionhandler.h b/framework/actions/actionhandler.h index 762b8d45..09ed13c6 100644 --- a/framework/actions/actionhandler.h +++ b/framework/actions/actionhandler.h @@ -55,6 +55,8 @@ public: typedef std::function Handler; typedef std::function(Context*)> JobHandler; + ActionHandlerHelper(const Handler &); + ActionHandlerHelper(const IsReadyFunction &, const Handler &); ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const Handler &); ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const JobHandler &); diff --git a/framework/actions/context.cpp b/framework/actions/context.cpp index a7f87d16..205b1606 100644 --- a/framework/actions/context.cpp +++ b/framework/actions/context.cpp @@ -19,6 +19,7 @@ #include "context.h" #include +#include using namespace Kube; @@ -27,3 +28,18 @@ Context::Context(QObject *parent) { } + +QDebug operator<<(QDebug dbg, const Kube::Context &context) +{ + dbg << "Kube::Context {\n"; + auto metaObject = context.QObject::metaObject(); + for (auto i = metaObject->propertyOffset(); i < metaObject->propertyCount(); i++) { + auto property = metaObject->property(i); + dbg << property.name() << context.property(property.name()) << "\n"; + } + for (const auto &p : context.dynamicPropertyNames()) { + dbg << p << context.property(p) << "\n"; + } + dbg << "\n}"; + return dbg; +} diff --git a/framework/actions/context.h b/framework/actions/context.h index 7289f850..562e110e 100644 --- a/framework/actions/context.h +++ b/framework/actions/context.h @@ -31,5 +31,7 @@ public: } +QDebug operator<<(QDebug dbg, const Kube::Context &); + Q_DECLARE_METATYPE(Kube::Context*); -- cgit v1.2.3