1
0
forked from 0ad/0ad

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.
This commit is contained in:
Yves 2014-07-20 19:45:18 +00:00
parent 31f9ca9ebf
commit a9048fa43d
2 changed files with 40 additions and 11 deletions

View File

@ -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<ScriptInterface::StructuredClone> 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);

View File

@ -367,6 +367,18 @@ public:
jsval ReadStructuredClone(const shared_ptr<StructuredClone>& 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 <typename T>
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<typename T>
inline void ScriptInterface::AssignOrToJSVal(JS::MutableHandleValue handle, const T& a)
{
ToJSVal(GetContext(), handle, a);
}
template<>
inline void ScriptInterface::AssignOrToJSVal<JS::RootedValue>(JS::MutableHandleValue handle, const JS::RootedValue& a)
{
handle.set(a);
}
template<typename T0>
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<typename T>
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<typename T>
@ -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);
}