diff --git a/playground/invoker/main.cpp b/playground/invoker/main.cpp index fc4de90c..c6955835 100644 --- a/playground/invoker/main.cpp +++ b/playground/invoker/main.cpp @@ -8,11 +8,21 @@ #include #include +static void debugNone() +{ + qDebug() << "None"; +} + static void debugValueI( int i ) { qDebug() << i; } +static void debugValueD( qreal d ) +{ + qDebug() << d; +} + static void debugValue( qreal d, int i ) { qDebug() << d << i; @@ -85,8 +95,10 @@ int main( int argc, char* argv[] ) #if 1 invoker.addCallback( QskMetaFunction() ); + invoker.addCallback( debugNone ); invoker.addCallback( debugValue ); invoker.addCallback( debugValueI ); + invoker.addCallback( debugValueD ); invoker.addCallback( &object, &MyObject::print1 ); invoker.addCallback( &object2, &MyObject2::print1 ); invoker.addCallback( &object, &MyObject::print2 ); diff --git a/src/common/QskMetaCallback.cpp b/src/common/QskMetaCallback.cpp index 27aecd3a..ce480b7f 100644 --- a/src/common/QskMetaCallback.cpp +++ b/src/common/QskMetaCallback.cpp @@ -237,7 +237,7 @@ void QskMetaCallback::invoke( void* args[] ) } case MetaFunction: { - QskMetaFunction function( m_functionData.invokable, m_functionData.parameterTypes ); + QskMetaFunction function( m_functionData.invokable ); function.invoke( object, args, connectionType() ); break; diff --git a/src/common/QskMetaFunction.cpp b/src/common/QskMetaFunction.cpp index 33f37cc8..3646afcf 100644 --- a/src/common/QskMetaFunction.cpp +++ b/src/common/QskMetaFunction.cpp @@ -29,31 +29,26 @@ static inline void qskInvokeFunctionQueued( QObject* object, } QskMetaFunction::QskMetaFunction(): - m_invokable( nullptr ), - m_parameterTypes( nullptr ) + m_invokable( nullptr ) { } -QskMetaFunction::QskMetaFunction( - QskMetaInvokable* invokable, const int* parameterTypes ): - m_invokable( invokable ), - m_parameterTypes( parameterTypes ) +QskMetaFunction::QskMetaFunction( QskMetaInvokable* invokable ): + m_invokable( invokable ) { if ( m_invokable ) m_invokable->ref(); } QskMetaFunction::QskMetaFunction( const QskMetaFunction& other ): - m_invokable( other.m_invokable ), - m_parameterTypes( other.m_parameterTypes ) + m_invokable( other.m_invokable ) { if ( m_invokable ) m_invokable->ref(); } QskMetaFunction::QskMetaFunction( QskMetaFunction&& other ): - m_invokable( other.m_invokable ), - m_parameterTypes( other.m_parameterTypes ) + m_invokable( other.m_invokable ) { other.m_invokable = nullptr; } @@ -75,8 +70,6 @@ QskMetaFunction& QskMetaFunction::operator=( QskMetaFunction&& other ) other.m_invokable = nullptr; } - m_parameterTypes = other.m_parameterTypes; - return *this; } @@ -93,18 +86,16 @@ QskMetaFunction& QskMetaFunction::operator=( const QskMetaFunction& other ) m_invokable->ref(); } - m_parameterTypes = other.m_parameterTypes; - return *this; } size_t QskMetaFunction::parameterCount() const { - if ( m_parameterTypes ) + if ( auto types = parameterTypes() ) { for ( int i = 1;; i++ ) { - if ( m_parameterTypes[ i ] == QMetaType::UnknownType ) + if ( types[ i ] == QMetaType::UnknownType ) return i + 1; // including the return type } } @@ -168,6 +159,7 @@ void QskMetaFunction::invoke( types[0] = QMetaType::UnknownType; // a return type is not possible arguments[0] = nullptr; + const int* parameterTypes = m_invokable->parameterTypes(); for ( uint i = 1; i < argc; i++ ) { if ( argv[i] == nullptr ) @@ -180,8 +172,8 @@ void QskMetaFunction::invoke( return; } - types[i] = m_parameterTypes[i - 1]; - arguments[i] = QMetaType::create( m_parameterTypes[i - 1], argv[i] ); + types[i] = parameterTypes[i - 1]; + arguments[i] = QMetaType::create( parameterTypes[i - 1], argv[i] ); } if ( connectionType == Qt::QueuedConnection ) diff --git a/src/common/QskMetaFunction.h b/src/common/QskMetaFunction.h index d87b7875..27fe0f2a 100644 --- a/src/common/QskMetaFunction.h +++ b/src/common/QskMetaFunction.h @@ -19,13 +19,13 @@ namespace QskMetaFunctionTraits using IsMemberFunction = typename std::enable_if< FunctionPointer< T >::IsPointerToMemberFunction, std::true_type >::type; - template< typename T > - using IsFunction = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction - && FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type; - template< typename T > using IsFunctor = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction && FunctionPointer< T >::ArgumentCount == -1, std::true_type >::type; + + template< typename T > + using IsFunction = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction + && FunctionPointer< T >::ArgumentCount >= 0, std::true_type >::type; } class QSK_EXPORT QskMetaFunction @@ -57,10 +57,10 @@ public: template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr > QskMetaFunction( T ); - template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr > + template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr > QskMetaFunction( T ); - template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr > + template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr > QskMetaFunction( T ); ~QskMetaFunction(); @@ -81,12 +81,11 @@ public: protected: friend class QskMetaCallback; - QskMetaFunction( QskMetaInvokable*, const int* ); + QskMetaFunction( QskMetaInvokable* ); QskMetaInvokable* invokable() const; private: QskMetaInvokable* m_invokable; - const int* m_parameterTypes; }; inline QskMetaInvokable* QskMetaFunction::invokable() const @@ -96,7 +95,7 @@ inline QskMetaInvokable* QskMetaFunction::invokable() const inline const int* QskMetaFunction::parameterTypes() const { - return m_parameterTypes; + return m_invokable ? m_invokable->parameterTypes() : nullptr; } template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* > @@ -111,26 +110,8 @@ inline QskMetaFunction::QskMetaFunction( T function ) m_invokable = QskMetaInvokable::instance( QskMetaMemberInvokable< T, Args, void >::invoke, + ConnectionTypes< typename Traits::Arguments >::types(), reinterpret_cast< void** >( &function ) ); - - m_parameterTypes = ConnectionTypes< typename Traits::Arguments >::types(); -} - -template< typename T, QskMetaFunctionTraits::IsFunction< T >* > -inline QskMetaFunction::QskMetaFunction( T function ) -{ - using namespace QtPrivate; - - using Traits = FunctionPointer< T >; - - constexpr int Argc = Traits::ArgumentCount; - using Args = typename List_Left< typename Traits::Arguments, Argc >::Value; - - m_invokable = QskMetaInvokable::instance( - QskMetaFunctionInvokable< T, Args, void >::invoke, - reinterpret_cast< void** >( &function ) ); - - m_parameterTypes = ConnectionTypes< typename Traits::Arguments >::types(); } template< typename T, QskMetaFunctionTraits::IsFunctor< T >* > @@ -144,10 +125,25 @@ inline QskMetaFunction::QskMetaFunction( T functor ) using Args = typename List_Left< typename Traits::Arguments, Argc >::Value; m_invokable = QskMetaInvokable::instance( - QskMetaFunctorInvokable< T, Argc, Args, void >::invoke, - reinterpret_cast< void** >( &functor ) ); + QskMetaFunctorInvokable< T, Argc, Args, void >::invoke, + ConnectionTypes< typename Traits::Arguments >::types(), + reinterpret_cast< void** >( &functor ) ); +} - m_parameterTypes = ConnectionTypes< typename Traits::Arguments >::types(); +template< typename T, QskMetaFunctionTraits::IsFunction< T >* > +inline QskMetaFunction::QskMetaFunction( T function ) +{ + using namespace QtPrivate; + + using Traits = FunctionPointer< T >; + + constexpr int Argc = Traits::ArgumentCount; + using Args = typename List_Left< typename Traits::Arguments, Argc >::Value; + + m_invokable = QskMetaInvokable::instance( + QskMetaFunctionInvokable< T, Args, void >::invoke, + ConnectionTypes< typename Traits::Arguments >::types(), + reinterpret_cast< void** >( &function ) ); } Q_DECLARE_METATYPE( QskMetaFunction ) diff --git a/src/common/QskMetaInvokable.cpp b/src/common/QskMetaInvokable.cpp index 6940200d..bb8bc025 100644 --- a/src/common/QskMetaInvokable.cpp +++ b/src/common/QskMetaInvokable.cpp @@ -12,6 +12,7 @@ namespace { QAtomicInt ref; QskMetaInvokable::InvokeFunction invoke; + const int* parameterTypes; }; static_assert( sizeof( SlotObject ) == sizeof( QskMetaInvokable ), @@ -19,7 +20,7 @@ namespace } QskMetaInvokable* QskMetaInvokable::instance( - InvokeFunction invoke, void** functor ) + InvokeFunction invoke, const int* parameterTypes, void** functor ) { /* In opposite to QObject::connect we share the Invokable for callbacks to the same @@ -36,6 +37,8 @@ QskMetaInvokable* QskMetaInvokable::instance( else invoke( Create, nullptr, nullptr, args, nullptr ); + invokable->m_parameterTypes = parameterTypes; + return invokable; } diff --git a/src/common/QskMetaInvokable.h b/src/common/QskMetaInvokable.h index 0903eec5..399d8da4 100644 --- a/src/common/QskMetaInvokable.h +++ b/src/common/QskMetaInvokable.h @@ -27,13 +27,24 @@ public: int typeInfo() const; int refCount() const; - static QskMetaInvokable* instance( InvokeFunction, void** function ); + inline const int* parameterTypes() const + { + return m_parameterTypes; + } + + static QskMetaInvokable* instance( InvokeFunction, + const int* parameterTypes, void** function ); protected: - explicit inline QskMetaInvokable( InvokeFunction f ): - QSlotObjectBase( f ) + explicit inline QskMetaInvokable( InvokeFunction f, + const int* m_parameterTypes = nullptr ): + QSlotObjectBase( f ), + m_parameterTypes( m_parameterTypes ) { } + +private: + const int* m_parameterTypes; // static array ! }; template< typename Function, typename Args, typename R >