198 lines
5.3 KiB
C
198 lines
5.3 KiB
C
|
/******************************************************************************
|
||
|
* 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&, 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;
|
||
|
|
||
|
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
|