6#include "QskMetaFunction.h"
8#include <qcoreapplication.h>
13#include <qsemaphore.h>
17#include <private/qobject_p.h>
28 FunctionCall::InvokeFunction invoke;
29 const int* parameterTypes;
32 static_assert(
sizeof( SlotObject ) ==
sizeof( FunctionCall ),
33 "Bad cast: QskMetaFunction does not match" );
36int QskMetaFunction::FunctionCall::typeInfo()
const
38 auto that =
const_cast< FunctionCall*
>( this );
42 reinterpret_cast< SlotObject*
>( that )->invoke(
43 TypeInfo, that,
nullptr,
reinterpret_cast< void**
>( &value ), nullptr );
48int QskMetaFunction::FunctionCall::refCount()
const
50 auto that =
const_cast< FunctionCall*
>( this );
51 return reinterpret_cast< SlotObject*
>( that )->ref.loadRelaxed();
54QskMetaFunction::QskMetaFunction()
55 : m_functionCall( nullptr )
59QskMetaFunction::QskMetaFunction( FunctionCall* functionCall )
60 : m_functionCall( functionCall )
63 m_functionCall->ref();
67 : m_functionCall( other.m_functionCall )
70 m_functionCall->ref();
74 : m_functionCall( other.m_functionCall )
76 other.m_functionCall =
nullptr;
79QskMetaFunction::~QskMetaFunction()
82 m_functionCall->destroyIfLastRef();
87 if ( m_functionCall != other.m_functionCall )
90 m_functionCall->destroyIfLastRef();
92 m_functionCall = other.m_functionCall;
93 other.m_functionCall =
nullptr;
101 if ( m_functionCall != other.m_functionCall )
103 if ( m_functionCall )
104 m_functionCall->destroyIfLastRef();
106 m_functionCall = other.m_functionCall;
108 if ( m_functionCall )
109 m_functionCall->ref();
117 if ( m_functionCall == other.m_functionCall )
129 if ( m_functionCall && other.m_functionCall )
131 if ( m_functionCall->typeInfo() == StaticFunction &&
132 other.m_functionCall->typeInfo() == StaticFunction )
135 return m_functionCall->compare(
136 reinterpret_cast< void**
>( other.m_functionCall ) );
143int QskMetaFunction::returnType()
const
145 return QMetaType::Void;
148size_t QskMetaFunction::parameterCount()
const
152 if (
auto types = parameterTypes() )
154 while ( types[ count ] != QMetaType::UnknownType )
161QskMetaFunction::Type QskMetaFunction::functionType()
const
163 if ( m_functionCall ==
nullptr )
166 return static_cast< QskMetaFunction::Type
>( m_functionCall->typeInfo() );
169void QskMetaFunction::invoke( QObject*
object,
170 void* argv[], Qt::ConnectionType connectionType )
181 if ( m_functionCall ==
nullptr )
184 QPointer< QObject > receiver(
object );
186 int invokeType = connectionType & 0x3;
188 if ( invokeType == Qt::AutoConnection )
190 invokeType = ( receiver && receiver->thread() != QThread::currentThread() )
191 ? Qt::QueuedConnection : Qt::DirectConnection;
194 switch ( invokeType )
196 case Qt::DirectConnection:
198 m_functionCall->call( receiver, argv );
201 case Qt::BlockingQueuedConnection:
203 if ( receiver.isNull() ||
204 ( receiver->thread() == QThread::currentThread() ) )
211 QSemaphore semaphore;
213 auto event =
new QMetaCallEvent(
214 m_functionCall,
nullptr, 0, argv, &semaphore );
216 auto event =
new QMetaCallEvent(
217 m_functionCall,
nullptr, 0, argv,
nullptr );
220 QCoreApplication::postEvent( receiver, event );
228 case Qt::QueuedConnection:
230 if ( receiver.isNull() )
233 const auto argc = parameterCount() + 1;
235 auto event =
new QMetaCallEvent( m_functionCall,
nullptr, 0, argc );
237 auto types =
event->types();
238 auto arguments =
event->args();
240#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
241 types[0] = QMetaType();
242 arguments[ 0 ] =
nullptr;
245 arguments[ 0 ] =
nullptr;
248 const int* parameterTypes = m_functionCall->parameterTypes();
249 for ( uint i = 1; i < argc; i++ )
251 if ( argv[ i ] ==
nullptr )
253 Q_ASSERT( arguments[ i ] !=
nullptr );
258 const auto type = parameterTypes[i - 1];
260#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
261 types[ i ] = QMetaType( type );
262 arguments[ i ] = QMetaType( type ).create( argv[ i ] );
265 arguments[ i ] = QMetaType::create( type, argv[ i ] );
270 QCoreApplication::postEvent( receiver, event );
279#include "moc_QskMetaFunction.cpp"