QskMeta classes improved

This commit is contained in:
Uwe Rathmann 2018-03-02 06:57:08 +01:00
parent b7a48ae910
commit 3970b11330
6 changed files with 68 additions and 54 deletions

View File

@ -8,11 +8,21 @@
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QTimer>
static void debugNone()
{
qDebug() << "None";
}
static void debugValueI( int i ) static void debugValueI( int i )
{ {
qDebug() << i; qDebug() << i;
} }
static void debugValueD( qreal d )
{
qDebug() << d;
}
static void debugValue( qreal d, int i ) static void debugValue( qreal d, int i )
{ {
qDebug() << d << i; qDebug() << d << i;
@ -85,8 +95,10 @@ int main( int argc, char* argv[] )
#if 1 #if 1
invoker.addCallback( QskMetaFunction() ); invoker.addCallback( QskMetaFunction() );
invoker.addCallback( debugNone );
invoker.addCallback( debugValue ); invoker.addCallback( debugValue );
invoker.addCallback( debugValueI ); invoker.addCallback( debugValueI );
invoker.addCallback( debugValueD );
invoker.addCallback( &object, &MyObject::print1 ); invoker.addCallback( &object, &MyObject::print1 );
invoker.addCallback( &object2, &MyObject2::print1 ); invoker.addCallback( &object2, &MyObject2::print1 );
invoker.addCallback( &object, &MyObject::print2 ); invoker.addCallback( &object, &MyObject::print2 );

View File

@ -237,7 +237,7 @@ void QskMetaCallback::invoke( void* args[] )
} }
case MetaFunction: case MetaFunction:
{ {
QskMetaFunction function( m_functionData.invokable, m_functionData.parameterTypes ); QskMetaFunction function( m_functionData.invokable );
function.invoke( object, args, connectionType() ); function.invoke( object, args, connectionType() );
break; break;

View File

@ -29,31 +29,26 @@ static inline void qskInvokeFunctionQueued( QObject* object,
} }
QskMetaFunction::QskMetaFunction(): QskMetaFunction::QskMetaFunction():
m_invokable( nullptr ), m_invokable( nullptr )
m_parameterTypes( nullptr )
{ {
} }
QskMetaFunction::QskMetaFunction( QskMetaFunction::QskMetaFunction( QskMetaInvokable* invokable ):
QskMetaInvokable* invokable, const int* parameterTypes ): m_invokable( invokable )
m_invokable( invokable ),
m_parameterTypes( parameterTypes )
{ {
if ( m_invokable ) if ( m_invokable )
m_invokable->ref(); m_invokable->ref();
} }
QskMetaFunction::QskMetaFunction( const QskMetaFunction& other ): QskMetaFunction::QskMetaFunction( const QskMetaFunction& other ):
m_invokable( other.m_invokable ), m_invokable( other.m_invokable )
m_parameterTypes( other.m_parameterTypes )
{ {
if ( m_invokable ) if ( m_invokable )
m_invokable->ref(); m_invokable->ref();
} }
QskMetaFunction::QskMetaFunction( QskMetaFunction&& other ): QskMetaFunction::QskMetaFunction( QskMetaFunction&& other ):
m_invokable( other.m_invokable ), m_invokable( other.m_invokable )
m_parameterTypes( other.m_parameterTypes )
{ {
other.m_invokable = nullptr; other.m_invokable = nullptr;
} }
@ -75,8 +70,6 @@ QskMetaFunction& QskMetaFunction::operator=( QskMetaFunction&& other )
other.m_invokable = nullptr; other.m_invokable = nullptr;
} }
m_parameterTypes = other.m_parameterTypes;
return *this; return *this;
} }
@ -93,18 +86,16 @@ QskMetaFunction& QskMetaFunction::operator=( const QskMetaFunction& other )
m_invokable->ref(); m_invokable->ref();
} }
m_parameterTypes = other.m_parameterTypes;
return *this; return *this;
} }
size_t QskMetaFunction::parameterCount() const size_t QskMetaFunction::parameterCount() const
{ {
if ( m_parameterTypes ) if ( auto types = parameterTypes() )
{ {
for ( int i = 1;; i++ ) for ( int i = 1;; i++ )
{ {
if ( m_parameterTypes[ i ] == QMetaType::UnknownType ) if ( types[ i ] == QMetaType::UnknownType )
return i + 1; // including the return type return i + 1; // including the return type
} }
} }
@ -168,6 +159,7 @@ void QskMetaFunction::invoke(
types[0] = QMetaType::UnknownType; // a return type is not possible types[0] = QMetaType::UnknownType; // a return type is not possible
arguments[0] = nullptr; arguments[0] = nullptr;
const int* parameterTypes = m_invokable->parameterTypes();
for ( uint i = 1; i < argc; i++ ) for ( uint i = 1; i < argc; i++ )
{ {
if ( argv[i] == nullptr ) if ( argv[i] == nullptr )
@ -180,8 +172,8 @@ void QskMetaFunction::invoke(
return; return;
} }
types[i] = m_parameterTypes[i - 1]; types[i] = parameterTypes[i - 1];
arguments[i] = QMetaType::create( m_parameterTypes[i - 1], argv[i] ); arguments[i] = QMetaType::create( parameterTypes[i - 1], argv[i] );
} }
if ( connectionType == Qt::QueuedConnection ) if ( connectionType == Qt::QueuedConnection )

View File

@ -19,13 +19,13 @@ namespace QskMetaFunctionTraits
using IsMemberFunction = typename std::enable_if< FunctionPointer< T >::IsPointerToMemberFunction, using IsMemberFunction = typename std::enable_if< FunctionPointer< T >::IsPointerToMemberFunction,
std::true_type >::type; 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 > template< typename T >
using IsFunctor = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction using IsFunctor = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
&& FunctionPointer< T >::ArgumentCount == -1, std::true_type >::type; && 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 class QSK_EXPORT QskMetaFunction
@ -57,10 +57,10 @@ public:
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr > template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr >
QskMetaFunction( T ); QskMetaFunction( T );
template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr > template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
QskMetaFunction( T ); QskMetaFunction( T );
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr > template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr >
QskMetaFunction( T ); QskMetaFunction( T );
~QskMetaFunction(); ~QskMetaFunction();
@ -81,12 +81,11 @@ public:
protected: protected:
friend class QskMetaCallback; friend class QskMetaCallback;
QskMetaFunction( QskMetaInvokable*, const int* ); QskMetaFunction( QskMetaInvokable* );
QskMetaInvokable* invokable() const; QskMetaInvokable* invokable() const;
private: private:
QskMetaInvokable* m_invokable; QskMetaInvokable* m_invokable;
const int* m_parameterTypes;
}; };
inline QskMetaInvokable* QskMetaFunction::invokable() const inline QskMetaInvokable* QskMetaFunction::invokable() const
@ -96,7 +95,7 @@ inline QskMetaInvokable* QskMetaFunction::invokable() const
inline const int* QskMetaFunction::parameterTypes() const inline const int* QskMetaFunction::parameterTypes() const
{ {
return m_parameterTypes; return m_invokable ? m_invokable->parameterTypes() : nullptr;
} }
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* > template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* >
@ -111,26 +110,8 @@ inline QskMetaFunction::QskMetaFunction( T function )
m_invokable = QskMetaInvokable::instance( m_invokable = QskMetaInvokable::instance(
QskMetaMemberInvokable< T, Args, void >::invoke, QskMetaMemberInvokable< T, Args, void >::invoke,
ConnectionTypes< typename Traits::Arguments >::types(),
reinterpret_cast< void** >( &function ) ); 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 >* > template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
@ -145,9 +126,24 @@ inline QskMetaFunction::QskMetaFunction( T functor )
m_invokable = QskMetaInvokable::instance( m_invokable = QskMetaInvokable::instance(
QskMetaFunctorInvokable< T, Argc, Args, void >::invoke, QskMetaFunctorInvokable< T, Argc, Args, void >::invoke,
ConnectionTypes< typename Traits::Arguments >::types(),
reinterpret_cast< void** >( &functor ) ); 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 ) Q_DECLARE_METATYPE( QskMetaFunction )

View File

@ -12,6 +12,7 @@ namespace
{ {
QAtomicInt ref; QAtomicInt ref;
QskMetaInvokable::InvokeFunction invoke; QskMetaInvokable::InvokeFunction invoke;
const int* parameterTypes;
}; };
static_assert( sizeof( SlotObject ) == sizeof( QskMetaInvokable ), static_assert( sizeof( SlotObject ) == sizeof( QskMetaInvokable ),
@ -19,7 +20,7 @@ namespace
} }
QskMetaInvokable* QskMetaInvokable::instance( 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 In opposite to QObject::connect we share the Invokable for callbacks to the same
@ -36,6 +37,8 @@ QskMetaInvokable* QskMetaInvokable::instance(
else else
invoke( Create, nullptr, nullptr, args, nullptr ); invoke( Create, nullptr, nullptr, args, nullptr );
invokable->m_parameterTypes = parameterTypes;
return invokable; return invokable;
} }

View File

@ -27,13 +27,24 @@ public:
int typeInfo() const; int typeInfo() const;
int refCount() 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: protected:
explicit inline QskMetaInvokable( InvokeFunction f ): explicit inline QskMetaInvokable( InvokeFunction f,
QSlotObjectBase( 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 > template< typename Function, typename Args, typename R >