#ifndef HSQML_MANAGER_H #define HSQML_MANAGER_H #include #include #include #include #include #include #include #include #include #include #include "hsqml.h" #define HSQML_LOG(ll, msg) if (gManager->checkLogLevel(ll)) gManager->log(msg) class HsQMLManagerApp; class HsQMLClass; class HsQMLEngine; class HsQMLManager { public: enum CounterId { ClassCount, ObjectCount, QObjectCount, VariantCount, EngineCount, ClassSerial, ObjectSerial, EngineSerial, TotalCounters }; HsQMLManager( void (*)(HsFunPtr), void (*)(HsStablePtr)); void setLogLevel(int); bool checkLogLevel(int); void log(const QString&); int updateCounter(CounterId, int); void freeFun(HsFunPtr); void freeStable(HsStablePtr); bool setArgs(const QStringList&); QVector& argsPtrs(); bool setFlag(HsQMLGlobalFlag, bool); bool getFlag(HsQMLGlobalFlag); void registerObject(const QObject*); void unregisterObject(const QObject*); void hookedConstruct(QVariant::Private*, const void*); void hookedClear(QVariant::Private*); bool isEventThread(); typedef HsQMLEventLoopStatus EventLoopStatus; EventLoopStatus runEventLoop( HsQMLTrivialCb, HsQMLTrivialCb, HsQMLTrivialCb); EventLoopStatus requireEventLoop(); void releaseEventLoop(); void notifyJobs(); void setActiveEngine(HsQMLEngine*); HsQMLEngine* activeEngine(); void postAppEvent(QEvent*); void zombifyClass(HsQMLClass*); EventLoopStatus shutdown(); private: friend class HsQMLManagerApp; Q_DISABLE_COPY(HsQMLManager) int mLogLevel; QMutex mLogLock; QAtomicInt mCounters[TotalCounters]; bool mAtExit; void (*mFreeFun)(HsFunPtr); void (*mFreeStable)(HsStablePtr); QVector mArgs; QVector mArgsPtrs; QSet mObjectSet; QVector mZombieClasses; const QVariant::Handler* mOriginalHandler; HsQMLManagerApp* mApp; QMutex mLock; bool mRunning; int mRunCount; bool mShutdown; void* mStackBase; HsQMLTrivialCb mStartCb; HsQMLTrivialCb mJobsCb; HsQMLTrivialCb mYieldCb; HsQMLEngine* mActiveEngine; }; class HsQMLManagerApp : public QObject { Q_OBJECT public: HsQMLManagerApp(); virtual ~HsQMLManagerApp(); virtual void customEvent(QEvent*); virtual void timerEvent(QTimerEvent*); int exec(); enum CustomEventIndicies { StartedLoopEventIndex, StopLoopEventIndex, PendingJobsEventIndex, RemoveGCLockEventIndex, CreateEngineEventIndex, }; static const QEvent::Type StartedLoopEvent = static_cast(QEvent::User+StartedLoopEventIndex); static const QEvent::Type StopLoopEvent = static_cast(QEvent::User+StopLoopEventIndex); static const QEvent::Type PendingJobsEvent = static_cast(QEvent::User+PendingJobsEventIndex); static const QEvent::Type RemoveGCLockEvent = static_cast(QEvent::User+RemoveGCLockEventIndex); static const QEvent::Type CreateEngineEvent = static_cast(QEvent::User+CreateEngineEventIndex); private: Q_DISABLE_COPY(HsQMLManagerApp) QVariant::Handler mHookedHandler; int mArgC; QApplication mApp; }; class ManagerPointer : public QAtomicPointer { public: HsQMLManager* operator->() const { return load(); } operator HsQMLManager*() const { return load(); } }; extern ManagerPointer gManager; #endif /*HSQML_MANAGER_H*/