[Qt] Port meta method/signal/slot handling in run-time bridge to use JSC C API
[WebKit-https.git] / Source / WebCore / bridge / qt / qt_runtime.h
1 /*
2  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19
20 #ifndef BINDINGS_QT_RUNTIME_H_
21 #define BINDINGS_QT_RUNTIME_H_
22
23 #include "BridgeJSC.h"
24 #include "JSDOMBinding.h"
25 #include "JavaScript.h"
26 #include "Weak.h"
27 #include "qt_instance.h"
28 #include "runtime_method.h"
29
30 #include <QPointer>
31
32 #include <qbytearray.h>
33 #include <qmetaobject.h>
34 #include <qvariant.h>
35
36 namespace WebCore {
37 class JSDOMGlobalObject;
38 }
39
40 namespace JSC {
41 namespace Bindings {
42
43 class QtField : public Field {
44 public:
45
46     typedef enum {
47         MetaProperty,
48 #ifndef QT_NO_PROPERTIES
49         DynamicProperty,
50 #endif
51         ChildObject
52     } QtFieldType;
53
54     QtField(const QMetaProperty &p)
55         : m_type(MetaProperty), m_property(p)
56         {}
57
58 #ifndef QT_NO_PROPERTIES
59     QtField(const QByteArray &b)
60         : m_type(DynamicProperty), m_dynamicProperty(b)
61         {}
62 #endif
63
64     QtField(QObject *child)
65         : m_type(ChildObject), m_childObject(child)
66         {}
67
68     virtual JSValue valueFromInstance(ExecState*, const Instance*) const;
69     virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const;
70     QByteArray name() const;
71     QtFieldType fieldType() const {return m_type;}
72 private:
73     QtFieldType m_type;
74     QByteArray m_dynamicProperty;
75     QMetaProperty m_property;
76     QPointer<QObject> m_childObject;
77 };
78
79
80 template <typename T> class QtArray : public Array
81 {
82 public:
83     QtArray(QList<T> list, QMetaType::Type type, PassRefPtr<RootObject>);
84     virtual ~QtArray();
85
86     RootObject* rootObject() const;
87
88     virtual void setValueAt(ExecState*, unsigned index, JSValue) const;
89     virtual JSValue valueAt(ExecState*, unsigned index) const;
90     virtual unsigned int getLength() const {return m_length;}
91
92 private:
93     mutable QList<T> m_list; // setValueAt is const!
94     unsigned int m_length;
95     QMetaType::Type m_type;
96 };
97
98 class QtRuntimeMethod {
99 public:
100     enum MethodFlags {
101         MethodIsSignal = 1,
102         AllowPrivate = 2
103     };
104
105     QtRuntimeMethod(JSContextRef, JSValueRef* exception, QObject*, const QByteArray& identifier, int signalIndex, int flags, QtInstance*);
106     ~QtRuntimeMethod();
107
108     static JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
109     static JSValueRef connect(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
110     static JSValueRef disconnect(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
111
112     JSObjectRef jsObjectRef(JSContextRef, JSValueRef* exception);
113
114     const QByteArray& name() { return m_identifier; }
115
116 private:
117     static const JSStaticFunction connectFunction;
118     static const JSStaticFunction disconnectFunction;
119
120     static JSValueRef connectOrDisconnect(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception, bool connect);
121     QPointer<QObject> m_object;
122     QByteArray m_identifier;
123     int m_index;
124     int m_flags;
125     Weak<JSObject> m_jsObject;
126     QtInstance* m_instance;
127 };
128
129 // A QtConnectionObject represents a connection created inside JS. It will connect its own execute() slot
130 // with the appropriate signal of 'sender'. When execute() is called, it will call JS 'receiverFunction'.
131 class QtConnectionObject : public QObject
132 {
133     Q_OBJECT_FAKE
134 public:
135     QtConnectionObject(JSContextRef, PassRefPtr<QtInstance> senderInstance, int signalIndex, JSObjectRef receiver, JSObjectRef receiverFunction);
136     ~QtConnectionObject();
137
138     void execute(void **argv);
139
140     bool match(JSContextRef, QObject* sender, int signalIndex, JSObjectRef thisObject, JSObjectRef funcObject);
141
142 private:
143     JSGlobalContextRef m_context;
144     RefPtr<QtInstance> m_senderInstance;
145
146     // We use this as key in active connections multimap.
147     QObject* m_originalSender;
148
149     int m_signalIndex;
150     JSObjectRef m_receiver;
151     JSObjectRef m_receiverFunction;
152
153     friend class QtRuntimeMethod;
154     static QMultiMap<QObject*, QtConnectionObject*> connections;
155 };
156
157
158 typedef QVariant (*ConvertToVariantFunction)(JSObject* object, int *distance, HashSet<JSObject*>* visitedObjects);
159 typedef JSValue (*ConvertToJSValueFunction)(ExecState* exec, WebCore::JSDOMGlobalObject* globalObject, const QVariant& variant);
160
161 void registerCustomType(int qtMetaTypeId, ConvertToVariantFunction, ConvertToJSValueFunction);
162
163 QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance);
164 JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant);
165
166 void setException(JSContextRef, JSValueRef* exception, const QString& text);
167
168 } // namespace Bindings
169 } // namespace JSC
170
171 #endif