mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 20:43:39 +02:00
vec3ToScriptValue optimizations
This commit is contained in:
parent
43939290b2
commit
8b9cd84df7
4 changed files with 77 additions and 47 deletions
|
@ -33,12 +33,7 @@
|
|||
#include "ScriptEngineCast.h"
|
||||
#include "ScriptValueIterator.h"
|
||||
#include "ScriptEngineLogging.h"
|
||||
|
||||
#define CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
#include "v8/FastScriptValueUtils.h"
|
||||
#endif
|
||||
|
||||
bool isListOfStrings(const ScriptValue& arg) {
|
||||
if (!arg.isArray()) {
|
||||
|
@ -65,11 +60,7 @@ void registerMetaTypes(ScriptEngine* engine) {
|
|||
scriptRegisterMetaType<QVector3D, qVector3DToScriptValue, qVector3DFromScriptValue>(engine);
|
||||
|
||||
scriptRegisterMetaType<glm::vec2, vec2ToScriptValue, vec2FromScriptValue>(engine);
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
scriptRegisterMetaType<glm::vec3, vec3ToScriptValueFast, vec3FromScriptValueFast>(engine);
|
||||
#else
|
||||
scriptRegisterMetaType<glm::vec3, vec3ToScriptValue, vec3FromScriptValue>(engine);
|
||||
#endif
|
||||
scriptRegisterMetaType<glm::u8vec3, u8vec3ToScriptValue, u8vec3FromScriptValue>(engine);
|
||||
scriptRegisterMetaType<glm::vec4, vec4toScriptValue, vec4FromScriptValue>(engine);
|
||||
scriptRegisterMetaType<glm::quat, quatToScriptValue, quatFromScriptValue>(engine);
|
||||
|
@ -127,11 +118,7 @@ bool qVector2DFromScriptValue(const ScriptValue& object, QVector2D& qVector2D) {
|
|||
|
||||
ScriptValue qVector3DToScriptValue(ScriptEngine* engine, const QVector3D& qVector3D) {
|
||||
glm::vec3 vec3(qVector3D.x(), qVector3D.y(), qVector3D.z());
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
return vec3ToScriptValueFast(engine, vec3);
|
||||
#else
|
||||
return vec3ToScriptValue(engine, vec3);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool qVector3DFromScriptValue(const ScriptValue& object, QVector3D& qVector3D) {
|
||||
|
@ -191,6 +178,7 @@ bool vec2FromScriptValue(const ScriptValue& object, glm::vec2& vec2) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifndef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
|
||||
auto prototype = engine->globalObject().property("__hifi_vec3__");
|
||||
if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
|
||||
|
@ -215,6 +203,7 @@ ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
|
|||
value.setPrototype(prototype);
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
|
||||
auto prototype = engine->globalObject().property("__hifi_vec3_color__");
|
||||
|
@ -242,6 +231,7 @@ ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3)
|
|||
}
|
||||
|
||||
// V8TODO: add similar checks to rest of the conversions
|
||||
#ifndef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
|
||||
if (object.isNumber()) {
|
||||
vec3 = glm::vec3(object.toVariant().toFloat());
|
||||
|
@ -301,6 +291,7 @@ bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
ScriptValue u8vec3ToScriptValue(ScriptEngine* engine, const glm::u8vec3& vec3) {
|
||||
auto prototype = engine->globalObject().property("__hifi_u8vec3__");
|
||||
|
@ -470,11 +461,7 @@ ScriptValue qVectorVec3ColorToScriptValue(ScriptEngine* engine, const QVector<gl
|
|||
ScriptValue qVectorVec3ToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) {
|
||||
ScriptValue array = engine->newArray();
|
||||
for (int i = 0; i < vector.size(); i++) {
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
array.setProperty(i, vec3ToScriptValueFast(engine, vector.at(i)));
|
||||
#else
|
||||
array.setProperty(i, vec3ToScriptValue(engine, vector.at(i)));
|
||||
#endif
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
@ -794,17 +781,9 @@ bool qURLFromScriptValue(const ScriptValue& object, QUrl& url) {
|
|||
|
||||
ScriptValue pickRayToScriptValue(ScriptEngine* engine, const PickRay& pickRay) {
|
||||
ScriptValue obj = engine->newObject();
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
ScriptValue origin = vec3ToScriptValueFast(engine, pickRay.origin);
|
||||
#else
|
||||
ScriptValue origin = vec3ToScriptValue(engine, pickRay.origin);
|
||||
#endif
|
||||
obj.setProperty("origin", origin);
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
ScriptValue direction = vec3ToScriptValueFast(engine, pickRay.direction);
|
||||
#else
|
||||
ScriptValue direction = vec3ToScriptValue(engine, pickRay.direction);
|
||||
#endif
|
||||
obj.setProperty("direction", direction);
|
||||
return obj;
|
||||
}
|
||||
|
@ -850,15 +829,9 @@ ScriptValue collisionToScriptValue(ScriptEngine* engine, const Collision& collis
|
|||
obj.setProperty("type", collision.type);
|
||||
obj.setProperty("idA", quuidToScriptValue(engine, collision.idA));
|
||||
obj.setProperty("idB", quuidToScriptValue(engine, collision.idB));
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
obj.setProperty("penetration", vec3ToScriptValueFast(engine, collision.penetration));
|
||||
obj.setProperty("contactPoint", vec3ToScriptValueFast(engine, collision.contactPoint));
|
||||
obj.setProperty("velocityChange", vec3ToScriptValueFast(engine, collision.velocityChange));
|
||||
#else
|
||||
obj.setProperty("penetration", vec3ToScriptValue(engine, collision.penetration));
|
||||
obj.setProperty("contactPoint", vec3ToScriptValue(engine, collision.contactPoint));
|
||||
obj.setProperty("velocityChange", vec3ToScriptValue(engine, collision.velocityChange));
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
#include "V8Types.h"
|
||||
#include "ScriptValueV8Wrapper.h"
|
||||
|
||||
ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
|
||||
auto prototype = engine->globalObject().property("__hifi_vec3__");
|
||||
if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
|
||||
ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
|
||||
//auto prototype = engine->globalObject().property("__hifi_vec3__");
|
||||
/*if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
|
||||
prototype = engine->evaluate(
|
||||
"__hifi_vec3__ = Object.defineProperties({}, { "
|
||||
"defined: { value: true },"
|
||||
|
@ -33,7 +35,7 @@ ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
|
|||
"green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
|
||||
"blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }"
|
||||
"})");
|
||||
}
|
||||
}*/
|
||||
ScriptValue value = engine->newObject();
|
||||
|
||||
ScriptValueV8Wrapper *proxy = ScriptValueV8Wrapper::unwrap(value);
|
||||
|
@ -49,6 +51,51 @@ ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
|
|||
V8ScriptValue v8ScriptValue = proxy->toV8Value();
|
||||
v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(v8ScriptValue.get());
|
||||
|
||||
v8::Local<v8::Value> prototype;
|
||||
bool hasPrototype = false;
|
||||
|
||||
if (context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "__hifi_vec3__").ToLocalChecked()).ToLocal(&prototype)) {
|
||||
if (!prototype->IsNullOrUndefined() && prototype->IsObject()) {
|
||||
v8::Local<v8::Object> prototypeObject = v8::Local<v8::Object>::Cast(prototype);
|
||||
v8::Local<v8::Value> isDefined;
|
||||
if (prototypeObject->Get(context, v8::String::NewFromUtf8(isolate, "defined").ToLocalChecked()).ToLocal(&isDefined)) {
|
||||
if ((!isDefined->IsNullOrUndefined()) && isDefined->BooleanValue(isolate)) {
|
||||
hasPrototype = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasPrototype) {
|
||||
QString sourceCode("globalThis.__hifi_vec3__ = Object.defineProperties({}, { "
|
||||
"defined: { value: true },"
|
||||
"0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } },"
|
||||
"1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
|
||||
"2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } },"
|
||||
"r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } },"
|
||||
"g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
|
||||
"b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } },"
|
||||
"red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } },"
|
||||
"green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
|
||||
"blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }"
|
||||
"})");
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
v8::ScriptOrigin scriptOrigin(isolate, v8::String::NewFromUtf8(isolate, "Vec3prototype").ToLocalChecked());
|
||||
v8::Local<v8::Script> script;
|
||||
if (!v8::Script::Compile(context, v8::String::NewFromUtf8(isolate, sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
v8::Local<v8::Value> result;
|
||||
if (!script->Run(context).ToLocal(&result)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
if (!context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "__hifi_vec3__").ToLocalChecked()).ToLocal(&prototype)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
Q_ASSERT(!tryCatch.HasCaught());
|
||||
qDebug() <<"vec3ToScriptValue: creating prototype";
|
||||
}
|
||||
|
||||
if (!v8Object->Set(context, v8::String::NewFromUtf8(isolate, "x").ToLocalChecked(), v8::Number::New(isolate, vec3.x)).FromMaybe(false)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
@ -59,15 +106,15 @@ ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
|
|||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
auto v8Prototype = ScriptValueV8Wrapper::fullUnwrap(engineV8, prototype);
|
||||
if (!v8Object->SetPrototype(context, v8Prototype.get()).FromMaybe(false)) {
|
||||
//auto v8Prototype = ScriptValueV8Wrapper::fullUnwrap(engineV8, prototype);
|
||||
if (!v8Object->SetPrototype(context, prototype).FromMaybe(false)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
value.setPrototype(prototype);
|
||||
//value.setPrototype(prototype);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool vec3FromScriptValueFast(const ScriptValue& object, glm::vec3& vec3) {
|
||||
bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
|
||||
ScriptValueV8Wrapper *proxy = ScriptValueV8Wrapper::unwrap(object);
|
||||
|
||||
auto engineV8 = proxy->getV8Engine();
|
||||
|
@ -185,3 +232,5 @@ bool vec3FromScriptValueFast(const ScriptValue& object, glm::vec3& vec3) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,7 +9,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// Contains V8-specific implementations of th
|
||||
// Contains V8-specific implementations of the function converting Overte datatypes to and from script values.
|
||||
// These are used instead of generic implementations if CONVERSIONS_OPTIMIZED_FOR_V8 is defined.
|
||||
// V8-specific implementations can make script engine several times faster.
|
||||
|
||||
#ifndef overte_FastScriptValueUtils_h
|
||||
#define overte_FastScriptValueUtils_h
|
||||
|
@ -19,8 +21,12 @@
|
|||
|
||||
#include "../ScriptValue.h"
|
||||
|
||||
ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3);
|
||||
#define CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
|
||||
bool vec3FromScriptValueFast(const ScriptValue& object, glm::vec3& vec3);
|
||||
#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
|
||||
ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3);
|
||||
|
||||
bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3);
|
||||
#endif
|
||||
|
||||
#endif // overte_FastScriptValueUtils_h
|
||||
|
|
|
@ -937,13 +937,15 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
|||
v8::Isolate::Scope isolateScope(_v8Isolate);
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(getContext());
|
||||
v8::TryCatch tryCatch(getIsolate());
|
||||
v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked());
|
||||
v8::Local<v8::Script> script;
|
||||
if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
setUncaughtException(tryCatch, "Error while compiling script");
|
||||
_evaluatingCounter--;
|
||||
return nullValue();
|
||||
{
|
||||
v8::TryCatch tryCatch(getIsolate());
|
||||
if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
setUncaughtException(tryCatch, "Error while compiling script");
|
||||
_evaluatingCounter--;
|
||||
return nullValue();
|
||||
}
|
||||
}
|
||||
//qCDebug(scriptengine_v8) << "Script compilation succesful: " << fileName;
|
||||
|
||||
|
|
Loading…
Reference in a new issue