qskinny/src/common/QskMetaInvokable.h

227 lines
5.8 KiB
C
Raw Normal View History

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-02 05:57:08 +00:00
inline const int* parameterTypes() const
{
return m_parameterTypes;
}
static QskMetaInvokable* instance( InvokeFunction,
const int* parameterTypes, void** function );
2018-02-28 15:48:46 +00:00
2018-03-01 11:18:58 +00:00
protected:
2018-03-02 05:57:08 +00:00
explicit inline QskMetaInvokable( InvokeFunction f,
const int* m_parameterTypes = nullptr ):
QSlotObjectBase( f ),
m_parameterTypes( m_parameterTypes )
2018-02-28 09:43:15 +00:00
{
}
2018-03-02 05:57:08 +00:00
private:
const int* m_parameterTypes; // static array !
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 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-03-01 16:11:59 +00:00
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::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 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