18 #ifndef hifi_ScriptObjectV8Proxy_h
19 #define hifi_ScriptObjectV8Proxy_h
21 #include <QtCore/QHash>
22 #include <QtCore/QList>
23 #include <QtCore/QPointer>
24 #include <QtCore/QString>
26 #include "../ScriptEngine.h"
27 #include "../Scriptable.h"
28 #include "ScriptEngineV8.h"
31 #include <shared/ReadWriteLockable.h>
34 class ScriptSignalV8Proxy;
47 PropertyDef(QString
string, uint
id) : name(
string), _id(
id) {};
49 ScriptValue::PropertyFlags flags;
54 MethodDef(QString
string, uint
id) : name(
string), _id(
id) {};
57 QList<QMetaMethod> methods;
62 SignalDef(QString
string, uint
id) : name(
string), _id(
id) {};
67 using PropertyDefMap = QHash<uint, PropertyDef>;
68 using MethodDefMap = QHash<uint, MethodDef>;
69 using SignalDefMap = QHash<uint, SignalDef>;
70 using InstanceMap = QHash<uint, QPointer<ScriptSignalV8Proxy> >;
71 using PropertyNameMap = QHash<QString, PropertyDef*>;
72 using MethodNameMap = QHash<QString, MethodDef*>;
73 using SignalNameMap = QHash<QString, SignalDef*>;
75 static constexpr uint PROPERTY_TYPE = 0x1000;
76 static constexpr uint METHOD_TYPE = 0x2000;
77 static constexpr uint SIGNAL_TYPE = 0x3000;
78 static constexpr uint TYPE_MASK = 0xF000;
81 ScriptObjectV8Proxy(ScriptEngineV8* engine, QObject*
object,
bool ownsObject,
const ScriptEngine::QObjectWrapOptions& options);
84 static V8ScriptValue newQObject(ScriptEngineV8* engine,
87 const ScriptEngine::QObjectWrapOptions& options = ScriptEngine::QObjectWrapOptions());
90 static QObject* unwrap(
const V8ScriptValue& val);
91 inline QObject* toQObject()
const {
return _object; }
92 inline v8::Local<v8::Object> toV8Value()
const {
93 v8::EscapableHandleScope handleScope(_engine->getIsolate());
94 return handleScope.Escape(_v8Object.Get(_engine->getIsolate()));
100 HandlesReadAccess = 0x00000001,
101 HandlesWriteAccess = 0x00000002,
103 Q_DECLARE_FLAGS(QueryFlags, QueryFlag);
105 virtual QString name()
const;
107 virtual V8ScriptValue property(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id);
108 virtual ScriptValue::PropertyFlags propertyFlags(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id);
109 virtual QueryFlags queryProperty(
const V8ScriptValue&
object,
const V8ScriptString& name, QueryFlags flags, uint*
id);
110 virtual void setProperty(V8ScriptValue&
object,
const V8ScriptString& name, uint
id,
const V8ScriptValue& value);
111 v8::Local<v8::Array> getPropertyNames();
112 static void v8Get(v8::Local<v8::Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info);
113 static void v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> value_obj,
const v8::PropertyCallbackInfo<v8::Value>& info);
114 static void v8GetPropertyNames(
const v8::PropertyCallbackInfo<v8::Array>& info);
119 static void weakHandleCallback(
const v8::WeakCallbackInfo<ScriptObjectV8Proxy> &info);
122 ScriptEngineV8* _engine;
123 const ScriptEngine::QObjectWrapOptions _wrapOptions;
124 PropertyDefMap _props;
125 MethodDefMap _methods;
126 SignalDefMap _signals;
128 PropertyNameMap _propNameMap;
129 MethodNameMap _methodNameMap;
130 SignalNameMap _signalNameMap;
131 InstanceMap _signalInstances;
132 const bool _ownsObject;
133 QPointer<QObject> _object;
135 v8::Persistent<v8::Object> _v8Object;
159 static V8ScriptValue newVariant(ScriptEngineV8* engine,
const QVariant& variant, V8ScriptValue proto);
167 static QVariant unwrap(
const V8ScriptValue& val);
168 inline QVariant toQVariant()
const {
return _variant; }
169 inline v8::Local<v8::Object> toV8Value()
const {
170 v8::EscapableHandleScope handleScope(_engine->getIsolate());
171 return handleScope.Escape(_v8Object.Get(_engine->getIsolate()));
175 virtual QString name()
const {
return _name; }
177 virtual V8ScriptValue prototype()
const {
return _scriptProto; }
179 virtual V8ScriptValue property(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id) {
180 return _proto->property(
object, name,
id);
182 virtual ScriptValue::PropertyFlags propertyFlags(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id) {
183 return _proto->propertyFlags(
object, name,
id);
185 virtual void setProperty(V8ScriptValue&
object,
const V8ScriptString& name, uint
id,
const V8ScriptValue& value) {
186 return _proto->setProperty(
object, name,
id, value);
188 static void v8Get(v8::Local<v8::Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info);
189 static void v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> value_obj,
const v8::PropertyCallbackInfo<v8::Value>& info);
190 static void v8GetPropertyNames(
const v8::PropertyCallbackInfo<v8::Array>& info);
193 ScriptEngineV8* _engine;
195 V8ScriptValue _scriptProto;
198 v8::UniquePersistent<v8::Object> _v8Object;
203 class ScriptMethodV8Proxy final :
public QObject {
206 ScriptMethodV8Proxy(ScriptEngineV8* engine, QObject*
object, V8ScriptValue lifetime,
207 const QList<QMetaMethod>& metas,
int numMaxParams);
208 virtual ~ScriptMethodV8Proxy();
211 virtual QString name()
const {
return fullName(); }
212 static void callback(
const v8::FunctionCallbackInfo<v8::Value>& arguments);
213 void call(
const v8::FunctionCallbackInfo<v8::Value>& arguments);
214 static V8ScriptValue newMethod(ScriptEngineV8* engine, QObject*
object, V8ScriptValue lifetime,
215 const QList<QMetaMethod>& metas,
int numMaxParams);
218 static void weakHandleCallback(
const v8::WeakCallbackInfo<ScriptMethodV8Proxy> &info);
219 QString fullName()
const;
222 const int _numMaxParams;
223 ScriptEngineV8* _engine;
224 QPointer<QObject> _object;
225 v8::Persistent<v8::Value> _objectLifetime;
227 const QList<QMetaMethod> _metas;
229 Q_DISABLE_COPY(ScriptMethodV8Proxy)
235 class ScriptSignalV8ProxyBase :
public QObject,
protected Scriptable {
243 class ScriptSignalV8Proxy final :
public ScriptSignalV8ProxyBase,
public ReadWriteLockable {
247 V8ScriptValue thisValue;
248 V8ScriptValue callback;
249 Connection(
const V8ScriptValue &v8ThisValue,
const V8ScriptValue &v8Callback) :
250 thisValue(v8ThisValue), callback(v8Callback) {};
252 using ConnectionList = QList<Connection>;
255 inline ScriptSignalV8Proxy(ScriptEngineV8* engine, QObject*
object, V8ScriptValue lifetime,
const QMetaMethod& meta);
257 ~ScriptSignalV8Proxy();
260 virtual int qt_metacall(QMetaObject::Call call,
int id,
void** arguments)
override;
261 int discoverMetaCallIdx();
262 ConnectionList::iterator findConnection(V8ScriptValue thisObject, V8ScriptValue callback);
264 static void weakHandleCallback(
const v8::WeakCallbackInfo<ScriptSignalV8Proxy> &info);
271 QString fullName()
const;
274 void disconnectAll() { QObject::disconnect(
this,
nullptr,
nullptr,
nullptr); };
278 ScriptEngineV8* _engine;
279 QPointer<QObject> _object;
280 v8::Persistent<v8::Value> _objectLifetime;
282 const QMetaMethod _meta;
283 const int _metaCallId;
284 ConnectionList _connections;
285 bool _isConnected{
false };
287 v8::UniquePersistent<v8::Context> _v8Context;
290 float _totalCallTime_s{ 0.0 };
292 Q_DISABLE_COPY(ScriptSignalV8Proxy)
ValueOwnership
Who owns a given object.
Definition: ScriptEngine.h:109
@ QtOwnership
Object is managed by Qt.
Definition: ScriptEngine.h:114
Definition: ScriptObjectV8Proxy.h:43
[ScriptInterface] Provides an engine-independent interface for QScriptValue
Definition: ScriptValue.h:40
[V8] (re-)implements the translation layer between ScriptValue and QVariant where a prototype is set.
Definition: ScriptObjectV8Proxy.h:154
static QVariant * unwrapQVariantPointer(v8::Isolate *isolate, const v8::Local< v8::Value > &value)
Used to retrieve QVariant pointer contained inside script value. This is indirectly used by ScriptVar...
Definition: ScriptObjectV8Proxy.cpp:793
[ScriptInterface] Provides an engine-independent interface for QScriptable
Definition: Scriptable.h:29