diff options
Diffstat (limited to 'src/scxml')
-rw-r--r-- | src/scxml/qscxmlstatemachine.cpp | 96 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine.h | 78 |
2 files changed, 174 insertions, 0 deletions
diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index 326cb80..915844c 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -177,6 +177,102 @@ Q_LOGGING_CATEGORY(scxmlLog, "scxml.statemachine") Returns a handle to the connection, which can be used later to disconnect. */ +/*! + \fn auto QScxmlStateMachine::onEntry(const QObject *receiver, + const char *method) + + Returns a functor that accepts a boolean argument and calls the given + \a method on \a receiver using QMetaObject::invokeMethod() if that argument + is \c true and \a receiver has not been deleted, yet. + + The given \a method must not accept any arguments. \a method is the plain + method name, not enclosed in \c SIGNAL() or \c SLOT(). + + This is useful to wrap handlers for connectToState() that should only + be executed when the state is entered. + + onEntry() is only available if the compiler supports return type + deduction for functions. +*/ + +/*! + \fn auto QScxmlStateMachine::onExit(const QObject *receiver, + const char *method) + + Returns a functor that accepts a boolean argument and calls the given + \a method on \a receiver using QMetaObject::invokeMethod() if that argument + is \c false and \a receiver has not been deleted, yet. + + The given \a method must not accept any arguments. \a method is the plain + method name, not enclosed in SIGNAL(...) or SLOT(...). + + This is useful to wrap handlers for connectToState() that should only + be executed when the state is left. + + onExit() is only available if the compiler supports return type + deduction for functions. +*/ + +/*! + \fn QScxmlStateMachine::onEntry(Functor functor) + + Returns a functor that accepts a boolean argument and calls the given + \a functor if that argument is \c true. The given \a functor must not + accept any arguments. + + This is useful to wrap handlers for connectToState() that should only + be executed when the state is entered. + + onEntry() is only available if the compiler supports return type + deduction for functions. + */ + +/*! + \fn QScxmlStateMachine::onExit(Functor functor) + + Returns a functor that accepts a boolean argument and calls the given + \a functor if that argument is \c false. The given \a functor must not + accept any arguments. + + This is useful to wrap handlers for connectToState() that should only + be executed when the state is left. + + onExit() is only available if the compiler supports return type + deduction for functions. + */ + +/*! + \fn QScxmlStateMachine::onEntry(const QObject *receiver, + PointerToMemberFunction method) + + Returns a functor that accepts a boolean argument and calls the given + \a method on \a receiver if that argument is \c true and the \a receiver + has not been deleted, yet. The given \a method must not accept any + arguments. + + This is useful to wrap handlers for connectToState() that should only + be executed when the state is entered. + + onEntry() is only available if the compiler supports return type + deduction for functions. + */ + +/*! + \fn QScxmlStateMachine::onExit(const QObject *receiver, + PointerToMemberFunction method) + + Returns a functor that accepts a boolean argument and calls the given + \a method on \a receiver if that argument is \c false and the \a receiver + has not been deleted, yet. The given \a method must not accept any + arguments. + + This is useful to wrap handlers for connectToState() that should only + be executed when the state is left. + + onExit() is only available if the compiler supports return type + deduction for functions. + */ + namespace QScxmlInternal { static int signalIndex(const QMetaObject *meta, const QByteArray &signalName) diff --git a/src/scxml/qscxmlstatemachine.h b/src/scxml/qscxmlstatemachine.h index 787a7c6..e5a0b92 100644 --- a/src/scxml/qscxmlstatemachine.h +++ b/src/scxml/qscxmlstatemachine.h @@ -50,6 +50,7 @@ #include <QVector> #include <QUrl> #include <QVariantList> +#include <QPointer> QT_BEGIN_NAMESPACE class QIODevice; @@ -169,6 +170,83 @@ public: } #endif +#ifdef Q_QDOC + static auto onEntry(const QObject *receiver, const char *method); + static auto onExit(const QObject *receiver, const char *method); + + template<typename Functor> + static auto onEntry(Functor functor); + + template<typename Functor> + static auto onExit(Functor functor); + + template<typename PointerToMemberFunction> + static auto onEntry(const QObject *receiver, PointerToMemberFunction method); + + template<typename PointerToMemberFunction> + static auto onExit(const QObject *receiver, PointerToMemberFunction method); +#elif defined(__cpp_return_type_deduction) && __cpp_return_type_deduction == 201304 + static auto onEntry(const QObject *receiver, const char *method) + { + const QPointer<QObject> receiverPointer(const_cast<QObject *>(receiver)); + return [receiverPointer, method](bool isEnteringState) { + if (isEnteringState && !receiverPointer.isNull()) + QMetaObject::invokeMethod(const_cast<QObject *>(receiverPointer.data()), method); + }; + } + + static auto onExit(const QObject *receiver, const char *method) + { + const QPointer<QObject> receiverPointer(const_cast<QObject *>(receiver)); + return [receiverPointer, method](bool isEnteringState) { + if (!isEnteringState && !receiverPointer.isNull()) + QMetaObject::invokeMethod(receiverPointer.data(), method); + }; + } + + template<typename Functor> + static auto onEntry(Functor functor) + { + return [functor](bool isEnteringState) { + if (isEnteringState) + functor(); + }; + } + + template<typename Functor> + static auto onExit(Functor functor) + { + return [functor](bool isEnteringState) { + if (!isEnteringState) + functor(); + }; + } + + template<typename Func1> + static auto onEntry(const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, + Func1 slot) + { + typedef typename QtPrivate::FunctionPointer<Func1>::Object Object; + const QPointer<Object> receiverPointer(const_cast<Object *>(receiver)); + return [receiverPointer, slot](bool isEnteringState) { + if (isEnteringState && !receiverPointer.isNull()) + (receiverPointer->*slot)(); + }; + } + + template<typename Func1> + static auto onExit(const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, + Func1 slot) + { + typedef typename QtPrivate::FunctionPointer<Func1>::Object Object; + const QPointer<Object> receiverPointer(const_cast<Object *>(receiver)); + return [receiverPointer, slot](bool isEnteringState) { + if (!isEnteringState && !receiverPointer.isNull()) + (receiverPointer->*slot)(); + }; + } +#endif // defined(__cpp_return_type_deduction) && __cpp_return_type_deduction == 201304 + QMetaObject::Connection connectToEvent(const QString &scxmlEventSpec, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection); |