From a9048fa43d9eee327f36f94baf5e024978651d00 Mon Sep 17 00:00:00 2001 From: Yves Date: Sun, 20 Jul 2014 19:45:18 +0000 Subject: [PATCH] Adds support for passing JS::HandleValue to SetProperty and CallFunctionVoid without using ugly casing. Also includes one little "demo-usecase", but additional code will be changed to use that in future commits. Refs #2415 Refs #2462 This was SVN commit r15542. --- source/ps/SavedGame.cpp | 6 ++-- source/scriptinterface/ScriptInterface.h | 45 +++++++++++++++++++----- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp index fc0efee3ea..7b75534f01 100644 --- a/source/ps/SavedGame.cpp +++ b/source/ps/SavedGame.cpp @@ -55,6 +55,8 @@ Status SavedGames::SavePrefix(const std::wstring& prefix, const std::wstring& de Status SavedGames::Save(const std::wstring& name, const std::wstring& description, CSimulation2& simulation, shared_ptr guiMetadataClone, int playerID) { + JSContext* cx = simulation.GetScriptInterface().GetContext(); + JSAutoRequest rq(cx); // Determine the filename to save under const VfsPath basenameFormat(L"saves/" + name); const VfsPath filename = basenameFormat.ChangeExtension(L".0adsave"); @@ -87,7 +89,7 @@ Status SavedGames::Save(const std::wstring& name, const std::wstring& descriptio simulation.GetScriptInterface().SetProperty(metadata.get(), "player", playerID); simulation.GetScriptInterface().SetProperty(metadata.get(), "initAttributes", simulation.GetInitAttributes()); - CScriptVal guiMetadata = simulation.GetScriptInterface().ReadStructuredClone(guiMetadataClone); + JS::RootedValue guiMetadata(cx, simulation.GetScriptInterface().ReadStructuredClone(guiMetadataClone)); // get some camera data CScriptVal cameraMetadata; @@ -98,7 +100,7 @@ Status SavedGames::Save(const std::wstring& name, const std::wstring& descriptio simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "RotX", g_Game->GetView()->GetCameraRotX()); simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "RotY", g_Game->GetView()->GetCameraRotY()); simulation.GetScriptInterface().SetProperty(cameraMetadata.get(), "Zoom", g_Game->GetView()->GetCameraZoom()); - simulation.GetScriptInterface().SetProperty(guiMetadata.get(), "camera", cameraMetadata); + simulation.GetScriptInterface().SetProperty(guiMetadata, "camera", cameraMetadata); simulation.GetScriptInterface().SetProperty(metadata.get(), "gui", guiMetadata); simulation.GetScriptInterface().SetProperty(metadata.get(), "description", description); diff --git a/source/scriptinterface/ScriptInterface.h b/source/scriptinterface/ScriptInterface.h index ff64d2f1d6..2d1c12794b 100644 --- a/source/scriptinterface/ScriptInterface.h +++ b/source/scriptinterface/ScriptInterface.h @@ -367,6 +367,18 @@ public: jsval ReadStructuredClone(const shared_ptr& ptr); private: + + /** + * Converts |a| if needed and assigns it to |handle|. + * This is meant for use in other templates where we want to use the same code for JS::RootedValue&/JS::HandleValue and + * other types. Note that functions are meant to take JS::HandleValue instead of JS::RootedValue&, but this implicit + * conversion does not work for templates (exact type matches required for type deduction). + * A similar functionality could also be implemented as a ToJSVal specialization. The current approach was preferred + * because "conversions" from JS::HandleValue to JS::MutableHandleValue are unusual and should not happen "by accident". + */ + template + void AssignOrToJSVal(JS::MutableHandleValue handle, const T& a); + bool CallFunction_(JS::HandleValue val, const char* name, uint argc, jsval* argv, JS::MutableHandleValue ret); bool Eval_(const char* code, JS::MutableHandleValue ret); bool Eval_(const wchar_t* code, JS::MutableHandleValue ret); @@ -414,6 +426,18 @@ public: // Implement those declared functions #include "NativeWrapperDefns.h" +template +inline void ScriptInterface::AssignOrToJSVal(JS::MutableHandleValue handle, const T& a) +{ + ToJSVal(GetContext(), handle, a); +} + +template<> +inline void ScriptInterface::AssignOrToJSVal(JS::MutableHandleValue handle, const JS::RootedValue& a) +{ + handle.set(a); +} + template bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0) { @@ -423,7 +447,7 @@ bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0 JS::RootedValue val1(cx, val); JS::AutoValueVector argv(cx); argv.resize(1); - ToJSVal(cx, argv.handleAt(0), a0); + AssignOrToJSVal(argv.handleAt(0), a0); return CallFunction_(val1, name, 1, argv.begin(), &jsRet); } @@ -436,8 +460,8 @@ bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0 JS::RootedValue val1(cx, val); JS::AutoValueVector argv(cx); argv.resize(2); - ToJSVal(cx, argv.handleAt(0), a0); - ToJSVal(cx, argv.handleAt(1), a1); + AssignOrToJSVal(argv.handleAt(0), a0); + AssignOrToJSVal(argv.handleAt(1), a1); return CallFunction_(val1, name, 2, argv.begin(), &jsRet); } @@ -450,9 +474,9 @@ bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0 JS::RootedValue val1(cx, val); JS::AutoValueVector argv(cx); argv.resize(3); - ToJSVal(cx, argv.handleAt(0), a0); - ToJSVal(cx, argv.handleAt(1), a1); - ToJSVal(cx, argv.handleAt(2), a2); + AssignOrToJSVal(argv.handleAt(0), a0); + AssignOrToJSVal(argv.handleAt(1), a1); + AssignOrToJSVal(argv.handleAt(2), a2); return CallFunction_(val1, name, 3, argv.begin(), &jsRet); } @@ -470,14 +494,17 @@ bool ScriptInterface::SetProperty(jsval obj, const char* name, const T& value, b { JSAutoRequest rq(GetContext()); JS::RootedValue val(GetContext()); - ToJSVal(GetContext(), &val, value); + AssignOrToJSVal(&val, value); return SetProperty_(obj, name, val, readonly, enumerate); } template bool ScriptInterface::SetProperty(jsval obj, const wchar_t* name, const T& value, bool readonly, bool enumerate) { - return SetProperty_(obj, name, ToJSVal(GetContext(), value), readonly, enumerate); + JSAutoRequest rq(GetContext()); + JS::RootedValue val(GetContext()); + AssignOrToJSVal(&val, value); + return SetProperty_(obj, name, val, readonly, enumerate); } template @@ -485,7 +512,7 @@ bool ScriptInterface::SetPropertyInt(jsval obj, int name, const T& value, bool r { JSAutoRequest rq(GetContext()); JS::RootedValue val(GetContext()); - ToJSVal(GetContext(), &val, value); + AssignOrToJSVal(&val, value); return SetPropertyInt_(obj, name, val, readonly, enumerate); }