#ifndef HSQML_OBJECT_H #define HSQML_OBJECT_H #include #include #include #include #include #include #include #include "hsqml.h" class HsQMLEngine; class HsQMLClass; class HsQMLObject; class HsQMLObjectProxy; class HsQMLObjectFinaliser : public QSharedData { public: typedef QExplicitlySharedDataPointer Ref; HsQMLObjectFinaliser(HsQMLObjFinaliserCb); ~HsQMLObjectFinaliser(); void finalise(HsQMLObjectProxy*) const; private: Q_DISABLE_COPY(HsQMLObjectFinaliser); HsQMLObjFinaliserCb mFinaliseCb; }; class HsQMLObjectProxy { public: HsQMLObjectProxy(HsStablePtr, HsQMLClass*); virtual ~HsQMLObjectProxy(); HsStablePtr haskell() const; HsQMLClass* klass() const; HsQMLObject* object(HsQMLEngine*); void clearObject(); void tryGCLock(); void removeGCLock(); void addFinaliser(const HsQMLObjectFinaliser::Ref&); void runFinalisers(); HsQMLEngine* engine() const; enum RefSrc {Handle, WeakHandle, Engine, Variant, Object, Event}; void ref(RefSrc); void deref(RefSrc); private: Q_DISABLE_COPY(HsQMLObjectProxy); HsStablePtr mHaskell; HsQMLClass* mKlass; int mSerial; HsQMLObject* volatile mObject; QAtomicInt mRefCount; QAtomicInt mStrongCount; QMutex mFinaliseMutex; typedef QVarLengthArray Finalisers; Finalisers mFinalisers; }; class HsQMLObjectEvent : public QEvent { public: HsQMLObjectEvent(HsQMLObjectProxy*); virtual ~HsQMLObjectEvent(); void process(); private: HsQMLObjectProxy* mProxy; }; class HsQMLObject : public QObject { public: HsQMLObject(HsQMLObjectProxy*, HsQMLEngine*); virtual ~HsQMLObject(); virtual const QMetaObject* metaObject() const; virtual void* qt_metacast(const char*); virtual int qt_metacall(QMetaObject::Call, int, void**); void setGCLock(); void clearGCLock(); bool isGCLocked() const; QJSValue* gcLockVar(); HsQMLObjectProxy* proxy() const; HsQMLEngine* engine() const; private: Q_DISABLE_COPY(HsQMLObject); HsQMLObjectProxy* mProxy; HsStablePtr mHaskell; HsQMLClass* mKlass; HsQMLEngine* mEngine; QJSValue mGCLock; }; #endif /*HSQML_OBJECT_H*/