From 2dbb48d8bba5dcae8ab6cc8cd92b4984c55b6029 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 2 Mar 2018 07:07:19 +0100 Subject: [PATCH] dh --- playground/invoker/main.cpp | 12 ++++++-- src/common/QskMetaFunction.cpp | 7 +++++ src/common/QskMetaFunction.h | 7 +++++ src/common/QskMetaInvokable.cpp | 54 +++++++++++++++++++++++++++++++++ src/common/QskMetaInvokable.h | 15 +++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) diff --git a/playground/invoker/main.cpp b/playground/invoker/main.cpp index c6955835..96dd10d6 100644 --- a/playground/invoker/main.cpp +++ b/playground/invoker/main.cpp @@ -8,9 +8,14 @@ #include #include -static void debugNone() +static void debugNone1() { - qDebug() << "None"; + qDebug() << "None 1"; +} + +static void debugNone2() +{ + qDebug() << "None 2"; } static void debugValueI( int i ) @@ -95,7 +100,8 @@ int main( int argc, char* argv[] ) #if 1 invoker.addCallback( QskMetaFunction() ); - invoker.addCallback( debugNone ); + invoker.addCallback( debugNone1 ); + invoker.addCallback( debugNone2 ); invoker.addCallback( debugValue ); invoker.addCallback( debugValueI ); invoker.addCallback( debugValueD ); diff --git a/src/common/QskMetaFunction.cpp b/src/common/QskMetaFunction.cpp index 3646afcf..799bc539 100644 --- a/src/common/QskMetaFunction.cpp +++ b/src/common/QskMetaFunction.cpp @@ -33,6 +33,13 @@ QskMetaFunction::QskMetaFunction(): { } +QskMetaFunction::QskMetaFunction( void(*function)() ): + m_invokable( QskMetaInvokable::instance( + QskMetaFunctionInvokable0::invoke, nullptr, + reinterpret_cast< void** >( &function ) ) ) +{ +} + QskMetaFunction::QskMetaFunction( QskMetaInvokable* invokable ): m_invokable( invokable ) { diff --git a/src/common/QskMetaFunction.h b/src/common/QskMetaFunction.h index 27fe0f2a..951313d2 100644 --- a/src/common/QskMetaFunction.h +++ b/src/common/QskMetaFunction.h @@ -26,6 +26,11 @@ namespace QskMetaFunctionTraits template< typename T > using IsFunction = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction && FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type; + + template< typename T > + using IsFunction0 = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction + && FunctionPointer< T >::ArgumentCount == 0, std::true_type >::type; + } class QSK_EXPORT QskMetaFunction @@ -54,6 +59,8 @@ public: QskMetaFunction( const QskMetaFunction& ); QskMetaFunction( QskMetaFunction&& ); + QskMetaFunction( void(*function)() ); + template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr > QskMetaFunction( T ); diff --git a/src/common/QskMetaInvokable.cpp b/src/common/QskMetaInvokable.cpp index bb8bc025..8182a1ce 100644 --- a/src/common/QskMetaInvokable.cpp +++ b/src/common/QskMetaInvokable.cpp @@ -19,6 +19,16 @@ namespace "Bad cast: QskMetaInvokable does not match" ); } +static inline void qskCallFunction( void (*function)(), + void** args, const int* types ) +{ + if ( types == nullptr || args == nullptr ) + { + function(); + return; + } +} + QskMetaInvokable* QskMetaInvokable::instance( InvokeFunction invoke, const int* parameterTypes, void** functor ) { @@ -59,3 +69,47 @@ int QskMetaInvokable::refCount() const auto that = const_cast< QskMetaInvokable* >( this ); return reinterpret_cast< SlotObject* >( that )->ref.load(); } + +QskMetaFunctionInvokable0::QskMetaFunctionInvokable0( Function function ): + QskMetaInvokable( &invoke, nullptr ), + m_function( function ) +{ +} + +void QskMetaFunctionInvokable0::invoke(int which, QtPrivate::QSlotObjectBase* invokable, + QObject*, void** args, bool* ) +{ + switch ( which ) + { + case Find: + { + *reinterpret_cast< void** >( args[0] ) = nullptr; + break; + } + case Create: + { + *reinterpret_cast< void** >( args[0] ) = + new Invokable( *reinterpret_cast< Function* >( args[1] ) ); + + break; + } + case Destroy: + { + delete static_cast< Invokable* >( invokable ); + break; + } + case Call: + { + auto invokable01 = static_cast< Invokable* >( invokable ); + qskCallFunction( invokable01->m_function, + args, invokable01->parameterTypes() ); + + break; + } + case TypeInfo: + { + *reinterpret_cast< int* >( args ) = 1; // QskMetaFunction::Function + break; + } + } +} diff --git a/src/common/QskMetaInvokable.h b/src/common/QskMetaInvokable.h index 399d8da4..430f9d0f 100644 --- a/src/common/QskMetaInvokable.h +++ b/src/common/QskMetaInvokable.h @@ -47,6 +47,21 @@ private: const int* m_parameterTypes; // static array ! }; +class QSK_EXPORT QskMetaFunctionInvokable0 : public QskMetaInvokable +{ + using Function = void(*)(); + using Invokable = QskMetaFunctionInvokable0; + +public: + explicit QskMetaFunctionInvokable0( Function function ); + + static void invoke(int which, QtPrivate::QSlotObjectBase*, + QObject* object, void** args, bool* ); + +private: + Function m_function; +}; + template< typename Function, typename Args, typename R > class QskMetaFunctionInvokable : public QskMetaInvokable {