6#include "QskMetaFunction.h"
7#include "QskInternalMacros.h"
9#include <qcoreapplication.h>
14#include <qsemaphore.h>
18#include <private/qobject_p.h>
29 FunctionCall::InvokeFunction invoke;
30 const int* parameterTypes;
33 static_assert(
sizeof( SlotObject ) ==
sizeof( FunctionCall ),
34 "Bad cast: QskMetaFunction does not match" );
37int QskMetaFunction::FunctionCall::typeInfo()
const
39 auto that =
const_cast< FunctionCall*
>( this );
43 reinterpret_cast< SlotObject*
>( that )->invoke(
44 TypeInfo, that,
nullptr,
reinterpret_cast< void**
>( &value ), nullptr );
49int QskMetaFunction::FunctionCall::refCount()
const
51 auto that =
const_cast< FunctionCall*
>( this );
52 return reinterpret_cast< SlotObject*
>( that )->ref.loadRelaxed();
55QskMetaFunction::QskMetaFunction()
56 : m_functionCall( nullptr )
60QskMetaFunction::QskMetaFunction( FunctionCall* functionCall )
61 : m_functionCall( functionCall )
64 m_functionCall->ref();
68 : m_functionCall( other.m_functionCall )
71 m_functionCall->ref();
75 : m_functionCall( other.m_functionCall )
77 other.m_functionCall =
nullptr;
80QskMetaFunction::~QskMetaFunction()
83 m_functionCall->destroyIfLastRef();
88 if ( m_functionCall != other.m_functionCall )
91 m_functionCall->destroyIfLastRef();
93 m_functionCall = other.m_functionCall;
94 other.m_functionCall =
nullptr;
102 if ( m_functionCall != other.m_functionCall )
104 if ( m_functionCall )
105 m_functionCall->destroyIfLastRef();
107 m_functionCall = other.m_functionCall;
109 if ( m_functionCall )
110 m_functionCall->ref();
118 if ( m_functionCall == other.m_functionCall )
130 if ( m_functionCall && other.m_functionCall )
132 if ( m_functionCall->typeInfo() == StaticFunction &&
133 other.m_functionCall->typeInfo() == StaticFunction )
136 return m_functionCall->compare(
137 reinterpret_cast< void**
>( other.m_functionCall ) );
144int QskMetaFunction::returnType()
const
146 return QMetaType::Void;
149size_t QskMetaFunction::parameterCount()
const
153 if (
auto types = parameterTypes() )
155 while ( types[ count ] != QMetaType::UnknownType )
162QskMetaFunction::Type QskMetaFunction::functionType()
const
164 if ( m_functionCall ==
nullptr )
167 return static_cast< QskMetaFunction::Type
>( m_functionCall->typeInfo() );
170void QskMetaFunction::invoke( QObject*
object,
171 void* argv[], Qt::ConnectionType connectionType )
182 if ( m_functionCall ==
nullptr )
185 QPointer< QObject > receiver(
object );
187 int invokeType = connectionType & 0x3;
189 if ( invokeType == Qt::AutoConnection )
191 invokeType = ( receiver && receiver->thread() != QThread::currentThread() )
192 ? Qt::QueuedConnection : Qt::DirectConnection;
195 switch ( invokeType )
197 case Qt::DirectConnection:
199 m_functionCall->call( receiver, argv );
202 case Qt::BlockingQueuedConnection:
204 if ( receiver.isNull() ||
205 ( receiver->thread() == QThread::currentThread() ) )
212 QSemaphore semaphore;
214 auto event =
new QMetaCallEvent(
215 m_functionCall,
nullptr, 0, argv, &semaphore );
217 auto event =
new QMetaCallEvent(
218 m_functionCall,
nullptr, 0, argv,
nullptr );
221 QCoreApplication::postEvent( receiver, event );
229 case Qt::QueuedConnection:
231 if ( receiver.isNull() )
234 const auto argc = parameterCount() + 1;
236 auto event =
new QMetaCallEvent( m_functionCall,
nullptr, 0, argc );
238 auto types =
event->types();
239 auto arguments =
event->args();
241#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
242 types[0] = QMetaType();
243 arguments[ 0 ] =
nullptr;
246 arguments[ 0 ] =
nullptr;
249 const int* parameterTypes = m_functionCall->parameterTypes();
250 for ( uint i = 1; i < argc; i++ )
252 if ( argv[ i ] ==
nullptr )
254 Q_ASSERT( arguments[ i ] !=
nullptr );
259 const auto type = parameterTypes[i - 1];
261#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
262 types[ i ] = QMetaType( type );
263 arguments[ i ] = QMetaType( type ).create( argv[ i ] );
266 arguments[ i ] = QMetaType::create( type, argv[ i ] );
271 QCoreApplication::postEvent( receiver, event );
280#include "moc_QskMetaFunction.cpp"