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 <QTimer>
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 );

View File

@ -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;

View File

@ -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 )

View File

@ -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 )

View File

@ -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;
}

View File

@ -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 >