mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 03:03:35 +02:00
Fixed method calls
This commit is contained in:
parent
3b9f198546
commit
a8f913a359
5 changed files with 108 additions and 33 deletions
|
@ -23,6 +23,10 @@
|
||||||
#include "ScriptEngineLogging.h"
|
#include "ScriptEngineLogging.h"
|
||||||
#include "ScriptManager.h"
|
#include "ScriptManager.h"
|
||||||
|
|
||||||
|
Vec3::~Vec3() {
|
||||||
|
qDebug(scriptengine) << "ScriptMethodV8Proxy destroyed";
|
||||||
|
printf("ScriptMethodV8Proxy destroyed");
|
||||||
|
}
|
||||||
|
|
||||||
float Vec3::orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3) {
|
float Vec3::orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3) {
|
||||||
float radians = glm::orientedAngle(glm::normalize(v1), glm::normalize(v2), glm::normalize(v3));
|
float radians = glm::orientedAngle(glm::normalize(v1), glm::normalize(v2), glm::normalize(v3));
|
||||||
|
|
|
@ -418,6 +418,10 @@ private:
|
||||||
const glm::vec3& RIGHT() { return Vectors::RIGHT; }
|
const glm::vec3& RIGHT() { return Vectors::RIGHT; }
|
||||||
const glm::vec3& UP() { return Vectors::UP; }
|
const glm::vec3& UP() { return Vectors::UP; }
|
||||||
const glm::vec3& FRONT() { return Vectors::FRONT; }
|
const glm::vec3& FRONT() { return Vectors::FRONT; }
|
||||||
|
|
||||||
|
//V8TODO delete after V8 works - used only for debugging
|
||||||
|
public:
|
||||||
|
virtual ~Vec3();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Vec3_h
|
#endif // hifi_Vec3_h
|
||||||
|
|
|
@ -184,7 +184,9 @@ public: // not for public use, but I don't like how Qt strings this along with p
|
||||||
using ObjectWrapperMap = QMap<QObject*, QWeakPointer<ScriptObjectV8Proxy>>;
|
using ObjectWrapperMap = QMap<QObject*, QWeakPointer<ScriptObjectV8Proxy>>;
|
||||||
mutable QMutex _qobjectWrapperMapProtect;
|
mutable QMutex _qobjectWrapperMapProtect;
|
||||||
ObjectWrapperMap _qobjectWrapperMap;
|
ObjectWrapperMap _qobjectWrapperMap;
|
||||||
|
// Second map, from which wrappers are removed by script engine upon deletion
|
||||||
|
// V8TODO add a V8 callback that removes pointer from the map so that it gets deleted
|
||||||
|
QMap<QObject*, QSharedPointer<ScriptObjectV8Proxy>> _qobjectWrapperMapV8;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// like `newFunction`, but allows mapping inline C++ lambdas with captures as callable V8ScriptValues
|
// like `newFunction`, but allows mapping inline C++ lambdas with captures as callable V8ScriptValues
|
||||||
|
|
|
@ -33,7 +33,7 @@ Q_DECLARE_METATYPE(QSharedPointer<ScriptVariantV8Proxy>)
|
||||||
static const void *internalPointsToQObjectProxy = (void *)0x13370000;
|
static const void *internalPointsToQObjectProxy = (void *)0x13370000;
|
||||||
static const void *internalPointsToQVariantProxy = (void *)0x13371000;
|
static const void *internalPointsToQVariantProxy = (void *)0x13371000;
|
||||||
static const void *internalPointsToSignalProxy = (void *)0x13372000;
|
static const void *internalPointsToSignalProxy = (void *)0x13372000;
|
||||||
static const void *internalPointsToMethodProxy = (void *)0x13372000;
|
static const void *internalPointsToMethodProxy = (void *)0x13373000;
|
||||||
|
|
||||||
// Used strictly to replace the "this" object value for property access. May expand to a full context element
|
// Used strictly to replace the "this" object value for property access. May expand to a full context element
|
||||||
// if we find it necessary to, but hopefully not needed
|
// if we find it necessary to, but hopefully not needed
|
||||||
|
@ -114,9 +114,10 @@ V8ScriptValue ScriptObjectV8Proxy::newQObject(ScriptEngineV8* engine, QObject* o
|
||||||
return V8ScriptValue(engine->getIsolate(), proxy.get()->toV8Value());
|
return V8ScriptValue(engine->getIsolate(), proxy.get()->toV8Value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// V8TODO add a V8 callback that removes pointer from the map so that it gets deleted
|
||||||
// register the wrapper with the engine and make sure it cleans itself up
|
// register the wrapper with the engine and make sure it cleans itself up
|
||||||
engine->_qobjectWrapperMap.insert(object, proxy);
|
engine->_qobjectWrapperMap.insert(object, proxy);
|
||||||
|
engine->_qobjectWrapperMapV8.insert(object, proxy);
|
||||||
QPointer<ScriptEngineV8> enginePtr = engine;
|
QPointer<ScriptEngineV8> enginePtr = engine;
|
||||||
object->connect(object, &QObject::destroyed, engine, [enginePtr, object]() {
|
object->connect(object, &QObject::destroyed, engine, [enginePtr, object]() {
|
||||||
if (!enginePtr) return;
|
if (!enginePtr) return;
|
||||||
|
@ -137,13 +138,16 @@ ScriptObjectV8Proxy* ScriptObjectV8Proxy::unwrapProxy(const V8ScriptValue& val)
|
||||||
v8::HandleScope handleScope(const_cast<v8::Isolate*>(val.constGetIsolate()));
|
v8::HandleScope handleScope(const_cast<v8::Isolate*>(val.constGetIsolate()));
|
||||||
auto v8Value = val.constGet();
|
auto v8Value = val.constGet();
|
||||||
if (!v8Value->IsObject()) {
|
if (!v8Value->IsObject()) {
|
||||||
|
qDebug(scriptengine) << "Cannot unwrap proxy - value is not an object";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(v8Value);
|
v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(v8Value);
|
||||||
if (v8Object->InternalFieldCount() != 2) {
|
if (v8Object->InternalFieldCount() != 2) {
|
||||||
|
qDebug(scriptengine) << "Cannot unwrap proxy - wrong number of internal fields";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (v8Object->GetAlignedPointerFromInternalField(0) == internalPointsToQObjectProxy) {
|
if (v8Object->GetAlignedPointerFromInternalField(0) != internalPointsToQObjectProxy) {
|
||||||
|
qDebug(scriptengine) << "Cannot unwrap proxy - internal fields don't point to object proxy";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return reinterpret_cast<ScriptObjectV8Proxy*>(v8Object->GetAlignedPointerFromInternalField(1));
|
return reinterpret_cast<ScriptObjectV8Proxy*>(v8Object->GetAlignedPointerFromInternalField(1));
|
||||||
|
@ -155,6 +159,7 @@ QObject* ScriptObjectV8Proxy::unwrap(const V8ScriptValue& val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptObjectV8Proxy::~ScriptObjectV8Proxy() {
|
ScriptObjectV8Proxy::~ScriptObjectV8Proxy() {
|
||||||
|
qDebug(scriptengine) << "Deleting object proxy: " << name();
|
||||||
if (_ownsObject) {
|
if (_ownsObject) {
|
||||||
QObject* qobject = _object;
|
QObject* qobject = _object;
|
||||||
if(qobject) qobject->deleteLater();
|
if(qobject) qobject->deleteLater();
|
||||||
|
@ -170,11 +175,18 @@ void ScriptObjectV8Proxy::investigate() {
|
||||||
v8::Context::Scope contextScope(_engine->getContext());
|
v8::Context::Scope contextScope(_engine->getContext());
|
||||||
|
|
||||||
auto objectTemplate = _v8ObjectTemplate.Get(_engine->getIsolate());
|
auto objectTemplate = _v8ObjectTemplate.Get(_engine->getIsolate());
|
||||||
objectTemplate->SetInternalFieldCount(3);
|
objectTemplate->SetInternalFieldCount(2);
|
||||||
objectTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(v8Get, v8Set));
|
objectTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(v8Get, v8Set));
|
||||||
|
|
||||||
const QMetaObject* metaObject = qobject->metaObject();
|
const QMetaObject* metaObject = qobject->metaObject();
|
||||||
|
|
||||||
|
qDebug(scriptengine) << "Investigate: " << metaObject->className();
|
||||||
|
if (QString("Vec3") == metaObject->className()) {
|
||||||
|
printf("Vec3");
|
||||||
|
}
|
||||||
|
if (QString("ConsoleScriptingInterface") == metaObject->className()) {
|
||||||
|
printf("ConsoleScriptingInterface");
|
||||||
|
}
|
||||||
// discover properties
|
// discover properties
|
||||||
int startIdx = _wrapOptions & ScriptEngine::ExcludeSuperClassProperties ? metaObject->propertyOffset() : 0;
|
int startIdx = _wrapOptions & ScriptEngine::ExcludeSuperClassProperties ? metaObject->propertyOffset() : 0;
|
||||||
int num = metaObject->propertyCount();
|
int num = metaObject->propertyCount();
|
||||||
|
@ -182,6 +194,7 @@ void ScriptObjectV8Proxy::investigate() {
|
||||||
QMetaProperty prop = metaObject->property(idx);
|
QMetaProperty prop = metaObject->property(idx);
|
||||||
if (!prop.isScriptable()) continue;
|
if (!prop.isScriptable()) continue;
|
||||||
|
|
||||||
|
qDebug(scriptengine) << "Investigate: " << metaObject->className() << " Property: " << prop.name();
|
||||||
// always exclude child objects (at least until we decide otherwise)
|
// always exclude child objects (at least until we decide otherwise)
|
||||||
int metaTypeId = prop.userType();
|
int metaTypeId = prop.userType();
|
||||||
if (metaTypeId != QMetaType::UnknownType) {
|
if (metaTypeId != QMetaType::UnknownType) {
|
||||||
|
@ -204,6 +217,7 @@ void ScriptObjectV8Proxy::investigate() {
|
||||||
QHash<V8ScriptString, int> methodNames;
|
QHash<V8ScriptString, int> methodNames;
|
||||||
for (int idx = startIdx; idx < num; ++idx) {
|
for (int idx = startIdx; idx < num; ++idx) {
|
||||||
QMetaMethod method = metaObject->method(idx);
|
QMetaMethod method = metaObject->method(idx);
|
||||||
|
qDebug(scriptengine) << "Investigate: " << metaObject->className() << " Method: " << method.name();
|
||||||
|
|
||||||
// perhaps keep this comment? Calls (like AudioScriptingInterface::playSound) seem to expect non-public methods to be script-accessible
|
// perhaps keep this comment? Calls (like AudioScriptingInterface::playSound) seem to expect non-public methods to be script-accessible
|
||||||
/* if (method.access() != QMetaMethod::Public) continue;*/
|
/* if (method.access() != QMetaMethod::Public) continue;*/
|
||||||
|
@ -281,7 +295,7 @@ void ScriptObjectV8Proxy::investigate() {
|
||||||
v8::Local<v8::Object> v8Object = objectTemplate->NewInstance(_engine->getContext()).ToLocalChecked();
|
v8::Local<v8::Object> v8Object = objectTemplate->NewInstance(_engine->getContext()).ToLocalChecked();
|
||||||
v8Object->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToQObjectProxy));
|
v8Object->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToQObjectProxy));
|
||||||
v8Object->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
|
v8Object->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
|
||||||
|
|
||||||
_v8Object.Reset(_engine->getIsolate(), v8Object);
|
_v8Object.Reset(_engine->getIsolate(), v8Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,24 +309,31 @@ QString ScriptObjectV8Proxy::name() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8ScriptValue& object, const V8ScriptString& name, QueryFlags flags, uint* id) {
|
ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8ScriptValue& object, const V8ScriptString& name, QueryFlags flags, uint* id) {
|
||||||
// check for properties
|
v8::HandleScope handleScope(_engine->getIsolate());
|
||||||
for (PropertyDefMap::const_iterator trans = _props.cbegin(); trans != _props.cend(); ++trans) {
|
// V8TODO: this might be inefficient when there's large number of properties
|
||||||
const PropertyDef& propDef = trans.value();
|
v8::Local<v8::Context> context = _engine->getContext();
|
||||||
if (propDef.name.constGet() != name.constGet()) continue;
|
v8::String::Utf8Value nameStr(_engine->getIsolate(), name.constGet());
|
||||||
*id = trans.key() | PROPERTY_TYPE;
|
|
||||||
return flags & (HandlesReadAccess | HandlesWriteAccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for methods
|
// check for methods
|
||||||
for (MethodDefMap::const_iterator trans = _methods.cbegin(); trans != _methods.cend(); ++trans) {
|
for (MethodDefMap::const_iterator trans = _methods.cbegin(); trans != _methods.cend(); ++trans) {
|
||||||
if (trans.value().name.constGet() != name.constGet()) continue;
|
v8::String::Utf8Value methodNameStr(_engine->getIsolate(), trans.value().name.constGet());
|
||||||
|
qDebug(scriptengine) << "queryProperty : " << *nameStr << " method: " << *methodNameStr;
|
||||||
|
if (!(trans.value().name == name)) continue;
|
||||||
*id = trans.key() | METHOD_TYPE;
|
*id = trans.key() | METHOD_TYPE;
|
||||||
return flags & (HandlesReadAccess | HandlesWriteAccess);
|
return flags & (HandlesReadAccess | HandlesWriteAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for properties
|
||||||
|
for (PropertyDefMap::const_iterator trans = _props.cbegin(); trans != _props.cend(); ++trans) {
|
||||||
|
const PropertyDef& propDef = trans.value();
|
||||||
|
if (!(propDef.name == name)) continue;
|
||||||
|
*id = trans.key() | PROPERTY_TYPE;
|
||||||
|
return flags & (HandlesReadAccess | HandlesWriteAccess);
|
||||||
|
}
|
||||||
|
|
||||||
// check for signals
|
// check for signals
|
||||||
for (SignalDefMap::const_iterator trans = _signals.cbegin(); trans != _signals.cend(); ++trans) {
|
for (SignalDefMap::const_iterator trans = _signals.cbegin(); trans != _signals.cend(); ++trans) {
|
||||||
if (trans.value().name.constGet() != name.constGet()) continue;
|
if (!(trans.value().name == name)) continue;
|
||||||
*id = trans.key() | SIGNAL_TYPE;
|
*id = trans.key() | SIGNAL_TYPE;
|
||||||
return flags & (HandlesReadAccess | HandlesWriteAccess);
|
return flags & (HandlesReadAccess | HandlesWriteAccess);
|
||||||
}
|
}
|
||||||
|
@ -348,17 +369,51 @@ ScriptValue::PropertyFlags ScriptObjectV8Proxy::propertyFlags(const V8ScriptValu
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptObjectV8Proxy::v8Get(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
void ScriptObjectV8Proxy::v8Get(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||||
// V8TODO
|
v8::HandleScope handleScope(info.GetIsolate());
|
||||||
//info.GetReturnValue().Set();
|
v8::String::Utf8Value utf8Value(info.GetIsolate(), name);
|
||||||
|
qDebug(scriptengine) << "Get: " << *utf8Value;
|
||||||
|
V8ScriptValue object(info.GetIsolate(), info.This());
|
||||||
|
ScriptObjectV8Proxy *proxy = ScriptObjectV8Proxy::unwrapProxy(object);
|
||||||
|
if (!proxy) {
|
||||||
|
qDebug(scriptengine) << "Proxy object not found when getting: " << *utf8Value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
V8ScriptString nameString(info.GetIsolate(), v8::Local<v8::String>::Cast(name));
|
||||||
|
uint id;
|
||||||
|
QueryFlags flags = proxy->queryProperty(object, nameString, HandlesReadAccess, &id);
|
||||||
|
if (flags) {
|
||||||
|
V8ScriptValue value = proxy->property(object, nameString, id);
|
||||||
|
info.GetReturnValue().Set(value.get());
|
||||||
|
} else {
|
||||||
|
qDebug(scriptengine) << "Value not found: " << *utf8Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptObjectV8Proxy::v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
void ScriptObjectV8Proxy::v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||||
// V8TODO
|
v8::HandleScope handleScope(info.GetIsolate());
|
||||||
info.GetReturnValue().Set(value);
|
v8::String::Utf8Value utf8Value(info.GetIsolate(), name);
|
||||||
|
qDebug(scriptengine) << "Set: " << *utf8Value;
|
||||||
|
V8ScriptValue object(info.GetIsolate(), info.This());
|
||||||
|
ScriptObjectV8Proxy *proxy = ScriptObjectV8Proxy::unwrapProxy(object);
|
||||||
|
if (!proxy) {
|
||||||
|
qDebug(scriptengine) << "Proxy object not found when setting: " << *utf8Value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
V8ScriptString nameString(info.GetIsolate(), v8::Local<v8::String>::Cast(name));
|
||||||
|
//V8ScriptString nameString(info.GetIsolate(), name->ToString(proxy->_engine->getContext()).ToLocalChecked());
|
||||||
|
uint id;
|
||||||
|
QueryFlags flags = proxy->queryProperty(object, nameString, HandlesWriteAccess, &id);
|
||||||
|
if (flags) {
|
||||||
|
proxy->setProperty(object, nameString, id, V8ScriptValue(info.GetIsolate(), value));
|
||||||
|
info.GetReturnValue().Set(value);
|
||||||
|
} else {
|
||||||
|
qDebug(scriptengine) << "Value not found: " << *utf8Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V8ScriptString& name, uint id) {
|
V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V8ScriptString& name, uint id) {
|
||||||
|
v8::HandleScope handleScope(_engine->getIsolate());
|
||||||
QObject* qobject = _object;
|
QObject* qobject = _object;
|
||||||
if (!qobject) {
|
if (!qobject) {
|
||||||
_engine->getIsolate()->ThrowError("Referencing deleted native object");
|
_engine->getIsolate()->ThrowError("Referencing deleted native object");
|
||||||
|
@ -390,7 +445,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V
|
||||||
if((*iter).returnType() == QMetaType::UnknownType) {
|
if((*iter).returnType() == QMetaType::UnknownType) {
|
||||||
qDebug(scriptengine) << "Method with QMetaType::UnknownType " << metaObject->className() << " " << (*iter).name();
|
qDebug(scriptengine) << "Method with QMetaType::UnknownType " << metaObject->className() << " " << (*iter).name();
|
||||||
}
|
}
|
||||||
}
|
} //V8TODO: is new method created during every call? It needs to be cached instead
|
||||||
return ScriptMethodV8Proxy::newMethod(_engine, qobject, object, methodDef.methods, methodDef.numMaxParms);
|
return ScriptMethodV8Proxy::newMethod(_engine, qobject, object, methodDef.methods, methodDef.numMaxParms);
|
||||||
}
|
}
|
||||||
case SIGNAL_TYPE: {
|
case SIGNAL_TYPE: {
|
||||||
|
@ -417,6 +472,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptObjectV8Proxy::setProperty(V8ScriptValue& object, const V8ScriptString& name, uint id, const V8ScriptValue& value) {
|
void ScriptObjectV8Proxy::setProperty(V8ScriptValue& object, const V8ScriptString& name, uint id, const V8ScriptValue& value) {
|
||||||
|
v8::HandleScope handleScope(_engine->getIsolate());
|
||||||
if (!(id & PROPERTY_TYPE)) return;
|
if (!(id & PROPERTY_TYPE)) return;
|
||||||
QObject* qobject = _object;
|
QObject* qobject = _object;
|
||||||
if (!qobject) {
|
if (!qobject) {
|
||||||
|
@ -483,7 +539,7 @@ ScriptVariantV8Proxy* ScriptVariantV8Proxy::unwrapProxy(const V8ScriptValue& val
|
||||||
if (v8Object->InternalFieldCount() != 2) {
|
if (v8Object->InternalFieldCount() != 2) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (v8Object->GetAlignedPointerFromInternalField(0) == internalPointsToQVariantProxy) {
|
if (v8Object->GetAlignedPointerFromInternalField(0) != internalPointsToQVariantProxy) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return reinterpret_cast<ScriptVariantV8Proxy*>(v8Object->GetAlignedPointerFromInternalField(1));
|
return reinterpret_cast<ScriptVariantV8Proxy*>(v8Object->GetAlignedPointerFromInternalField(1));
|
||||||
|
@ -495,8 +551,13 @@ QVariant ScriptVariantV8Proxy::unwrap(const V8ScriptValue& val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptMethodV8Proxy::ScriptMethodV8Proxy(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime,
|
ScriptMethodV8Proxy::ScriptMethodV8Proxy(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime,
|
||||||
const QList<QMetaMethod>& metas, int numMaxParms) :
|
const QList<QMetaMethod>& metas, int numMaxParams) :
|
||||||
_numMaxParms(numMaxParms), _engine(engine), _object(object), _objectLifetime(lifetime), _metas(metas) {
|
_numMaxParams(numMaxParams), _engine(engine), _object(object), _objectLifetime(lifetime), _metas(metas) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptMethodV8Proxy::~ScriptMethodV8Proxy() {
|
||||||
|
qDebug(scriptengine) << "ScriptMethodV8Proxy destroyed";
|
||||||
|
printf("ScriptMethodV8Proxy destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
V8ScriptValue ScriptMethodV8Proxy::newMethod(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime,
|
V8ScriptValue ScriptMethodV8Proxy::newMethod(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime,
|
||||||
|
@ -534,23 +595,25 @@ QString ScriptMethodV8Proxy::fullName() const {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
void ScriptMethodV8Proxy::callback(const v8::FunctionCallbackInfo<v8::Value>& arguments) {
|
void ScriptMethodV8Proxy::callback(const v8::FunctionCallbackInfo<v8::Value>& arguments) {
|
||||||
if (!arguments.This()->IsObject()) {
|
v8::HandleScope handleScope(arguments.GetIsolate());
|
||||||
|
if (!arguments.Data()->IsObject()) {
|
||||||
arguments.GetIsolate()->ThrowError("Method value is not an object");
|
arguments.GetIsolate()->ThrowError("Method value is not an object");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!arguments.This()->IsCallable()) {
|
v8::Local<v8::Object> data = v8::Local<v8::Object>::Cast(arguments.Data());
|
||||||
|
/*if (!arguments.Data()->IsCallable()) {
|
||||||
arguments.GetIsolate()->ThrowError("Method value is not callable");
|
arguments.GetIsolate()->ThrowError("Method value is not callable");
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
if (arguments.This()->InternalFieldCount() != 2) {
|
if (data->InternalFieldCount() != 2) {
|
||||||
arguments.GetIsolate()->ThrowError("Incorrect number of internal fields during method call");
|
arguments.GetIsolate()->ThrowError("Incorrect number of internal fields during method call");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (arguments.This()->GetAlignedPointerFromInternalField(0) == internalPointsToMethodProxy) {
|
if (data->GetAlignedPointerFromInternalField(0) != internalPointsToMethodProxy) {
|
||||||
arguments.GetIsolate()->ThrowError("Internal field 0 of ScriptMethodV8Proxy V8 object has wrong value");
|
arguments.GetIsolate()->ThrowError("Internal field 0 of ScriptMethodV8Proxy V8 object has wrong value");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ScriptMethodV8Proxy *proxy = reinterpret_cast<ScriptMethodV8Proxy*>(arguments.This()->GetAlignedPointerFromInternalField(1));
|
ScriptMethodV8Proxy *proxy = reinterpret_cast<ScriptMethodV8Proxy*>(data->GetAlignedPointerFromInternalField(1));
|
||||||
proxy->call(arguments);
|
proxy->call(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +628,7 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
|
||||||
v8::HandleScope handleScope(_engine->getIsolate());
|
v8::HandleScope handleScope(_engine->getIsolate());
|
||||||
|
|
||||||
int scriptNumArgs = arguments.Length();
|
int scriptNumArgs = arguments.Length();
|
||||||
int numArgs = std::min(scriptNumArgs, _numMaxParms);
|
int numArgs = std::min(scriptNumArgs, _numMaxParams);
|
||||||
|
|
||||||
const int scriptValueTypeId = qMetaTypeId<ScriptValue>();
|
const int scriptValueTypeId = qMetaTypeId<ScriptValue>();
|
||||||
|
|
||||||
|
@ -739,7 +802,7 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
|
||||||
}
|
}
|
||||||
|
|
||||||
int scriptNumArgs = context->argumentCount();
|
int scriptNumArgs = context->argumentCount();
|
||||||
int numArgs = std::min(scriptNumArgs, _numMaxParms);
|
int numArgs = std::min(scriptNumArgs, _numMaxParams);
|
||||||
|
|
||||||
const int scriptValueTypeId = qMetaTypeId<ScriptValue>();
|
const int scriptValueTypeId = qMetaTypeId<ScriptValue>();
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ private: // storage
|
||||||
v8::UniquePersistent<v8::ObjectTemplate> _v8ObjectTemplate;
|
v8::UniquePersistent<v8::ObjectTemplate> _v8ObjectTemplate;
|
||||||
// V8TODO Maybe it doesn't really need to point to itsef?
|
// V8TODO Maybe it doesn't really need to point to itsef?
|
||||||
v8::UniquePersistent<v8::Object> _v8Object;
|
v8::UniquePersistent<v8::Object> _v8Object;
|
||||||
|
int pointerCorruptionTest = 12345678;
|
||||||
|
|
||||||
Q_DISABLE_COPY(ScriptObjectV8Proxy)
|
Q_DISABLE_COPY(ScriptObjectV8Proxy)
|
||||||
};
|
};
|
||||||
|
@ -167,7 +168,8 @@ private: // storage
|
||||||
class ScriptMethodV8Proxy final {
|
class ScriptMethodV8Proxy final {
|
||||||
public: // construction
|
public: // construction
|
||||||
ScriptMethodV8Proxy(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime,
|
ScriptMethodV8Proxy(ScriptEngineV8* engine, QObject* object, V8ScriptValue lifetime,
|
||||||
const QList<QMetaMethod>& metas, int numMaxParms);
|
const QList<QMetaMethod>& metas, int numMaxParams);
|
||||||
|
virtual ~ScriptMethodV8Proxy();
|
||||||
|
|
||||||
public: // QScriptClass implementation
|
public: // QScriptClass implementation
|
||||||
virtual QString name() const { return fullName(); }
|
virtual QString name() const { return fullName(); }
|
||||||
|
@ -182,7 +184,7 @@ private:
|
||||||
QString fullName() const;
|
QString fullName() const;
|
||||||
|
|
||||||
private: // storage
|
private: // storage
|
||||||
const int _numMaxParms;
|
const int _numMaxParams;
|
||||||
ScriptEngineV8* _engine;
|
ScriptEngineV8* _engine;
|
||||||
QPointer<QObject> _object;
|
QPointer<QObject> _object;
|
||||||
V8ScriptValue _objectLifetime;
|
V8ScriptValue _objectLifetime;
|
||||||
|
|
Loading…
Reference in a new issue