QskMetaFunction.hpp introduced

This commit is contained in:
Uwe Rathmann 2018-03-03 15:52:42 +01:00
parent 05e2b91c01
commit b5a5b56a1d
8 changed files with 317 additions and 292 deletions

View File

@ -9,6 +9,31 @@
#include <QMetaMethod> #include <QMetaMethod>
namespace
{
class Function: public QskMetaFunction
{
public:
inline Function( void* functionCall ):
QskMetaFunction( static_cast< FunctionCall* >( functionCall ) )
{
}
static inline void ref( void* functionCall )
{
if ( functionCall )
static_cast< FunctionCall* >( functionCall )->ref();
}
static inline void deref( void* functionCall )
{
if ( functionCall )
static_cast< FunctionCall* >( functionCall )->destroyIfLastRef();
}
};
}
QskMetaCallback::QskMetaCallback( const QObject* object, QskMetaCallback::QskMetaCallback( const QObject* object,
const QMetaMethod& method, Qt::ConnectionType connectionType ): const QMetaMethod& method, Qt::ConnectionType connectionType ):
m_object( const_cast< QObject* >( object ) ), m_object( const_cast< QObject* >( object ) ),
@ -28,13 +53,12 @@ QskMetaCallback::QskMetaCallback( const QObject* object,
QskMetaCallback::QskMetaCallback( const QObject* object, QskMetaCallback::QskMetaCallback( const QObject* object,
const QskMetaFunction& function, Qt::ConnectionType connectionType ): const QskMetaFunction& function, Qt::ConnectionType connectionType ):
m_object( const_cast< QObject* >( object ) ), m_object( const_cast< QObject* >( object ) ),
m_functionData { function.invokable(), function.parameterTypes() }, m_functionData { function.functionCall(), function.parameterTypes() },
m_type( MetaFunction ), m_type( MetaFunction ),
m_hasObject( object != nullptr ), m_hasObject( object != nullptr ),
m_connectionType( static_cast< ushort >( connectionType & ~Qt::UniqueConnection ) ) m_connectionType( static_cast< ushort >( connectionType & ~Qt::UniqueConnection ) )
{ {
if ( m_functionData.invokable ) Function::ref( m_functionData.functionCall );
m_functionData.invokable->ref();
} }
QskMetaCallback::QskMetaCallback( const QskMetaCallback& other ): QskMetaCallback::QskMetaCallback( const QskMetaCallback& other ):
@ -54,9 +78,8 @@ QskMetaCallback::QskMetaCallback( const QskMetaCallback& other ):
} }
case MetaFunction: case MetaFunction:
{ {
m_functionData.invokable = other.m_functionData.invokable; m_functionData.functionCall = other.m_functionData.functionCall;
if ( m_functionData.invokable ) Function::ref( m_functionData.functionCall );
m_functionData.invokable->ref();
m_functionData.parameterTypes = other.m_functionData.parameterTypes; m_functionData.parameterTypes = other.m_functionData.parameterTypes;
break; break;
@ -69,8 +92,8 @@ QskMetaCallback::QskMetaCallback( const QskMetaCallback& other ):
QskMetaCallback::~QskMetaCallback() QskMetaCallback::~QskMetaCallback()
{ {
if ( ( m_type == MetaFunction ) && m_functionData.invokable ) if ( m_type == MetaFunction )
m_functionData.invokable->destroyIfLastRef(); Function::deref( m_functionData.functionCall );
} }
QskMetaCallback& QskMetaCallback::operator=( const QskMetaCallback& other ) QskMetaCallback& QskMetaCallback::operator=( const QskMetaCallback& other )
@ -84,8 +107,8 @@ QskMetaCallback& QskMetaCallback::operator=( const QskMetaCallback& other )
{ {
case MetaMethod: case MetaMethod:
{ {
if ( m_type == MetaFunction && m_functionData.invokable ) if ( m_type == MetaFunction )
m_functionData.invokable->destroyIfLastRef(); Function::deref( m_functionData.functionCall );
m_methodData.metaObject = other.m_methodData.metaObject; m_methodData.metaObject = other.m_methodData.metaObject;
m_methodData.methodIndex = other.m_methodData.methodIndex; m_methodData.methodIndex = other.m_methodData.methodIndex;
@ -94,21 +117,19 @@ QskMetaCallback& QskMetaCallback::operator=( const QskMetaCallback& other )
} }
case MetaFunction: case MetaFunction:
{ {
if ( ( m_type == MetaFunction ) && m_functionData.invokable ) if ( m_type == MetaFunction )
m_functionData.invokable->destroyIfLastRef(); Function::deref( m_functionData.functionCall );
m_functionData.invokable = other.m_functionData.invokable; m_functionData.functionCall = other.m_functionData.functionCall;
Function::ref( m_functionData.functionCall );
if ( m_functionData.invokable )
m_functionData.invokable->ref();
m_functionData.parameterTypes = other.m_functionData.parameterTypes; m_functionData.parameterTypes = other.m_functionData.parameterTypes;
break; break;
} }
default: default:
if ( ( m_type == MetaFunction ) && m_functionData.invokable ) if ( m_type == MetaFunction )
m_functionData.invokable->destroyIfLastRef(); Function::deref( m_functionData.functionCall );
} }
m_type = other.m_type; m_type = other.m_type;
@ -137,7 +158,7 @@ bool QskMetaCallback::isValid() const
case MetaFunction: case MetaFunction:
{ {
return m_functionData.invokable != nullptr; return m_functionData.functionCall != nullptr;
} }
default: default:
@ -155,8 +176,8 @@ void QskMetaCallback::reset()
m_object = nullptr; m_object = nullptr;
m_hasObject = false; m_hasObject = false;
if ( m_type == MetaFunction && m_functionData.invokable ) if ( m_type == MetaFunction )
m_functionData.invokable->destroyIfLastRef(); Function::deref( m_functionData.functionCall );
m_functionData = { nullptr, nullptr }; // for the debugger m_functionData = { nullptr, nullptr }; // for the debugger
m_type = Invalid; m_type = Invalid;
@ -222,8 +243,11 @@ void QskMetaCallback::invoke( void* args[] )
} }
case MetaFunction: case MetaFunction:
{ {
QskMetaFunction function( m_functionData.invokable ); if ( m_functionData.functionCall )
{
Function function( m_functionData.functionCall );
function.invoke( object, args, connectionType() ); function.invoke( object, args, connectionType() );
}
break; break;
} }

View File

@ -12,7 +12,6 @@
#include <QVector> #include <QVector>
#include <QObject> #include <QObject>
class QskMetaInvokable;
class QskMetaFunction; class QskMetaFunction;
class QMetaObject; class QMetaObject;
class QMetaMethod; class QMetaMethod;
@ -67,7 +66,7 @@ private:
struct FunctionData struct FunctionData
{ {
QskMetaInvokable* invokable; void* functionCall;
const int* parameterTypes; const int* parameterTypes;
}; };

View File

@ -16,58 +16,92 @@ QSK_QT_PRIVATE_BEGIN
QSK_QT_PRIVATE_END QSK_QT_PRIVATE_END
static inline void qskInvokeFunctionQueued( QObject* object, static inline void qskInvokeFunctionQueued( QObject* object,
QskMetaInvokable* invokable, int argc, int* types, void* argv[], QskMetaFunction::FunctionCall* functionCall, int argc, int* types, void* argv[],
QSemaphore* semaphore = nullptr ) QSemaphore* semaphore = nullptr )
{ {
constexpr QObject* sender = nullptr; constexpr QObject* sender = nullptr;
constexpr int signalId = 0; constexpr int signalId = 0;
auto event = new QMetaCallEvent( auto event = new QMetaCallEvent(
invokable, sender, signalId, argc, types, argv, semaphore ); functionCall, sender, signalId, argc, types, argv, semaphore );
QCoreApplication::postEvent( object, event ); QCoreApplication::postEvent( object, event );
} }
namespace
{
using FunctionCall = QskMetaFunction::FunctionCall;
// to have access to the private section of QSlotObjectBase
struct SlotObject
{
QAtomicInt ref;
FunctionCall::InvokeFunction invoke;
const int* parameterTypes;
};
static_assert( sizeof( SlotObject ) == sizeof( FunctionCall ),
"Bad cast: QskMetaFunction does not match" );
}
int QskMetaFunction::FunctionCall::typeInfo() const
{
auto that = const_cast< FunctionCall* >( this );
int value;
reinterpret_cast< SlotObject* >( that )->invoke( TypeInfo, that,
nullptr, reinterpret_cast< void** >( &value ), nullptr );
return value;
}
int QskMetaFunction::FunctionCall::refCount() const
{
auto that = const_cast< FunctionCall* >( this );
return reinterpret_cast< SlotObject* >( that )->ref.load();
}
QskMetaFunction::QskMetaFunction(): QskMetaFunction::QskMetaFunction():
m_invokable( nullptr ) m_functionCall( nullptr )
{ {
} }
QskMetaFunction::QskMetaFunction( QskMetaInvokable* invokable ): QskMetaFunction::QskMetaFunction( FunctionCall* functionCall ):
m_invokable( invokable ) m_functionCall( functionCall )
{ {
if ( m_invokable ) if ( m_functionCall )
m_invokable->ref(); m_functionCall->ref();
} }
QskMetaFunction::QskMetaFunction( const QskMetaFunction& other ): QskMetaFunction::QskMetaFunction( const QskMetaFunction& other ):
m_invokable( other.m_invokable ) m_functionCall( other.m_functionCall )
{ {
if ( m_invokable ) if ( m_functionCall )
m_invokable->ref(); m_functionCall->ref();
} }
QskMetaFunction::QskMetaFunction( QskMetaFunction&& other ): QskMetaFunction::QskMetaFunction( QskMetaFunction&& other ):
m_invokable( other.m_invokable ) m_functionCall( other.m_functionCall )
{ {
other.m_invokable = nullptr; other.m_functionCall = nullptr;
} }
QskMetaFunction::~QskMetaFunction() QskMetaFunction::~QskMetaFunction()
{ {
if ( m_invokable ) if ( m_functionCall )
m_invokable->destroyIfLastRef(); m_functionCall->destroyIfLastRef();
} }
QskMetaFunction& QskMetaFunction::operator=( QskMetaFunction&& other ) QskMetaFunction& QskMetaFunction::operator=( QskMetaFunction&& other )
{ {
if ( m_invokable != other.m_invokable ) if ( m_functionCall != other.m_functionCall )
{ {
if ( m_invokable ) if ( m_functionCall )
m_invokable->destroyIfLastRef(); m_functionCall->destroyIfLastRef();
m_invokable = other.m_invokable; m_functionCall = other.m_functionCall;
other.m_invokable = nullptr; other.m_functionCall = nullptr;
} }
return *this; return *this;
@ -75,15 +109,15 @@ QskMetaFunction& QskMetaFunction::operator=( QskMetaFunction&& other )
QskMetaFunction& QskMetaFunction::operator=( const QskMetaFunction& other ) QskMetaFunction& QskMetaFunction::operator=( const QskMetaFunction& other )
{ {
if ( m_invokable != other.m_invokable ) if ( m_functionCall != other.m_functionCall )
{ {
if ( m_invokable ) if ( m_functionCall )
m_invokable->destroyIfLastRef(); m_functionCall->destroyIfLastRef();
m_invokable = other.m_invokable; m_functionCall = other.m_functionCall;
if ( m_invokable ) if ( m_functionCall )
m_invokable->ref(); m_functionCall->ref();
} }
return *this; return *this;
@ -106,10 +140,10 @@ size_t QskMetaFunction::parameterCount() const
QskMetaFunction::Type QskMetaFunction::functionType() const QskMetaFunction::Type QskMetaFunction::functionType() const
{ {
if ( m_invokable == nullptr ) if ( m_functionCall == nullptr )
return Invalid; return Invalid;
return static_cast< QskMetaFunction::Type >( m_invokable->typeInfo() ); return static_cast< QskMetaFunction::Type >( m_functionCall->typeInfo() );
} }
void QskMetaFunction::invoke( void QskMetaFunction::invoke(
@ -119,7 +153,7 @@ void QskMetaFunction::invoke(
QPointer< QObject > receiver( object ); QPointer< QObject > receiver( object );
if ( m_invokable == nullptr ) if ( m_functionCall == nullptr )
return; return;
int invokeType = connectionType & 0x3; int invokeType = connectionType & 0x3;
@ -134,7 +168,7 @@ void QskMetaFunction::invoke(
{ {
case Qt::DirectConnection: case Qt::DirectConnection:
{ {
m_invokable->call( receiver, argv ); m_functionCall->call( receiver, argv );
break; break;
} }
case Qt::BlockingQueuedConnection: case Qt::BlockingQueuedConnection:
@ -148,7 +182,7 @@ void QskMetaFunction::invoke(
QSemaphore semaphore; QSemaphore semaphore;
qskInvokeFunctionQueued( receiver, m_invokable, qskInvokeFunctionQueued( receiver, m_functionCall,
0, nullptr, argv, &semaphore ); 0, nullptr, argv, &semaphore );
semaphore.acquire(); semaphore.acquire();
@ -170,7 +204,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(); const int* parameterTypes = m_functionCall->parameterTypes();
for ( uint i = 1; i < argc; i++ ) for ( uint i = 1; i < argc; i++ )
{ {
if ( argv[i] == nullptr ) if ( argv[i] == nullptr )
@ -193,7 +227,7 @@ void QskMetaFunction::invoke(
return; return;
} }
qskInvokeFunctionQueued( object, m_invokable, argc, types, arguments ); qskInvokeFunctionQueued( object, m_functionCall, argc, types, arguments );
break; break;
} }
} }

View File

@ -7,8 +7,6 @@
#define QSK_META_FUNCTION_H 1 #define QSK_META_FUNCTION_H 1
#include "QskGlobal.h" #include "QskGlobal.h"
#include "QskMetaInvokable.h"
#include <QMetaType> #include <QMetaType>
namespace QskMetaFunctionTraits namespace QskMetaFunctionTraits
@ -82,38 +80,41 @@ public:
Type functionType() const; Type functionType() const;
protected: class FunctionCall;
friend class QskMetaCallback; FunctionCall* functionCall() const;
QskMetaFunction( QskMetaInvokable* ); protected:
QskMetaInvokable* invokable() const; QskMetaFunction( FunctionCall* );
private: private:
QskMetaInvokable* m_invokable; FunctionCall* m_functionCall;
}; };
inline QskMetaInvokable* QskMetaFunction::invokable() const #include "QskMetaFunction.hpp"
inline QskMetaFunction::FunctionCall* QskMetaFunction::functionCall() const
{ {
return m_invokable; return m_functionCall;
} }
inline const int* QskMetaFunction::parameterTypes() const inline const int* QskMetaFunction::parameterTypes() const
{ {
return m_invokable ? m_invokable->parameterTypes() : nullptr; return m_functionCall ? m_functionCall->parameterTypes() : nullptr;
} }
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* > template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function ) inline QskMetaFunction::QskMetaFunction( T function )
{ {
using namespace QtPrivate; using namespace QtPrivate;
using namespace QskMetaFunctionCall;
using Traits = FunctionPointer< T >; using Traits = FunctionPointer< T >;
constexpr int Argc = Traits::ArgumentCount; constexpr int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value; using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
m_invokable = new QskMetaMemberInvokable< T, Args, void >( function ); m_functionCall = new MemberFunctionCall< T, Args, void >( function );
m_invokable->setParameterTypes( m_functionCall->setParameterTypes(
ConnectionTypes< typename Traits::Arguments >::types() ); ConnectionTypes< typename Traits::Arguments >::types() );
} }
@ -121,14 +122,15 @@ template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
inline QskMetaFunction::QskMetaFunction( T functor ) inline QskMetaFunction::QskMetaFunction( T functor )
{ {
using namespace QtPrivate; using namespace QtPrivate;
using namespace QskMetaFunctionCall;
using Traits = FunctionPointer< decltype( &T::operator() ) >; using Traits = FunctionPointer< decltype( &T::operator() ) >;
constexpr int Argc = Traits::ArgumentCount; constexpr int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value; using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
m_invokable = new QskMetaFunctorInvokable< T, Argc, Args, void >( functor ); m_functionCall = new FunctorFunctionCall< T, Argc, Args, void >( functor );
m_invokable->setParameterTypes( m_functionCall->setParameterTypes(
ConnectionTypes< typename Traits::Arguments >::types() ); ConnectionTypes< typename Traits::Arguments >::types() );
} }
@ -136,14 +138,15 @@ template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function ) inline QskMetaFunction::QskMetaFunction( T function )
{ {
using namespace QtPrivate; using namespace QtPrivate;
using namespace QskMetaFunctionCall;
using Traits = FunctionPointer< T >; using Traits = FunctionPointer< T >;
constexpr int Argc = Traits::ArgumentCount; constexpr int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value; using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
m_invokable = new QskMetaFunctionInvokable< T, Args, void >( function ); m_functionCall = new StaticFunctionCall< T, Args, void >( function );
m_invokable->setParameterTypes( m_functionCall->setParameterTypes(
ConnectionTypes< typename Traits::Arguments >::types() ); ConnectionTypes< typename Traits::Arguments >::types() );
} }

View File

@ -0,0 +1,183 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_META_FUNCTION_HPP
#define QSK_META_FUNCTION_HPP 1
#include "QskGlobal.h"
#include <QObject>
class QskMetaFunction::FunctionCall : public QtPrivate::QSlotObjectBase
{
public:
typedef void (* InvokeFunction)(
int which, QtPrivate::QSlotObjectBase*, QObject*, void**, bool* );
enum
{
TypeInfo = NumOperations + 1
};
int typeInfo() const;
int refCount() const;
inline const int* parameterTypes() const
{
return m_parameterTypes;
}
inline void setParameterTypes( const int* types )
{
m_parameterTypes = types;
}
protected:
explicit inline FunctionCall( InvokeFunction f,
const int* m_parameterTypes = nullptr ):
QSlotObjectBase( f ),
m_parameterTypes( m_parameterTypes )
{
}
private:
const int* m_parameterTypes; // static array, only needed for Qt::QueuedConnection
};
namespace QskMetaFunctionCall
{
using FunctionCall = QskMetaFunction::FunctionCall;
using namespace QtPrivate;
template< typename Function, typename Args, typename R >
class StaticFunctionCall : public FunctionCall
{
using MetaCall = StaticFunctionCall< Function, Args, R >;
public:
explicit inline StaticFunctionCall( Function function ):
FunctionCall( &invoke ),
m_function( function )
{
}
static void invoke(int which, QSlotObjectBase* functionCall,
QObject* object, void** args, bool* )
{
switch ( which )
{
case Destroy:
{
delete static_cast< MetaCall* >( functionCall );
break;
}
case Call:
{
typedef FunctionPointer< Function > FuncType;
FuncType::template call< Args, R >(
static_cast< MetaCall* >( functionCall )->m_function, object, args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::Function;
break;
}
}
}
private:
Function m_function;
};
template< typename Function, typename Args, typename R >
class MemberFunctionCall : public FunctionCall
{
using MetaCall = MemberFunctionCall< Function, Args, R >;
public:
explicit inline MemberFunctionCall( Function function ):
FunctionCall( &invoke ),
m_function( function )
{
}
static void invoke( int which, QSlotObjectBase* functionCall,
QObject* object, void** args, bool* )
{
switch (which)
{
case Destroy:
{
delete static_cast< MetaCall* >( functionCall );
break;
}
case Call:
{
typedef FunctionPointer< Function > FuncType;
FuncType::template call< Args, R >(
static_cast< MetaCall* >( functionCall )->m_function,
static_cast< typename FuncType::Object* >( object ), args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::Member;
break;
}
}
}
private:
Function m_function;
};
template< typename Function, int N, typename Args, typename R >
class FunctorFunctionCall : public FunctionCall
{
using MetaCall = FunctorFunctionCall< Function, N, Args, R >;
public:
explicit inline FunctorFunctionCall( Function function ):
FunctionCall( &invoke ),
m_function( function )
{
}
static void invoke( int which, QSlotObjectBase* slotObject,
QObject* object, void** args, bool* )
{
switch (which)
{
case Destroy:
{
delete static_cast< MetaCall* >( slotObject );
break;
}
case Call:
{
typedef Functor< Function, N > FuncType;
FuncType::template call< Args, R >(
static_cast< MetaCall* >( slotObject )->m_function, object, args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = QskMetaFunction::Functor;
break;
}
}
}
private:
Function m_function;
};
}
#endif

View File

@ -1,38 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskMetaInvokable.h"
namespace
{
// to have access to the private section of QSlotObjectBase
struct SlotObject
{
QAtomicInt ref;
QskMetaInvokable::InvokeFunction invoke;
const int* parameterTypes;
};
static_assert( sizeof( SlotObject ) == sizeof( QskMetaInvokable ),
"Bad cast: QskMetaInvokable does not match" );
}
int QskMetaInvokable::typeInfo() const
{
auto that = const_cast< QskMetaInvokable* >( this );
int value;
reinterpret_cast< SlotObject* >( that )->invoke( TypeInfo, that,
nullptr, reinterpret_cast< void** >( &value ), nullptr );
return value;
}
int QskMetaInvokable::refCount() const
{
auto that = const_cast< QskMetaInvokable* >( this );
return reinterpret_cast< SlotObject* >( that )->ref.load();
}

View File

@ -1,179 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_META_INVOKABLE_H
#define QSK_META_INVOKABLE_H 1
#include "QskGlobal.h"
#include <QObject>
// helper classes for QskMetaFunction
class QSK_EXPORT QskMetaInvokable : public QtPrivate::QSlotObjectBase
{
public:
typedef void (* InvokeFunction)(
int which, QtPrivate::QSlotObjectBase*, QObject*, void**, bool* );
enum
{
TypeInfo = NumOperations + 1
};
int typeInfo() const;
int refCount() const;
inline const int* parameterTypes() const
{
return m_parameterTypes;
}
inline void setParameterTypes( const int* types )
{
m_parameterTypes = types;
}
protected:
explicit inline QskMetaInvokable( InvokeFunction f,
const int* m_parameterTypes = nullptr ):
QSlotObjectBase( f ),
m_parameterTypes( m_parameterTypes )
{
}
private:
const int* m_parameterTypes; // static array, only needed for Qt::QueuedConnection
};
template< typename Function, typename Args, typename R >
class QskMetaFunctionInvokable : public QskMetaInvokable
{
using Invokable = QskMetaFunctionInvokable< Function, Args, R >;
public:
explicit inline QskMetaFunctionInvokable( Function function ):
QskMetaInvokable( &invoke ),
m_function( function )
{
}
static void invoke(int which, QtPrivate::QSlotObjectBase* invokable,
QObject* object, void** args, bool* )
{
switch ( which )
{
case Destroy:
{
delete static_cast< Invokable* >( invokable );
break;
}
case Call:
{
typedef QtPrivate::FunctionPointer< Function > FuncType;
FuncType::template call< Args, R >(
static_cast< Invokable* >( invokable )->m_function, object, args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = 1; // QskMetaFunction::Function
break;
}
}
}
private:
Function m_function;
};
template< typename Function, typename Args, typename R >
class QskMetaMemberInvokable : public QskMetaInvokable
{
using Invokable = QskMetaMemberInvokable< Function, Args, R >;
public:
explicit inline QskMetaMemberInvokable( Function function ):
QskMetaInvokable( &invoke ),
m_function( function )
{
}
static void invoke( int which, QtPrivate::QSlotObjectBase* slotObject,
QObject* object, void** args, bool* )
{
switch (which)
{
case Destroy:
{
delete static_cast< Invokable* >( slotObject );
break;
}
case Call:
{
typedef QtPrivate::FunctionPointer< Function > FuncType;
FuncType::template call< Args, R >(
static_cast< Invokable* >( slotObject )->m_function,
static_cast< typename FuncType::Object* >( object ), args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = 0; // = QskMetaFunction::Member
break;
}
}
}
private:
Function m_function;
};
template< typename Function, int N, typename Args, typename R >
class QskMetaFunctorInvokable : public QskMetaInvokable
{
using Invokable = QskMetaFunctorInvokable< Function, N, Args, R >;
public:
explicit inline QskMetaFunctorInvokable( Function function ):
QskMetaInvokable( &invoke ),
m_function( function )
{
}
static void invoke( int which, QSlotObjectBase* slotObject,
QObject* object, void** args, bool* )
{
switch (which)
{
case Destroy:
{
delete static_cast< Invokable* >( slotObject );
break;
}
case Call:
{
typedef QtPrivate::Functor< Function, N > FuncType;
FuncType::template call< Args, R >(
static_cast< Invokable* >( slotObject )->m_function, object, args );
break;
}
case TypeInfo:
{
*reinterpret_cast< int* >( args ) = 2; // QskMetaFunction::Functor
break;
}
}
}
private:
Function m_function;
};
#endif

View File

@ -42,7 +42,7 @@ HEADERS += \
common/QskMargins.h \ common/QskMargins.h \
common/QskMetaCallback.h \ common/QskMetaCallback.h \
common/QskMetaFunction.h \ common/QskMetaFunction.h \
common/QskMetaInvokable.cpp \ common/QskMetaFunction.hpp \
common/QskMetaMethod.h \ common/QskMetaMethod.h \
common/QskModule.h \ common/QskModule.h \
common/QskNamespace.h \ common/QskNamespace.h \
@ -62,7 +62,6 @@ SOURCES += \
common/QskMargins.cpp \ common/QskMargins.cpp \
common/QskMetaCallback.cpp \ common/QskMetaCallback.cpp \
common/QskMetaFunction.cpp \ common/QskMetaFunction.cpp \
common/QskMetaInvokable.cpp \
common/QskMetaMethod.cpp \ common/QskMetaMethod.cpp \
common/QskModule.cpp \ common/QskModule.cpp \
common/QskObjectCounter.cpp \ common/QskObjectCounter.cpp \