mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 10:37:56 +02:00
V8 fixes
This commit is contained in:
parent
f65e72c8f2
commit
5cf32a968c
14 changed files with 142 additions and 17 deletions
|
@ -1,4 +1,4 @@
|
||||||
'use strict';
|
'no use strict';
|
||||||
//
|
//
|
||||||
// activator-doppleganger.js
|
// activator-doppleganger.js
|
||||||
//
|
//
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
autoUpdate: true
|
autoUpdate: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// V8TODO: does this need to be fixed? Right now it refers to global object in non-strict mode,
|
||||||
|
// and in strict mode it's undefined
|
||||||
this.preload = function(entityID) {
|
this.preload = function(entityID) {
|
||||||
thisEntityID = entityID;
|
thisEntityID = entityID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ WindowScriptingInterface::~WindowScriptingInterface() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptValue WindowScriptingInterface::hasFocus() {
|
ScriptValue WindowScriptingInterface::hasFocus() {
|
||||||
|
Q_ASSERT(engine);
|
||||||
return engine()->newValue(qApp->hasFocus());
|
return engine()->newValue(qApp->hasFocus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +106,7 @@ void WindowScriptingInterface::alert(const QString& message) {
|
||||||
/// \param const QString& message message to display
|
/// \param const QString& message message to display
|
||||||
/// \return ScriptValue `true` if 'Yes' was clicked, `false` otherwise
|
/// \return ScriptValue `true` if 'Yes' was clicked, `false` otherwise
|
||||||
ScriptValue WindowScriptingInterface::confirm(const QString& message) {
|
ScriptValue WindowScriptingInterface::confirm(const QString& message) {
|
||||||
|
Q_ASSERT(engine);
|
||||||
return engine()->newValue((QMessageBox::Yes == OffscreenUi::question("", message, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)));
|
return engine()->newValue((QMessageBox::Yes == OffscreenUi::question("", message, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +116,7 @@ ScriptValue WindowScriptingInterface::confirm(const QString& message) {
|
||||||
/// \return ScriptValue string text value in text box if the dialog was accepted, `null` otherwise.
|
/// \return ScriptValue string text value in text box if the dialog was accepted, `null` otherwise.
|
||||||
ScriptValue WindowScriptingInterface::prompt(const QString& message, const QString& defaultText) {
|
ScriptValue WindowScriptingInterface::prompt(const QString& message, const QString& defaultText) {
|
||||||
QString result = OffscreenUi::getText(nullptr, "", message, QLineEdit::Normal, defaultText);
|
QString result = OffscreenUi::getText(nullptr, "", message, QLineEdit::Normal, defaultText);
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto sResult = engine()->newValue(result);
|
auto sResult = engine()->newValue(result);
|
||||||
if (sResult.equals(engine()->newValue(""))) {
|
if (sResult.equals(engine()->newValue(""))) {
|
||||||
return engine()->nullValue();
|
return engine()->nullValue();
|
||||||
|
@ -232,6 +235,7 @@ ScriptValue WindowScriptingInterface::browseDir(const QString& title, const QStr
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(engine);
|
||||||
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +280,7 @@ ScriptValue WindowScriptingInterface::browse(const QString& title, const QString
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(engine);
|
||||||
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +328,7 @@ ScriptValue WindowScriptingInterface::save(const QString& title, const QString&
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(engine);
|
||||||
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +379,7 @@ ScriptValue WindowScriptingInterface::browseAssets(const QString& title, const Q
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
setPreviousBrowseAssetLocation(QFileInfo(result).absolutePath());
|
setPreviousBrowseAssetLocation(QFileInfo(result).absolutePath());
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(engine);
|
||||||
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
return result.isEmpty() ? engine()->nullValue() : engine()->newValue(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2557,6 +2557,7 @@ QDataStream& operator>>(QDataStream& in, AttachmentData& attachment) {
|
||||||
void AttachmentDataObject::setModelURL(const QString& modelURL) {
|
void AttachmentDataObject::setModelURL(const QString& modelURL) {
|
||||||
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
||||||
data.modelURL = modelURL;
|
data.modelURL = modelURL;
|
||||||
|
Q_ASSERT(engine);
|
||||||
thisObject() = engine()->toScriptValue(data);
|
thisObject() = engine()->toScriptValue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2567,6 +2568,7 @@ QString AttachmentDataObject::getModelURL() const {
|
||||||
void AttachmentDataObject::setJointName(const QString& jointName) {
|
void AttachmentDataObject::setJointName(const QString& jointName) {
|
||||||
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
||||||
data.jointName = jointName;
|
data.jointName = jointName;
|
||||||
|
Q_ASSERT(engine);
|
||||||
thisObject() = engine()->toScriptValue(data);
|
thisObject() = engine()->toScriptValue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2577,6 +2579,7 @@ QString AttachmentDataObject::getJointName() const {
|
||||||
void AttachmentDataObject::setTranslation(const glm::vec3& translation) {
|
void AttachmentDataObject::setTranslation(const glm::vec3& translation) {
|
||||||
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
||||||
data.translation = translation;
|
data.translation = translation;
|
||||||
|
Q_ASSERT(engine);
|
||||||
thisObject() = engine()->toScriptValue(data);
|
thisObject() = engine()->toScriptValue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2587,6 +2590,7 @@ glm::vec3 AttachmentDataObject::getTranslation() const {
|
||||||
void AttachmentDataObject::setRotation(const glm::quat& rotation) {
|
void AttachmentDataObject::setRotation(const glm::quat& rotation) {
|
||||||
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
||||||
data.rotation = rotation;
|
data.rotation = rotation;
|
||||||
|
Q_ASSERT(engine);
|
||||||
thisObject() = engine()->toScriptValue(data);
|
thisObject() = engine()->toScriptValue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2597,6 +2601,7 @@ glm::quat AttachmentDataObject::getRotation() const {
|
||||||
void AttachmentDataObject::setScale(float scale) {
|
void AttachmentDataObject::setScale(float scale) {
|
||||||
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
||||||
data.scale = scale;
|
data.scale = scale;
|
||||||
|
Q_ASSERT(engine);
|
||||||
thisObject() = engine()->toScriptValue(data);
|
thisObject() = engine()->toScriptValue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2607,6 +2612,7 @@ float AttachmentDataObject::getScale() const {
|
||||||
void AttachmentDataObject::setIsSoft(bool isSoft) {
|
void AttachmentDataObject::setIsSoft(bool isSoft) {
|
||||||
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
AttachmentData data = scriptvalue_cast<AttachmentData>(thisObject());
|
||||||
data.isSoft = isSoft;
|
data.isSoft = isSoft;
|
||||||
|
Q_ASSERT(engine);
|
||||||
thisObject() = engine()->toScriptValue(data);
|
thisObject() = engine()->toScriptValue(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ void AssetScriptingInterface::uploadData(QString data, const ScriptValue& callba
|
||||||
auto upload = DependencyManager::get<AssetClient>()->createUpload(dataByteArray);
|
auto upload = DependencyManager::get<AssetClient>()->createUpload(dataByteArray);
|
||||||
|
|
||||||
Promise deferred = makePromise(__FUNCTION__);
|
Promise deferred = makePromise(__FUNCTION__);
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto scriptEngine = engine();
|
auto scriptEngine = engine();
|
||||||
deferred->ready([=](QString error, QVariantMap result) {
|
deferred->ready([=](QString error, QVariantMap result) {
|
||||||
auto url = result.value("url").toString();
|
auto url = result.value("url").toString();
|
||||||
|
@ -96,6 +97,7 @@ void AssetScriptingInterface::setMapping(QString path, QString hash, const Scrip
|
||||||
auto handler = jsBindCallback(thisObject(), callback);
|
auto handler = jsBindCallback(thisObject(), callback);
|
||||||
auto setMappingRequest = assetClient()->createSetMappingRequest(path, hash);
|
auto setMappingRequest = assetClient()->createSetMappingRequest(path, hash);
|
||||||
Promise deferred = makePromise(__FUNCTION__);
|
Promise deferred = makePromise(__FUNCTION__);
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto scriptEngine = engine();
|
auto scriptEngine = engine();
|
||||||
deferred->ready([=](QString error, QVariantMap result) {
|
deferred->ready([=](QString error, QVariantMap result) {
|
||||||
jsCallback(handler, scriptEngine->newValue(error), result);
|
jsCallback(handler, scriptEngine->newValue(error), result);
|
||||||
|
@ -133,6 +135,7 @@ void AssetScriptingInterface::downloadData(QString urlString, const ScriptValue&
|
||||||
auto assetRequest = assetClient->createRequest(hash);
|
auto assetRequest = assetClient->createRequest(hash);
|
||||||
|
|
||||||
Promise deferred = makePromise(__FUNCTION__);
|
Promise deferred = makePromise(__FUNCTION__);
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto scriptEngine = engine();
|
auto scriptEngine = engine();
|
||||||
deferred->ready([=](QString error, QVariantMap result) {
|
deferred->ready([=](QString error, QVariantMap result) {
|
||||||
// FIXME: to remain backwards-compatible the signature here is "callback(data, n/a)"
|
// FIXME: to remain backwards-compatible the signature here is "callback(data, n/a)"
|
||||||
|
@ -196,6 +199,7 @@ void AssetScriptingInterface::getMapping(QString asset, const ScriptValue& callb
|
||||||
JS_VERIFY(AssetUtils::isValidFilePath(path), "invalid ATP file path: " + asset + "(path:"+path+")");
|
JS_VERIFY(AssetUtils::isValidFilePath(path), "invalid ATP file path: " + asset + "(path:"+path+")");
|
||||||
JS_VERIFY(callback.isFunction(), "expected second parameter to be a callback function");
|
JS_VERIFY(callback.isFunction(), "expected second parameter to be a callback function");
|
||||||
Promise promise = getAssetInfo(path);
|
Promise promise = getAssetInfo(path);
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto scriptEngine = engine();
|
auto scriptEngine = engine();
|
||||||
promise->ready([=](QString error, QVariantMap result) {
|
promise->ready([=](QString error, QVariantMap result) {
|
||||||
jsCallback(handler, scriptEngine->newValue(error), scriptEngine->newValue(result.value("hash").toString()));
|
jsCallback(handler, scriptEngine->newValue(error), scriptEngine->newValue(result.value("hash").toString()));
|
||||||
|
@ -229,6 +233,7 @@ Promise AssetScriptingInterface::jsPromiseReady(Promise promise, const ScriptVal
|
||||||
if (!jsVerify(handler.isValid(), "jsPromiseReady -- invalid callback handler")) {
|
if (!jsVerify(handler.isValid(), "jsPromiseReady -- invalid callback handler")) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto scriptEngine = engine();
|
auto scriptEngine = engine();
|
||||||
return promise->ready([this, handler, scriptEngine](QString error, QVariantMap result) {
|
return promise->ready([this, handler, scriptEngine](QString error, QVariantMap result) {
|
||||||
jsCallback(handler, scriptEngine->newValue(error), result);
|
jsCallback(handler, scriptEngine->newValue(error), result);
|
||||||
|
@ -238,6 +243,7 @@ Promise AssetScriptingInterface::jsPromiseReady(Promise promise, const ScriptVal
|
||||||
void AssetScriptingInterface::jsCallback(const ScriptValue& handler,
|
void AssetScriptingInterface::jsCallback(const ScriptValue& handler,
|
||||||
const ScriptValue& error, const ScriptValue& result) {
|
const ScriptValue& error, const ScriptValue& result) {
|
||||||
Q_ASSERT(thread() == QThread::currentThread());
|
Q_ASSERT(thread() == QThread::currentThread());
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto errorValue = !error.toBool() ? engine()->nullValue() : error;
|
auto errorValue = !error.toBool() ? engine()->nullValue() : error;
|
||||||
JS_VERIFY(handler.isObject() && handler.property("callback").isFunction(),
|
JS_VERIFY(handler.isObject() && handler.property("callback").isFunction(),
|
||||||
QString("jsCallback -- .callback is not a function (%1)")
|
QString("jsCallback -- .callback is not a function (%1)")
|
||||||
|
@ -536,6 +542,7 @@ void AssetScriptingInterface::loadFromCache(const ScriptValue& options, const Sc
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetScriptingInterface::canWriteCacheValue(const QUrl& url) {
|
bool AssetScriptingInterface::canWriteCacheValue(const QUrl& url) {
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto scriptManager = engine()->manager();
|
auto scriptManager = engine()->manager();
|
||||||
if (!scriptManager) {
|
if (!scriptManager) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -80,12 +80,14 @@ ScriptValue ConsoleScriptingInterface::exception(ScriptContext* context, ScriptE
|
||||||
void ConsoleScriptingInterface::time(QString labelName) {
|
void ConsoleScriptingInterface::time(QString labelName) {
|
||||||
_timerDetails.insert(labelName, QDateTime::currentDateTime().toUTC());
|
_timerDetails.insert(labelName, QDateTime::currentDateTime().toUTC());
|
||||||
QString message = QString("%1: Timer started").arg(labelName);
|
QString message = QString("%1: Timer started").arg(labelName);
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
scriptManager->scriptPrintedMessage(message);
|
scriptManager->scriptPrintedMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleScriptingInterface::timeEnd(QString labelName) {
|
void ConsoleScriptingInterface::timeEnd(QString labelName) {
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
if (!_timerDetails.contains(labelName)) {
|
if (!_timerDetails.contains(labelName)) {
|
||||||
scriptManager->scriptErrorMessage("No such label found " + labelName);
|
scriptManager->scriptErrorMessage("No such label found " + labelName);
|
||||||
|
@ -134,6 +136,7 @@ ScriptValue ConsoleScriptingInterface::assertion(ScriptContext* context, ScriptE
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleScriptingInterface::trace() {
|
void ConsoleScriptingInterface::trace() {
|
||||||
|
Q_ASSERT(engine);
|
||||||
ScriptEnginePointer scriptEngine = engine();
|
ScriptEnginePointer scriptEngine = engine();
|
||||||
if (ScriptManager* scriptManager = scriptEngine->manager()) {
|
if (ScriptManager* scriptManager = scriptEngine->manager()) {
|
||||||
scriptManager->scriptPrintedMessage
|
scriptManager->scriptPrintedMessage
|
||||||
|
@ -143,6 +146,7 @@ void ConsoleScriptingInterface::trace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleScriptingInterface::clear() {
|
void ConsoleScriptingInterface::clear() {
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
scriptManager->clearDebugLogWindow();
|
scriptManager->clearDebugLogWindow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ void Mat4::print(const QString& label, const glm::mat4& m, bool transpose) const
|
||||||
QString message = QString("%1 %2").arg(qPrintable(label));
|
QString message = QString("%1 %2").arg(qPrintable(label));
|
||||||
message = message.arg(glm::to_string(out).c_str());
|
message = message.arg(glm::to_string(out).c_str());
|
||||||
qCDebug(scriptengine) << message;
|
qCDebug(scriptengine) << message;
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
scriptManager->print(message);
|
scriptManager->print(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,7 @@ void Quat::print(const QString& label, const glm::quat& q, bool asDegrees) {
|
||||||
message = message.arg(glm::to_string(glm::dquat(q)).c_str());
|
message = message.arg(glm::to_string(glm::dquat(q)).c_str());
|
||||||
}
|
}
|
||||||
qCDebug(scriptengine) << message;
|
qCDebug(scriptengine) << message;
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
scriptManager->print(message);
|
scriptManager->print(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ void ScriptUUID::print(const QString& label, const QUuid& id) {
|
||||||
QString message = QString("%1 %2").arg(qPrintable(label));
|
QString message = QString("%1 %2").arg(qPrintable(label));
|
||||||
message = message.arg(id.toString());
|
message = message.arg(id.toString());
|
||||||
qCDebug(scriptengine) << message;
|
qCDebug(scriptengine) << message;
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
scriptManager->print(message);
|
scriptManager->print(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ void Vec3::print(const QString& label, const glm::vec3& v) {
|
||||||
QString message = QString("%1 %2").arg(qPrintable(label));
|
QString message = QString("%1 %2").arg(qPrintable(label));
|
||||||
message = message.arg(glm::to_string(glm::dvec3(v)).c_str());
|
message = message.arg(glm::to_string(glm::dvec3(v)).c_str());
|
||||||
qCDebug(scriptengine) << message;
|
qCDebug(scriptengine) << message;
|
||||||
|
Q_ASSERT(engine);
|
||||||
if (ScriptManager* scriptManager = engine()->manager()) {
|
if (ScriptManager* scriptManager = engine()->manager()) {
|
||||||
scriptManager->print(message);
|
scriptManager->print(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,7 +427,6 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
||||||
v8::Context::Scope contextScope(context);
|
v8::Context::Scope contextScope(context);
|
||||||
_contexts.append(std::make_shared<ScriptContextV8Wrapper>(this,context, ScriptContextPointer()));
|
_contexts.append(std::make_shared<ScriptContextV8Wrapper>(this,context, ScriptContextPointer()));
|
||||||
|
|
||||||
|
|
||||||
V8ScriptValue nullScriptValue(this, v8::Null(_v8Isolate));
|
V8ScriptValue nullScriptValue(this, v8::Null(_v8Isolate));
|
||||||
_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
|
_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
|
||||||
|
|
||||||
|
@ -802,6 +801,32 @@ const v8::Local<v8::Context> ScriptEngineV8::getConstContext() const {
|
||||||
Q_ASSERT(!_contexts.isEmpty());
|
Q_ASSERT(!_contexts.isEmpty());
|
||||||
return handleScope.Escape(_contexts.last().get()->toV8Value());
|
return handleScope.Escape(_contexts.last().get()->toV8Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stored objects are used to create global objects for evaluateInClosure
|
||||||
|
void ScriptEngineV8::storeGlobalObjectContents() {
|
||||||
|
if (areGlobalObjectContentsStored) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
v8::Locker locker(_v8Isolate);
|
||||||
|
v8::Isolate::Scope isolateScope(_v8Isolate);
|
||||||
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
|
auto context = getContext();
|
||||||
|
v8::Context::Scope contextScope(context);
|
||||||
|
v8::Local<v8::Object> globalMemberObjects = v8::Object::New(_v8Isolate);
|
||||||
|
|
||||||
|
auto globalMemberNames = context->Global()->GetPropertyNames(context).ToLocalChecked();
|
||||||
|
for (size_t i = 0; i < globalMemberNames->Length(); i++) {
|
||||||
|
auto name = globalMemberNames->Get(context, i).ToLocalChecked();
|
||||||
|
if(!globalMemberObjects->Set(context, name, context->Global()->Get(context, name).ToLocalChecked()).FromMaybe(false)) {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_globalObjectContents.Reset(_v8Isolate, globalMemberObjects);
|
||||||
|
qDebug() << "ScriptEngineV8::storeGlobalObjectContents: " << globalMemberNames->Length() << " objects stored";
|
||||||
|
areGlobalObjectContentsStored = true;
|
||||||
|
}
|
||||||
|
|
||||||
ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
const ScriptProgramPointer& _program) {
|
const ScriptProgramPointer& _program) {
|
||||||
PROFILE_RANGE(script, "evaluateInClosure");
|
PROFILE_RANGE(script, "evaluateInClosure");
|
||||||
|
@ -812,6 +837,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
v8::Locker locker(_v8Isolate);
|
v8::Locker locker(_v8Isolate);
|
||||||
v8::Isolate::Scope isolateScope(_v8Isolate);
|
v8::Isolate::Scope isolateScope(_v8Isolate);
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
|
storeGlobalObjectContents();
|
||||||
|
|
||||||
v8::Local<v8::Object> closureObject;
|
v8::Local<v8::Object> closureObject;
|
||||||
//v8::Local<v8::Value> oldGlobal;
|
//v8::Local<v8::Value> oldGlobal;
|
||||||
|
@ -896,6 +922,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
if (!unwrappedProgram->compile()) {
|
if (!unwrappedProgram->compile()) {
|
||||||
qDebug(scriptengine) << "Can't compile script for evaluating in closure";
|
qDebug(scriptengine) << "Can't compile script for evaluating in closure";
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
popContext();
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
const V8ScriptProgram& program = unwrappedProgram->toV8Value();
|
const V8ScriptProgram& program = unwrappedProgram->toV8Value();
|
||||||
|
@ -928,18 +955,35 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
{
|
{
|
||||||
v8::TryCatch tryCatch(getIsolate());
|
v8::TryCatch tryCatch(getIsolate());
|
||||||
// Since V8 cannot use arbitrary object as global object, objects from main global need to be copied to closure's global object
|
// Since V8 cannot use arbitrary object as global object, objects from main global need to be copied to closure's global object
|
||||||
auto oldGlobalMemberNames = oldContext->Global()->GetPropertyNames(oldContext).ToLocalChecked();
|
auto globalObjectContents = _globalObjectContents.Get(_v8Isolate);
|
||||||
for (size_t i = 0; i < oldGlobalMemberNames->Length(); i++) {
|
auto globalMemberNames = globalObjectContents->GetPropertyNames(globalObjectContents->CreationContext()).ToLocalChecked();
|
||||||
auto name = oldGlobalMemberNames->Get(closureContext, i).ToLocalChecked();
|
for (size_t i = 0; i < globalMemberNames->Length(); i++) {
|
||||||
if(!closureContext->Global()->Set(closureContext, name, oldContext->Global()->Get(oldContext, name).ToLocalChecked()).FromMaybe(false)) {
|
auto name = globalMemberNames->Get(closureContext, i).ToLocalChecked();
|
||||||
|
if(!closureContext->Global()->Set(closureContext, name, globalObjectContents->Get(globalObjectContents->CreationContext(), name).ToLocalChecked()).FromMaybe(false)) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
qDebug() << "ScriptEngineV8::evaluateInClosure: " << globalMemberNames->Length() << " objects added to global";
|
||||||
|
|
||||||
|
/*auto oldGlobalMemberNames = oldContext->Global()->GetPropertyNames(oldContext).ToLocalChecked();
|
||||||
|
//auto oldGlobalMemberNames = oldContext->Global()->GetPropertyNames(closureContext).ToLocalChecked();
|
||||||
|
for (size_t i = 0; i < oldGlobalMemberNames->Length(); i++) {
|
||||||
|
auto name = oldGlobalMemberNames->Get(closureContext, i).ToLocalChecked();
|
||||||
|
//auto name = oldGlobalMemberNames->Get(oldContext, i).ToLocalChecked();
|
||||||
|
if(!closureContext->Global()->Set(closureContext, name, oldContext->Global()->Get(oldContext, name).ToLocalChecked()).FromMaybe(false)) {
|
||||||
|
//if(!closureContext->Global()->Set(closureContext, name, oldContext->Global()->Get(closureContext, name).ToLocalChecked()).FromMaybe(false)) {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
// Objects from closure need to be copied to global object too
|
// Objects from closure need to be copied to global object too
|
||||||
|
// V8TODO: I'm not sure which context to use with Get
|
||||||
auto closureMemberNames = closureObject->GetPropertyNames(closureContext).ToLocalChecked();
|
auto closureMemberNames = closureObject->GetPropertyNames(closureContext).ToLocalChecked();
|
||||||
|
//auto closureMemberNames = closureObject->GetPropertyNames(oldContext).ToLocalChecked();
|
||||||
for (size_t i = 0; i < closureMemberNames->Length(); i++) {
|
for (size_t i = 0; i < closureMemberNames->Length(); i++) {
|
||||||
auto name = closureMemberNames->Get(closureContext, i).ToLocalChecked();
|
auto name = closureMemberNames->Get(closureContext, i).ToLocalChecked();
|
||||||
|
//auto name = closureMemberNames->Get(oldContext, i).ToLocalChecked();
|
||||||
if(!closureContext->Global()->Set(closureContext, name, closureObject->Get(closureContext, name).ToLocalChecked()).FromMaybe(false)) {
|
if(!closureContext->Global()->Set(closureContext, name, closureObject->Get(closureContext, name).ToLocalChecked()).FromMaybe(false)) {
|
||||||
|
//if(!closureContext->Global()->Set(closureContext, name, closureObject->Get(oldContext, name).ToLocalChecked()).FromMaybe(false)) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1455,6 +1499,7 @@ ScriptContext* ScriptEngineV8::currentContext() const {
|
||||||
// I'm not sure how to do this without discarding const
|
// I'm not sure how to do this without discarding const
|
||||||
_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this));
|
_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this));
|
||||||
}*/
|
}*/
|
||||||
|
// V8TODO: add FunctionCallbackInfo or PropertyCallbackInfo when necessary
|
||||||
return _contexts.last().get();
|
return _contexts.last().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1501,7 +1546,7 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
|
||||||
ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>
|
ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>
|
||||||
(object->GetAlignedPointerFromInternalField(1));
|
(object->GetAlignedPointerFromInternalField(1));
|
||||||
ScriptContextV8Wrapper scriptContext(scriptEngine, &info, scriptEngine->getContext(), scriptEngine->currentContext()->parentContext());
|
ScriptContextV8Wrapper scriptContext(scriptEngine, &info, scriptEngine->getContext(), scriptEngine->currentContext()->parentContext());
|
||||||
//V8TODO: this scriptContext needs to have FunctionCallbackInfo added
|
ScriptContextGuard scriptContextGuard(&scriptContext);
|
||||||
ScriptValue result = function(&scriptContext, scriptEngine);
|
ScriptValue result = function(&scriptContext, scriptEngine);
|
||||||
ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
|
ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
|
||||||
if (unwrapped) {
|
if (unwrapped) {
|
||||||
|
|
|
@ -202,6 +202,8 @@ public: // not for public use, but I don't like how Qt strings this along with p
|
||||||
|
|
||||||
ScriptContextV8Pointer pushContext(v8::Local<v8::Context> context);
|
ScriptContextV8Pointer pushContext(v8::Local<v8::Context> context);
|
||||||
void popContext();
|
void popContext();
|
||||||
|
// V8TODO: call this after initializing global object
|
||||||
|
void storeGlobalObjectContents();
|
||||||
|
|
||||||
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
|
||||||
|
@ -240,6 +242,8 @@ protected:
|
||||||
//mutable ScriptContextV8Pointer _currContext;
|
//mutable ScriptContextV8Pointer _currContext;
|
||||||
// Current context stack. Main context is first on the list and current one is last.
|
// Current context stack. Main context is first on the list and current one is last.
|
||||||
QList<ScriptContextV8Pointer> _contexts;
|
QList<ScriptContextV8Pointer> _contexts;
|
||||||
|
v8::Persistent<v8::Object> _globalObjectContents;
|
||||||
|
bool areGlobalObjectContentsStored {false};
|
||||||
|
|
||||||
//V8TODO
|
//V8TODO
|
||||||
//ArrayBufferClass* _arrayBufferClass;
|
//ArrayBufferClass* _arrayBufferClass;
|
||||||
|
|
|
@ -39,9 +39,9 @@ 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
|
||||||
class ScriptPropertyContextQtWrapper final : public ScriptContext {
|
class ScriptPropertyContextV8Wrapper final : public ScriptContext {
|
||||||
public: // construction
|
public: // construction
|
||||||
inline ScriptPropertyContextQtWrapper(const ScriptValue& object, ScriptContext* parentContext) :
|
inline ScriptPropertyContextV8Wrapper(const ScriptValue& object, ScriptContext* parentContext) :
|
||||||
_parent(parentContext), _object(object) {}
|
_parent(parentContext), _object(object) {}
|
||||||
|
|
||||||
public: // ScriptContext implementation
|
public: // ScriptContext implementation
|
||||||
|
@ -568,7 +568,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V
|
||||||
|
|
||||||
QMetaProperty prop = metaObject->property(propId);
|
QMetaProperty prop = metaObject->property(propId);
|
||||||
ScriptValue scriptThis = ScriptValue(new ScriptValueV8Wrapper(_engine, object));
|
ScriptValue scriptThis = ScriptValue(new ScriptValueV8Wrapper(_engine, object));
|
||||||
ScriptPropertyContextQtWrapper ourContext(scriptThis, _engine->currentContext());
|
ScriptPropertyContextV8Wrapper ourContext(scriptThis, _engine->currentContext());
|
||||||
ScriptContextGuard guard(&ourContext);
|
ScriptContextGuard guard(&ourContext);
|
||||||
|
|
||||||
QVariant varValue = prop.read(qobject);
|
QVariant varValue = prop.read(qobject);
|
||||||
|
@ -611,7 +611,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V
|
||||||
ScriptEngine::QObjectWrapOptions options = ScriptEngine::ExcludeSuperClassContents |
|
ScriptEngine::QObjectWrapOptions options = ScriptEngine::ExcludeSuperClassContents |
|
||||||
//V8TODO ScriptEngine::ExcludeDeleteLater |
|
//V8TODO ScriptEngine::ExcludeDeleteLater |
|
||||||
ScriptEngine::PreferExistingWrapperObject;
|
ScriptEngine::PreferExistingWrapperObject;
|
||||||
//V8TODO: why is it returning new object every time?
|
// It's not necessarily new, newQObject looks for it first in object wrapper map
|
||||||
return ScriptObjectV8Proxy::newQObject(_engine, proxy, ScriptEngine::ScriptOwnership, options);
|
return ScriptObjectV8Proxy::newQObject(_engine, proxy, ScriptEngine::ScriptOwnership, options);
|
||||||
//return _engine->newQObject(proxy, ScriptEngine::ScriptOwnership, options);
|
//return _engine->newQObject(proxy, ScriptEngine::ScriptOwnership, options);
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ void ScriptObjectV8Proxy::setProperty(V8ScriptValue& object, const V8ScriptStrin
|
||||||
QMetaProperty prop = metaObject->property(propId);
|
QMetaProperty prop = metaObject->property(propId);
|
||||||
|
|
||||||
ScriptValue scriptThis = ScriptValue(new ScriptValueV8Wrapper(_engine, object));
|
ScriptValue scriptThis = ScriptValue(new ScriptValueV8Wrapper(_engine, object));
|
||||||
ScriptPropertyContextQtWrapper ourContext(scriptThis, _engine->currentContext());
|
ScriptPropertyContextV8Wrapper ourContext(scriptThis, _engine->currentContext());
|
||||||
ScriptContextGuard guard(&ourContext);
|
ScriptContextGuard guard(&ourContext);
|
||||||
|
|
||||||
int propTypeId = prop.userType();
|
int propTypeId = prop.userType();
|
||||||
|
@ -883,8 +883,10 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValidMetaSelected) {
|
if (isValidMetaSelected) {
|
||||||
//ScriptContextV8Wrapper ourContext(_engine, context);
|
// V8TODO: is this the correct wrapper?
|
||||||
//ScriptContextGuard guard(&ourContext);
|
ScriptContextV8Wrapper ourContext(_engine, &arguments, _engine->getContext(),
|
||||||
|
_engine->currentContext()->parentContext());
|
||||||
|
ScriptContextGuard guard(&ourContext);
|
||||||
const QMetaMethod& meta = _metas[bestMeta];
|
const QMetaMethod& meta = _metas[bestMeta];
|
||||||
int returnTypeId = meta.returnType();
|
int returnTypeId = meta.returnType();
|
||||||
QVector <QGenericArgument> &qGenArgs = qGenArgsVectors[bestMeta];
|
QVector <QGenericArgument> &qGenArgs = qGenArgsVectors[bestMeta];
|
||||||
|
@ -1333,8 +1335,15 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) {
|
||||||
v8::Local<v8::Function> destFunction = v8::Local<v8::Function>::Cast(callback.get());
|
v8::Local<v8::Function> destFunction = v8::Local<v8::Function>::Cast(callback.get());
|
||||||
v8::Local<v8::String> destDataName = v8::String::NewFromUtf8(isolate, "__data__").ToLocalChecked();
|
v8::Local<v8::String> destDataName = v8::String::NewFromUtf8(isolate, "__data__").ToLocalChecked();
|
||||||
v8::Local<v8::Value> destData;
|
v8::Local<v8::Value> destData;
|
||||||
auto destFunctionContext = destFunction->CreationContext();
|
// V8TODO: I'm not sure which context to use here
|
||||||
|
//auto destFunctionContext = destFunction->CreationContext();
|
||||||
|
auto destFunctionContext = _engine->getContext();
|
||||||
|
Q_ASSERT(thisObject().isObject());
|
||||||
V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject());
|
V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject());
|
||||||
|
Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8ThisObject));
|
||||||
|
ScriptSignalV8Proxy* thisProxy = dynamic_cast<ScriptSignalV8Proxy*>(ScriptObjectV8Proxy::unwrapProxy(v8ThisObject)->toQObject());
|
||||||
|
Q_ASSERT(thisProxy);
|
||||||
|
qDebug(scriptengine) << "ScriptSignalV8Proxy::connect: " << thisProxy->fullName() << " fullName: " << fullName();
|
||||||
//Q_ASSERT(destFunction->InternalFieldCount() == 4);
|
//Q_ASSERT(destFunction->InternalFieldCount() == 4);
|
||||||
//Q_ASSERT(destData.get()->IsArray());
|
//Q_ASSERT(destData.get()->IsArray());
|
||||||
//v8::Local<v8::Value> destData = destFunction->GetInternalField(3);
|
//v8::Local<v8::Value> destData = destFunction->GetInternalField(3);
|
||||||
|
@ -1344,15 +1353,27 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) {
|
||||||
if (destData->IsArray()) {
|
if (destData->IsArray()) {
|
||||||
v8::Local<v8::Array> destArray = v8::Local<v8::Array>::Cast(destData);
|
v8::Local<v8::Array> destArray = v8::Local<v8::Array>::Cast(destData);
|
||||||
int length = destArray->Length();//destData.property("length").toInteger();
|
int length = destArray->Length();//destData.property("length").toInteger();
|
||||||
|
// V8TODO: Maybe copying array is unnecessary?
|
||||||
v8::Local<v8::Array> newArray = v8::Array::New(isolate, length + 1);
|
v8::Local<v8::Array> newArray = v8::Array::New(isolate, length + 1);
|
||||||
bool foundIt = false;
|
bool foundIt = false;
|
||||||
for (int idx = 0; idx < length && !foundIt; ++idx) {
|
for (int idx = 0; idx < length && !foundIt; ++idx) {
|
||||||
v8::Local<v8::Value> entry = destArray->Get(destFunctionContext, idx).ToLocalChecked();
|
v8::Local<v8::Value> entry = destArray->Get(destFunctionContext, idx).ToLocalChecked();
|
||||||
|
{
|
||||||
|
qDebug() << "ScriptSignalV8Proxy::connect: entry details: " << _engine->scriptValueDebugDetailsV8(V8ScriptValue(_engine, entry));
|
||||||
|
Q_ASSERT(entry->IsObject());
|
||||||
|
V8ScriptValue v8EntryObject(_engine, entry);
|
||||||
|
Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8EntryObject));
|
||||||
|
// For debugging
|
||||||
|
ScriptSignalV8Proxy* entryProxy = dynamic_cast<ScriptSignalV8Proxy*>(ScriptObjectV8Proxy::unwrapProxy(v8EntryObject)->toQObject());
|
||||||
|
Q_ASSERT(thisProxy);
|
||||||
|
qDebug(scriptengine) << "ScriptSignalV8Proxy::connect: entry proxy: " << entryProxy->fullName();
|
||||||
|
}
|
||||||
if (!newArray->Set(destFunctionContext, idx, entry).FromMaybe(false)) {
|
if (!newArray->Set(destFunctionContext, idx, entry).FromMaybe(false)) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!newArray->Set(destFunctionContext, length, v8ThisObject.get()).FromMaybe(false)) {
|
if (!newArray->Set(destFunctionContext, length, v8ThisObject.get()).FromMaybe(false)) {
|
||||||
|
//if (!newArray->Set(destFunctionContext, length, v8ThisObject.get()).FromMaybe(false)) {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
if (!destFunction->Set(destFunctionContext, destDataName, newArray).FromMaybe(false)) {
|
if (!destFunction->Set(destFunctionContext, destDataName, newArray).FromMaybe(false)) {
|
||||||
|
@ -1448,8 +1469,16 @@ void ScriptSignalV8Proxy::disconnect(ScriptValue arg0, ScriptValue arg1) {
|
||||||
v8::Local<v8::Function> destFunction = v8::Local<v8::Function>::Cast(callback.get());
|
v8::Local<v8::Function> destFunction = v8::Local<v8::Function>::Cast(callback.get());
|
||||||
v8::Local<v8::String> destDataName = v8::String::NewFromUtf8(isolate, "__data__").ToLocalChecked();
|
v8::Local<v8::String> destDataName = v8::String::NewFromUtf8(isolate, "__data__").ToLocalChecked();
|
||||||
v8::Local<v8::Value> destData;
|
v8::Local<v8::Value> destData;
|
||||||
auto destFunctionContext = destFunction->CreationContext();
|
|
||||||
|
//auto destFunctionContext = destFunction->CreationContext();
|
||||||
|
auto destFunctionContext = _engine->getContext();
|
||||||
|
Q_ASSERT(thisObject().isObject());
|
||||||
V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject());
|
V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject());
|
||||||
|
Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8ThisObject));
|
||||||
|
// For debugging
|
||||||
|
ScriptSignalV8Proxy* thisProxy = dynamic_cast<ScriptSignalV8Proxy*>(ScriptObjectV8Proxy::unwrapProxy(v8ThisObject)->toQObject());
|
||||||
|
Q_ASSERT(thisProxy);
|
||||||
|
qDebug(scriptengine) << "ScriptSignalV8Proxy::disconnect: " << thisProxy->fullName() << " fullName: " << fullName();
|
||||||
//V8ScriptValue destData = callback.data();
|
//V8ScriptValue destData = callback.data();
|
||||||
//Q_ASSERT(destData->IsArray());
|
//Q_ASSERT(destData->IsArray());
|
||||||
if (!destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData)) {
|
if (!destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData)) {
|
||||||
|
@ -1463,8 +1492,22 @@ void ScriptSignalV8Proxy::disconnect(ScriptValue arg0, ScriptValue arg1) {
|
||||||
int newIndex = 0;
|
int newIndex = 0;
|
||||||
for (int idx = 0; idx < length && !foundIt; ++idx) {
|
for (int idx = 0; idx < length && !foundIt; ++idx) {
|
||||||
v8::Local<v8::Value> entry = destArray->Get(destFunctionContext, idx).ToLocalChecked();
|
v8::Local<v8::Value> entry = destArray->Get(destFunctionContext, idx).ToLocalChecked();
|
||||||
|
// For debugging:
|
||||||
|
{
|
||||||
|
_engine->logBacktrace("ScriptSignalV8Proxy::disconnect");
|
||||||
|
qDebug() << "ScriptSignalV8Proxy::disconnect: entry details: " << _engine->scriptValueDebugDetailsV8(V8ScriptValue(_engine, entry));
|
||||||
|
Q_ASSERT(entry->IsObject());
|
||||||
|
V8ScriptValue v8EntryObject(_engine, entry);
|
||||||
|
Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8EntryObject));
|
||||||
|
// For debugging
|
||||||
|
ScriptSignalV8Proxy* entryProxy = dynamic_cast<ScriptSignalV8Proxy*>(ScriptObjectV8Proxy::unwrapProxy(v8EntryObject)->toQObject());
|
||||||
|
Q_ASSERT(thisProxy);
|
||||||
|
qDebug(scriptengine) << "ScriptSignalV8Proxy::disconnect: entry proxy: " << entryProxy->fullName();
|
||||||
|
}
|
||||||
if (entry->StrictEquals(v8ThisObject.get())) {
|
if (entry->StrictEquals(v8ThisObject.get())) {
|
||||||
|
//V8TODO: compare proxies instead?
|
||||||
foundIt = true;
|
foundIt = true;
|
||||||
|
qDebug() << "ScriptSignalV8Proxy::disconnect foundIt";
|
||||||
//V8ScriptValueList args;
|
//V8ScriptValueList args;
|
||||||
//args << idx << 1;
|
//args << idx << 1;
|
||||||
//destData.property("splice").call(destData, args);
|
//destData.property("splice").call(destData, args);
|
||||||
|
|
|
@ -235,12 +235,14 @@ private: // implementation
|
||||||
virtual int qt_metacall(QMetaObject::Call call, int id, void** arguments) override;
|
virtual int qt_metacall(QMetaObject::Call call, int id, void** arguments) override;
|
||||||
int discoverMetaCallIdx();
|
int discoverMetaCallIdx();
|
||||||
ConnectionList::iterator findConnection(V8ScriptValue thisObject, V8ScriptValue callback);
|
ConnectionList::iterator findConnection(V8ScriptValue thisObject, V8ScriptValue callback);
|
||||||
QString fullName() const;
|
//QString fullName() const;
|
||||||
|
|
||||||
public: // API
|
public: // API
|
||||||
// arg1 was had Null default value, but that needs isolate pointer to create Null in V8
|
// arg1 was had Null default value, but that needs isolate pointer to create Null in V8
|
||||||
virtual void connect(ScriptValue arg0, ScriptValue arg1 = ScriptValue()) override;
|
virtual void connect(ScriptValue arg0, ScriptValue arg1 = ScriptValue()) override;
|
||||||
virtual void disconnect(ScriptValue arg0, ScriptValue arg1 = ScriptValue()) override;
|
virtual void disconnect(ScriptValue arg0, ScriptValue arg1 = ScriptValue()) override;
|
||||||
|
//Moved to public temporarily for debugging:
|
||||||
|
QString fullName() const;
|
||||||
|
|
||||||
//virtual void connect(V8ScriptValue arg0) override;
|
//virtual void connect(V8ScriptValue arg0) override;
|
||||||
//virtual void disconnect(V8ScriptValue arg0) override;
|
//virtual void disconnect(V8ScriptValue arg0) override;
|
||||||
|
|
|
@ -162,6 +162,7 @@ namespace REPLACE_ME_WITH_UNIQUE_NAME {
|
||||||
* settings = null; // optional best pratice; allows the object to be reclaimed ASAP by the JS garbage collector
|
* settings = null; // optional best pratice; allows the object to be reclaimed ASAP by the JS garbage collector
|
||||||
*/
|
*/
|
||||||
ScriptValue getScopedSettings(const QString& scope) {
|
ScriptValue getScopedSettings(const QString& scope) {
|
||||||
|
Q_ASSERT(engine);
|
||||||
auto engine = Scriptable::engine();
|
auto engine = Scriptable::engine();
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
return ScriptValue();
|
return ScriptValue();
|
||||||
|
|
Loading…
Reference in a new issue