Add hasProperty for checking whether a property exists

This commit is contained in:
Dale Glass 2023-01-09 22:20:36 +01:00 committed by ksuprynowicz
parent 5f2c13da52
commit ac7ebe2888
6 changed files with 47 additions and 5 deletions

View file

@ -44,6 +44,7 @@ public:
virtual ScriptValue property(quint32 arrayIndex, virtual ScriptValue property(quint32 arrayIndex,
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override; const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override;
virtual void setData(const ScriptValue& val) override; virtual void setData(const ScriptValue& val) override;
virtual bool hasProperty(const QString &name) const override;
virtual void setProperty(const QString& name, virtual void setProperty(const QString& name,
const ScriptValue& value, const ScriptValue& value,
const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override; const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override;
@ -178,6 +179,13 @@ void ScriptValueProxyNull::setData(const ScriptValue& val) {
qCWarning(scriptengine_script, "ScriptValue::setData called on empty value"); qCWarning(scriptengine_script, "ScriptValue::setData called on empty value");
} }
bool ScriptValueProxyNull::hasProperty(const QString& name) const {
Q_ASSERT(false);
qCWarning(scriptengine_script, "ScriptValue::hasProperty called on empty value");
return false;
}
void ScriptValueProxyNull::setProperty(const QString& name, void ScriptValueProxyNull::setProperty(const QString& name,
const ScriptValue& value, const ScriptValue::PropertyFlags& flags) { const ScriptValue& value, const ScriptValue::PropertyFlags& flags) {
Q_ASSERT(false); Q_ASSERT(false);

View file

@ -88,6 +88,7 @@ public:
inline ScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const; inline ScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const;
inline ScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const; inline ScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const;
inline void setData(const ScriptValue& val); inline void setData(const ScriptValue& val);
inline bool hasProperty(const QString &name) const;
inline void setProperty(const QString& name, inline void setProperty(const QString& name,
const ScriptValue& value, const ScriptValue& value,
const PropertyFlags& flags = KeepExistingFlags); const PropertyFlags& flags = KeepExistingFlags);
@ -152,6 +153,7 @@ public:
virtual ScriptValue property(quint32 arrayIndex, virtual ScriptValue property(quint32 arrayIndex,
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const = 0; const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const = 0;
virtual void setData(const ScriptValue& val) = 0; virtual void setData(const ScriptValue& val) = 0;
virtual bool hasProperty(const QString &name) const = 0;
virtual void setProperty(const QString& name, virtual void setProperty(const QString& name,
const ScriptValue& value, const ScriptValue& value,
const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) = 0; const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) = 0;
@ -318,6 +320,12 @@ void ScriptValue::setData(const ScriptValue& val) {
return _proxy->setData(val); return _proxy->setData(val);
} }
bool ScriptValue::hasProperty(const QString& name) const {
Q_ASSERT(_proxy != nullptr);
return _proxy->hasProperty(name);
}
void ScriptValue::setProperty(const QString& name, const ScriptValue& value, const PropertyFlags& flags) { void ScriptValue::setProperty(const QString& name, const ScriptValue& value, const PropertyFlags& flags) {
Q_ASSERT(_proxy != nullptr); Q_ASSERT(_proxy != nullptr);
return _proxy->setProperty(name, value, flags); return _proxy->setProperty(name, value, flags);

View file

@ -140,7 +140,7 @@ bool vec2FromScriptValue(const ScriptValue& object, glm::vec2& vec2) {
ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) { ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
auto prototype = engine->globalObject().property("__hifi_vec3__"); auto prototype = engine->globalObject().property("__hifi_vec3__");
if (!prototype.property("defined").toBool()) { if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
prototype = engine->evaluate( prototype = engine->evaluate(
"__hifi_vec3__ = Object.defineProperties({}, { " "__hifi_vec3__ = Object.defineProperties({}, { "
"defined: { value: true }," "defined: { value: true },"

View file

@ -172,6 +172,28 @@ ScriptValueIteratorPointer ScriptValueV8Wrapper::newIterator() const {
return std::make_shared<ScriptValueIteratorV8Wrapper>(_engine, _value); return std::make_shared<ScriptValueIteratorV8Wrapper>(_engine, _value);
} }
bool ScriptValueV8Wrapper::hasProperty(const QString& name) const {
auto isolate = _engine->getIsolate();
v8::Locker locker(_engine->getIsolate());
v8::Isolate::Scope isolateScope(_engine->getIsolate());
v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(_engine->getContext());
if (_value.constGet()->IsObject()) {
//V8TODO: what about flags?
v8::Local<v8::Value> resultLocal;
v8::Local<v8::String> key = v8::String::NewFromUtf8(_engine->getIsolate(), name.toStdString().c_str(),v8::NewStringType::kNormal).ToLocalChecked();
const v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(_value.constGet());
if (object->Get(_value.constGetContext(), key).ToLocal(&resultLocal)) {
return true;
} else {
return false;
}
}
return false;
}
ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValue::ResolveFlags &mode) const { ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValue::ResolveFlags &mode) const {
auto isolate = _engine->getIsolate(); auto isolate = _engine->getIsolate();
v8::Locker locker(_engine->getIsolate()); v8::Locker locker(_engine->getIsolate());

View file

@ -54,6 +54,9 @@ public: // ScriptValue implementation
virtual ScriptValue property(quint32 arrayIndex, virtual ScriptValue property(quint32 arrayIndex,
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override; const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override;
virtual void setData(const ScriptValue& val) override; virtual void setData(const ScriptValue& val) override;
virtual bool hasProperty(const QString &name) const;
virtual void setProperty(const QString& name, virtual void setProperty(const QString& name,
const ScriptValue& value, const ScriptValue& value,
const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override; const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override;

View file

@ -87,7 +87,8 @@ void ScriptEngineTests::scriptTest() {
qInfo() << "Running test script: " << script; qInfo() << "Running test script: " << script;
ac->loadOneScript(script); ac->loadOneScript(script);
}*/ }*/
ac->loadOneScript("tests/script-engine/tests/003_vector_math.js"); ac->loadOneScript("tests/003_vector_math.js");
ac->loadOneScript("tests/004_require.js");
qDebug() << ac->getRunning(); qDebug() << ac->getRunning();