2018-02-28 09:43:15 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* 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
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
class QSK_EXPORT QskMetaInvokable : public QtPrivate::QSlotObjectBase
|
2018-02-28 09:43:15 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef void (* InvokeFunction)(
|
|
|
|
int which, QtPrivate::QSlotObjectBase*, QObject*, void**, bool* );
|
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
TypeInfo = NumOperations + 1,
|
|
|
|
Create,
|
|
|
|
Find
|
|
|
|
};
|
2018-02-28 09:43:15 +00:00
|
|
|
|
|
|
|
int typeInfo() const;
|
|
|
|
int refCount() const;
|
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
static QskMetaInvokable* instance( InvokeFunction, void** function );
|
2018-02-28 15:48:46 +00:00
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
protected:
|
2018-03-01 14:13:55 +00:00
|
|
|
explicit inline QskMetaInvokable( InvokeFunction f ):
|
2018-02-28 09:43:15 +00:00
|
|
|
QSlotObjectBase( f )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
template< typename Function, typename Args, typename R >
|
2018-02-28 09:43:15 +00:00
|
|
|
class QskMetaFunctionInvokable : public QskMetaInvokable
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
using Invokable = QskMetaFunctionInvokable< Function, Args, R >;
|
2018-02-28 09:43:15 +00:00
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
public:
|
|
|
|
explicit inline QskMetaFunctionInvokable( Function function ):
|
2018-02-28 09:43:15 +00:00
|
|
|
QskMetaInvokable( &invoke ),
|
2018-02-28 15:48:46 +00:00
|
|
|
m_function( function )
|
2018-02-28 09:43:15 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
static void invoke(int which, QtPrivate::QSlotObjectBase*,
|
2018-02-28 09:43:15 +00:00
|
|
|
QObject* object, void** args, bool* )
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
static Invokable* invokable = nullptr;
|
2018-02-28 09:43:15 +00:00
|
|
|
|
|
|
|
switch ( which )
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
case Find:
|
|
|
|
{
|
|
|
|
*reinterpret_cast< void** >( args[0] ) = invokable;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Create:
|
|
|
|
{
|
|
|
|
invokable = new Invokable( *reinterpret_cast< Function* >( args[1] ) );
|
|
|
|
*reinterpret_cast< void** >( args[0] ) = invokable;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-02-28 09:43:15 +00:00
|
|
|
case Destroy:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
delete invokable;
|
|
|
|
invokable = nullptr;
|
2018-02-28 15:48:46 +00:00
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Call:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
typedef QtPrivate::FunctionPointer< Function > FuncType;
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
FuncType::template call< Args, R >(
|
2018-03-01 11:18:58 +00:00
|
|
|
invokable->m_function, object, args );
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TypeInfo:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
*reinterpret_cast< int* >( args ) = 1; // QskMetaFunction::Function
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
private:
|
2018-02-28 15:48:46 +00:00
|
|
|
Function m_function;
|
2018-02-28 09:43:15 +00:00
|
|
|
};
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
template< typename Function, typename Args, typename R >
|
2018-02-28 09:43:15 +00:00
|
|
|
class QskMetaMemberInvokable : public QskMetaInvokable
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
using Invokable = QskMetaMemberInvokable< Function, Args, R >;
|
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
public:
|
2018-03-01 11:18:58 +00:00
|
|
|
explicit inline QskMetaMemberInvokable( Function function ):
|
2018-02-28 09:43:15 +00:00
|
|
|
QskMetaInvokable( &invoke ),
|
2018-02-28 15:48:46 +00:00
|
|
|
m_function( function )
|
2018-02-28 09:43:15 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
static void invoke( int which, QtPrivate::QSlotObjectBase*,
|
2018-02-28 09:43:15 +00:00
|
|
|
QObject* object, void** args, bool* ret )
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
static Invokable* invokable = nullptr;
|
2018-02-28 09:43:15 +00:00
|
|
|
|
|
|
|
switch (which)
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
case Find:
|
|
|
|
{
|
|
|
|
*reinterpret_cast< void** >( args[0] ) = invokable;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Create:
|
|
|
|
{
|
|
|
|
invokable = new Invokable( *reinterpret_cast< Function* >( args[1] ) );
|
|
|
|
*reinterpret_cast< void** >( args[0] ) = invokable;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-02-28 09:43:15 +00:00
|
|
|
case Destroy:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
delete invokable;
|
|
|
|
invokable = nullptr;
|
2018-02-28 15:48:46 +00:00
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Call:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
typedef QtPrivate::FunctionPointer< Function > FuncType;
|
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
FuncType::template call< Args, R >(
|
2018-03-01 11:18:58 +00:00
|
|
|
invokable->m_function,
|
2018-02-28 15:48:46 +00:00
|
|
|
static_cast< typename FuncType::Object* >( object ), args );
|
2018-02-28 09:43:15 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Compare:
|
|
|
|
{
|
2018-02-28 15:48:46 +00:00
|
|
|
const auto function = *reinterpret_cast< Function* >( args );
|
2018-03-01 11:18:58 +00:00
|
|
|
*ret = function == invokable->m_function;
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TypeInfo:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
*reinterpret_cast< int* >( args ) = 0; // = QskMetaFunction::Member
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-02-28 15:48:46 +00:00
|
|
|
Function m_function;
|
2018-02-28 09:43:15 +00:00
|
|
|
};
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
template< typename Function, int N, typename Args, typename R >
|
2018-02-28 09:43:15 +00:00
|
|
|
class QskMetaFunctorInvokable : public QskMetaInvokable
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
using Invokable = QskMetaFunctorInvokable< Function, N, Args, R >;
|
2018-02-28 09:43:15 +00:00
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
public:
|
|
|
|
explicit inline QskMetaFunctorInvokable( Function function ):
|
2018-02-28 09:43:15 +00:00
|
|
|
QskMetaInvokable( &invoke ),
|
2018-03-01 11:18:58 +00:00
|
|
|
m_function( function )
|
2018-02-28 09:43:15 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:18:58 +00:00
|
|
|
static void invoke( int which, QSlotObjectBase*, QObject* object, void** args, bool* )
|
2018-02-28 09:43:15 +00:00
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
static Invokable* invokable = nullptr;
|
2018-02-28 09:43:15 +00:00
|
|
|
|
|
|
|
switch (which)
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
case Find:
|
|
|
|
{
|
|
|
|
*reinterpret_cast< void** >( args[0] ) = invokable;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Create:
|
|
|
|
{
|
|
|
|
invokable = new Invokable( *reinterpret_cast< Function* >( args[1] ) );
|
|
|
|
*reinterpret_cast< void** >( args[0] ) = invokable;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-02-28 09:43:15 +00:00
|
|
|
case Destroy:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
delete invokable;
|
|
|
|
invokable = nullptr;
|
2018-02-28 15:48:46 +00:00
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Call:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
typedef QtPrivate::Functor< Function, N > FuncType;
|
|
|
|
|
2018-02-28 15:48:46 +00:00
|
|
|
FuncType::template call< Args, R >(
|
2018-03-01 11:18:58 +00:00
|
|
|
invokable->m_function, object, args );
|
|
|
|
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TypeInfo:
|
|
|
|
{
|
2018-03-01 11:18:58 +00:00
|
|
|
*reinterpret_cast< int* >( args ) = 2; // QskMetaFunction::Functor
|
2018-02-28 09:43:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-02-28 15:48:46 +00:00
|
|
|
Function m_function;
|
2018-02-28 09:43:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|