Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / QtCollider / QObjectProxy.h
blob3bb6e869d1db1f04de92d4e20818fdfbb413bafc
1 /************************************************************************
3 * Copyright 2010-2011 Jakob Leben (jakob.leben@gmail.com)
5 * This file is part of SuperCollider Qt GUI.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ************************************************************************/
22 #ifndef QC_QOBJECT_PROXY_H
23 #define QC_QOBJECT_PROXY_H
25 #include "Common.h"
27 #include <QObject>
28 #include <QString>
29 #include <QVariant>
30 #include <QVector>
31 #include <QEvent>
33 #include <PyrObject.h>
34 #include <PyrSlot.h>
35 #include <PyrSymbol.h>
37 #define qcProxyDebugMsg( LEVEL, MSG ) \
38 qcDebugMsg( LEVEL, QString("[%1]: ").arg(_scClassName) + QString(MSG) )
40 struct VariantList;
42 class QObjectProxy;
43 class QcSignalSpy;
44 class QcMethodSignalHandler;
45 class QcFunctionSignalHandler;
47 namespace QtCollider {
48 struct SetPropertyEvent;
49 class DestroyEvent;
50 struct ScMethodCallEvent;
52 class ProxyToken : public QObject {
53 Q_OBJECT
54 public:
55 ProxyToken( QObjectProxy *p, QObject *parent )
56 : QObject(parent), proxy(p) { }
57 QObjectProxy *proxy;
61 class QObjectProxy : public QObject
63 friend class QcMethodSignalHandler;
64 friend class QcFunctionSignalHandler;
66 Q_OBJECT
68 public:
70 enum DestroyAction {
71 DestroyProxy,
72 DestroyObject,
73 DestroyProxyAndObject,
76 struct EventHandlerData
78 EventHandlerData() : type( QEvent::None ) {}
79 int type;
80 PyrSymbol *method;
81 QtCollider::Synchronicity sync;
82 bool enabled;
85 QObjectProxy( QObject *qObject, PyrObject *scObject );
87 virtual ~QObjectProxy();
89 // Check if this is the right thread.
90 // WARNING: must be called with language locked!
91 bool compareThread();
93 // WARNING: must be called with language locked!
94 void finalize() { _scObject = 0; }
96 inline QObject *object() const { return qObject; }
97 inline PyrObject *scObject() const { return _scObject; }
99 // Lock for usage of object() outside Qt thread.
100 inline void lock() { mutex.lock(); }
101 inline void unlock() { mutex.unlock(); }
103 QString scClassName() const { return _scClassName; }
105 QList<PyrObject*> children( PyrSymbol *className );
106 PyrObject *parent( PyrSymbol *className );
107 virtual bool setParent( QObjectProxy *parent );
109 bool setProperty( const char *property, const QVariant & val );
110 QVariant property( const char *property );
112 bool connectObject( const char *signal, PyrObject *object, Qt::ConnectionType );
113 bool connectMethod( const char *signal, PyrSymbol *method, Qt::ConnectionType );
114 bool disconnectObject( const char *signal, PyrObject *object );
115 bool disconnectMethod( const char *signal, PyrSymbol *method);
116 bool setEventHandler( int eventType, PyrSymbol *method, QtCollider::Synchronicity, bool enabled = true );
117 bool setEventHandlerEnabled( int eventType, bool enabled );
119 // thread-safe if connection == queued
120 bool invokeMethod( const char *method, PyrSlot *ret, PyrSlot *arg, Qt::ConnectionType );
122 void destroy( DestroyAction );
124 static QObjectProxy *fromObject( QObject * );
126 protected:
128 void invokeScMethod
129 ( PyrSymbol *method, const QList<QVariant> & args = QList<QVariant>(),
130 PyrSlot *result = 0, bool locked = false );
132 virtual bool eventFilter( QObject * watched, QEvent * event );
134 virtual void customEvent( QEvent * );
136 virtual bool filterEvent( QObject *, QEvent *, EventHandlerData &, QList<QVariant> & args );
138 bool invokeEventHandler( QEvent *e, EventHandlerData &, QList<QVariant> & args );
140 const QVector<EventHandlerData> & eventHandlers() { return _eventHandlers; }
142 private Q_SLOTS:
144 void invalidate();
146 private:
148 void scMethodCallEvent( QtCollider::ScMethodCallEvent * );
149 bool setPropertyEvent( QtCollider::SetPropertyEvent * );
150 bool destroyEvent( QtCollider::DestroyEvent * );
152 QObject *qObject;
153 // NOTE: scObject is protected by the language lock. Should not use it without it!
154 PyrObject *_scObject;
155 // NOTE: for the reason above we extract SC class name at construction
156 QString _scClassName;
158 QVector<EventHandlerData> _eventHandlers;
159 QList<QcMethodSignalHandler*> methodSigHandlers;
160 QList<QcFunctionSignalHandler*> funcSigHandlers;
161 QMutex mutex;
164 namespace QtCollider {
166 struct SetPropertyEvent : public QEvent
168 SetPropertyEvent() : QEvent( (QEvent::Type) QtCollider::Event_Proxy_SetProperty ) {}
169 PyrSymbol *property;
170 QVariant value;
173 class DestroyEvent : public QEvent
175 public:
176 DestroyEvent( QObjectProxy::DestroyAction act ) :
177 QEvent( (QEvent::Type) QtCollider::Event_Proxy_Destroy ),
178 _action( act )
180 QObjectProxy::DestroyAction action() { return _action; }
181 private:
182 QObjectProxy::DestroyAction _action;
185 struct ScMethodCallEvent : public QEvent
187 ScMethodCallEvent( PyrSymbol *m,
188 const QList<QVariant> &l = QList<QVariant>(),
189 bool b_locked = false )
190 : QEvent( (QEvent::Type) QtCollider::Event_ScMethodCall ),
191 method( m ),
192 args( l ),
193 locked( b_locked )
196 PyrSymbol *method;
197 QList<QVariant> args;
198 bool locked;
201 } // namespace
203 Q_DECLARE_METATYPE( QObjectProxy * );
205 #endif //QC_QOBJECT_PROXY_H