QskMeta classes reorganized

This commit is contained in:
Uwe Rathmann 2018-02-28 10:43:15 +01:00
parent 6b87084678
commit 0075ccbdbd
9 changed files with 434 additions and 447 deletions

View File

@ -1,220 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskMetaCall.h"
#include <QMetaMethod>
#include <QCoreApplication>
#include <QThread>
#include <QObject>
#include <QSemaphore>
#include <private/qobject_p.h>
namespace
{
// to get access to the private section of QSlotObjectBase
struct SlotObject
{
QAtomicInt ref;
QskMetaCall::Invokable::InvokeFunction invoke;
};
}
namespace QskMetaCall
{
inline Invokable::InvokeFunction invokeCall( const Invokable* invokable )
{
return ( ( SlotObject* )( invokable ) )->invoke;
}
int Invokable::typeInfo() const
{
int value;
auto f = invokeCall( this );
f( TypeInfo, const_cast< Invokable* >( this ),
nullptr, reinterpret_cast< void** >( &value ), nullptr );
return value;
}
int Invokable::refCount() const
{
return ( ( SlotObject* )( this ) )->ref.load();
}
}
namespace
{
using namespace QskMetaCall;
class FunctionCallEvent : public QMetaCallEvent
{
public:
FunctionCallEvent( Invokable* invokable,
int nargs, int* types, void* args[], QSemaphore* semaphore = nullptr ):
QMetaCallEvent( invokable, nullptr, 0, nargs, types, args, semaphore ),
m_invokable ( invokable )
{
}
virtual ~FunctionCallEvent()
{
}
private:
Invokable* m_invokable;
};
class MethodCallEvent : public QMetaCallEvent
{
public:
MethodCallEvent( const QMetaObject* mo, ushort methodIndex,
int nargs, int* types, void* args[], QSemaphore* semaphore = nullptr ):
QMetaCallEvent(
mo->methodOffset(), methodIndex, mo->d.static_metacall,
nullptr, -1, nargs, types, args, semaphore )
{
}
virtual ~MethodCallEvent()
{
}
};
}
void QskMetaCall::invoke( QObject* object,
const QMetaMethod& method, void* args[],
Qt::ConnectionType connectionType )
{
auto metaObject = method.enclosingMetaObject();
const int methodOffset = metaObject->methodOffset();
const int methodIndex = method.methodIndex() - methodOffset;
if ( connectionType == Qt::AutoConnection )
{
connectionType = ( object->thread() == QThread::currentThread() )
? Qt::DirectConnection : Qt::QueuedConnection;
}
if ( connectionType == Qt::DirectConnection )
{
if ( metaObject->d.static_metacall )
{
metaObject->d.static_metacall(object,
QMetaObject::InvokeMetaMethod, methodIndex, args );
}
else
{
QMetaObject::metacall( object,
QMetaObject::InvokeMetaMethod, methodIndex, args );
}
}
else
{
const int paramCount = method.parameterCount();
auto types = static_cast< int* >( malloc( paramCount * sizeof( int ) ) );
auto arguments = static_cast< void** >( malloc( paramCount * sizeof( void* ) ) );
types[0] = QMetaType::UnknownType; // a return type is not possible
arguments[0] = nullptr;
for ( int i = 1; i < paramCount; i++ )
{
if ( arguments[i] == nullptr )
{
Q_ASSERT( arguments[i] != nullptr );
free( types );
free( arguments );
return;
}
types[i] = method.parameterType( i );
arguments[i] = args[i - 1];
}
Q_ASSERT( args[paramCount] == nullptr );
if ( connectionType == Qt::QueuedConnection )
{
auto event = new MethodCallEvent(
metaObject, methodIndex, paramCount + 1, types, args );
QCoreApplication::postEvent(object, event );
}
else
{
QSemaphore semaphore;
auto event = new MethodCallEvent(
metaObject, methodIndex, paramCount + 1, types, args, &semaphore );
QCoreApplication::postEvent( object, event );
semaphore.acquire();
}
}
}
void QskMetaCall::invoke( QObject* object,
const Invokable& invokable, int argc, const int argTypes[], void* argv[],
Qt::ConnectionType connectionType )
{
//connectionType &= ~Qt::UniqueConnection;
auto invokablePtr = const_cast< Invokable* >( &invokable );
if ( connectionType == Qt::AutoConnection )
{
connectionType = ( object->thread() == QThread::currentThread() )
? Qt::DirectConnection : Qt::QueuedConnection;
}
if ( connectionType == Qt::DirectConnection )
{
invokablePtr->call( object, argv );
}
else
{
auto types = static_cast< int* >( malloc( argc * sizeof( int ) ) );
auto arguments = static_cast< void** >( malloc( argc * sizeof( void* ) ) );
types[0] = QMetaType::UnknownType; // a return type is not possible
arguments[0] = nullptr;
for ( int i = 1; i < argc; i++ )
{
if ( argv[i] == nullptr )
{
Q_ASSERT( arguments[i] != nullptr );
free( types );
free( arguments );
return;
}
types[i] = argTypes[i - 1];
arguments[i] = QMetaType::create( argTypes[i - 1], argv[i] );
}
if ( connectionType == Qt::QueuedConnection )
{
auto event = new FunctionCallEvent(
invokablePtr, argc, types, arguments, nullptr );
QCoreApplication::postEvent( object, event );
}
else // Qt::BlockingQueuedConnection ???
{
// ....
}
}
}

View File

@ -1,198 +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_CALL_H
#define QSK_META_CALL_H 1
#include "QskGlobal.h"
#include <QObject>
namespace QskMetaCall
{
class Invokable;
QSK_EXPORT void invoke( QObject* object,
const QMetaMethod&, void* args[],
Qt::ConnectionType = Qt::AutoConnection );
QSK_EXPORT void invoke( QObject*,
const Invokable&, int argc, const int argTypes[], void* args[],
Qt::ConnectionType = Qt::AutoConnection );
}
namespace QskMetaCall
{
using namespace QtPrivate;
class QSK_EXPORT Invokable : public QSlotObjectBase
{
public:
typedef void (* InvokeFunction)( int which, QSlotObjectBase*,
QObject*, void**, bool* );
enum { TypeInfo = NumOperations + 1 };
int typeInfo() const;
int refCount() const;
protected:
explicit Invokable( InvokeFunction f ):
QSlotObjectBase( f )
{
}
};
template< typename Func, typename Args, typename R >
class FunctionInvokable : public Invokable
{
public:
typedef FunctionPointer< Func > FuncType;
explicit FunctionInvokable( Func f ):
Invokable( &invoke ),
function(f)
{
}
static void invoke(int which, QSlotObjectBase* invokable,
QObject* object, void** args, bool* )
{
auto f = static_cast< FunctionInvokable* >( invokable );
switch ( which )
{
case Destroy:
{
delete f;
break;
}
case Call:
{
FuncType::template call< Args, R >( f->function, object, args );
break;
}
case TypeInfo:
{
int* typeInfo = reinterpret_cast< int* >( args );
//*typeInfo = QskMetaFunction::Function;
*typeInfo = 1;
break;
}
}
}
Func function;
};
template< typename Func, typename Args, typename R >
class MemberFunctionInvokable : public Invokable
{
public:
explicit MemberFunctionInvokable( Func f ):
Invokable( &invoke ),
function(f)
{
}
static void invoke( int which, QSlotObjectBase* invokable,
QObject* object, void** args, bool* ret )
{
typedef FunctionPointer< Func > FuncType;
auto f = static_cast< MemberFunctionInvokable* >( invokable );
switch (which)
{
case Destroy:
{
delete f;
break;
}
case Call:
{
FuncType::template call< Args, R >(
f->function, static_cast< typename FuncType::Object* >( object ), args );
break;
}
case Compare:
{
*ret = *reinterpret_cast< Func* >( args ) == f->function;
break;
}
case TypeInfo:
{
int* typeInfo = reinterpret_cast< int* >( args );
*typeInfo = 0;
//*typeInfo = QskMetaFunction::Member;
break;
}
}
}
private:
Func function;
};
template< typename Func, int N, typename Args, typename R >
class FunctorInvokable : public Invokable
{
public:
typedef Functor< Func, N > FuncType;
explicit FunctorInvokable( Func f ):
Invokable( &invoke ),
function( std::move( f ) )
{
}
static void invoke( int which, QSlotObjectBase* invokable,
QObject* object, void** args, bool* )
{
auto f = static_cast< FunctorInvokable* >( invokable );
switch (which)
{
case Destroy:
{
delete f;
break;
}
case Call:
{
FuncType::template call< Args, R >( f->function, object, args );
break;
}
case TypeInfo:
{
int* typeInfo = reinterpret_cast< int* >( args );
*typeInfo = 2;
//*typeInfo = QskMetaFunction::Functor;
break;
}
}
}
private:
Func function;
};
template< typename T >
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;
}
#endif

View File

@ -4,8 +4,29 @@
*****************************************************************************/
#include "QskMetaCallback.h"
#include <QObject>
#include <QVector>
#include <QCoreApplication>
#include <QThread>
#include <QSemaphore>
QSK_QT_PRIVATE_BEGIN
#include <private/qobject_p.h>
QSK_QT_PRIVATE_END
static inline void qskInvokeMethodQueued( QObject* object,
const QMetaObject* metaObject, ushort methodIndex,
int nargs, int* types, void* args[], QSemaphore* semaphore = nullptr )
{
constexpr QObject* sender = nullptr;
constexpr int signalId = -1;
auto event = new QMetaCallEvent(
metaObject->methodOffset(), methodIndex, metaObject->d.static_metacall,
sender, signalId, nargs, types, args, semaphore );
QCoreApplication::postEvent( object, event );
}
QskMetaCallback::QskMetaCallback( const QObject* object,
const QMetaMethod& method, Qt::ConnectionType connectionType ):
@ -147,8 +168,7 @@ void QskMetaCallback::invoke( void* args[] )
{
case MetaMethod:
{
if ( object )
QskMetaCall::invoke( object, *m_method, args, connectionType() );
qskInvokeMethod( object, *m_method, args, connectionType() );
break;
}
case MetaFunction:
@ -161,3 +181,80 @@ void QskMetaCallback::invoke( void* args[] )
break;
}
}
void qskInvokeMethod( QObject* object,
const QMetaMethod& method, void* args[],
Qt::ConnectionType connectionType )
{
if ( object == nullptr )
return;
auto metaObject = method.enclosingMetaObject();
const int methodOffset = metaObject->methodOffset();
const int methodIndex = method.methodIndex() - methodOffset;
if ( connectionType == Qt::AutoConnection )
{
connectionType = ( object->thread() == QThread::currentThread() )
? Qt::DirectConnection : Qt::QueuedConnection;
}
if ( connectionType == Qt::DirectConnection )
{
if ( metaObject->d.static_metacall )
{
metaObject->d.static_metacall(object,
QMetaObject::InvokeMetaMethod, methodIndex, args );
}
else
{
QMetaObject::metacall( object,
QMetaObject::InvokeMetaMethod, methodIndex, args );
}
}
else
{
const int paramCount = method.parameterCount();
auto types = static_cast< int* >( malloc( paramCount * sizeof( int ) ) );
auto arguments = static_cast< void** >( malloc( paramCount * sizeof( void* ) ) );
types[0] = QMetaType::UnknownType; // a return type is not possible
arguments[0] = nullptr;
for ( int i = 1; i < paramCount; i++ )
{
if ( arguments[i] == nullptr )
{
Q_ASSERT( arguments[i] != nullptr );
free( types );
free( arguments );
return;
}
types[i] = method.parameterType( i );
arguments[i] = args[i - 1];
}
Q_ASSERT( args[paramCount] == nullptr );
if ( connectionType == Qt::QueuedConnection )
{
qskInvokeMethodQueued( object,
metaObject, methodIndex, paramCount + 1, types, args );
}
else
{
QSemaphore semaphore;
qskInvokeMethodQueued( object,
metaObject, methodIndex, paramCount + 1, types, args, &semaphore );
semaphore.acquire();
}
}
}

View File

@ -89,6 +89,10 @@ inline Qt::ConnectionType QskMetaCallback::connectionType() const
return static_cast< Qt::ConnectionType >( m_connectionType );
}
QSK_EXPORT void qskInvokeMethod(
QObject* object, const QMetaMethod&, void* args[],
Qt::ConnectionType = Qt::AutoConnection );
Q_DECLARE_METATYPE( QskMetaCallback )
#endif

View File

@ -4,9 +4,30 @@
*****************************************************************************/
#include "QskGlobal.h"
#include "QskMetaCall.h"
#include "QskMetaFunction.h"
#include <QCoreApplication>
#include <QThread>
#include <QObject>
#include <QSemaphore>
QSK_QT_PRIVATE_BEGIN
#include <private/qobject_p.h>
QSK_QT_PRIVATE_END
static inline void qskInvokeFunctionQueued( QObject* object,
QskMetaInvokable* invokable, int argc, int* types, void* argv[],
QSemaphore* semaphore = nullptr )
{
constexpr QObject* sender = nullptr;
constexpr int signalId = 0;
auto event = new QMetaCallEvent(
invokable, sender, signalId, argc, types, argv, semaphore );
QCoreApplication::postEvent( object, event );
}
QskMetaFunction::QskMetaFunction():
m_invokable( nullptr ),
m_parameterTypes( nullptr )
@ -68,15 +89,10 @@ QskMetaFunction& QskMetaFunction::operator=( const QskMetaFunction& other )
return *this;
}
void QskMetaFunction::init( QskMetaCall::Invokable* invokable,
void QskMetaFunction::init( QskMetaInvokable* invokable,
const int* parameterTypes )
{
m_invokable = invokable;
#if 0
if ( m_invokable )
m_invokable->ref();
#endif
m_parameterTypes = parameterTypes;
}
@ -111,9 +127,78 @@ QskMetaFunction::Type QskMetaFunction::functionType() const
void QskMetaFunction::invoke(
QObject* object, void* argv[], Qt::ConnectionType connectionType )
{
if ( m_invokable )
if ( m_invokable == nullptr )
return;
int invokeType = connectionType & 0x3;
if ( invokeType == Qt::AutoConnection )
{
QskMetaCall::invoke( object, *m_invokable,
parameterCount(), parameterTypes(), argv, connectionType );
invokeType = ( object->thread() == QThread::currentThread() )
? Qt::DirectConnection : Qt::QueuedConnection;
}
else if ( invokeType == Qt::BlockingQueuedConnection )
{
if ( object->thread() == QThread::currentThread() )
{
// We would end up in a deadlock, better do nothing
return;
}
}
if ( invokeType == Qt::DirectConnection )
{
m_invokable->call( object, argv );
}
else
{
if ( object == nullptr )
{
#if 1
/*
object might be deleted in another thread
during this call - TODO ...
*/
#endif
return;
}
const auto argc = parameterCount();
auto types = static_cast< int* >( malloc( argc * sizeof( int ) ) );
auto arguments = static_cast< void** >( malloc( argc * sizeof( void* ) ) );
types[0] = QMetaType::UnknownType; // a return type is not possible
arguments[0] = nullptr;
for ( uint i = 1; i < argc; i++ )
{
if ( argv[i] == nullptr )
{
Q_ASSERT( arguments[i] != nullptr );
free( types );
free( arguments );
return;
}
types[i] = m_parameterTypes[i - 1];
arguments[i] = QMetaType::create( m_parameterTypes[i - 1], argv[i] );
}
if ( connectionType == Qt::QueuedConnection )
{
qskInvokeFunctionQueued( object, m_invokable, argc, types, arguments );
}
else // Qt::BlockingQueuedConnection ???
{
QSemaphore semaphore;
qskInvokeFunctionQueued( object,
m_invokable, argc, types, arguments, &semaphore );
semaphore.acquire();
}
}
}

View File

@ -7,10 +7,27 @@
#define QSK_META_FUNCTION_H 1
#include "QskGlobal.h"
#include "QskMetaCall.h"
#include "QskMetaInvokable.h"
#include <QMetaType>
namespace QskMetaFunctionTraits
{
using namespace QtPrivate;
template< typename T >
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;
}
class QSK_EXPORT QskMetaFunction
{
Q_GADGET
@ -37,13 +54,13 @@ public:
QskMetaFunction( const QskMetaFunction& );
QskMetaFunction( QskMetaFunction&& );
template< typename T, QskMetaCall::IsMemberFunction< T >* = nullptr >
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr >
QskMetaFunction( T );
template< typename T, QskMetaCall::IsFunction< T >* = nullptr >
template< typename T, QskMetaFunctionTraits::IsFunction< T >* = nullptr >
QskMetaFunction( T );
template< typename T, QskMetaCall::IsFunctor< T >* = nullptr >
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* = nullptr >
QskMetaFunction( T );
~QskMetaFunction();
@ -62,44 +79,42 @@ public:
Type functionType() const;
private:
void init( QskMetaCall::Invokable*, const int* );
void init( QskMetaInvokable*, const int* );
QskMetaCall::Invokable* m_invokable;
QskMetaInvokable* m_invokable;
const int* m_parameterTypes;
};
template< typename T, QskMetaCall::IsMemberFunction< T >* >
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function )
{
using namespace QtPrivate;
using namespace QskMetaCall;
using Traits = FunctionPointer< T >;
const int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
init( new MemberFunctionInvokable< T, Args, void >( function ),
init( new QskMetaMemberInvokable< T, Args, void >( function ),
ConnectionTypes< typename Traits::Arguments >::types() );
}
template< typename T, QskMetaCall::IsFunction< T >* >
template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
inline QskMetaFunction::QskMetaFunction( T function )
{
using namespace QtPrivate;
using namespace QskMetaCall;
using Traits = FunctionPointer< T >;
const int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
init( new FunctionInvokable< T, Args, void >( function ),
init( new QskMetaFunctionInvokable< T, Args, void >( function ),
ConnectionTypes< typename Traits::Arguments >::types() );
}
template< typename T, QskMetaCall::IsFunctor< T >* >
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
inline QskMetaFunction::QskMetaFunction( T functor )
{
using namespace QtPrivate;
@ -109,7 +124,7 @@ inline QskMetaFunction::QskMetaFunction( T functor )
const int Argc = Traits::ArgumentCount;
using Args = typename List_Left< typename Traits::Arguments, Argc >::Value;
init( new QskMetaCall::FunctorInvokable< T, Argc, Args, void > ( functor ),
init( new QskMetaFunctorInvokable< T, Argc, Args, void > ( functor ),
ConnectionTypes< typename Traits::Arguments >::types() );
}

View File

@ -0,0 +1,37 @@
/******************************************************************************
* 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;
};
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

@ -0,0 +1,167 @@
/******************************************************************************
* 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 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;
protected:
explicit QskMetaInvokable( InvokeFunction f ):
QSlotObjectBase( f )
{
}
};
template< typename Func, typename Args, typename R >
class QskMetaFunctionInvokable : public QskMetaInvokable
{
public:
typedef QtPrivate::FunctionPointer< Func > FuncType;
explicit QskMetaFunctionInvokable( Func f ):
QskMetaInvokable( &invoke ),
function(f)
{
}
static void invoke(int which, QtPrivate::QSlotObjectBase* invokable,
QObject* object, void** args, bool* )
{
auto f = static_cast< QskMetaFunctionInvokable* >( invokable );
switch ( which )
{
case Destroy:
{
delete f;
break;
}
case Call:
{
FuncType::template call< Args, R >( f->function, object, args );
break;
}
case TypeInfo:
{
int* typeInfo = reinterpret_cast< int* >( args );
*typeInfo = 1; // = QskMetaFunction::Function
break;
}
}
}
Func function;
};
template< typename Func, typename Args, typename R >
class QskMetaMemberInvokable : public QskMetaInvokable
{
public:
explicit QskMetaMemberInvokable( Func f ):
QskMetaInvokable( &invoke ),
function(f)
{
}
static void invoke( int which, QtPrivate::QSlotObjectBase* invokable,
QObject* object, void** args, bool* ret )
{
typedef QtPrivate::FunctionPointer< Func > FuncType;
auto f = static_cast< QskMetaMemberInvokable* >( invokable );
switch (which)
{
case Destroy:
{
delete f;
break;
}
case Call:
{
FuncType::template call< Args, R >(
f->function, static_cast< typename FuncType::Object* >( object ), args );
break;
}
case Compare:
{
*ret = *reinterpret_cast< Func* >( args ) == f->function;
break;
}
case TypeInfo:
{
int* typeInfo = reinterpret_cast< int* >( args );
*typeInfo = 0; // = QskMetaFunction::Member
break;
}
}
}
private:
Func function;
};
template< typename Func, int N, typename Args, typename R >
class QskMetaFunctorInvokable : public QskMetaInvokable
{
public:
typedef QtPrivate::Functor< Func, N > FuncType;
explicit QskMetaFunctorInvokable( Func f ):
QskMetaInvokable( &invoke ),
function( std::move( f ) )
{
}
static void invoke( int which, QSlotObjectBase* invokable,
QObject* object, void** args, bool* )
{
auto f = static_cast< QskMetaFunctorInvokable* >( invokable );
switch (which)
{
case Destroy:
{
delete f;
break;
}
case Call:
{
FuncType::template call< Args, R >( f->function, object, args );
break;
}
case TypeInfo:
{
int* typeInfo = reinterpret_cast< int* >( args );
*typeInfo = 2; // QskMetaFunction::Functor;
break;
}
}
}
private:
Func function;
};
#endif

View File

@ -40,9 +40,9 @@ HEADERS += \
common/QskGlobal.h \
common/QskGradient.h \
common/QskMargins.h \
common/QskMetaCall.h \
common/QskMetaCallback.h \
common/QskMetaFunction.h \
common/QskMetaInvokable.cpp \
common/QskModule.h \
common/QskNamespace.h \
common/QskObjectCounter.h \
@ -59,9 +59,9 @@ SOURCES += \
common/QskFunctions.cpp \
common/QskGradient.cpp \
common/QskMargins.cpp \
common/QskMetaCall.cpp \
common/QskMetaCallback.cpp \
common/QskMetaFunction.cpp \
common/QskMetaInvokable.cpp \
common/QskModule.cpp \
common/QskObjectCounter.cpp \
common/QskSizePolicy.cpp \