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 "ScriptEngineDebugFlags.h"
27 #include "../ScriptEngine.h"
28 #include "../Scriptable.h"
29 #include "ScriptEngineV8.h"
32 #include <shared/ReadWriteLockable.h>
35 class ScriptSignalV8Proxy;
48 PropertyDef(QString
string, uint
id) : name(
string), _id(
id) {};
50 ScriptValue::PropertyFlags flags;
55 MethodDef(QString
string, uint
id) : name(
string), _id(
id) {};
58 QList<QMetaMethod> methods;
63 SignalDef(QString
string, uint
id) : name(
string), _id(
id) {};
68 using PropertyDefMap = QHash<uint, PropertyDef>;
69 using MethodDefMap = QHash<uint, MethodDef>;
70 using SignalDefMap = QHash<uint, SignalDef>;
71 using InstanceMap = QHash<uint, QPointer<ScriptSignalV8Proxy> >;
72 using PropertyNameMap = QHash<QString, PropertyDef*>;
73 using MethodNameMap = QHash<QString, MethodDef*>;
74 using SignalNameMap = QHash<QString, SignalDef*>;
76 static constexpr uint PROPERTY_TYPE = 0x1000;
77 static constexpr uint METHOD_TYPE = 0x2000;
78 static constexpr uint SIGNAL_TYPE = 0x3000;
79 static constexpr uint TYPE_MASK = 0xF000;
82 ScriptObjectV8Proxy(ScriptEngineV8* engine, QObject*
object,
bool ownsObject,
const ScriptEngine::QObjectWrapOptions& options);
85 static V8ScriptValue newQObject(ScriptEngineV8* engine,
88 const ScriptEngine::QObjectWrapOptions& options = ScriptEngine::QObjectWrapOptions());
91 static QObject* unwrap(
const V8ScriptValue& val);
92 inline QObject* toQObject()
const {
return _object; }
93 inline v8::Local<v8::Object> toV8Value()
const {
94 v8::EscapableHandleScope handleScope(_engine->getIsolate());
95 return handleScope.Escape(_v8Object.Get(_engine->getIsolate()));
101 HandlesReadAccess = 0x00000001,
102 HandlesWriteAccess = 0x00000002,
104 Q_DECLARE_FLAGS(QueryFlags, QueryFlag);
106 virtual QString name()
const;
108 virtual V8ScriptValue property(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id);
109 virtual ScriptValue::PropertyFlags propertyFlags(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id);
110 virtual QueryFlags queryProperty(
const V8ScriptValue&
object,
const V8ScriptString& name, QueryFlags flags, uint*
id);
111 virtual void setProperty(V8ScriptValue&
object,
const V8ScriptString& name, uint
id,
const V8ScriptValue& value);
112 v8::Local<v8::Array> getPropertyNames();
113 static void v8Get(v8::Local<v8::Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info);
114 static void v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> value_obj,
const v8::PropertyCallbackInfo<v8::Value>& info);
115 static void v8GetPropertyNames(
const v8::PropertyCallbackInfo<v8::Array>& info);
120 static void weakHandleCallback(
const v8::WeakCallbackInfo<ScriptObjectV8Proxy> &info);
123 ScriptEngineV8* _engine;
124 const ScriptEngine::QObjectWrapOptions _wrapOptions;
125 PropertyDefMap _props;
126 MethodDefMap _methods;
127 SignalDefMap _signals;
129 PropertyNameMap _propNameMap;
130 MethodNameMap _methodNameMap;
131 SignalNameMap _signalNameMap;
132 InstanceMap _signalInstances;
133 const bool _ownsObject;
134 QPointer<QObject> _object;
136 v8::Persistent<v8::Object> _v8Object;
137 bool _wasDestroyed{
false};
161 static V8ScriptValue newVariant(ScriptEngineV8* engine,
const QVariant& variant, V8ScriptValue proto);
169 static QVariant unwrap(
const V8ScriptValue& val);
170 inline QVariant toQVariant()
const {
return _variant; }
171 inline v8::Local<v8::Object> toV8Value()
const {
172 v8::EscapableHandleScope handleScope(_engine->getIsolate());
173 return handleScope.Escape(_v8Object.Get(_engine->getIsolate()));
177 virtual QString name()
const {
return _name; }
179 virtual V8ScriptValue prototype()
const {
return _scriptProto; }
181 virtual V8ScriptValue property(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id) {
182 return _proto->property(
object, name,
id);
184 virtual ScriptValue::PropertyFlags propertyFlags(
const V8ScriptValue&
object,
const V8ScriptString& name, uint
id) {
185 return _proto->propertyFlags(
object, name,
id);
187 virtual void setProperty(V8ScriptValue&
object,
const V8ScriptString& name, uint
id,
const V8ScriptValue& value) {
188 return _proto->setProperty(
object, name,
id, value);
190 static void v8Get(v8::Local<v8::Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info);
191 static void v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> value_obj,
const v8::PropertyCallbackInfo<v8::Value>& info);
192 static void v8GetPropertyNames(
const v8::PropertyCallbackInfo<v8::Array>& info);
195 ScriptEngineV8* _engine;
197 V8ScriptValue _scriptProto;
200 v8::UniquePersistent<v8::Object> _v8Object;
205 class ScriptMethodV8Proxy final :
public QObject {
208 ScriptMethodV8Proxy(ScriptEngineV8* engine, QObject*
object, V8ScriptValue lifetime,
209 const QList<QMetaMethod>& metas,
int numMaxParams);
210 virtual ~ScriptMethodV8Proxy();
213 virtual QString name()
const {
return fullName(); }
214 static void callback(
const v8::FunctionCallbackInfo<v8::Value>& arguments);
215 void call(
const v8::FunctionCallbackInfo<v8::Value>& arguments);
216 static V8ScriptValue newMethod(ScriptEngineV8* engine, QObject*
object, V8ScriptValue lifetime,
217 const QList<QMetaMethod>& metas,
int numMaxParams);
220 static void weakHandleCallback(
const v8::WeakCallbackInfo<ScriptMethodV8Proxy> &info);
221 QString fullName()
const;
224 const int _numMaxParams;
225 ScriptEngineV8* _engine;
226 QPointer<QObject> _object;
227 v8::Persistent<v8::Value> _objectLifetime;
229 const QList<QMetaMethod> _metas;
231 Q_DISABLE_COPY(ScriptMethodV8Proxy)
237 class ScriptSignalV8ProxyBase :
public QObject,
protected Scriptable {
245 class ScriptSignalV8Proxy final :
public ScriptSignalV8ProxyBase,
public ReadWriteLockable {
249 V8ScriptValue thisValue;
250 V8ScriptValue callback;
251 Connection(
const V8ScriptValue &v8ThisValue,
const V8ScriptValue &v8Callback) :
252 thisValue(v8ThisValue), callback(v8Callback) {};
254 using ConnectionList = QList<Connection>;
257 inline ScriptSignalV8Proxy(ScriptEngineV8* engine, QObject*
object, V8ScriptValue lifetime,
const QMetaMethod& meta);
259 ~ScriptSignalV8Proxy();
262 virtual int qt_metacall(QMetaObject::Call call,
int id,
void** arguments)
override;
263 int discoverMetaCallIdx();
264 ConnectionList::iterator findConnection(V8ScriptValue thisObject, V8ScriptValue callback);
266 static void weakHandleCallback(
const v8::WeakCallbackInfo<ScriptSignalV8Proxy> &info);
273 QString fullName()
const;
276 void disconnectAll();
279 void disconnectAllScriptSignalProxies();
283 ScriptEngineV8* _engine;
284 QPointer<QObject> _object;
285 v8::Persistent<v8::Value> _objectLifetime;
287 const QMetaMethod _meta;
288 const int _metaCallId;
289 ConnectionList _connections;
290 bool _isConnected{
false };
293 bool _cleanup{
false };
295 v8::UniquePersistent<v8::Context> _v8Context;
298 float _totalCallTime_s{ 0.0 };
299 #ifdef OVERTE_SCRIPT_USE_AFTER_DELETE_GUARD
300 std::atomic<bool> _wasDeleted{
false};
303 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:44
[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:156
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:816
[ScriptInterface] Provides an engine-independent interface for QScriptable
Definition: Scriptable.h:29