QskMetaFunction.hpp introduced
This commit is contained in:
parent
05e2b91c01
commit
b5a5b56a1d
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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 \
|
||||||
|
|
Loading…
Reference in New Issue