non working ideas removed
This commit is contained in:
parent
686f4ff2d8
commit
a9f5e0a528
@ -4,6 +4,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "Invoker.h"
|
#include "Invoker.h"
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
Invoker::Invoker( QObject* parent ):
|
Invoker::Invoker( QObject* parent ):
|
||||||
QObject( parent )
|
QObject( parent )
|
||||||
@ -47,9 +48,28 @@ void Invoker::invoke( qreal realValue, int intValue,
|
|||||||
|
|
||||||
callback.setConnectionType( connectionType );
|
callback.setConnectionType( connectionType );
|
||||||
|
|
||||||
if ( connectionType == Qt::DirectConnection )
|
const int callType = connectionType & 0x3;
|
||||||
callback.invoke( args );
|
switch( callType )
|
||||||
else if ( callback.object() )
|
{
|
||||||
callback.invoke( args );
|
case Qt::DirectConnection:
|
||||||
|
{
|
||||||
|
callback.invoke( args );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Qt::QueuedConnection:
|
||||||
|
{
|
||||||
|
if ( callback.object() )
|
||||||
|
callback.invoke( args );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Qt::BlockingQueuedConnection:
|
||||||
|
{
|
||||||
|
const auto receiver = callback.object();
|
||||||
|
if ( receiver && receiver->thread() != QThread::currentThread() )
|
||||||
|
callback.invoke( args );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
static void debugNone1()
|
static void debugNone1()
|
||||||
{
|
{
|
||||||
@ -40,17 +41,20 @@ static void debugValue( qreal d, int i )
|
|||||||
|
|
||||||
class MyObject : public QObject
|
class MyObject : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MyObject( QObject* parent = nullptr ):
|
MyObject( QObject* parent = nullptr ):
|
||||||
QObject( parent )
|
QObject( parent )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print0( double d, int i ) const
|
||||||
|
{
|
||||||
|
qDebug() << "print0" << d << i;
|
||||||
|
}
|
||||||
|
|
||||||
void print1( double d, int i ) const
|
void print1( double d, int i ) const
|
||||||
{
|
{
|
||||||
qDebug() << d << i;
|
qDebug() << "print1" << d << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print2( int i, double d ) const
|
void print2( int i, double d ) const
|
||||||
@ -67,83 +71,96 @@ public:
|
|||||||
{
|
{
|
||||||
qDebug() << i;
|
qDebug() << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void done( double, int );
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyObject2: public MyObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MyObject2( QObject* parent = nullptr ):
|
|
||||||
MyObject( parent )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MyObject2()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void noop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto fs = []( int i, double d ) { qDebug() << i << d; };
|
static auto fs = []( int i, double d ) { qDebug() << i << d; };
|
||||||
|
|
||||||
|
class Application: public QCoreApplication
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Application( int &argc, char *argv[] ):
|
||||||
|
QCoreApplication( argc, argv ),
|
||||||
|
m_object( new MyObject() ),
|
||||||
|
m_thread( new QThread( this ) )
|
||||||
|
{
|
||||||
|
auto f = [this]( int i, double d ) { qDebug() << i << d << (++m_num); };
|
||||||
|
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print0 );
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print1 );
|
||||||
|
m_invoker.addCallback( QskMetaFunction() );
|
||||||
|
m_invoker.addCallback( debugNone1 );
|
||||||
|
m_invoker.addCallback( debugNone2 );
|
||||||
|
m_invoker.addCallback( debugValue );
|
||||||
|
m_invoker.addCallback( debugValueI1 );
|
||||||
|
m_invoker.addCallback( debugValueI2 );
|
||||||
|
m_invoker.addCallback( debugValueD );
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print0 );
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print1 );
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print2 );
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print3 );
|
||||||
|
m_invoker.addCallback( m_object, &MyObject::print4 );
|
||||||
|
m_invoker.addCallback( m_object, []( double d, int i ) { qDebug() << d << i; } );
|
||||||
|
|
||||||
|
m_invoker.addCallback( m_object, f );
|
||||||
|
m_invoker.addCallback( m_object, fs );
|
||||||
|
|
||||||
|
m_invoker.addCallback( m_object, []( double d ) { qDebug() << d; } );
|
||||||
|
m_invoker.addCallback( []() { qDebug() << "HERE"; } );
|
||||||
|
m_invoker.addCallback( []( int i, double d ) { qDebug() << i << d; } );
|
||||||
|
m_invoker.addCallback( []( int i ) { qDebug() << "I1" << i; } );
|
||||||
|
m_invoker.addCallback( []( int i ) { qDebug() << "I2" << i; } );
|
||||||
|
m_invoker.addCallback( []( double d ) { qDebug() << "V" << d; } );
|
||||||
|
m_invoker.addCallback( []( const double& d ) { qDebug() << "R" << d; } );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Application()
|
||||||
|
{
|
||||||
|
delete m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invokeDirect()
|
||||||
|
{
|
||||||
|
qDebug() << "== Direct Connections";
|
||||||
|
m_invoker.invoke( 3.14, 35, Qt::DirectConnection );
|
||||||
|
}
|
||||||
|
|
||||||
|
void invokeQueued()
|
||||||
|
{
|
||||||
|
qDebug() << "== Queued Connections";
|
||||||
|
m_invoker.invoke( 0.07, 42, Qt::QueuedConnection );
|
||||||
|
}
|
||||||
|
|
||||||
|
void invokeBlockingQueued()
|
||||||
|
{
|
||||||
|
m_thread->start();
|
||||||
|
|
||||||
|
m_object->moveToThread( m_thread );
|
||||||
|
|
||||||
|
qDebug() << "== Blocking Queued Connections";
|
||||||
|
m_invoker.invoke( 0.54, 88, Qt::BlockingQueuedConnection );
|
||||||
|
|
||||||
|
QTimer::singleShot( 10, m_thread, &QThread::quit );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Invoker m_invoker;
|
||||||
|
MyObject* m_object;
|
||||||
|
QThread* m_thread;
|
||||||
|
|
||||||
|
int m_num = 111;
|
||||||
|
};
|
||||||
|
|
||||||
int main( int argc, char* argv[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
QCoreApplication app( argc, argv );
|
Application app( argc, argv );
|
||||||
|
|
||||||
MyObject object;
|
app.invokeDirect();
|
||||||
MyObject2 object2;
|
|
||||||
|
|
||||||
int num = 111;
|
QTimer::singleShot( 0, &app, &Application::invokeQueued );
|
||||||
auto f = [&num]( int i, double d ) { qDebug() << i << d << (++num); };
|
QTimer::singleShot( 20, &app, &Application::invokeBlockingQueued );
|
||||||
|
|
||||||
Invoker invoker;
|
QTimer::singleShot( 50, &app, QCoreApplication::quit );
|
||||||
|
|
||||||
#if 1
|
|
||||||
invoker.addCallback( QskMetaFunction() );
|
|
||||||
invoker.addCallback( debugNone1 );
|
|
||||||
invoker.addCallback( debugNone2 );
|
|
||||||
invoker.addCallback( debugValue );
|
|
||||||
invoker.addCallback( debugValueI1 );
|
|
||||||
invoker.addCallback( debugValueI2 );
|
|
||||||
invoker.addCallback( debugValueD );
|
|
||||||
invoker.addCallback( &object, &MyObject::print1 );
|
|
||||||
invoker.addCallback( &object2, &MyObject2::print1 );
|
|
||||||
invoker.addCallback( &object, &MyObject::print2 );
|
|
||||||
invoker.addCallback( &object, &MyObject::print3 );
|
|
||||||
invoker.addCallback( &object, &MyObject::print4 );
|
|
||||||
invoker.addCallback( &object, []( double d, int i ) { qDebug() << d << i; } );
|
|
||||||
|
|
||||||
invoker.addCallback( &object, f );
|
|
||||||
invoker.addCallback( &object2, f );
|
|
||||||
invoker.addCallback( &object, fs );
|
|
||||||
invoker.addCallback( &object2, fs );
|
|
||||||
|
|
||||||
invoker.addCallback( &object, []( double d ) { qDebug() << d; } );
|
|
||||||
invoker.addCallback( []() { qDebug() << "HERE"; } );
|
|
||||||
invoker.addCallback( []( int i, double d ) { qDebug() << i << d; } );
|
|
||||||
invoker.addCallback( []( int i ) { qDebug() << "I1" << i; } );
|
|
||||||
invoker.addCallback( []( int i ) { qDebug() << "I2" << i; } );
|
|
||||||
invoker.addCallback( []( double d ) { qDebug() << d; } );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
qDebug() << "== Direct Connections";
|
|
||||||
invoker.invoke( 3.14, 35, Qt::DirectConnection );
|
|
||||||
|
|
||||||
qDebug() << "\n\n== Queued Connections";
|
|
||||||
|
|
||||||
QTimer::singleShot( 0,
|
|
||||||
[&invoker] { invoker.invoke( 0.07, 42, Qt::QueuedConnection ); } );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QTimer::singleShot( 100, &app, QCoreApplication::quit );
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "main.moc"
|
|
||||||
|
@ -33,13 +33,6 @@ QskMetaFunction::QskMetaFunction():
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QskMetaFunction::QskMetaFunction( void(*function)() ):
|
|
||||||
m_invokable( QskMetaInvokable::instance(
|
|
||||||
QskMetaFunctionInvokable0::invoke, nullptr,
|
|
||||||
reinterpret_cast< void** >( &function ) ) )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QskMetaFunction::QskMetaFunction( QskMetaInvokable* invokable ):
|
QskMetaFunction::QskMetaFunction( QskMetaInvokable* invokable ):
|
||||||
m_invokable( invokable )
|
m_invokable( invokable )
|
||||||
{
|
{
|
||||||
@ -122,6 +115,10 @@ QskMetaFunction::Type QskMetaFunction::functionType() const
|
|||||||
void QskMetaFunction::invoke(
|
void QskMetaFunction::invoke(
|
||||||
QObject* object, void* argv[], Qt::ConnectionType connectionType )
|
QObject* object, void* argv[], Qt::ConnectionType connectionType )
|
||||||
{
|
{
|
||||||
|
// code is not thread safe - TODO ...
|
||||||
|
|
||||||
|
QPointer<QObject> receiver( object );
|
||||||
|
|
||||||
if ( m_invokable == nullptr )
|
if ( m_invokable == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -129,72 +126,73 @@ void QskMetaFunction::invoke(
|
|||||||
|
|
||||||
if ( invokeType == Qt::AutoConnection )
|
if ( invokeType == Qt::AutoConnection )
|
||||||
{
|
{
|
||||||
invokeType = ( object && object->thread() != QThread::currentThread() )
|
invokeType = ( receiver && receiver->thread() != QThread::currentThread() )
|
||||||
? Qt::QueuedConnection : Qt::DirectConnection;
|
? Qt::QueuedConnection : Qt::DirectConnection;
|
||||||
}
|
}
|
||||||
else if ( invokeType == Qt::BlockingQueuedConnection )
|
|
||||||
|
switch( invokeType )
|
||||||
{
|
{
|
||||||
if ( ( object == nullptr ) || object->thread() == QThread::currentThread() )
|
case Qt::DirectConnection:
|
||||||
{
|
{
|
||||||
// We would end up in a deadlock, better do nothing
|
m_invokable->call( receiver, argv );
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
case Qt::BlockingQueuedConnection:
|
||||||
|
|
||||||
if ( invokeType == Qt::DirectConnection )
|
|
||||||
{
|
|
||||||
m_invokable->call( object, argv );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( object == nullptr )
|
|
||||||
{
|
{
|
||||||
#if 1
|
if ( receiver.isNull()
|
||||||
/*
|
|| ( receiver->thread() == QThread::currentThread() ) )
|
||||||
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;
|
|
||||||
|
|
||||||
const int* parameterTypes = m_invokable->parameterTypes();
|
|
||||||
for ( uint i = 1; i < argc; i++ )
|
|
||||||
{
|
|
||||||
if ( argv[i] == nullptr )
|
|
||||||
{
|
{
|
||||||
Q_ASSERT( arguments[i] != nullptr );
|
// We would end up in a deadlock, better do nothing
|
||||||
|
|
||||||
free( types );
|
|
||||||
free( arguments );
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
types[i] = parameterTypes[i - 1];
|
|
||||||
arguments[i] = QMetaType::create( parameterTypes[i - 1], argv[i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( connectionType == Qt::QueuedConnection )
|
|
||||||
{
|
|
||||||
qskInvokeFunctionQueued( object, m_invokable, argc, types, arguments );
|
|
||||||
}
|
|
||||||
else // Qt::BlockingQueuedConnection ???
|
|
||||||
{
|
|
||||||
QSemaphore semaphore;
|
QSemaphore semaphore;
|
||||||
|
|
||||||
qskInvokeFunctionQueued( object,
|
qskInvokeFunctionQueued( receiver, m_invokable,
|
||||||
m_invokable, argc, types, arguments, &semaphore );
|
0, nullptr, argv, &semaphore );
|
||||||
|
|
||||||
semaphore.acquire();
|
semaphore.acquire();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Qt::QueuedConnection:
|
||||||
|
{
|
||||||
|
if ( receiver.isNull() )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
const int* parameterTypes = m_invokable->parameterTypes();
|
||||||
|
for ( uint i = 1; i < argc; i++ )
|
||||||
|
{
|
||||||
|
if ( argv[i] == nullptr )
|
||||||
|
{
|
||||||
|
Q_ASSERT( arguments[i] != nullptr );
|
||||||
|
receiver = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
types[i] = parameterTypes[i - 1];
|
||||||
|
arguments[i] = QMetaType::create( parameterTypes[i - 1], argv[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( receiver.isNull() )
|
||||||
|
{
|
||||||
|
// object might have died in the meantime
|
||||||
|
free( types );
|
||||||
|
free( arguments );
|
||||||
|
}
|
||||||
|
|
||||||
|
qskInvokeFunctionQueued( object, m_invokable, argc, types, arguments );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ namespace QskMetaFunctionTraits
|
|||||||
template< typename T >
|
template< typename T >
|
||||||
using IsFunction0 = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
|
using IsFunction0 = typename std::enable_if< !FunctionPointer< T >::IsPointerToMemberFunction
|
||||||
&& FunctionPointer< T >::ArgumentCount == 0, std::true_type >::type;
|
&& FunctionPointer< T >::ArgumentCount == 0, std::true_type >::type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class QSK_EXPORT QskMetaFunction
|
class QSK_EXPORT QskMetaFunction
|
||||||
@ -59,8 +58,6 @@ public:
|
|||||||
QskMetaFunction( const QskMetaFunction& );
|
QskMetaFunction( const QskMetaFunction& );
|
||||||
QskMetaFunction( QskMetaFunction&& );
|
QskMetaFunction( QskMetaFunction&& );
|
||||||
|
|
||||||
QskMetaFunction( void(*function)() );
|
|
||||||
|
|
||||||
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr >
|
template< typename T, QskMetaFunctionTraits::IsMemberFunction< T >* = nullptr >
|
||||||
QskMetaFunction( T );
|
QskMetaFunction( T );
|
||||||
|
|
||||||
@ -115,10 +112,9 @@ inline QskMetaFunction::QskMetaFunction( T function )
|
|||||||
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 = QskMetaInvokable::instance(
|
m_invokable = new QskMetaMemberInvokable< T, Args, void >( function );
|
||||||
QskMetaMemberInvokable< T, Args, void >::invoke,
|
m_invokable->setParameterTypes(
|
||||||
ConnectionTypes< typename Traits::Arguments >::types(),
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
||||||
reinterpret_cast< void** >( &function ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
|
template< typename T, QskMetaFunctionTraits::IsFunctor< T >* >
|
||||||
@ -131,10 +127,9 @@ inline QskMetaFunction::QskMetaFunction( T functor )
|
|||||||
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 = QskMetaInvokable::instance(
|
m_invokable = new QskMetaFunctorInvokable< T, Argc, Args, void >( functor );
|
||||||
QskMetaFunctorInvokable< T, Argc, Args, void >::invoke,
|
m_invokable->setParameterTypes(
|
||||||
ConnectionTypes< typename Traits::Arguments >::types(),
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
||||||
reinterpret_cast< void** >( &functor ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
|
template< typename T, QskMetaFunctionTraits::IsFunction< T >* >
|
||||||
@ -146,11 +141,10 @@ inline QskMetaFunction::QskMetaFunction( T function )
|
|||||||
|
|
||||||
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 = QskMetaInvokable::instance(
|
m_invokable = new QskMetaFunctionInvokable< T, Args, void >( function );
|
||||||
QskMetaFunctionInvokable< T, Args, void >::invoke,
|
m_invokable->setParameterTypes(
|
||||||
ConnectionTypes< typename Traits::Arguments >::types(),
|
ConnectionTypes< typename Traits::Arguments >::types() );
|
||||||
reinterpret_cast< void** >( &function ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE( QskMetaFunction )
|
Q_DECLARE_METATYPE( QskMetaFunction )
|
||||||
|
@ -19,39 +19,6 @@ namespace
|
|||||||
"Bad cast: QskMetaInvokable does not match" );
|
"Bad cast: QskMetaInvokable does not match" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void qskCallFunction( void (*function)(),
|
|
||||||
void** args, const int* types )
|
|
||||||
{
|
|
||||||
if ( types == nullptr || args == nullptr )
|
|
||||||
{
|
|
||||||
function();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QskMetaInvokable* QskMetaInvokable::instance(
|
|
||||||
InvokeFunction invoke, const int* parameterTypes, void** functor )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
In opposite to QObject::connect we share the Invokable for callbacks to the same
|
|
||||||
function/functor - like f.e QQuickItem::update(). But we have to pay an extra static
|
|
||||||
pointer inside of each callback instance.
|
|
||||||
*/
|
|
||||||
QskMetaInvokable* invokable;
|
|
||||||
void* args[] = { &invokable, functor };
|
|
||||||
|
|
||||||
invoke( Find, nullptr, nullptr, args, nullptr );
|
|
||||||
|
|
||||||
if ( invokable )
|
|
||||||
invokable->ref();
|
|
||||||
else
|
|
||||||
invoke( Create, nullptr, nullptr, args, nullptr );
|
|
||||||
|
|
||||||
invokable->m_parameterTypes = parameterTypes;
|
|
||||||
|
|
||||||
return invokable;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QskMetaInvokable::typeInfo() const
|
int QskMetaInvokable::typeInfo() const
|
||||||
{
|
{
|
||||||
auto that = const_cast< QskMetaInvokable* >( this );
|
auto that = const_cast< QskMetaInvokable* >( this );
|
||||||
@ -69,47 +36,3 @@ int QskMetaInvokable::refCount() const
|
|||||||
auto that = const_cast< QskMetaInvokable* >( this );
|
auto that = const_cast< QskMetaInvokable* >( this );
|
||||||
return reinterpret_cast< SlotObject* >( that )->ref.load();
|
return reinterpret_cast< SlotObject* >( that )->ref.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
QskMetaFunctionInvokable0::QskMetaFunctionInvokable0( Function function ):
|
|
||||||
QskMetaInvokable( &invoke, nullptr ),
|
|
||||||
m_function( function )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskMetaFunctionInvokable0::invoke(int which, QtPrivate::QSlotObjectBase* invokable,
|
|
||||||
QObject*, void** args, bool* )
|
|
||||||
{
|
|
||||||
switch ( which )
|
|
||||||
{
|
|
||||||
case Find:
|
|
||||||
{
|
|
||||||
*reinterpret_cast< void** >( args[0] ) = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Create:
|
|
||||||
{
|
|
||||||
*reinterpret_cast< void** >( args[0] ) =
|
|
||||||
new Invokable( *reinterpret_cast< Function* >( args[1] ) );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Destroy:
|
|
||||||
{
|
|
||||||
delete static_cast< Invokable* >( invokable );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Call:
|
|
||||||
{
|
|
||||||
auto invokable01 = static_cast< Invokable* >( invokable );
|
|
||||||
qskCallFunction( invokable01->m_function,
|
|
||||||
args, invokable01->parameterTypes() );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TypeInfo:
|
|
||||||
{
|
|
||||||
*reinterpret_cast< int* >( args ) = 1; // QskMetaFunction::Function
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -19,9 +19,7 @@ public:
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TypeInfo = NumOperations + 1,
|
TypeInfo = NumOperations + 1
|
||||||
Create,
|
|
||||||
Find
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int typeInfo() const;
|
int typeInfo() const;
|
||||||
@ -32,8 +30,10 @@ public:
|
|||||||
return m_parameterTypes;
|
return m_parameterTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QskMetaInvokable* instance( InvokeFunction,
|
inline void setParameterTypes( const int* types )
|
||||||
const int* parameterTypes, void** function );
|
{
|
||||||
|
m_parameterTypes = types;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit inline QskMetaInvokable( InvokeFunction f,
|
explicit inline QskMetaInvokable( InvokeFunction f,
|
||||||
@ -44,22 +44,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int* m_parameterTypes; // static array !
|
const int* m_parameterTypes; // static array, only needed for Qt::QueuedConnection
|
||||||
};
|
|
||||||
|
|
||||||
class QSK_EXPORT QskMetaFunctionInvokable0 : public QskMetaInvokable
|
|
||||||
{
|
|
||||||
using Function = void(*)();
|
|
||||||
using Invokable = QskMetaFunctionInvokable0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QskMetaFunctionInvokable0( Function function );
|
|
||||||
|
|
||||||
static void invoke(int which, QtPrivate::QSlotObjectBase*,
|
|
||||||
QObject* object, void** args, bool* );
|
|
||||||
|
|
||||||
private:
|
|
||||||
Function m_function;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Function, typename Args, typename R >
|
template< typename Function, typename Args, typename R >
|
||||||
@ -79,18 +64,6 @@ public:
|
|||||||
{
|
{
|
||||||
switch ( which )
|
switch ( which )
|
||||||
{
|
{
|
||||||
case Find:
|
|
||||||
{
|
|
||||||
*reinterpret_cast< void** >( args[0] ) = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Create:
|
|
||||||
{
|
|
||||||
*reinterpret_cast< void** >( args[0] ) =
|
|
||||||
new Invokable( *reinterpret_cast< Function* >( args[1] ) );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Destroy:
|
case Destroy:
|
||||||
{
|
{
|
||||||
delete static_cast< Invokable* >( invokable );
|
delete static_cast< Invokable* >( invokable );
|
||||||
@ -128,30 +101,14 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void invoke( int which, QtPrivate::QSlotObjectBase*,
|
static void invoke( int which, QtPrivate::QSlotObjectBase* slotObject,
|
||||||
QObject* object, void** args, bool* )
|
QObject* object, void** args, bool* )
|
||||||
{
|
{
|
||||||
static Invokable* invokable = nullptr;
|
|
||||||
|
|
||||||
switch (which)
|
switch (which)
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
}
|
|
||||||
case Destroy:
|
case Destroy:
|
||||||
{
|
{
|
||||||
delete invokable;
|
delete static_cast< Invokable* >( slotObject );
|
||||||
invokable = nullptr;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Call:
|
case Call:
|
||||||
@ -159,7 +116,7 @@ public:
|
|||||||
typedef QtPrivate::FunctionPointer< Function > FuncType;
|
typedef QtPrivate::FunctionPointer< Function > FuncType;
|
||||||
|
|
||||||
FuncType::template call< Args, R >(
|
FuncType::template call< Args, R >(
|
||||||
invokable->m_function,
|
static_cast< Invokable* >( slotObject )->m_function,
|
||||||
static_cast< typename FuncType::Object* >( object ), args );
|
static_cast< typename FuncType::Object* >( object ), args );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -188,29 +145,14 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void invoke( int which, QSlotObjectBase*, QObject* object, void** args, bool* )
|
static void invoke( int which, QSlotObjectBase* slotObject,
|
||||||
|
QObject* object, void** args, bool* )
|
||||||
{
|
{
|
||||||
static Invokable* invokable = nullptr;
|
|
||||||
|
|
||||||
switch (which)
|
switch (which)
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
}
|
|
||||||
case Destroy:
|
case Destroy:
|
||||||
{
|
{
|
||||||
delete invokable;
|
delete static_cast< Invokable* >( slotObject );
|
||||||
invokable = nullptr;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Call:
|
case Call:
|
||||||
@ -218,7 +160,7 @@ public:
|
|||||||
typedef QtPrivate::Functor< Function, N > FuncType;
|
typedef QtPrivate::Functor< Function, N > FuncType;
|
||||||
|
|
||||||
FuncType::template call< Args, R >(
|
FuncType::template call< Args, R >(
|
||||||
invokable->m_function, object, args );
|
static_cast< Invokable* >( slotObject )->m_function, object, args );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user