From 410848ed82b09226b8a24b16d30d670d3812581a Mon Sep 17 00:00:00 2001
From: ksuprynowicz <ksuprynowicz@post.pl>
Date: Wed, 29 Nov 2023 22:41:20 +0100
Subject: [PATCH 1/3] Remove excessive getContext calls

---
 .../src/v8/FastScriptValueUtils.cpp           |  4 +-
 .../script-engine/src/v8/ScriptEngineV8.cpp   | 85 +++++++++++--------
 .../src/v8/ScriptEngineV8_cast.cpp            |  4 +-
 .../src/v8/ScriptObjectV8Proxy.cpp            | 51 ++++++-----
 .../src/v8/ScriptValueV8Wrapper.cpp           | 75 +++++++++-------
 5 files changed, 126 insertions(+), 93 deletions(-)

diff --git a/libraries/script-engine/src/v8/FastScriptValueUtils.cpp b/libraries/script-engine/src/v8/FastScriptValueUtils.cpp
index 66c5fce2e4..4a6d872801 100644
--- a/libraries/script-engine/src/v8/FastScriptValueUtils.cpp
+++ b/libraries/script-engine/src/v8/FastScriptValueUtils.cpp
@@ -31,7 +31,7 @@ ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
     auto context = engineV8->getContext();
-    v8::Context::Scope contextScope(engineV8->getContext());
+    v8::Context::Scope contextScope(context);
     V8ScriptValue v8ScriptValue = proxy->toV8Value();
     v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(v8ScriptValue.get());
 
@@ -106,7 +106,7 @@ bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
     auto context = engineV8->getContext();
-    v8::Context::Scope contextScope(engineV8->getContext());
+    v8::Context::Scope contextScope(context);
     V8ScriptValue v8ScriptValue = proxy->toV8Value();
 
     v8::Local<v8::Value> v8Value = v8ScriptValue.get();
diff --git a/libraries/script-engine/src/v8/ScriptEngineV8.cpp b/libraries/script-engine/src/v8/ScriptEngineV8.cpp
index e4f6ad66f2..61dbdd00e0 100644
--- a/libraries/script-engine/src/v8/ScriptEngineV8.cpp
+++ b/libraries/script-engine/src/v8/ScriptEngineV8.cpp
@@ -307,7 +307,7 @@ void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
     v8::Local<v8::Context> context = getContext();
-    v8::Context::Scope contextScope(getContext());
+    v8::Context::Scope contextScope(context);
     QStringList pathToValue = valueName.split(".");
     int partsToGo = pathToValue.length();
     v8::Local<v8::Object> partObject = context->Global();
@@ -370,17 +370,17 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object,
     Q_ASSERT(_v8Isolate->IsCurrent());
     v8::Local<v8::Context> context = getContext();
     v8::Context::Scope contextScope(context);
-    v8::Local<v8::Object> v8GlobalObject = getContext()->Global();
+    v8::Local<v8::Object> v8GlobalObject = context->Global();
     v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
 
-    if (!v8GlobalObject->Get(getContext(), v8Name).IsEmpty()) {
+    if (!v8GlobalObject->Get(context, v8Name).IsEmpty()) {
         if (object) {
             V8ScriptValue value = ScriptObjectV8Proxy::newQObject(this, object, ScriptEngine::QtOwnership);
-            if(!v8GlobalObject->Set(getContext(), v8Name, value.get()).FromMaybe(false)) {
+            if(!v8GlobalObject->Set(context, v8Name, value.get()).FromMaybe(false)) {
                 Q_ASSERT(false);
             }
         } else {
-            if(!v8GlobalObject->Set(getContext(), v8Name, v8::Null(_v8Isolate)).FromMaybe(false)) {
+            if(!v8GlobalObject->Set(context, v8Name, v8::Null(_v8Isolate)).FromMaybe(false)) {
                 Q_ASSERT(false);
             }
         }
@@ -458,7 +458,8 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
         v8::Locker locker(_v8Isolate);
         v8::Isolate::Scope isolateScope(_v8Isolate);
         v8::HandleScope handleScope(_v8Isolate);
-        v8::Context::Scope contextScope(getContext());
+        auto context = getContext();
+        v8::Context::Scope contextScope(context);
 
         ScriptValue setterFunction = newFunction(setter, 1);
         ScriptValue getterFunction = newFunction(getter);
@@ -482,7 +483,7 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
                 } else {
                     v8ObjectToSetProperty = v8ParentObject;
                 }
-                    if (!v8ObjectToSetProperty->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
+                    if (!v8ObjectToSetProperty->DefineProperty(context, v8propertyName, propertyDescriptor).FromMaybe(false)) {
                     qCDebug(scriptengine_v8) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for parent: \""
                                           << parent << "\"";
                 }
@@ -493,7 +494,7 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
         } else {
             v8::Local<v8::String> v8propertyName =
                 v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
-            if (!getContext()->Global()->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
+            if (!context->Global()->DefineProperty(context, v8propertyName, propertyDescriptor).FromMaybe(false)) {
                 qCDebug(scriptengine_v8) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for global object";
             }
         }
@@ -557,7 +558,8 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
     ScriptProgramV8Wrapper* unwrappedProgram;
 
     {
-        v8::Context::Scope contextScope(getContext());
+        auto context = getContext();
+        v8::Context::Scope contextScope(context);
         unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
         if (unwrappedProgram == nullptr) {
             _evaluatingCounter--;
@@ -588,7 +590,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
         closureObject = v8::Local<v8::Object>::Cast(closure.constGet());
         qCDebug(scriptengine_v8) << "Closure object members:" << scriptValueDebugListMembersV8(closure);
         v8::Local<v8::Object> testObject = v8::Object::New(_v8Isolate);
-        if(!testObject->Set(getContext(), v8::String::NewFromUtf8(_v8Isolate, "test_value").ToLocalChecked(), closureObject).FromMaybe(false)) {
+        if(!testObject->Set(context, v8::String::NewFromUtf8(_v8Isolate, "test_value").ToLocalChecked(), closureObject).FromMaybe(false)) {
             Q_ASSERT(false);
         }
         qCDebug(scriptengine_v8) << "Test object members:" << scriptValueDebugListMembersV8(V8ScriptValue(this, testObject));
@@ -770,12 +772,13 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    auto context = getContext();
+    v8::Context::Scope contextScope(context);
     v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked());
     v8::Local<v8::Script> script;
     {
         v8::TryCatch tryCatch(getIsolate());
-        if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
+        if (!v8::Script::Compile(context, v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
             QString errorMessage(QString("Error while compiling script: \"") + fileName + QString("\" ") + formatErrorMessageFromTryCatch(tryCatch));
             if (_manager) {
                 _manager->scriptErrorMessage(errorMessage);
@@ -790,7 +793,7 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
 
     v8::Local<v8::Value> result;
     v8::TryCatch tryCatchRun(getIsolate());
-    if (!script->Run(getContext()).ToLocal(&result)) {
+    if (!script->Run(context).ToLocal(&result)) {
         Q_ASSERT(tryCatchRun.HasCaught());
         auto runError = tryCatchRun.Message();
         ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, runError->Get())));
@@ -829,7 +832,8 @@ void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QS
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    v8::Local<v8::Context> context = getContext();
+    v8::Context::Scope contextScope(context);
     QString result("");
 
     QString errorMessage = "";
@@ -844,10 +848,10 @@ void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QS
 
     v8::Local<v8::Message> exceptionMessage = tryCatch.Message();
     if (!exceptionMessage.IsEmpty()) {
-        ex->errorLine = exceptionMessage->GetLineNumber(getContext()).FromJust();
-        ex->errorColumn = exceptionMessage->GetStartColumn(getContext()).FromJust();
+        ex->errorLine = exceptionMessage->GetLineNumber(context).FromJust();
+        ex->errorColumn = exceptionMessage->GetStartColumn(context).FromJust();
         v8::Local<v8::Value> backtraceV8String;
-        if (tryCatch.StackTrace(getContext()).ToLocal(&backtraceV8String)) {
+        if (tryCatch.StackTrace(context).ToLocal(&backtraceV8String)) {
             if (backtraceV8String->IsString()) {
                 if (v8::Local<v8::String>::Cast(backtraceV8String)->Length() > 0) {
                     v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String);
@@ -875,7 +879,8 @@ QString ScriptEngineV8::formatErrorMessageFromTryCatch(v8::TryCatch &tryCatch) {
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    auto context = getContext();
+    v8::Context::Scope contextScope(context);
     QString result("");
     int errorColumnNumber = 0;
     int errorLineNumber = 0;
@@ -885,10 +890,10 @@ QString ScriptEngineV8::formatErrorMessageFromTryCatch(v8::TryCatch &tryCatch) {
     errorMessage = QString(*utf8Value);
     v8::Local<v8::Message> exceptionMessage = tryCatch.Message();
     if (!exceptionMessage.IsEmpty()) {
-        errorLineNumber = exceptionMessage->GetLineNumber(getContext()).FromJust();
-        errorColumnNumber = exceptionMessage->GetStartColumn(getContext()).FromJust();
+        errorLineNumber = exceptionMessage->GetLineNumber(context).FromJust();
+        errorColumnNumber = exceptionMessage->GetStartColumn(context).FromJust();
         v8::Local<v8::Value> backtraceV8String;
-        if (tryCatch.StackTrace(getContext()).ToLocal(&backtraceV8String)) {
+        if (tryCatch.StackTrace(context).ToLocal(&backtraceV8String)) {
             if (backtraceV8String->IsString()) {
                 if (v8::Local<v8::String>::Cast(backtraceV8String)->Length() > 0) {
                     v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String);
@@ -1000,7 +1005,8 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
         v8::Locker locker(_v8Isolate);
         v8::Isolate::Scope isolateScope(_v8Isolate);
         v8::HandleScope handleScope(_v8Isolate);
-        v8::Context::Scope contextScope(getContext());
+        auto context = getContext();
+        v8::Context::Scope contextScope(context);
         ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
         if (!unwrapped) {
             setUncaughtEngineException("Could not unwrap program", "Compile error");
@@ -1020,7 +1026,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
             const V8ScriptProgram& v8Program = unwrapped->toV8Value();
 
             v8::TryCatch tryCatchRun(getIsolate());
-            if (!v8Program.constGet()->Run(getContext()).ToLocal(&result)) {
+            if (!v8Program.constGet()->Run(context).ToLocal(&result)) {
                 Q_ASSERT(tryCatchRun.HasCaught());
                 auto runError = tryCatchRun.Message();
                 errorValue = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, runError->Get())));
@@ -1252,7 +1258,8 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    auto context = getContext();
+    v8::Context::Scope contextScope(context);
 
     auto v8FunctionCallback = [](const v8::FunctionCallbackInfo<v8::Value>& info) {
         //V8TODO: is using GetCurrentContext ok, or context wrapper needs to be added?
@@ -1276,10 +1283,10 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
         }
     };
     auto functionDataTemplate = getFunctionDataTemplate();
-    auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked();
+    auto functionData = functionDataTemplate->NewInstance(context).ToLocalChecked();
     functionData->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(fun));
     functionData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
-    auto v8Function = v8::Function::New(getContext(), v8FunctionCallback, functionData, length).ToLocalChecked();
+    auto v8Function = v8::Function::New(context, v8FunctionCallback, functionData, length).ToLocalChecked();
     V8ScriptValue result(this, v8Function);
     return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));
 }
@@ -1293,11 +1300,12 @@ bool ScriptEngineV8::setProperty(const char* name, const QVariant& value) {
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
-    v8::Local<v8::Object> global = getContext()->Global();
+    v8::Local<v8::Context> context = getContext();
+    v8::Context::Scope contextScope(context);
+    v8::Local<v8::Object> global = context->Global();
     auto v8Name = v8::String::NewFromUtf8(getIsolate(), name).ToLocalChecked();
     V8ScriptValue v8Value = castVariantToValue(value);
-    return global->Set(getContext(), v8Name, v8Value.get()).FromMaybe(false);
+    return global->Set(context, v8Name, v8Value.get()).FromMaybe(false);
 }
 
 void ScriptEngineV8::setProcessEventsInterval(int interval) {
@@ -1411,10 +1419,11 @@ void ScriptEngineV8::compileTest() {
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    auto context = getContext();
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Script> script;
     v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(),"test").ToLocalChecked());
-    if (v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), "print(\"hello world\");").ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
+    if (v8::Script::Compile(context, v8::String::NewFromUtf8(getIsolate(), "print(\"hello world\");").ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
         qCDebug(scriptengine_v8) << "Compile test successful";
     } else {
         qCDebug(scriptengine_v8) << "Compile test failed";
@@ -1436,14 +1445,15 @@ QString ScriptEngineV8::scriptValueDebugListMembersV8(const V8ScriptValue &v8Val
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    v8::Local<v8::Context> context = getContext();
+    v8::Context::Scope contextScope(context);
 
     QString membersString("");
     if (v8Value.constGet()->IsObject()) {
         v8::Local<v8::String> membersStringV8;
         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value.constGet());
-        auto names = object->GetPropertyNames(getContext()).ToLocalChecked();
-        if (v8::JSON::Stringify(getContext(), names).ToLocal(&membersStringV8)) {
+        auto names = object->GetPropertyNames(context).ToLocalChecked();
+        if (v8::JSON::Stringify(context, names).ToLocal(&membersStringV8)) {
             membersString = QString(*v8::String::Utf8Value(_v8Isolate, membersStringV8));
         }
         membersString = QString(*v8::String::Utf8Value(_v8Isolate, membersStringV8));
@@ -1457,16 +1467,17 @@ QString ScriptEngineV8::scriptValueDebugDetailsV8(const V8ScriptValue &v8Value)
     v8::Locker locker(_v8Isolate);
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
-    v8::Context::Scope contextScope(getContext());
+    v8::Local<v8::Context> context = getContext();
+    v8::Context::Scope contextScope(context);
 
     QString parentValueQString("");
     v8::Local<v8::String> parentValueString;
-    if (v8Value.constGet()->ToDetailString(getContext()).ToLocal(&parentValueString)) {
+    if (v8Value.constGet()->ToDetailString(context).ToLocal(&parentValueString)) {
         parentValueQString = QString(*v8::String::Utf8Value(_v8Isolate, parentValueString));
     }
     QString JSONQString;
     v8::Local<v8::String> JSONString;
-    if (v8::JSON::Stringify(getContext(), v8Value.constGet()).ToLocal(&JSONString)) {
+    if (v8::JSON::Stringify(context, v8Value.constGet()).ToLocal(&JSONString)) {
         JSONQString = QString(*v8::String::Utf8Value(_v8Isolate, JSONString));
     }
     return parentValueQString + QString(" JSON: ") + JSONQString;
diff --git a/libraries/script-engine/src/v8/ScriptEngineV8_cast.cpp b/libraries/script-engine/src/v8/ScriptEngineV8_cast.cpp
index 8dead23ddb..211da7582f 100644
--- a/libraries/script-engine/src/v8/ScriptEngineV8_cast.cpp
+++ b/libraries/script-engine/src/v8/ScriptEngineV8_cast.cpp
@@ -725,12 +725,12 @@ V8ScriptValue ScriptEngineV8::castVariantToValue(const QVariant& val) {
         case QMetaType::QDateTime:
             {
                 double timeMs = val.value<QDateTime>().currentMSecsSinceEpoch();
-                return V8ScriptValue(this, v8::Date::New(getContext(), timeMs).ToLocalChecked());
+                return V8ScriptValue(this, v8::Date::New(context, timeMs).ToLocalChecked());
             }
         case QMetaType::QDate:
             {
                 double timeMs = val.value<QDate>().startOfDay().currentMSecsSinceEpoch();
-                return V8ScriptValue(this, v8::Date::New(getContext(), timeMs).ToLocalChecked());
+                return V8ScriptValue(this, v8::Date::New(context, timeMs).ToLocalChecked());
             }
         default:
             // check to see if this is a pointer to a QObject-derived object
diff --git a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp
index 177eeb259f..09e7cb59bb 100644
--- a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp
+++ b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp
@@ -231,7 +231,8 @@ void ScriptObjectV8Proxy::investigate() {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(_engine->getIsolate());
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
 
     const QMetaObject* metaObject = qobject->metaObject();
 
@@ -348,7 +349,7 @@ void ScriptObjectV8Proxy::investigate() {
         }
     }
 
-    v8::Local<v8::Object> v8Object = objectTemplate->NewInstance(_engine->getContext()).ToLocalChecked();
+    v8::Local<v8::Object> v8Object = objectTemplate->NewInstance(context).ToLocalChecked();
 
     v8Object->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToQObjectProxy));
     v8Object->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
@@ -366,7 +367,7 @@ void ScriptObjectV8Proxy::investigate() {
     for (auto i = _methods.begin(); i != _methods.end(); i++) {
         V8ScriptValue method = ScriptMethodV8Proxy::newMethod(_engine, qobject, V8ScriptValue(_engine, v8Object),
                                                               i.value().methods, i.value().numMaxParams);
-        if(!propertiesObject->Set(_engine->getContext(), v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked(), method.get()).FromMaybe(false)) {
+        if(!propertiesObject->Set(context, v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked(), method.get()).FromMaybe(false)) {
             Q_ASSERT(false);
         }
     }
@@ -555,7 +556,7 @@ v8::Local<v8::Array> ScriptObjectV8Proxy::getPropertyNames() {
     v8::Isolate::Scope isolateScope(isolate);
     v8::EscapableHandleScope handleScope(_engine->getIsolate());
     auto context = _engine->getContext();
-    v8::Context::Scope contextScope(_engine->getContext());
+    v8::Context::Scope contextScope(context);
 
     //V8TODO: this is really slow. It could be cached if this is called often.
     v8::Local<v8::Array> properties = v8::Array::New(isolate, _props.size() + _methods.size() + _signals.size());
@@ -587,7 +588,8 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     QObject* qobject = _object;
     if (!qobject) {
         _engine->getIsolate()->ThrowError("Referencing deleted native object");
@@ -621,7 +623,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V
                 }
             } //V8TODO: is new method created during every call? It needs to be cached instead
             v8::Local<v8::Value> property;
-            if(_v8Object.Get(isolate)->GetInternalField(2).As<v8::Object>()->Get(_engine->getContext(), name.constGet()).ToLocal(&property)) {
+            if(_v8Object.Get(isolate)->GetInternalField(2).As<v8::Object>()->Get(context, name.constGet()).ToLocal(&property)) {
                 if (!property->IsUndefined()) {
                     return V8ScriptValue(_engine, property);
                 }
@@ -698,9 +700,10 @@ ScriptVariantV8Proxy::ScriptVariantV8Proxy(ScriptEngineV8* engine, const QVarian
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(engine->getContext());
+    auto context = engine->getContext();
+    v8::Context::Scope contextScope(context);
     auto variantDataTemplate = _engine->getVariantDataTemplate();
-    auto variantData = variantDataTemplate->NewInstance(engine->getContext()).ToLocalChecked();
+    auto variantData = variantDataTemplate->NewInstance(context).ToLocalChecked();
     variantData->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToQVariantInProxy));
     // Internal field doesn't point directly to QVariant, because then alignment would need to be guaranteed in all compilers
     variantData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
@@ -723,7 +726,8 @@ V8ScriptValue ScriptVariantV8Proxy::newVariant(ScriptEngineV8* engine, const QVa
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(engine->getContext());
+    auto context = engine->getContext();
+    v8::Context::Scope contextScope(context);
     ScriptObjectV8Proxy* protoProxy = ScriptObjectV8Proxy::unwrapProxy(proto);
     if (!protoProxy) {
         Q_ASSERT(protoProxy);
@@ -734,7 +738,7 @@ V8ScriptValue ScriptVariantV8Proxy::newVariant(ScriptEngineV8* engine, const QVa
     auto proxy = new ScriptVariantV8Proxy(engine, variant, proto, protoProxy);
 
     auto variantProxyTemplate = engine->getVariantProxyTemplate();
-    auto variantProxy = variantProxyTemplate->NewInstance(engine->getContext()).ToLocalChecked();
+    auto variantProxy = variantProxyTemplate->NewInstance(context).ToLocalChecked();
     variantProxy->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToQVariantProxy));
     variantProxy->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(proxy));
     return V8ScriptValue(engine, variantProxy);
@@ -912,12 +916,13 @@ V8ScriptValue ScriptMethodV8Proxy::newMethod(ScriptEngineV8* engine, QObject* ob
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(engine->getContext());
+    auto context = engine->getContext();
+    v8::Context::Scope contextScope(context);
     auto methodDataTemplate = engine->getMethodDataTemplate();
-    auto methodData = methodDataTemplate->NewInstance(engine->getContext()).ToLocalChecked();
+    auto methodData = methodDataTemplate->NewInstance(context).ToLocalChecked();
     methodData->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToMethodProxy));
     methodData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(new ScriptMethodV8Proxy(engine, object, lifetime, metas, numMaxParams)));
-    auto v8Function = v8::Function::New(engine->getContext(), callback, methodData, numMaxParams).ToLocalChecked();
+    auto v8Function = v8::Function::New(context, callback, methodData, numMaxParams).ToLocalChecked();
     return V8ScriptValue(engine, v8Function);
 }
 
@@ -964,7 +969,8 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
     ContextScopeV8 contextScopeV8(_engine);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     QObject* qobject = _object;
     if (!qobject) {
         isolate->ThrowError("Referencing deleted native object");
@@ -1057,7 +1063,7 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
 
     if (isValidMetaSelected) {
         // V8TODO: is this the correct wrapper?
-        ScriptContextV8Wrapper ourContext(_engine, &arguments, _engine->getContext(),
+        ScriptContextV8Wrapper ourContext(_engine, &arguments, context,
                                           _engine->currentContext()->parentContext());
         ScriptContextGuard guard(&ourContext);
         const QMetaMethod& meta = _metas[bestMeta];
@@ -1153,10 +1159,11 @@ ScriptSignalV8Proxy::ScriptSignalV8Proxy(ScriptEngineV8* engine, QObject* object
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     _objectLifetime.Reset(isolate, lifetime.get());
     _objectLifetime.SetWeak(this, weakHandleCallback, v8::WeakCallbackType::kParameter);
-    _v8Context.Reset(isolate, _engine->getContext());
+    _v8Context.Reset(isolate, context);
     _engine->_signalProxySetLock.lockForWrite();
     _engine->_signalProxySet.insert(this);
     _engine->_signalProxySetLock.unlock();
@@ -1313,7 +1320,8 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     QObject* qobject = _object;
     if (!qobject) {
         isolate->ThrowError("Referencing deleted native object");
@@ -1362,7 +1370,7 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) {
     v8::Local<v8::Value> destData;
     // V8TODO: I'm not sure which context to use here
     //auto destFunctionContext = destFunction->CreationContext();
-    auto destFunctionContext = _engine->getContext();
+    auto destFunctionContext = context;
     Q_ASSERT(thisObject().isObject());
     V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject());
     Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8ThisObject));
@@ -1435,7 +1443,8 @@ void ScriptSignalV8Proxy::disconnect(ScriptValue arg0, ScriptValue arg1) {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
 
     // untangle the arguments
     V8ScriptValue callback(_engine, v8::Null(isolate));
@@ -1481,7 +1490,7 @@ void ScriptSignalV8Proxy::disconnect(ScriptValue arg0, ScriptValue arg1) {
     v8::Local<v8::Value> destData;
 
     //auto destFunctionContext = destFunction->CreationContext();
-    auto destFunctionContext = _engine->getContext();
+    auto destFunctionContext = context;
     Q_ASSERT(thisObject().isObject());
     V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject());
     Q_ASSERT(ScriptObjectV8Proxy::unwrapProxy(v8ThisObject));
diff --git a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp
index fc329c9e19..40bfde0807 100644
--- a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp
+++ b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp
@@ -95,11 +95,11 @@ ScriptValue ScriptValueV8Wrapper::call(const ScriptValue& thisObject, const Scri
     if (v8This.get()->IsObject()) {
         recv = v8This.get();
     }else{
-        recv = _engine->getContext()->Global();
+        recv = context->Global();
     }
 
     lock.lockForRead();
-    auto maybeResult = v8Function->Call(_engine->getContext(), recv, args.length(), v8Args);
+    auto maybeResult = v8Function->Call(context, recv, args.length(), v8Args);
     lock.unlock();
     if (tryCatch.HasCaught()) {
         QString errorMessage(QString("Function call failed: \"") + _engine->formatErrorMessageFromTryCatch(tryCatch));
@@ -156,7 +156,8 @@ ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     Q_ASSERT(args.length() <= Q_METAMETHOD_INVOKE_MAX_ARGS);
     v8::Local<v8::Value> v8Args[Q_METAMETHOD_INVOKE_MAX_ARGS];
     int argIndex = 0;
@@ -174,7 +175,7 @@ ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) {
     // V8TODO: I'm not sure if this is correct, maybe use CallAsConstructor instead?
     // Maybe it's CallAsConstructor for function and NewInstance for class?
     lock.lockForRead();
-    auto maybeResult = v8Function->NewInstance(_engine->getContext(), args.length(), v8Args);
+    auto maybeResult = v8Function->NewInstance(context, args.length(), v8Args);
     lock.unlock();
     v8::Local<v8::Object> result;
     if (maybeResult.ToLocal(&result)) {
@@ -207,13 +208,14 @@ ScriptValue ScriptValueV8Wrapper::data() const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     // Private properties are an experimental feature for now on V8, so we are using regular value for now
     if (_value.constGet()->IsObject()) {
         auto v8Object = v8::Local<v8::Object>::Cast(_value.constGet());
          v8::Local<v8::Value> data;
          //bool createData = false;
-         if (!v8Object->Get(_engine->getContext(), v8::String::NewFromUtf8(isolate, "__data").ToLocalChecked()).ToLocal(&data)) {
+         if (!v8Object->Get(context, v8::String::NewFromUtf8(isolate, "__data").ToLocalChecked()).ToLocal(&data)) {
              data = v8::Undefined(isolate);
              Q_ASSERT(false);
              //createData = true;
@@ -268,7 +270,8 @@ bool ScriptValueV8Wrapper::hasProperty(const QString& name) const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     //V8TODO: does function return true on IsObject too?
     if (_value.constGet()->IsObject()) {
     //V8TODO: what about flags?
@@ -276,7 +279,7 @@ bool ScriptValueV8Wrapper::hasProperty(const QString& name) const {
         v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, name.toStdString().c_str(),v8::NewStringType::kNormal).ToLocalChecked();
         const v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(_value.constGet());
         //V8TODO: Which context?
-        if (object->Get(_engine->getContext(), key).ToLocal(&resultLocal)) {
+        if (object->Get(context, key).ToLocal(&resultLocal)) {
             return true;
         } else {
             return false;
@@ -292,7 +295,8 @@ ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValu
     v8::Locker locker(_engine->getIsolate());
     v8::Isolate::Scope isolateScope(_engine->getIsolate());
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     if (_value.constGet()->IsNullOrUndefined()) {
         return _engine->undefinedValue();
     }
@@ -303,14 +307,14 @@ ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValu
         const v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(_value.constGet());
         //V8TODO: Which context?
         lock.lockForRead();
-        if (object->Get(_engine->getContext(), key).ToLocal(&resultLocal)) {
+        if (object->Get(context, key).ToLocal(&resultLocal)) {
             V8ScriptValue result(_engine, resultLocal);
             lock.unlock();
             return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
         } else {
             QString parentValueQString("");
             v8::Local<v8::String> parentValueString;
-            if (_value.constGet()->ToDetailString(_engine->getContext()).ToLocal(&parentValueString)) {
+            if (_value.constGet()->ToDetailString(context).ToLocal(&parentValueString)) {
                 QString(*v8::String::Utf8Value(isolate, parentValueString));
             }
             qCDebug(scriptengine_v8) << "Failed to get property, parent of value: " << name << ", parent type: " << QString(*v8::String::Utf8Value(isolate, _value.constGet()->TypeOf(isolate))) << " parent value: " << parentValueQString;
@@ -371,7 +375,8 @@ void ScriptValueV8Wrapper::setData(const ScriptValue& value) {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     V8ScriptValue unwrapped = fullUnwrap(value);
     // Private properties are an experimental feature for now on V8, so we are using regular value for now
     if (_value.constGet()->IsNullOrUndefined()) {
@@ -380,7 +385,7 @@ void ScriptValueV8Wrapper::setData(const ScriptValue& value) {
     }
     if (_value.constGet()->IsObject()) {
         auto v8Object = v8::Local<v8::Object>::Cast(_value.constGet());
-        if( !v8Object->Set(_engine->getContext(), v8::String::NewFromUtf8(isolate, "__data").ToLocalChecked(), unwrapped.constGet()).FromMaybe(false)) {
+        if( !v8Object->Set(context, v8::String::NewFromUtf8(isolate, "__data").ToLocalChecked(), unwrapped.constGet()).FromMaybe(false)) {
             qCDebug(scriptengine_v8) << "ScriptValueV8Wrapper::data(): Data object couldn't be created";
             Q_ASSERT(false);
         }
@@ -396,7 +401,8 @@ void ScriptValueV8Wrapper::setProperty(const QString& name, const ScriptValue& v
     v8::Locker locker(_engine->getIsolate());
     v8::Isolate::Scope isolateScope(_engine->getIsolate());
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     V8ScriptValue unwrapped = fullUnwrap(value);
     if (_value.constGet()->IsNullOrUndefined()) {
         qCDebug(scriptengine_v8) << "ScriptValueV8Wrapper::setProperty() was called on a value that is null or undefined";
@@ -415,7 +421,7 @@ void ScriptValueV8Wrapper::setProperty(const QString& name, const ScriptValue& v
     } else {
         v8::Local<v8::String> details;
         QString detailsString("");
-        if(_value.get()->ToDetailString(_engine->getContext()).ToLocal(&details)) {
+        if(_value.get()->ToDetailString(context).ToLocal(&details)) {
             v8::String::Utf8Value utf8Value(isolate,details);
             detailsString = *utf8Value;
         }
@@ -431,7 +437,8 @@ void ScriptValueV8Wrapper::setProperty(quint32 arrayIndex, const ScriptValue& va
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     V8ScriptValue unwrapped = fullUnwrap(value);
     if (_value.constGet()->IsNullOrUndefined()) {
         qCDebug(scriptengine_v8) << "ScriptValueV8Wrapper::setProperty() was called on a value that is null or undefined";
@@ -441,7 +448,7 @@ void ScriptValueV8Wrapper::setProperty(quint32 arrayIndex, const ScriptValue& va
         auto object = v8::Local<v8::Object>::Cast(_value.get());
         //V8TODO: I don't know which context to use here
         lock.lockForRead();
-        v8::Maybe<bool> retVal(object->Set(_engine->getContext(), arrayIndex, unwrapped.constGet()));
+        v8::Maybe<bool> retVal(object->Set(context, arrayIndex, unwrapped.constGet()));
         lock.unlock();
         if (retVal.IsJust() ? !retVal.FromJust() : true){
             qCDebug(scriptengine_v8) << "Failed to set property";
@@ -531,9 +538,10 @@ qint32 ScriptValueV8Wrapper::toInt32() const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Integer> integer;
-    if (!_value.constGet()->ToInteger(_engine->getContext()).ToLocal(&integer)) {
+    if (!_value.constGet()->ToInteger(context).ToLocal(&integer)) {
         Q_ASSERT(false);
     }
     return static_cast<int32_t>((integer)->Value());
@@ -544,9 +552,10 @@ double ScriptValueV8Wrapper::toInteger() const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Integer> integer;
-    if (!_value.constGet()->ToInteger(_engine->getContext()).ToLocal(&integer)) {
+    if (!_value.constGet()->ToInteger(context).ToLocal(&integer)) {
         Q_ASSERT(false);
     }
     return (integer)->Value();
@@ -557,9 +566,10 @@ double ScriptValueV8Wrapper::toNumber() const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Number> number;
-    if (!_value.constGet()->ToNumber(_engine->getContext()).ToLocal(&number)) {
+    if (!_value.constGet()->ToNumber(context).ToLocal(&number)) {
         Q_ASSERT(false);
     }
     return number->Value();
@@ -581,9 +591,10 @@ quint16 ScriptValueV8Wrapper::toUInt16() const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Uint32> integer;
-    if (!_value.constGet()->ToUint32(_engine->getContext()).ToLocal(&integer)) {
+    if (!_value.constGet()->ToUint32(context).ToLocal(&integer)) {
         Q_ASSERT(false);
     }
     return static_cast<uint16_t>(integer->Value());
@@ -594,9 +605,10 @@ quint32 ScriptValueV8Wrapper::toUInt32() const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Uint32> integer;
-    if (!_value.constGet()->ToUint32(_engine->getContext()).ToLocal(&integer)) {
+    if (!_value.constGet()->ToUint32(context).ToLocal(&integer)) {
         Q_ASSERT(false);
     }
     return integer->Value();
@@ -632,16 +644,17 @@ bool ScriptValueV8Wrapper::equals(const ScriptValue& other) const {
     v8::Locker locker(isolate);
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
-    v8::Context::Scope contextScope(_engine->getContext());
+    auto context = _engine->getContext();
+    v8::Context::Scope contextScope(context);
     ScriptValueV8Wrapper* unwrappedOther = unwrap(other);
     Q_ASSERT(_engine->getIsolate() == unwrappedOther->_engine->getIsolate());
     if (!unwrappedOther) {
         return false;
     }else{
-        if (_value.constGet()->Equals(_engine->getContext(), unwrappedOther->toV8Value().constGet()).IsNothing()) {
+        if (_value.constGet()->Equals(context, unwrappedOther->toV8Value().constGet()).IsNothing()) {
             return false;
         } else {
-            return _value.constGet()->Equals(_engine->getContext(), unwrappedOther->toV8Value().constGet()).FromJust();
+            return _value.constGet()->Equals(context, unwrappedOther->toV8Value().constGet()).FromJust();
         }
     }
 }
@@ -670,7 +683,7 @@ bool ScriptValueV8Wrapper::isError() const {
     v8::Isolate::Scope isolateScope(isolate);
     v8::HandleScope handleScope(isolate);
     auto context = _engine->getContext();
-    v8::Context::Scope contextScope(_engine->getContext());
+    v8::Context::Scope contextScope(context);
     v8::Local<v8::Value> error;
     if (!context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "Error").ToLocalChecked()).ToLocal(&error)) {
         Q_ASSERT(false);

From 5aeca97f83ff5e04a01199d1eaf176092d4454ee Mon Sep 17 00:00:00 2001
From: ksuprynowicz <ksuprynowicz@post.pl>
Date: Thu, 30 Nov 2023 00:26:01 +0100
Subject: [PATCH 2/3] Cache Controller.Standard in scripts for higher
 performance

---
 .../resources/modules/pickRayController.js    | 21 +++++----
 scripts/system/away.js                        | 30 ++++++------
 .../controllers/controllerDispatcher.js       | 46 ++++++++++---------
 .../controllerModules/equipEntity.js          |  3 +-
 .../controllerModules/farActionGrabEntity.js  |  4 +-
 .../controllerModules/farGrabEntity.js        |  6 ++-
 .../controllerModules/hudOverlayPointer.js    |  5 +-
 .../controllerModules/inEditMode.js           |  5 +-
 .../controllers/controllerModules/teleport.js | 14 +++---
 .../controllerModules/trackedHandTablet.js    | 10 ++--
 .../controllerModules/trackedHandWalk.js      | 14 +++---
 scripts/system/controllers/handTouch.js       | 17 +++----
 scripts/system/controllers/squeezeHands.js    | 18 ++++----
 ...oggleAdvancedMovementForHandControllers.js |  6 ++-
 .../touchControllerConfiguration.js           |  4 +-
 .../viveControllerConfiguration.js            |  6 ++-
 scripts/system/create/editModes/editVoxels.js | 33 ++++++-------
 .../entitySelectionTool.js                    | 30 ++++++------
 scripts/system/emote.js                       | 33 ++++++-------
 scripts/system/fingerPaint.js                 | 12 +++--
 scripts/system/libraries/Trigger.js           |  5 +-
 scripts/system/libraries/WebTablet.js         |  3 +-
 .../libraries/controllerDispatcherUtils.js    |  6 ++-
 scripts/system/libraries/controllers.js       |  6 ++-
 scripts/system/makeUserConnection.js          | 20 ++++----
 scripts/system/miniTablet.js                  | 12 +++--
 scripts/system/mod.js                         |  6 ++-
 scripts/system/notifications.js               |  6 ++-
 scripts/system/pal.js                         |  9 ++--
 scripts/system/tablet-ui/tabletUI.js          | 18 ++++----
 30 files changed, 230 insertions(+), 178 deletions(-)

diff --git a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/pickRayController.js b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/pickRayController.js
index 87d05fa838..fa9479b426 100644
--- a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/pickRayController.js
+++ b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/pickRayController.js
@@ -12,6 +12,9 @@
 
 
 var _this;
+
+var controllerStandard = Controller.Standard;
+
 function PickRayController(){
     _this = this;
 
@@ -36,9 +39,9 @@ function PickRayController(){
 
 // Returns the right UUID based on hand triggered
 function getUUIDFromLaser(hand) {
-    hand = hand === Controller.Standard.LeftHand
-        ? Controller.Standard.LeftHand
-        : Controller.Standard.RightHand;
+    hand = hand === controllerStandard.LeftHand
+        ? controllerStandard.LeftHand
+        : controllerStandard.RightHand;
 
     var pose = getControllerWorldLocation(hand);
     var start = pose.position;
@@ -61,7 +64,7 @@ function getGrabPointSphereOffset(handController) {
     // x = upward, y = forward, z = lateral
     var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 };
     var offset = GRAB_POINT_SPHERE_OFFSET;
-    if (handController === Controller.Standard.LeftHand) {
+    if (handController === controllerStandard.LeftHand) {
         offset = {
             x: -GRAB_POINT_SPHERE_OFFSET.x,
             y: GRAB_POINT_SPHERE_OFFSET.y,
@@ -84,7 +87,7 @@ function getControllerWorldLocation(handController, doOffset) {
         valid = pose.valid;
         var controllerJointIndex;
         if (pose.valid) {
-            if (handController === Controller.Standard.RightHand) {
+            if (handController === controllerStandard.RightHand) {
                 controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND");
             } else {
                 controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
@@ -192,21 +195,21 @@ function doublePressHandler(event) {
 function create(){
     _this.mapping = Controller.newMapping(_this.mappingName);
 
-    _this.mapping.from(Controller.Standard.LTClick).to(function (value) {
+    _this.mapping.from(controllerStandard.LTClick).to(function (value) {
         if (value === 0) {
             return;
         }
 
-        getUUIDFromLaser(Controller.Standard.LeftHand);
+        getUUIDFromLaser(controllerStandard.LeftHand);
     });
 
 
-    _this.mapping.from(Controller.Standard.RTClick).to(function (value) {
+    _this.mapping.from(controllerStandard.RTClick).to(function (value) {
         if (value === 0) {
             return;
         }
 
-        getUUIDFromLaser(Controller.Standard.RightHand);
+        getUUIDFromLaser(controllerStandard.RightHand);
     });
 
     return _this;
diff --git a/scripts/system/away.js b/scripts/system/away.js
index 87273b2727..3f41020c9e 100644
--- a/scripts/system/away.js
+++ b/scripts/system/away.js
@@ -17,6 +17,8 @@
 
 (function() { // BEGIN LOCAL_SCOPE
 
+var controllerStandard = Controller.Standard;
+
 var BASIC_TIMER_INTERVAL = 50; // 50ms = 20hz
 var OVERLAY_WIDTH = 1920;
 var OVERLAY_HEIGHT = 1080;
@@ -344,20 +346,20 @@ var maybeIntervalTimer = Script.setInterval(function() {
 
 Controller.mousePressEvent.connect(goActive);
 // Note peek() so as to not interfere with other mappings.
-eventMapping.from(Controller.Standard.LeftPrimaryThumb).peek().to(goActive);
-eventMapping.from(Controller.Standard.RightPrimaryThumb).peek().to(goActive);
-eventMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(goActive);
-eventMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(goActive);
-eventMapping.from(Controller.Standard.LT).peek().to(goActive);
-eventMapping.from(Controller.Standard.LB).peek().to(goActive);
-eventMapping.from(Controller.Standard.LS).peek().to(goActive);
-eventMapping.from(Controller.Standard.LeftGrip).peek().to(goActive);
-eventMapping.from(Controller.Standard.RT).peek().to(goActive);
-eventMapping.from(Controller.Standard.RB).peek().to(goActive);
-eventMapping.from(Controller.Standard.RS).peek().to(goActive);
-eventMapping.from(Controller.Standard.RightGrip).peek().to(goActive);
-eventMapping.from(Controller.Standard.Back).peek().to(goActive);
-eventMapping.from(Controller.Standard.Start).peek().to(goActive);
+eventMapping.from(controllerStandard.LeftPrimaryThumb).peek().to(goActive);
+eventMapping.from(controllerStandard.RightPrimaryThumb).peek().to(goActive);
+eventMapping.from(controllerStandard.LeftSecondaryThumb).peek().to(goActive);
+eventMapping.from(controllerStandard.RightSecondaryThumb).peek().to(goActive);
+eventMapping.from(controllerStandard.LT).peek().to(goActive);
+eventMapping.from(controllerStandard.LB).peek().to(goActive);
+eventMapping.from(controllerStandard.LS).peek().to(goActive);
+eventMapping.from(controllerStandard.LeftGrip).peek().to(goActive);
+eventMapping.from(controllerStandard.RT).peek().to(goActive);
+eventMapping.from(controllerStandard.RB).peek().to(goActive);
+eventMapping.from(controllerStandard.RS).peek().to(goActive);
+eventMapping.from(controllerStandard.RightGrip).peek().to(goActive);
+eventMapping.from(controllerStandard.Back).peek().to(goActive);
+eventMapping.from(controllerStandard.Start).peek().to(goActive);
 Controller.enableMapping(eventMappingName);
 
 function awayStateWhenFocusLostInVRChanged(enabled) {
diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js
index 16390a73bf..beee66221e 100644
--- a/scripts/system/controllers/controllerDispatcher.js
+++ b/scripts/system/controllers/controllerDispatcher.js
@@ -31,6 +31,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
 (function() {
     Script.include("/~/system/libraries/pointersUtils.js");
 
+    var controllerStandard = Controller.Standard;
+
     var NEAR_MAX_RADIUS = 0.1;
     var NEAR_TABLET_MAX_RADIUS = 0.05;
 
@@ -136,10 +138,10 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
 
         this.dataGatherers = {};
         this.dataGatherers.leftControllerLocation = function () {
-            return getControllerWorldLocation(Controller.Standard.LeftHand, true);
+            return getControllerWorldLocation(controllerStandard.LeftHand, true);
         };
         this.dataGatherers.rightControllerLocation = function () {
-            return getControllerWorldLocation(Controller.Standard.RightHand, true);
+            return getControllerWorldLocation(controllerStandard.RightHand, true);
         };
 
         this.updateTimings = function () {
@@ -178,8 +180,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
             var pinchOnBelowDistance = 0.016;
             var pinchOffAboveDistance = 0.035;
 
-            var leftIndexPose = Controller.getPoseValue(Controller.Standard.LeftHandIndex4);
-            var leftThumbPose = Controller.getPoseValue(Controller.Standard.LeftHandThumb4);
+            var leftIndexPose = Controller.getPoseValue(controllerStandard.LeftHandIndex4);
+            var leftThumbPose = Controller.getPoseValue(controllerStandard.LeftHandThumb4);
             var leftThumbToIndexDistance = Vec3.distance(leftIndexPose.translation, leftThumbPose.translation);
             if (leftIndexPose.valid && leftThumbPose.valid && leftThumbToIndexDistance < pinchOnBelowDistance) {
                 _this.leftTriggerClicked = 1;
@@ -191,8 +193,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
                 _this.leftTrackerClicked = false;
             }
 
-            var rightIndexPose = Controller.getPoseValue(Controller.Standard.RightHandIndex4);
-            var rightThumbPose = Controller.getPoseValue(Controller.Standard.RightHandThumb4);
+            var rightIndexPose = Controller.getPoseValue(controllerStandard.RightHandIndex4);
+            var rightThumbPose = Controller.getPoseValue(controllerStandard.RightHandThumb4);
             var rightThumbToIndexDistance = Vec3.distance(rightIndexPose.translation, rightThumbPose.translation);
             if (rightIndexPose.valid && rightThumbPose.valid && rightThumbToIndexDistance < pinchOnBelowDistance) {
                 _this.rightTriggerClicked = 1;
@@ -563,23 +565,23 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
 
         var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
         var mapping = Controller.newMapping(MAPPING_NAME);
-        mapping.from([Controller.Standard.RT]).peek().to(_this.rightTriggerPress);
-        mapping.from([Controller.Standard.RTClick]).peek().to(_this.rightTriggerClick);
-        mapping.from([Controller.Standard.LT]).peek().to(_this.leftTriggerPress);
-        mapping.from([Controller.Standard.LTClick]).peek().to(_this.leftTriggerClick);
+        mapping.from([controllerStandard.RT]).peek().to(_this.rightTriggerPress);
+        mapping.from([controllerStandard.RTClick]).peek().to(_this.rightTriggerClick);
+        mapping.from([controllerStandard.LT]).peek().to(_this.leftTriggerPress);
+        mapping.from([controllerStandard.LTClick]).peek().to(_this.leftTriggerClick);
 
-        mapping.from([Controller.Standard.RB]).peek().to(_this.rightSecondaryPress);
-        mapping.from([Controller.Standard.LB]).peek().to(_this.leftSecondaryPress);
-        mapping.from([Controller.Standard.LeftGrip]).peek().to(_this.leftSecondaryPress);
-        mapping.from([Controller.Standard.RightGrip]).peek().to(_this.rightSecondaryPress);
+        mapping.from([controllerStandard.RB]).peek().to(_this.rightSecondaryPress);
+        mapping.from([controllerStandard.LB]).peek().to(_this.leftSecondaryPress);
+        mapping.from([controllerStandard.LeftGrip]).peek().to(_this.leftSecondaryPress);
+        mapping.from([controllerStandard.RightGrip]).peek().to(_this.rightSecondaryPress);
 
         Controller.enableMapping(MAPPING_NAME);
 
         this.leftPointer = this.pointerManager.createPointer(false, PickType.Ray, {
             joint: "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
             filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE,
-            triggers: [{action: Controller.Standard.LTClick, button: "Focus"}, {action: Controller.Standard.LTClick, button: "Primary"}],
-            posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true),
+            triggers: [{action: controllerStandard.LTClick, button: "Focus"}, {action: controllerStandard.LTClick, button: "Primary"}],
+            posOffset: getGrabPointSphereOffset(controllerStandard.LeftHand, true),
             hover: true,
             scaleWithParent: true,
             distanceScaleEnd: true,
@@ -589,8 +591,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
         this.rightPointer = this.pointerManager.createPointer(false, PickType.Ray, {
             joint: "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND",
             filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE,
-            triggers: [{action: Controller.Standard.RTClick, button: "Focus"}, {action: Controller.Standard.RTClick, button: "Primary"}],
-            posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true),
+            triggers: [{action: controllerStandard.RTClick, button: "Focus"}, {action: controllerStandard.RTClick, button: "Primary"}],
+            posOffset: getGrabPointSphereOffset(controllerStandard.RightHand, true),
             hover: true,
             scaleWithParent: true,
             distanceScaleEnd: true,
@@ -601,8 +603,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
             joint: "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
             filter: Picks.PICK_HUD,
             maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
-            posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true),
-            triggers: [{action: Controller.Standard.LTClick, button: "Focus"}, {action: Controller.Standard.LTClick, button: "Primary"}],
+            posOffset: getGrabPointSphereOffset(controllerStandard.LeftHand, true),
+            triggers: [{action: controllerStandard.LTClick, button: "Focus"}, {action: controllerStandard.LTClick, button: "Primary"}],
             hover: true,
             scaleWithParent: true,
             distanceScaleEnd: true,
@@ -612,8 +614,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
             joint: "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND",
             filter: Picks.PICK_HUD,
             maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
-            posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true),
-            triggers: [{action: Controller.Standard.RTClick, button: "Focus"}, {action: Controller.Standard.RTClick, button: "Primary"}],
+            posOffset: getGrabPointSphereOffset(controllerStandard.RightHand, true),
+            triggers: [{action: controllerStandard.RTClick, button: "Focus"}, {action: controllerStandard.RTClick, button: "Primary"}],
             hover: true,
             scaleWithParent: true,
             distanceScaleEnd: true,
diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js
index 773d2852b7..4b24ef17b0 100644
--- a/scripts/system/controllers/controllerModules/equipEntity.js
+++ b/scripts/system/controllers/controllerModules/equipEntity.js
@@ -24,6 +24,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
 Script.include("/~/system/libraries/utils.js");
 
 
+var controllerStandard = Controller.Standard;
 var DEFAULT_SPHERE_MODEL_URL = Script.resolvePath("../../assets/models/equip-Fresnel-3.fbx");
 var EQUIP_SPHERE_SCALE_FACTOR = 0.65;
 
@@ -351,7 +352,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
         };
 
         this.handToController = function() {
-            return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
+            return (this.hand === RIGHT_HAND) ? controllerStandard.RightHand : controllerStandard.LeftHand;
         };
 
         this.updateSmoothedTrigger = function(controllerData) {
diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js
index 540668748a..7cd55734f7 100644
--- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js
+++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js
@@ -22,6 +22,8 @@ Script.include("/~/system/libraries/controllers.js");
 
 (function() {
 
+    var controllerStandard = Controller.Standard;
+
     var MARGIN = 25;
 
     function TargetObject(entityID, entityProps) {
@@ -104,7 +106,7 @@ Script.include("/~/system/libraries/controllers.js");
 
 
         this.handToController = function() {
-            return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
+            return (this.hand === RIGHT_HAND) ? controllerStandard.RightHand : controllerStandard.LeftHand;
         };
 
         this.distanceGrabTimescale = function(mass, distance) {
diff --git a/scripts/system/controllers/controllerModules/farGrabEntity.js b/scripts/system/controllers/controllerModules/farGrabEntity.js
index 5849c60553..b609215fa9 100644
--- a/scripts/system/controllers/controllerModules/farGrabEntity.js
+++ b/scripts/system/controllers/controllerModules/farGrabEntity.js
@@ -19,6 +19,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
 Script.include("/~/system/libraries/controllers.js");
 
 (function () {
+    var controllerStandard = Controller.Standard;
+
     var MARGIN = 25;
 
     function TargetObject(entityID, entityProps) {
@@ -120,7 +122,7 @@ Script.include("/~/system/libraries/controllers.js");
         };
 
         this.handToController = function () {
-            return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
+            return (this.hand === RIGHT_HAND) ? controllerStandard.RightHand : controllerStandard.LeftHand;
         };
 
         this.distanceGrabTimescale = function (mass, distance) {
@@ -276,7 +278,7 @@ Script.include("/~/system/libraries/controllers.js");
             // This block handles the user's ability to rotate the object they're FarGrabbing
             if (this.shouldManipulateTarget(controllerData)) {
                 // Get the pose of the controller that is not grabbing.
-                var pose = Controller.getPoseValue((this.getOffhand() ? Controller.Standard.RightHand : Controller.Standard.LeftHand));
+                var pose = Controller.getPoseValue((this.getOffhand() ? controllerStandard.RightHand : controllerStandard.LeftHand));
                 if (pose.valid) {
                     // If we weren't manipulating the object yet, initialize the entity's original position.
                     if (!this.manipulating) {
diff --git a/scripts/system/controllers/controllerModules/hudOverlayPointer.js b/scripts/system/controllers/controllerModules/hudOverlayPointer.js
index f7d5b5a2dd..4c818647cd 100644
--- a/scripts/system/controllers/controllerModules/hudOverlayPointer.js
+++ b/scripts/system/controllers/controllerModules/hudOverlayPointer.js
@@ -12,6 +12,7 @@
 
 /* global Script, Controller, RIGHT_HAND, LEFT_HAND, HMD, makeLaserParams */
 (function() {
+    var controllerStandard = Controller.Standard;
     Script.include("/~/system/libraries/controllers.js");
     var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
     var MARGIN = 25;
@@ -45,11 +46,11 @@
         };
 
         this.getOtherHandController = function() {
-            return (this.hand === RIGHT_HAND) ? Controller.Standard.LeftHand : Controller.Standard.RightHand;
+            return (this.hand === RIGHT_HAND) ? controllerStandard.LeftHand : controllerStandard.RightHand;
         };
 
         this.handToController = function() {
-            return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
+            return (this.hand === RIGHT_HAND) ? controllerStandard.RightHand : controllerStandard.LeftHand;
         };
 
         this.updateRecommendedArea = function() {
diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js
index d553bf5714..22ce55c703 100644
--- a/scripts/system/controllers/controllerModules/inEditMode.js
+++ b/scripts/system/controllers/controllerModules/inEditMode.js
@@ -20,6 +20,7 @@ Script.include("/~/system/libraries/controllers.js");
 Script.include("/~/system/libraries/utils.js");
 
 (function () {
+    var controllerStandard = Controller.Standard;
     var MARGIN = 25;
     function InEditMode(hand) {
         this.hand = hand;
@@ -48,7 +49,7 @@ Script.include("/~/system/libraries/utils.js");
         };
 
         this.handToController = function() {
-            return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
+            return (this.hand === RIGHT_HAND) ? controllerStandard.RightHand : controllerStandard.LeftHand;
         };
 
         this.pointingAtTablet = function(objectID) {
@@ -70,7 +71,7 @@ Script.include("/~/system/libraries/utils.js");
 
         this.sendPickData = function(controllerData) {
             if (controllerData.triggerClicks[this.hand]) {
-                var hand = this.hand === RIGHT_HAND ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
+                var hand = this.hand === RIGHT_HAND ? controllerStandard.RightHand : controllerStandard.LeftHand;
                 if (!this.triggerClicked) {
                     print("inEditMode click");
                     this.selectedTarget = controllerData.rayPicks[this.hand];
diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js
index 63106b6241..be45d3b70e 100644
--- a/scripts/system/controllers/controllerModules/teleport.js
+++ b/scripts/system/controllers/controllerModules/teleport.js
@@ -21,6 +21,8 @@ Script.include("/~/system/libraries/controllers.js");
 
 (function() { // BEGIN LOCAL_SCOPE
 
+    var controllerStandard = Controller.Standard;
+
     var TARGET_MODEL_URL = Script.resolvePath("../../assets/models/teleportationSpotBasev8.fbx");
     var SEAT_MODEL_URL = Script.resolvePath("../../assets/models/teleport-seat.fbx");
 
@@ -46,10 +48,10 @@ Script.include("/~/system/libraries/controllers.js");
 
     var handInfo = {
         right: {
-            controllerInput: Controller.Standard.RightHand
+            controllerInput: controllerStandard.RightHand
         },
         left: {
-            controllerInput: Controller.Standard.LeftHand
+            controllerInput: controllerStandard.LeftHand
         }
     };
 
@@ -1065,10 +1067,10 @@ Script.include("/~/system/libraries/controllers.js");
         registerGamePadMapping();
 
         // Teleport actions.
-        teleportMapping.from(Controller.Standard.LY).peek().to(leftTeleporter.getStandardLY);
-        teleportMapping.from(Controller.Standard.RY).peek().to(leftTeleporter.getStandardRY);
-        teleportMapping.from(Controller.Standard.LY).peek().to(rightTeleporter.getStandardLY);
-        teleportMapping.from(Controller.Standard.RY).peek().to(rightTeleporter.getStandardRY);
+        teleportMapping.from(controllerStandard.LY).peek().to(leftTeleporter.getStandardLY);
+        teleportMapping.from(controllerStandard.RY).peek().to(leftTeleporter.getStandardRY);
+        teleportMapping.from(controllerStandard.LY).peek().to(rightTeleporter.getStandardLY);
+        teleportMapping.from(controllerStandard.RY).peek().to(rightTeleporter.getStandardRY);
     }
 
     var leftTeleporter = new Teleporter(LEFT_HAND);
diff --git a/scripts/system/controllers/controllerModules/trackedHandTablet.js b/scripts/system/controllers/controllerModules/trackedHandTablet.js
index 66cf408af8..6aa5e88b34 100644
--- a/scripts/system/controllers/controllerModules/trackedHandTablet.js
+++ b/scripts/system/controllers/controllerModules/trackedHandTablet.js
@@ -12,6 +12,8 @@ Script.include("/~/system/libraries/controllers.js");
 
 (function() {
 
+    var controllerStandard = Controller.Standard;
+
     function TrackedHandTablet() {
         this.mappingName = 'hand-track-tablet-' + Math.random();
         this.inputMapping = Controller.newMapping(this.mappingName);
@@ -103,16 +105,16 @@ Script.include("/~/system/libraries/controllers.js");
 
         this.setup = function () {
             var _this = this;
-            this.inputMapping.from(Controller.Standard.LeftHandIndex4).peek().to(function (pose) {
+            this.inputMapping.from(controllerStandard.LeftHandIndex4).peek().to(function (pose) {
                 _this.leftIndexChanged(pose);
             });
-            this.inputMapping.from(Controller.Standard.LeftHandThumb4).peek().to(function (pose) {
+            this.inputMapping.from(controllerStandard.LeftHandThumb4).peek().to(function (pose) {
                 _this.leftThumbChanged(pose);
             });
-            this.inputMapping.from(Controller.Standard.RightHandIndex4).peek().to(function (pose) {
+            this.inputMapping.from(controllerStandard.RightHandIndex4).peek().to(function (pose) {
                 _this.rightIndexChanged(pose);
             });
-            this.inputMapping.from(Controller.Standard.RightHandThumb4).peek().to(function (pose) {
+            this.inputMapping.from(controllerStandard.RightHandThumb4).peek().to(function (pose) {
                 _this.rightThumbChanged(pose);
             });
 
diff --git a/scripts/system/controllers/controllerModules/trackedHandWalk.js b/scripts/system/controllers/controllerModules/trackedHandWalk.js
index 9ecc53a1fa..dc8f3f16c4 100644
--- a/scripts/system/controllers/controllerModules/trackedHandWalk.js
+++ b/scripts/system/controllers/controllerModules/trackedHandWalk.js
@@ -12,6 +12,8 @@ Script.include("/~/system/libraries/controllers.js");
 
 (function() {
 
+    var controllerStandard = Controller.Standard;
+
     function TrackedHandWalk() {
         this.gestureMappingName = 'hand-track-walk-gesture-' + Math.random();
         this.inputGestureMapping = Controller.newMapping(this.gestureMappingName);
@@ -114,16 +116,16 @@ Script.include("/~/system/libraries/controllers.js");
 
         this.setup = function () {
             var _this = this;
-            this.inputGestureMapping.from(Controller.Standard.LeftHandIndex4).peek().to(function (pose) {
+            this.inputGestureMapping.from(controllerStandard.LeftHandIndex4).peek().to(function (pose) {
                 _this.leftIndexChanged(pose);
             });
-            this.inputGestureMapping.from(Controller.Standard.LeftHandThumb4).peek().to(function (pose) {
+            this.inputGestureMapping.from(controllerStandard.LeftHandThumb4).peek().to(function (pose) {
                 _this.leftThumbChanged(pose);
             });
-            this.inputGestureMapping.from(Controller.Standard.RightHandIndex4).peek().to(function (pose) {
+            this.inputGestureMapping.from(controllerStandard.RightHandIndex4).peek().to(function (pose) {
                 _this.rightIndexChanged(pose);
             });
-            this.inputGestureMapping.from(Controller.Standard.RightHandThumb4).peek().to(function (pose) {
+            this.inputGestureMapping.from(controllerStandard.RightHandThumb4).peek().to(function (pose) {
                 _this.rightThumbChanged(pose);
             });
 
@@ -137,7 +139,7 @@ Script.include("/~/system/libraries/controllers.js");
                     // return currentPoint.z - _this.controlPoint.z;
                     return 0.5;
                 } else {
-                    // return Controller.getActionValue(Controller.Standard.TranslateZ);
+                    // return Controller.getActionValue(controllerStandard.TranslateZ);
                     return 0.0;
                 }
             }).to(Controller.Actions.TranslateZ);
@@ -147,7 +149,7 @@ Script.include("/~/system/libraries/controllers.js");
             //         var currentPoint = _this.getControlPoint();
             //         return currentPoint.x - _this.controlPoint.x;
             //     } else {
-            //         return Controller.getActionValue(Controller.Standard.Yaw);
+            //         return Controller.getActionValue(controllerStandard.Yaw);
             //     }
             // }).to(Controller.Actions.Yaw);
 
diff --git a/scripts/system/controllers/handTouch.js b/scripts/system/controllers/handTouch.js
index 5939c6e3d2..6d5d403512 100644
--- a/scripts/system/controllers/handTouch.js
+++ b/scripts/system/controllers/handTouch.js
@@ -16,6 +16,7 @@
 
 (function () {
 
+    var controllerStandard = Controller.Standard;
     var LEAP_MOTION_NAME = "LeapMotion";
     // Hand touch is disabled due to twitchy finger bug when walking near walls or tables. see BUGZ-154.
     var handTouchEnabled = false;
@@ -792,15 +793,15 @@
 
     var MAPPING_NAME = "com.highfidelity.handTouch";
     var mapping = Controller.newMapping(MAPPING_NAME);
-    mapping.from([Controller.Standard.RT]).peek().to(rightTriggerPress);
-    mapping.from([Controller.Standard.RTClick]).peek().to(rightTriggerClick);
-    mapping.from([Controller.Standard.LT]).peek().to(leftTriggerPress);
-    mapping.from([Controller.Standard.LTClick]).peek().to(leftTriggerClick);
+    mapping.from([controllerStandard.RT]).peek().to(rightTriggerPress);
+    mapping.from([controllerStandard.RTClick]).peek().to(rightTriggerClick);
+    mapping.from([controllerStandard.LT]).peek().to(leftTriggerPress);
+    mapping.from([controllerStandard.LTClick]).peek().to(leftTriggerClick);
 
-    mapping.from([Controller.Standard.RB]).peek().to(rightSecondaryPress);
-    mapping.from([Controller.Standard.LB]).peek().to(leftSecondaryPress);
-    mapping.from([Controller.Standard.LeftGrip]).peek().to(leftSecondaryPress);
-    mapping.from([Controller.Standard.RightGrip]).peek().to(rightSecondaryPress);
+    mapping.from([controllerStandard.RB]).peek().to(rightSecondaryPress);
+    mapping.from([controllerStandard.LB]).peek().to(leftSecondaryPress);
+    mapping.from([controllerStandard.LeftGrip]).peek().to(leftSecondaryPress);
+    mapping.from([controllerStandard.RightGrip]).peek().to(rightSecondaryPress);
 
     Controller.enableMapping(MAPPING_NAME);
 
diff --git a/scripts/system/controllers/squeezeHands.js b/scripts/system/controllers/squeezeHands.js
index 69f44f46a9..3f6df92b12 100644
--- a/scripts/system/controllers/squeezeHands.js
+++ b/scripts/system/controllers/squeezeHands.js
@@ -16,6 +16,8 @@
 
 (function() { // BEGIN LOCAL_SCOPE
 
+var controllerStandard = Controller.Standard;
+
 var lastLeftTrigger = 0;
 var lastRightTrigger = 0;
 var leftHandOverlayAlpha = 0;
@@ -86,8 +88,8 @@ function animStateHandler(props) {
 }
 
 function update(dt) {
-    var leftTrigger = clamp(Controller.getValue(Controller.Standard.LT) + Controller.getValue(Controller.Standard.LeftGrip), 0, 1);
-    var rightTrigger = clamp(Controller.getValue(Controller.Standard.RT) + Controller.getValue(Controller.Standard.RightGrip), 0, 1);
+    var leftTrigger = clamp(Controller.getValue(controllerStandard.LT) + Controller.getValue(controllerStandard.LeftGrip), 0, 1);
+    var rightTrigger = clamp(Controller.getValue(controllerStandard.RT) + Controller.getValue(controllerStandard.RightGrip), 0, 1);
 
     //  Average last few trigger values together for a bit of smoothing
     var tau = clamp(dt / TRIGGER_SMOOTH_TIMESCALE, 0, 1);
@@ -95,7 +97,7 @@ function update(dt) {
     lastRightTrigger = lerp(rightTrigger, lastRightTrigger, tau);
 
     // ramp on/off left hand overlay
-    var leftHandPose = Controller.getPoseValue(Controller.Standard.LeftHand);
+    var leftHandPose = Controller.getPoseValue(controllerStandard.LeftHand);
     if (leftHandPose.valid) {
         leftHandOverlayAlpha = clamp(leftHandOverlayAlpha + OVERLAY_RAMP_RATE * dt, 0, 1);
     } else {
@@ -103,7 +105,7 @@ function update(dt) {
     }
 
     // ramp on/off right hand overlay
-    var rightHandPose = Controller.getPoseValue(Controller.Standard.RightHand);
+    var rightHandPose = Controller.getPoseValue(controllerStandard.RightHand);
     if (rightHandPose.valid) {
         rightHandOverlayAlpha = clamp(rightHandOverlayAlpha + OVERLAY_RAMP_RATE * dt, 0, 1);
     } else {
@@ -111,10 +113,10 @@ function update(dt) {
     }
 
     // Pointing index fingers and raising thumbs
-    isLeftIndexPointing = (leftIndexPointingOverride > 0) || (leftHandPose.valid && Controller.getValue(Controller.Standard.LeftIndexPoint) === 1);
-    isRightIndexPointing = (rightIndexPointingOverride > 0) || (rightHandPose.valid && Controller.getValue(Controller.Standard.RightIndexPoint) === 1);
-    isLeftThumbRaised = (leftThumbRaisedOverride > 0) || (leftHandPose.valid && Controller.getValue(Controller.Standard.LeftThumbUp) === 1);
-    isRightThumbRaised = (rightThumbRaisedOverride > 0) || (rightHandPose.valid && Controller.getValue(Controller.Standard.RightThumbUp) === 1);
+    isLeftIndexPointing = (leftIndexPointingOverride > 0) || (leftHandPose.valid && Controller.getValue(controllerStandard.LeftIndexPoint) === 1);
+    isRightIndexPointing = (rightIndexPointingOverride > 0) || (rightHandPose.valid && Controller.getValue(controllerStandard.RightIndexPoint) === 1);
+    isLeftThumbRaised = (leftThumbRaisedOverride > 0) || (leftHandPose.valid && Controller.getValue(controllerStandard.LeftThumbUp) === 1);
+    isRightThumbRaised = (rightThumbRaisedOverride > 0) || (rightHandPose.valid && Controller.getValue(controllerStandard.RightThumbUp) === 1);
 }
 
 function handleMessages(channel, message, sender) {
diff --git a/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js b/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js
index 92f72f8724..b0b498fc29 100644
--- a/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js
+++ b/scripts/system/controllers/toggleAdvancedMovementForHandControllers.js
@@ -17,6 +17,8 @@
 
 (function() { // BEGIN LOCAL_SCOPE
 
+    var controllerStandard = Controller.Standard;
+
     var TWO_SECONDS_INTERVAL = 2000;
     var FLYING_MAPPING_NAME = 'Hifi-Flying-Dev-' + Math.random();
     var DRIVING_MAPPING_NAME = 'Hifi-Driving-Dev-' + Math.random();
@@ -44,7 +46,7 @@
     function registerBasicMapping() {
 
         drivingMapping = Controller.newMapping(DRIVING_MAPPING_NAME);
-        drivingMapping.from(Controller.Standard.LY).to(function(value) {
+        drivingMapping.from(controllerStandard.LY).to(function(value) {
             if (isDisabled) {
                 return;
             }
@@ -64,7 +66,7 @@
         });
 
         flyingMapping = Controller.newMapping(FLYING_MAPPING_NAME);
-        flyingMapping.from(Controller.Standard.RY).to(function(value) {
+        flyingMapping.from(controllerStandard.RY).to(function(value) {
             if (isDisabled) {
                 return;
             }
diff --git a/scripts/system/controllers/touchControllerConfiguration.js b/scripts/system/controllers/touchControllerConfiguration.js
index 991b77b8af..1944d54537 100644
--- a/scripts/system/controllers/touchControllerConfiguration.js
+++ b/scripts/system/controllers/touchControllerConfiguration.js
@@ -12,6 +12,8 @@
    Quat, Vec3, Script, MyAvatar, Controller */
 /* eslint camelcase: ["error", { "properties": "never" }] */
 
+var controllerStandard = Controller.Standard;
+
 var leftBaseRotation = Quat.multiply(
     Quat.fromPitchYawRollDegrees(-90, 0, 0),
     Quat.fromPitchYawRollDegrees(0, 0, 90)
@@ -89,7 +91,7 @@ TOUCH_CONTROLLER_CONFIGURATION_LEFT = {
                     naturalDimensions: { x: 0.027509, y: 0.025211, z: 0.018443 },
 
                     // rotational 
-                    input: Controller.Standard.LT,
+                    input: controllerStandard.LT,
                     origin: { x: 0, y: -0.015, z: -0.00 },
                     minValue: 0.0,
                     maxValue: 1.0,
diff --git a/scripts/system/controllers/viveControllerConfiguration.js b/scripts/system/controllers/viveControllerConfiguration.js
index 09fd8adacc..e0ae43c16c 100644
--- a/scripts/system/controllers/viveControllerConfiguration.js
+++ b/scripts/system/controllers/viveControllerConfiguration.js
@@ -15,6 +15,8 @@
 // var LEFT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_LEFTHAND");
 // var RIGHT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_RIGHTHAND");
 
+var controllerStandard = Controller.Standard;
+
 var leftBaseRotation = Quat.multiply(
     Quat.fromPitchYawRollDegrees(0, 0, 45),
     Quat.multiply(
@@ -141,7 +143,7 @@ VIVE_CONTROLLER_CONFIGURATION_LEFT = {
                 trigger: {
                     type: "rotational",
                     modelURL: BASE_URL + "meshes/controller/vive_trigger.fbx",
-                    input: Controller.Standard.LT,
+                    input: controllerStandard.LT,
                     naturalPosition: {"x":0.000004500150680541992,"y":-0.027690507471561432,"z":0.04830199480056763},
                     naturalDimensions: {x: 0.019105, y: 0.022189, z: 0.01909},
                     origin: { x: 0, y: -0.015, z: -0.00 },
@@ -283,7 +285,7 @@ VIVE_CONTROLLER_CONFIGURATION_RIGHT = {
                 trigger: {
                     type: "rotational",
                     modelURL: BASE_URL + "meshes/controller/vive_trigger.fbx",
-                    input: Controller.Standard.RT,
+                    input: controllerStandard.RT,
                     naturalPosition: {"x":0.000004500150680541992,"y":-0.027690507471561432,"z":0.04830199480056763},
                     naturalDimensions: {x: 0.019105, y: 0.022189, z: 0.01909},
                     origin: { x: 0, y: -0.015, z: -0.00 },
diff --git a/scripts/system/create/editModes/editVoxels.js b/scripts/system/create/editModes/editVoxels.js
index 13138e55e1..bd0f4bc15a 100644
--- a/scripts/system/create/editModes/editVoxels.js
+++ b/scripts/system/create/editModes/editVoxels.js
@@ -34,6 +34,7 @@ EditVoxels = function() {
     var that = {};
 
     const NO_HAND = -1;
+    var controllerStandard = Controller.Standard;
 
     var controlHeld = false;
     var shiftHeld = false;
@@ -325,10 +326,10 @@ EditVoxels = function() {
             }
         }else{
             inverseOperation = false;
-            if(that.triggeredHand === Controller.Standard.RightHand && Controller.getValue(Controller.Standard.RightGrip) > 0.5){
+            if(that.triggeredHand === controllerStandard.RightHand && Controller.getValue(controllerStandard.RightGrip) > 0.5){
                 inverseOperation = true;
             }
-            if(that.triggeredHand === Controller.Standard.LeftHand && Controller.getValue(Controller.Standard.LeftGrip) > 0.5){
+            if(that.triggeredHand === controllerStandard.LeftHand && Controller.getValue(controllerStandard.LeftGrip) > 0.5){
                 inverseOperation = true;
             }
         }
@@ -458,13 +459,13 @@ EditVoxels = function() {
     }
 
     function getDistanceBetweenControllers(){
-        var poseLeft = getControllerWorldLocation(Controller.Standard.LeftHand, true);
-        var poseRight = getControllerWorldLocation(Controller.Standard.RightHand, true);
+        var poseLeft = getControllerWorldLocation(controllerStandard.LeftHand, true);
+        var poseRight = getControllerWorldLocation(controllerStandard.RightHand, true);
         return Vec3.distance(poseLeft.translation, poseRight.translation);
     }
     function getEditSpherePosition( radius ){
-        var poseLeft = getControllerWorldLocation(Controller.Standard.LeftHand, true);
-        var poseRight = getControllerWorldLocation(Controller.Standard.RightHand, true);
+        var poseLeft = getControllerWorldLocation(controllerStandard.LeftHand, true);
+        var poseRight = getControllerWorldLocation(controllerStandard.RightHand, true);
         var handsPosition = Vec3.multiply(Vec3.sum(poseLeft.translation, poseRight.translation), 0.5);
         return Vec3.sum(handsPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: radius * -2.0 }));
     }
@@ -531,15 +532,15 @@ EditVoxels = function() {
                 return;
             }
             if (value > 0.5) {
-                if (hand === Controller.Standard.LeftHand) {
+                if (hand === controllerStandard.LeftHand) {
                     isLeftGripPressed = true;
-                } else if (hand === Controller.Standard.RightHand) {
+                } else if (hand === controllerStandard.RightHand) {
                     isRightGripPressed = true;
                 }
             } else if (value < 0.4){
-                if (hand === Controller.Standard.LeftHand) {
+                if (hand === controllerStandard.LeftHand) {
                     isLeftGripPressed = false;
-                } else if (hand === Controller.Standard.RightHand) {
+                } else if (hand === controllerStandard.RightHand) {
                     isRightGripPressed = false;
                 }
             }
@@ -664,12 +665,12 @@ EditVoxels = function() {
     Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
     Controller.keyPressEvent.connect(keyPressEvent);
     Controller.keyReleaseEvent.connect(keyReleaseEvent);
-    that.triggerClickMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
-    that.triggerClickMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
-    that.triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
-    that.triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
-    that.gripPressMapping.from(Controller.Standard.LeftGrip).peek().to(makeGripPressHandler(Controller.Standard.LeftHand));
-    that.gripPressMapping.from(Controller.Standard.RightGrip).peek().to(makeGripPressHandler(Controller.Standard.RightHand));
+    that.triggerClickMapping.from(controllerStandard.RTClick).peek().to(makeClickHandler(controllerStandard.RightHand));
+    that.triggerClickMapping.from(controllerStandard.LTClick).peek().to(makeClickHandler(controllerStandard.LeftHand));
+    that.triggerPressMapping.from(controllerStandard.RT).peek().to(makePressHandler(controllerStandard.RightHand));
+    that.triggerPressMapping.from(controllerStandard.LT).peek().to(makePressHandler(controllerStandard.LeftHand));
+    that.gripPressMapping.from(controllerStandard.LeftGrip).peek().to(makeGripPressHandler(controllerStandard.LeftHand));
+    that.gripPressMapping.from(controllerStandard.RightGrip).peek().to(makeGripPressHandler(controllerStandard.RightHand));
     that.enableTriggerMapping = function() {
         that.triggerClickMapping.enable();
         that.triggerPressMapping.enable();
diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js
index 7a188f3dc0..b948c7fa9e 100644
--- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js
+++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js
@@ -23,6 +23,8 @@ const SPACE_WORLD = "world";
 const HIGHLIGHT_LIST_NAME = "editHandleHighlightList";
 const MIN_DISTANCE_TO_REZ_FROM_AVATAR = 3;
 
+var controllerStandard = Controller.Standard;
+
 Script.include([
     "../../libraries/controllers.js",
     "../../libraries/controllerDispatcherUtils.js",
@@ -149,7 +151,7 @@ SelectionManager = (function() {
                 that.clearSelections();
             }
         } else if (messageParsed.method === "pointingAt") {
-            if (messageParsed.hand === Controller.Standard.RightHand) {
+            if (messageParsed.hand === controllerStandard.RightHand) {
                 that.pointingAtDesktopWindowRight = messageParsed.desktopWindow;
                 that.pointingAtTabletRight = messageParsed.tablet;
             } else {
@@ -940,8 +942,8 @@ SelectionDisplay = (function() {
 
     var toolEntityNames = [];
     var lastControllerPoses = [
-        getControllerWorldLocation(Controller.Standard.LeftHand, true),
-        getControllerWorldLocation(Controller.Standard.RightHand, true)
+        getControllerWorldLocation(controllerStandard.LeftHand, true),
+        getControllerWorldLocation(controllerStandard.RightHand, true)
     ];
 
     var worldRotationX;
@@ -1323,12 +1325,12 @@ SelectionDisplay = (function() {
         return that.triggeredHand !== NO_HAND;
     };
     function pointingAtDesktopWindowOrTablet(hand) {
-        var pointingAtDesktopWindow = (hand === Controller.Standard.RightHand && 
+        var pointingAtDesktopWindow = (hand === controllerStandard.RightHand &&
                                        SelectionManager.pointingAtDesktopWindowRight) ||
-                                      (hand === Controller.Standard.LeftHand && 
+                                      (hand === controllerStandard.LeftHand &&
                                        SelectionManager.pointingAtDesktopWindowLeft);
-        var pointingAtTablet = (hand === Controller.Standard.RightHand && SelectionManager.pointingAtTabletRight) ||
-                               (hand === Controller.Standard.LeftHand && SelectionManager.pointingAtTabletLeft);
+        var pointingAtTablet = (hand === controllerStandard.RightHand && SelectionManager.pointingAtTabletRight) ||
+                               (hand === controllerStandard.LeftHand && SelectionManager.pointingAtTabletLeft);
         return pointingAtDesktopWindow || pointingAtTablet;
     }
     function makeClickHandler(hand) {
@@ -1363,10 +1365,10 @@ SelectionDisplay = (function() {
             }
         }
     }
-    that.triggerClickMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
-    that.triggerClickMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
-    that.triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
-    that.triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
+    that.triggerClickMapping.from(controllerStandard.RTClick).peek().to(makeClickHandler(controllerStandard.RightHand));
+    that.triggerClickMapping.from(controllerStandard.LTClick).peek().to(makeClickHandler(controllerStandard.LeftHand));
+    that.triggerPressMapping.from(controllerStandard.RT).peek().to(makePressHandler(controllerStandard.RightHand));
+    that.triggerPressMapping.from(controllerStandard.LT).peek().to(makePressHandler(controllerStandard.LeftHand));
     that.enableTriggerMapping = function() {
         that.triggerClickMapping.enable();
         that.triggerPressMapping.enable();
@@ -1494,7 +1496,7 @@ SelectionDisplay = (function() {
                     that.editingHand = that.triggeredHand;
                     Messages.sendLocalMessage(INEDIT_STATUS_CHANNEL, JSON.stringify({
                         method: "editing",
-                        hand: that.editingHand === Controller.Standard.LeftHand ? LEFT_HAND : RIGHT_HAND,
+                        hand: that.editingHand === controllerStandard.LeftHand ? LEFT_HAND : RIGHT_HAND,
                         editing: true
                     }));
                     activeTool.onBegin(event, pickRay, results);
@@ -1705,7 +1707,7 @@ SelectionDisplay = (function() {
                 }
                 Messages.sendLocalMessage(INEDIT_STATUS_CHANNEL, JSON.stringify({
                     method: "editing",
-                    hand: that.editingHand === Controller.Standard.LeftHand ? LEFT_HAND : RIGHT_HAND,
+                    hand: that.editingHand === controllerStandard.LeftHand ? LEFT_HAND : RIGHT_HAND,
                     editing: false
                 }));
                 that.editingHand = NO_HAND;
@@ -1775,7 +1777,7 @@ SelectionDisplay = (function() {
     that.checkControllerMove = function() {
         if (SelectionManager.hasSelection()) {
             var controllerPose = getControllerWorldLocation(that.triggeredHand, true);
-            var hand = (that.triggeredHand === Controller.Standard.LeftHand) ? 0 : 1;
+            var hand = (that.triggeredHand === controllerStandard.LeftHand) ? 0 : 1;
             if (controllerPose.valid && lastControllerPoses[hand].valid && that.triggered()) {
                 if (!Vec3.equal(controllerPose.position, lastControllerPoses[hand].position) ||
                     !Vec3.equal(controllerPose.rotation, lastControllerPoses[hand].rotation)) {
diff --git a/scripts/system/emote.js b/scripts/system/emote.js
index 6dfd1ae1ef..0d56932b4b 100644
--- a/scripts/system/emote.js
+++ b/scripts/system/emote.js
@@ -15,6 +15,7 @@
 
 (function() { // BEGIN LOCAL_SCOPE
 
+var controllerStandard = Controller.Standard;
 
 var EMOTE_ANIMATIONS = 
     ['Crying', 'Surprised', 'Dancing', 'Cheering', 'Waving', 'Fall', 'Pointing', 'Clapping', 'Sit1', 'Sit2', 'Sit3', 'Love'];
@@ -138,22 +139,22 @@ function restoreAnimation() {
 }
                     
 // Note peek() so as to not interfere with other mappings.
-eventMapping.from(Controller.Standard.LeftPrimaryThumb).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RightPrimaryThumb).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.LB).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.LS).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RY).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RX).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.LY).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.LX).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.LeftGrip).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RB).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RS).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.RightGrip).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.Back).peek().to(restoreAnimation);
-eventMapping.from(Controller.Standard.Start).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LeftPrimaryThumb).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RightPrimaryThumb).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LeftSecondaryThumb).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RightSecondaryThumb).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LB).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LS).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RY).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RX).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LY).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LX).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.LeftGrip).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RB).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RS).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.RightGrip).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.Back).peek().to(restoreAnimation);
+eventMapping.from(controllerStandard.Start).peek().to(restoreAnimation);
 
 
 button.clicked.connect(onClicked);
diff --git a/scripts/system/fingerPaint.js b/scripts/system/fingerPaint.js
index 88245503e8..376a60e85d 100644
--- a/scripts/system/fingerPaint.js
+++ b/scripts/system/fingerPaint.js
@@ -9,6 +9,8 @@
 //
 
 (function () {
+    var controllerStandard = Controller.Standard;
+
     var tablet,
         button,
         BUTTON_NAME = "PAINT",
@@ -334,11 +336,11 @@
         leftHand = handController("left");
         rightHand = handController("right");
         var controllerMapping = Controller.newMapping(CONTROLLER_MAPPING_NAME);
-        controllerMapping.from(Controller.Standard.LT).to(leftHand.onTriggerPress);
-        controllerMapping.from(Controller.Standard.LeftGrip).to(leftHand.onGripPress);
-        controllerMapping.from(Controller.Standard.RT).to(rightHand.onTriggerPress);
-        controllerMapping.from(Controller.Standard.RightGrip).to(rightHand.onGripPress);
-        controllerMapping.from(Controller.Standard.B).to(onButtonClicked);
+        controllerMapping.from(controllerStandard.LT).to(leftHand.onTriggerPress);
+        controllerMapping.from(controllerStandard.LeftGrip).to(leftHand.onGripPress);
+        controllerMapping.from(controllerStandard.RT).to(rightHand.onTriggerPress);
+        controllerMapping.from(controllerStandard.RightGrip).to(rightHand.onGripPress);
+        controllerMapping.from(controllerStandard.B).to(onButtonClicked);
         Controller.enableMapping(CONTROLLER_MAPPING_NAME);
         
         if (!Settings.getValue("FingerPaintTutorialComplete")) {
diff --git a/scripts/system/libraries/Trigger.js b/scripts/system/libraries/Trigger.js
index ffde021f5d..c59b60d5ea 100644
--- a/scripts/system/libraries/Trigger.js
+++ b/scripts/system/libraries/Trigger.js
@@ -6,6 +6,7 @@
 Trigger = function(properties) {
     properties = properties || {};
     var that = this;
+    var controllerStandard = Controller.Standard;
     that.label = properties.label || Math.random();
     that.SMOOTH_RATIO = properties.smooth || 0.1; //  Time averaging of trigger - 0.0 disables smoothing
     that.DEADZONE = properties.deadzone || 0.10; // Once pressed, a trigger must fall below the deadzone to be considered un-pressed once pressed.
@@ -44,8 +45,8 @@ Trigger = function(properties) {
 
     
     // Private values
-    var controller = properties.controller || Controller.Standard.LT;
-    var controllerClick = properties.controllerClick || Controller.Standard.LTClick;
+    var controller = properties.controller || controllerStandard.LT;
+    var controllerClick = properties.controllerClick || controllerStandard.LTClick;
     that.mapping =  Controller.newMapping('com.highfidelity.controller.trigger.' + controller + '-' + controllerClick + '.' + that.label + Math.random());
     Script.scriptEnding.connect(that.mapping.disable);
 
diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js
index 53d4682c97..3e5f487695 100644
--- a/scripts/system/libraries/WebTablet.js
+++ b/scripts/system/libraries/WebTablet.js
@@ -51,7 +51,8 @@ var SUBMESH = 2;
 function calcSpawnInfo(hand, landscape) {
     var finalPosition;
 
-    var LEFT_HAND = Controller.Standard.LeftHand;
+    var controllerStandard = Controller.Standard;
+    var LEFT_HAND = controllerStandard.LeftHand;
     var sensorToWorldScale = MyAvatar.sensorToWorldScale;
     var headPos = (HMD.active && (Camera.mode === "first person" || Camera.mode === "first person look at")) ? HMD.position : Camera.position;
     var headRot = Quat.cancelOutRollAndPitch((HMD.active && (Camera.mode === "first person" || Camera.mode === "first person look at")) ?
diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js
index 83d6fd747b..f331c147e0 100644
--- a/scripts/system/libraries/controllerDispatcherUtils.js
+++ b/scripts/system/libraries/controllerDispatcherUtils.js
@@ -73,6 +73,8 @@
    handsAreTracked: true
 */
 
+var controllerStandard = Controller.Standard;
+
 var MSECS_PER_SEC = 1000.0;
 var INCHES_TO_METERS = 1.0 / 39.3701;
 
@@ -610,8 +612,8 @@ var worldPositionToRegistrationFrameMatrix = function(wptrProps, pos) {
 };
 
 var handsAreTracked = function () {
-    return Controller.getPoseValue(Controller.Standard.LeftHandIndex3).valid ||
-        Controller.getPoseValue(Controller.Standard.RightHandIndex3).valid;
+    return Controller.getPoseValue(controllerStandard.LeftHandIndex3).valid ||
+        Controller.getPoseValue(controllerStandard.RightHandIndex3).valid;
 };
 
 if (typeof module !== 'undefined') {
diff --git a/scripts/system/libraries/controllers.js b/scripts/system/libraries/controllers.js
index 5722458990..eff0bfcbe9 100644
--- a/scripts/system/libraries/controllers.js
+++ b/scripts/system/libraries/controllers.js
@@ -16,6 +16,8 @@
    getControllerWorldLocation:true
  */
 
+var controllerStandard = Controller.Standard;
+
 const GRAB_COMMUNICATIONS_SETTING = "io.highfidelity.isFarGrabbing";
 const setGrabCommunications = function setFarGrabCommunications(on) {
     Settings.setValue(GRAB_COMMUNICATIONS_SETTING, on ? "on" : "");
@@ -29,7 +31,7 @@ const getGrabCommunications = function getFarGrabCommunications() {
 const getGrabPointSphereOffset = function(handController, ignoreSensorToWorldScale) {
     var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 };  // x = upward, y = forward, z = lateral
     var offset = GRAB_POINT_SPHERE_OFFSET;
-    if (handController === Controller.Standard.LeftHand) {
+    if (handController === controllerStandard.LeftHand) {
         offset = {
             x: -GRAB_POINT_SPHERE_OFFSET.x,
             y: GRAB_POINT_SPHERE_OFFSET.y,
@@ -54,7 +56,7 @@ const getControllerWorldLocation = function (handController, doOffset) {
         valid = pose.valid;
         var controllerJointIndex;
         if (pose.valid) {
-            if (handController === Controller.Standard.RightHand) {
+            if (handController === controllerStandard.RightHand) {
                 controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND");
             } else {
                 controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js
index cecc17e705..572c6a764e 100644
--- a/scripts/system/makeUserConnection.js
+++ b/scripts/system/makeUserConnection.js
@@ -16,6 +16,8 @@
 
     var request = Script.require('request').request;
 
+    var controllerStandard = Controller.Standard;
+
     var WANT_DEBUG = Settings.getValue('MAKE_USER_CONNECTION_DEBUG', false);
     var LABEL = "makeUserConnection";
     var MAX_AVATAR_DISTANCE = 0.2; // m
@@ -150,10 +152,10 @@
     }
 
     function handToString(hand) {
-        if (hand === Controller.Standard.RightHand) {
+        if (hand === controllerStandard.RightHand) {
             return "RightHand";
         }
-        if (hand === Controller.Standard.LeftHand) {
+        if (hand === controllerStandard.LeftHand) {
             return "LeftHand";
         }
         debug("handToString called without valid hand! value: ", hand);
@@ -161,10 +163,10 @@
     }
 
     function handToHaptic(hand) {
-        if (hand === Controller.Standard.RightHand) {
+        if (hand === controllerStandard.RightHand) {
             return 1;
         }
-        if (hand === Controller.Standard.LeftHand) {
+        if (hand === controllerStandard.LeftHand) {
             return 0;
         }
         debug("handToHaptic called without a valid hand!");
@@ -917,25 +919,25 @@
     function keyPressEvent(event) {
         if ((event.text.toUpperCase() === "X") && !event.isAutoRepeat && !event.isShifted && !event.isMeta && !event.isControl
                 && !event.isAlt) {
-            updateTriggers(1.0, true, Controller.Standard.RightHand);
+            updateTriggers(1.0, true, controllerStandard.RightHand);
         }
     }
     function keyReleaseEvent(event) {
         if (event.text.toUpperCase() === "X" && !event.isAutoRepeat) {
-            updateTriggers(0.0, true, Controller.Standard.RightHand);
+            updateTriggers(0.0, true, controllerStandard.RightHand);
         }
     }
     // map controller actions
     var connectionMapping = Controller.newMapping(Script.resolvePath('') + '-grip');
-    connectionMapping.from(Controller.Standard.LeftGrip).peek().to(makeGripHandler(Controller.Standard.LeftHand));
-    connectionMapping.from(Controller.Standard.RightGrip).peek().to(makeGripHandler(Controller.Standard.RightHand));
+    connectionMapping.from(controllerStandard.LeftGrip).peek().to(makeGripHandler(controllerStandard.LeftHand));
+    connectionMapping.from(controllerStandard.RightGrip).peek().to(makeGripHandler(controllerStandard.RightHand));
 
     // setup keyboard initiation
     Controller.keyPressEvent.connect(keyPressEvent);
     Controller.keyReleaseEvent.connect(keyReleaseEvent);
 
     // Xbox controller because that is important
-    connectionMapping.from(Controller.Standard.RB).peek().to(makeGripHandler(Controller.Standard.RightHand, true));
+    connectionMapping.from(controllerStandard.RB).peek().to(makeGripHandler(controllerStandard.RightHand, true));
 
     // it is easy to forget this and waste a lot of time for nothing
     connectionMapping.enable();
diff --git a/scripts/system/miniTablet.js b/scripts/system/miniTablet.js
index 6271276584..acd0d96e9b 100644
--- a/scripts/system/miniTablet.js
+++ b/scripts/system/miniTablet.js
@@ -19,6 +19,8 @@
     Script.include("./libraries/utils.js");
     Script.include("./libraries/controllerDispatcherUtils.js");
 
+    var controllerStandard = Controller.Standard;
+
     var UI,
         ui = null,
         State,
@@ -647,15 +649,15 @@
                 now;
 
             // Shouldn't show mini tablet if hand isn't being controlled.
-            pose = Controller.getPoseValue(hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand);
+            pose = Controller.getPoseValue(hand === LEFT_HAND ? controllerStandard.LeftHand : controllerStandard.RightHand);
             show = pose.valid;
 
             // Shouldn't show mini tablet on hand if that hand's trigger or grip are pressed (i.e., laser is searching or hand 
             // is grabbing something) or the other hand's trigger is pressed unless it is pointing at the mini tablet. Allow 
             // the triggers to be pressed briefly to allow for the grabbing process.
             if (show) {
-                isLeftTriggerOff = Controller.getValue(Controller.Standard.LT) < TRIGGER_OFF_VALUE &&
-                    Controller.getValue(Controller.Standard.LeftGrip) < TRIGGER_OFF_VALUE;
+                isLeftTriggerOff = Controller.getValue(controllerStandard.LT) < TRIGGER_OFF_VALUE &&
+                    Controller.getValue(controllerStandard.LeftGrip) < TRIGGER_OFF_VALUE;
                 if (!isLeftTriggerOff) {
                     if (leftTriggerOn === 0) {
                         leftTriggerOn = Date.now();
@@ -665,8 +667,8 @@
                 } else {
                     leftTriggerOn = 0;
                 }
-                isRightTriggerOff = Controller.getValue(Controller.Standard.RT) < TRIGGER_OFF_VALUE &&
-                    Controller.getValue(Controller.Standard.RightGrip) < TRIGGER_OFF_VALUE;
+                isRightTriggerOff = Controller.getValue(controllerStandard.RT) < TRIGGER_OFF_VALUE &&
+                    Controller.getValue(controllerStandard.RightGrip) < TRIGGER_OFF_VALUE;
                 if (!isRightTriggerOff) {
                     if (rightTriggerOn === 0) {
                         rightTriggerOn = Date.now();
diff --git a/scripts/system/mod.js b/scripts/system/mod.js
index 71d2c32bac..8d443cf8c3 100644
--- a/scripts/system/mod.js
+++ b/scripts/system/mod.js
@@ -16,6 +16,8 @@
 
 Script.include("/~/system/libraries/controllers.js");
 
+var controllerStandard = Controller.Standard;
+
 // grab the toolbar
 var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
 
@@ -236,8 +238,8 @@ function makeClickHandler(hand) {
         }
     };
 }
-triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
-triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
+triggerMapping.from(controllerStandard.RTClick).peek().to(makeClickHandler(controllerStandard.RightHand));
+triggerMapping.from(controllerStandard.LTClick).peek().to(makeClickHandler(controllerStandard.LeftHand));
 
 triggerMapping.enable();
 
diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js
index 34795ab487..aaf1f1e6af 100644
--- a/scripts/system/notifications.js
+++ b/scripts/system/notifications.js
@@ -18,6 +18,8 @@
         "create/audioFeedback/audioFeedback.js"
     ]);
 
+    var controllerStandard = Controller.Standard;
+
     var NOTIFICATIONS_MESSAGE_CHANNEL = "Hifi-Notifications";
     var SETTING_ACTIVATION_SNAPSHOT_NOTIFICATIONS = "snapshotNotifications";
     var NOTIFICATION_LIFE_DURATION = 10000; //10 seconds (in millisecond) before expiration.
@@ -71,8 +73,8 @@
     }
 
     function checkHands() {
-        var myLeftHand = Controller.getPoseValue(Controller.Standard.LeftHand);
-        var myRightHand = Controller.getPoseValue(Controller.Standard.RightHand);
+        var myLeftHand = Controller.getPoseValue(controllerStandard.LeftHand);
+        var myRightHand = Controller.getPoseValue(controllerStandard.RightHand);
         var eyesPosition = MyAvatar.getEyePosition();
         var hipsPosition = MyAvatar.getJointPosition("Hips");
         var eyesRelativeHeight = eyesPosition.y - hipsPosition.y;
diff --git a/scripts/system/pal.js b/scripts/system/pal.js
index 0e4038cb01..743df2ef63 100644
--- a/scripts/system/pal.js
+++ b/scripts/system/pal.js
@@ -18,6 +18,7 @@
 //
 
 (function () { // BEGIN LOCAL_SCOPE
+var controllerStandard = Controller.Standard;
 
 var request = Script.require('request').request;
 var AppUi = Script.require('appUi');
@@ -715,10 +716,10 @@ function makePressHandler(hand) {
         handleTriggerPressed(hand, value);
     };
 }
-triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
-triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
-triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
-triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
+triggerMapping.from(controllerStandard.RTClick).peek().to(makeClickHandler(controllerStandard.RightHand));
+triggerMapping.from(controllerStandard.LTClick).peek().to(makeClickHandler(controllerStandard.LeftHand));
+triggerPressMapping.from(controllerStandard.RT).peek().to(makePressHandler(controllerStandard.RightHand));
+triggerPressMapping.from(controllerStandard.LT).peek().to(makePressHandler(controllerStandard.LeftHand));
 
 var ui;
 // Most apps can have people toggle the tablet closed and open again, and the app should remain "open" even while
diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js
index 1957ecea4d..e41b2a62a8 100644
--- a/scripts/system/tablet-ui/tabletUI.js
+++ b/scripts/system/tablet-ui/tabletUI.js
@@ -17,6 +17,8 @@
    MyAvatar, Menu, AvatarInputs, Vec3, cleanUpOldMaterialEntities */
 
 (function() { // BEGIN LOCAL_SCOPE
+    var controllerStandard = Controller.Standard;
+
     var tabletRezzed = false;
     var activeHand = null;
     var DEFAULT_WIDTH = 0.4375;
@@ -292,27 +294,27 @@
     var clickMapping = Controller.newMapping('tabletToggle-click');
     var wantsMenu = 0;
     clickMapping.from(function () { return wantsMenu; }).to(Controller.Actions.ContextMenu);
-    clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().when(Controller.Hardware.Application.LeftHandDominant).to(function (clicked) {
+    clickMapping.from(controllerStandard.RightSecondaryThumb).peek().when(Controller.Hardware.Application.LeftHandDominant).to(function (clicked) {
     if (clicked) {
-        //activeHudPoint2d(Controller.Standard.RightHand);
-        Messages.sendLocalMessage("toggleHand", Controller.Standard.RightHand);
+        //activeHudPoint2d(controllerStandard.RightHand);
+        Messages.sendLocalMessage("toggleHand", controllerStandard.RightHand);
     }
         wantsMenu = clicked;
     });
     
-    clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().when(Controller.Hardware.Application.RightHandDominant).to(function (clicked) {
+    clickMapping.from(controllerStandard.LeftSecondaryThumb).peek().when(Controller.Hardware.Application.RightHandDominant).to(function (clicked) {
         if (clicked) {
-            //activeHudPoint2d(Controller.Standard.LeftHand);
-            Messages.sendLocalMessage("toggleHand", Controller.Standard.LeftHand);
+            //activeHudPoint2d(controllerStandard.LeftHand);
+            Messages.sendLocalMessage("toggleHand", controllerStandard.LeftHand);
         }
         wantsMenu = clicked;
     });
 
-    clickMapping.from(Controller.Standard.Start).peek().to(function (clicked) {
+    clickMapping.from(controllerStandard.Start).peek().to(function (clicked) {
     if (clicked) {
         //activeHudPoint2dGamePad();
         var noHands = -1;
-        Messages.sendLocalMessage("toggleHand", Controller.Standard.LeftHand);
+        Messages.sendLocalMessage("toggleHand", controllerStandard.LeftHand);
     }
 
         wantsMenu = clicked;

From d387ea840b56018522260a089c56af7ae0a10061 Mon Sep 17 00:00:00 2001
From: ksuprynowicz <ksuprynowicz@post.pl>
Date: Fri, 1 Dec 2023 23:59:05 +0100
Subject: [PATCH 3/3] Add a warnning about Controller.Standard property

---
 interface/src/scripting/ControllerScriptingInterface.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h
index 175021e559..4128976fdc 100644
--- a/interface/src/scripting/ControllerScriptingInterface.h
+++ b/interface/src/scripting/ControllerScriptingInterface.h
@@ -216,6 +216,7 @@ class ScriptEngine;
  *
  * @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
  *     points in a {@link RouteObject} mapping. A synonym for <code>Controller.Hardware.Actions</code>.
+ *     Getting this property is computationally expensive, so it's best to cache it once on script start.
  *     <em>Read-only.</em>
  *     <p>Default mappings are provided from the <code>Controller.Hardware.Keyboard</code> and <code>Controller.Standard</code> 
  *     to actions in 
@@ -225,13 +226,16 @@ class ScriptEngine;
  *     standard.json</a>, respectively.</p>
  *
  * @property {Controller.Hardware} Hardware - Standard and hardware-specific controller and computer outputs, plus predefined 
- *     actions on Interface and the user's avatar. The outputs can be mapped to <code>Actions</code> or functions in a 
+ *     actions on Interface and the user's avatar. Getting this property is computationally expensive, so it's best to cache it
+ *     instead of calling on every update.
+ *     The outputs can be mapped to <code>Actions</code> or functions in a
  *     {@link RouteObject} mapping. Additionally, hardware-specific controller outputs can be mapped to 
  *     <code>Controller.Standard</code> controller outputs. <em>Read-only.</em>
  *
  * @property {Controller.Standard} Standard - Standard controller outputs that can be mapped to <code>Actions</code> or 
  *     functions in a {@link RouteObject} mapping. <em>Read-only.</em>
- *     <p>Each hardware device has a mapping from its outputs to <code>Controller.Standard</code> items, specified in a JSON file. 
+ *     <p>Each hardware device has a mapping from its outputs to <code>Controller.Standard</code> items, specified in a JSON file.
+ *     Getting this property is computationally expensive, so it's best to cache it once on script start.
  *     For example, <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/leapmotion.json">
  *     leapmotion.json</a> and 
  *     <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/vive.json">vive.json</a>.</p>