Index: ps/trunk/source/gui/GUIManager.cpp =================================================================== --- ps/trunk/source/gui/GUIManager.cpp +++ ps/trunk/source/gui/GUIManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -347,7 +347,7 @@ JSContext* cx = top()->GetScriptInterface()->GetContext(); JSAutoRequest rq(cx); JS::RootedValue global(cx, top()->GetGlobalObject()); - if (top()->GetScriptInterface()->CallFunction(global, "handleInputBeforeGui", *ev, top()->FindObjectUnderMouse(), handled)) + if (top()->GetScriptInterface()->CallFunction(global, "handleInputBeforeGui", handled, *ev, top()->FindObjectUnderMouse())) if (handled) return IN_HANDLED; } @@ -366,7 +366,7 @@ JS::RootedValue global(cx, top()->GetGlobalObject()); PROFILE("handleInputAfterGui"); - if (top()->GetScriptInterface()->CallFunction(global, "handleInputAfterGui", *ev, handled)) + if (top()->GetScriptInterface()->CallFunction(global, "handleInputAfterGui", handled, *ev)) if (handled) return IN_HANDLED; } Index: ps/trunk/source/scriptinterface/NativeWrapperDecls.h =================================================================== --- ps/trunk/source/scriptinterface/NativeWrapperDecls.h +++ ps/trunk/source/scriptinterface/NativeWrapperDecls.h @@ -30,10 +30,6 @@ #define NUMBERED_LIST_TAIL_MAYBE_REF(z, i, data) , typename MaybeRef::Type #define NUMBERED_LIST_BALANCED(z, i, data) BOOST_PP_COMMA_IF(i) data##i #define NUMBERED_LIST_BALANCED_MAYBE_REF(z, i, data) BOOST_PP_COMMA_IF(i) typename MaybeRef::Type -// Some other things -#define TYPED_ARGS(z, i, data) , T##i a##i -#define TYPED_ARGS_MAYBE_REF(z, i, data) , typename MaybeRef::Type a##i -#define TYPED_ARGS_CONST_REF(z, i, data) , const T##i& a##i // TODO: We allow optional parameters when the C++ type can be converted from JS::UndefinedValue. // FromJSVal is expected to either set a##i or return false (otherwise we could get undefined @@ -54,23 +50,17 @@ // List-generating macros, named roughly after their first list item #define TYPENAME_T0_HEAD(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_HEAD, typename T) // "typename T0, typename T1, " -#define TYPENAME_T0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, typename T) // ", typename T0, typename T1" #define T0(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_BALANCED, T) // "T0, T1" #define T0_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_BALANCED_MAYBE_REF, T) // "const T0&, T1" -#define T0_HEAD(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_HEAD, T) // "T0, T1, " #define T0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, T) // ", T0, T1" #define T0_TAIL_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL_MAYBE_REF, T) // ", const T0&, T1" -#define T0_A0(z, i) BOOST_PP_REPEAT_##z (i, TYPED_ARGS, ~) // ",T0 a0, T1 a1" -#define T0_A0_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, TYPED_ARGS_MAYBE_REF, ~) // ",const T0& a0, T1 a1" -#define T0_A0_TAIL_CONST_REF(z, i) BOOST_PP_REPEAT_##z (i, TYPED_ARGS_CONST_REF, ~) // ", const T0& a0, const T1& a1" -#define A0(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_BALANCED, a) // "a0, a1" #define A0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, a) // ", a0, a1" // Define RegisterFunction #define OVERLOADS(z, i, data) \ template \ void RegisterFunction(const char* name) { \ - Register(name, call, nargs<0 T0_TAIL(z,i)>()); \ + Register(name, call, nargs()); \ } BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) #undef OVERLOADS @@ -98,33 +88,24 @@ #undef OVERLOADS // Argument-number counter -#define OVERLOADS(z, i, data) \ - template /* add a dummy parameter so we still compile with 0 template args */ \ - static size_t nargs() { return i; } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS +template +static size_t nargs() { return sizeof...(Ts); } // Call the named property on the given object -#define OVERLOADS(z, i, data) \ - template \ - bool CallFunction(JS::HandleValue val, const char* name T0_A0_TAIL_CONST_REF(z,i), R& ret) const; -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS +template +bool CallFunction(JS::HandleValue val, const char* name, R& ret, const Ts&... params) const; // Implicit conversion from JS::Rooted* to JS::MutableHandle does not work with template argument deduction // (only exact type matches allowed). We need this overload to allow passing Rooted* using the & operator // (as people would expect it to work based on the SpiderMonkey rooting guide). -#define OVERLOADS(z, i, data) \ - template \ - bool CallFunction(JS::HandleValue val, const char* name T0_A0_TAIL_CONST_REF(z,i), JS::Rooted* ret) const; -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS +template +bool CallFunction(JS::HandleValue val, const char* name, JS::Rooted* ret, const Ts&... params) const; // This overload is for the case when a JS::MutableHandle type gets passed into CallFunction directly and // without requiring implicit conversion. -#define OVERLOADS(z, i, data) \ - template \ - bool CallFunction(JS::HandleValue val, const char* name T0_A0_TAIL_CONST_REF(z,i), JS::MutableHandle ret) const; -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS +template +bool CallFunction(JS::HandleValue val, const char* name, JS::MutableHandle ret, const Ts&... params) const; +// Call the named property on the given object, with void return type +template \ +bool CallFunctionVoid(JS::HandleValue val, const char* name, const Ts&... params) const; Index: ps/trunk/source/scriptinterface/NativeWrapperDefns.h =================================================================== --- ps/trunk/source/scriptinterface/NativeWrapperDefns.h +++ ps/trunk/source/scriptinterface/NativeWrapperDefns.h @@ -57,10 +57,8 @@ // remove them from here and check if this causes error C2244 when compiling. #undef NUMBERED_LIST_TAIL_MAYBE_REF #undef NUMBERED_LIST_BALANCED_MAYBE_REF -#undef TYPED_ARGS_MAYBE_REF #define NUMBERED_LIST_TAIL_MAYBE_REF(z, i, data) , typename ScriptInterface::MaybeRef::Type #define NUMBERED_LIST_BALANCED_MAYBE_REF(z, i, data) BOOST_PP_COMMA_IF(i) typename ScriptInterface::MaybeRef::Type -#define TYPED_ARGS_MAYBE_REF(z, i, data) , typename ScriptInterface::MaybeRef::Type a##i // (NativeWrapperDecls.h set up a lot of the macros we use here) @@ -69,52 +67,46 @@ // Templated on the return type so void can be handled separately template -struct ScriptInterface_NativeWrapper { - #define OVERLOADS(z, i, data) \ - template \ - static void call(JSContext* cx, JS::MutableHandleValue rval, F fptr T0_A0_MAYBE_REF(z,i)) { \ - ScriptInterface::AssignOrToJSValUnrooted(cx, rval, fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx) A0_TAIL(z,i))); \ - } - - BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) - #undef OVERLOADS +struct ScriptInterface_NativeWrapper +{ + template + static void call(JSContext* cx, JS::MutableHandleValue rval, F fptr, Ts... params) + { + ScriptInterface::AssignOrToJSValUnrooted(cx, rval, fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx), params...)); + } }; // Overloaded to ignore the return value from void functions template <> -struct ScriptInterface_NativeWrapper { - #define OVERLOADS(z, i, data) \ - template \ - static void call(JSContext* cx, JS::MutableHandleValue /*rval*/, F fptr T0_A0_MAYBE_REF(z,i)) { \ - fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx) A0_TAIL(z,i)); \ - } - BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) - #undef OVERLOADS +struct ScriptInterface_NativeWrapper +{ + template + static void call(JSContext* cx, JS::MutableHandleValue UNUSED(rval), F fptr, Ts... params) + { + fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx), params...); + } }; // Same idea but for method calls: template -struct ScriptInterface_NativeMethodWrapper { - #define OVERLOADS(z, i, data) \ - template \ - static void call(JSContext* cx, JS::MutableHandleValue rval, TC* c, F fptr T0_A0_MAYBE_REF(z,i)) { \ - ScriptInterface::AssignOrToJSValUnrooted(cx, rval, (c->*fptr)( A0(z,i) )); \ - } - - BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) - #undef OVERLOADS +struct ScriptInterface_NativeMethodWrapper +{ + template + static void call(JSContext* cx, JS::MutableHandleValue rval, TC* c, F fptr, Ts... params) + { + ScriptInterface::AssignOrToJSValUnrooted(cx, rval, (c->*fptr)(params...)); + } }; template -struct ScriptInterface_NativeMethodWrapper { - #define OVERLOADS(z, i, data) \ - template \ - static void call(JSContext* /*cx*/, JS::MutableHandleValue /*rval*/, TC* c, F fptr T0_A0_MAYBE_REF(z,i)) { \ - (c->*fptr)( A0(z,i) ); \ - } - BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) - #undef OVERLOADS +struct ScriptInterface_NativeMethodWrapper +{ + template + static void call(JSContext* UNUSED(cx), JS::MutableHandleValue UNUSED(rval), TC* c, F fptr, Ts... params) + { + (c->*fptr)(params...); + } }; // JSFastNative-compatible function that wraps the function identified in the template argument list @@ -126,7 +118,7 @@ JSAutoRequest rq(cx); \ BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \ JS::RootedValue rval(cx); \ - ScriptInterface_NativeWrapper::template call(cx, &rval, fptr A0_TAIL(z,i)); \ + ScriptInterface_NativeWrapper::template call(cx, &rval, fptr A0_TAIL(z,i)); \ args.rval().set(rval); \ return !ScriptInterface::IsExceptionPending(cx); \ } @@ -146,7 +138,7 @@ if (! c) return false; \ BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \ JS::RootedValue rval(cx); \ - ScriptInterface_NativeMethodWrapper::template call(cx, &rval, c, fptr A0_TAIL(z,i)); \ + ScriptInterface_NativeMethodWrapper::template call(cx, &rval, c, fptr A0_TAIL(z,i)); \ args.rval().set(rval); \ return !ScriptInterface::IsExceptionPending(cx); \ } @@ -166,65 +158,77 @@ if (! c) return false; \ BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \ JS::RootedValue rval(cx); \ - ScriptInterface_NativeMethodWrapper::template call(cx, &rval, c, fptr A0_TAIL(z,i)); \ + ScriptInterface_NativeMethodWrapper::template call(cx, &rval, c, fptr A0_TAIL(z,i)); \ args.rval().set(rval); \ return !ScriptInterface::IsExceptionPending(cx); \ } BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) #undef OVERLOADS -#define ASSIGN_OR_TO_JS_VAL(z, i, data) AssignOrToJSVal(cx, argv[i], a##i); +template +static void AssignOrToJSValHelper(JSContext* cx, JS::AutoValueVector& argv, const T& a, const Ts&... params) +{ + ScriptInterface::AssignOrToJSVal(cx, argv[i], a); + AssignOrToJSValHelper(cx, argv, params...); +} -#define OVERLOADS(z, i, data) \ -template \ -bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name T0_A0_TAIL_CONST_REF(z,i), R& ret) const \ -{ \ - JSContext* cx = GetContext(); \ - JSAutoRequest rq(cx); \ - JS::RootedValue jsRet(cx); \ - JS::AutoValueVector argv(cx); \ - argv.resize(i); \ - BOOST_PP_REPEAT_##z (i, ASSIGN_OR_TO_JS_VAL, ~) \ - bool ok = CallFunction_(val, name, argv, &jsRet); \ - if (!ok) \ - return false; \ - return FromJSVal(cx, jsRet, ret); \ +template +static void AssignOrToJSValHelper(JSContext* UNUSED(cx), JS::AutoValueVector& UNUSED(argv)) +{ + cassert(sizeof...(Ts) == 0); + // Nop, for terminating the template recursion. } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS -#define OVERLOADS(z, i, data) \ -template \ -bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name T0_A0_TAIL_CONST_REF(z,i), JS::Rooted* ret) const \ -{ \ - JSContext* cx = GetContext(); \ - JSAutoRequest rq(cx); \ - JS::MutableHandle jsRet(ret); \ - JS::AutoValueVector argv(cx); \ - argv.resize(i); \ - BOOST_PP_REPEAT_##z (i, ASSIGN_OR_TO_JS_VAL, ~) \ - return CallFunction_(val, name, argv, jsRet); \ +template +bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, R& ret, const Ts&... params) const +{ + JSContext* cx = GetContext(); + JSAutoRequest rq(cx); + JS::RootedValue jsRet(cx); + JS::AutoValueVector argv(cx); + argv.resize(sizeof...(Ts)); + AssignOrToJSValHelper<0>(cx, argv, params...); + bool ok = CallFunction_(val, name, argv, &jsRet); + if (!ok) + return false; + return FromJSVal(cx, jsRet, ret); } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS -#define OVERLOADS(z, i, data) \ -template \ -bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name T0_A0_TAIL_CONST_REF(z,i), JS::MutableHandle ret) const \ -{ \ - JSContext* cx = GetContext(); \ - JSAutoRequest rq(cx); \ - JS::AutoValueVector argv(cx); \ - argv.resize(i); \ - BOOST_PP_REPEAT_##z (i, ASSIGN_OR_TO_JS_VAL, ~) \ - bool ok = CallFunction_(val, name, argv, ret); \ - if (!ok) \ - return false; \ - return true; \ +template +bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, JS::Rooted* ret, const Ts&... params) const +{ + JSContext* cx = GetContext(); + JSAutoRequest rq(cx); + JS::MutableHandle jsRet(ret); + JS::AutoValueVector argv(cx); + argv.resize(sizeof...(Ts)); + AssignOrToJSValHelper<0>(cx, argv, params...); + return CallFunction_(val, name, argv, jsRet); +} + +template +bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, JS::MutableHandle ret, const Ts&... params) const +{ + JSContext* cx = GetContext(); + JSAutoRequest rq(cx); + JS::AutoValueVector argv(cx); + argv.resize(sizeof...(Ts)); + AssignOrToJSValHelper<0>(cx, argv, params...); + return CallFunction_(val, name, argv, ret); +} + +// Call the named property on the given object, with void return type +template +bool ScriptInterface::CallFunctionVoid(JS::HandleValue val, const char* name, const Ts&... params) const +{ + JSContext* cx = GetContext(); + JSAutoRequest rq(cx); + JS::RootedValue jsRet(cx); + JS::AutoValueVector argv(cx); + argv.resize(sizeof...(Ts)); + AssignOrToJSValHelper<0>(cx, argv, params...); + return CallFunction_(val, name, argv, &jsRet); } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS -#undef ASSIGN_OR_TO_JS_VAL // Clean up our mess #undef NUMBERED_LIST_HEAD @@ -232,19 +236,10 @@ #undef NUMBERED_LIST_TAIL_MAYBE_REF #undef NUMBERED_LIST_BALANCED #undef NUMBERED_LIST_BALANCED_MAYBE_REF -#undef TYPED_ARGS -#undef TYPED_ARGS_MAYBE_REF -#undef TYPED_ARGS_CONST_REF #undef CONVERT_ARG #undef TYPENAME_T0_HEAD -#undef TYPENAME_T0_TAIL #undef T0 #undef T0_MAYBE_REF -#undef T0_HEAD #undef T0_TAIL #undef T0_TAIL_MAYBE_REF -#undef T0_A0 -#undef T0_A0_MAYBE_REF -#undef T0_A0_TAIL_CONST_REF -#undef A0 #undef A0_TAIL Index: ps/trunk/source/scriptinterface/ScriptInterface.h =================================================================== --- ps/trunk/source/scriptinterface/ScriptInterface.h +++ ps/trunk/source/scriptinterface/ScriptInterface.h @@ -131,29 +131,6 @@ */ void CallConstructor(JS::HandleValue ctor, JS::HandleValueArray argv, JS::MutableHandleValue out); - /** - * Call the named property on the given object, with void return type and 0 arguments - */ - bool CallFunctionVoid(JS::HandleValue val, const char* name); - - /** - * Call the named property on the given object, with void return type and 1 argument - */ - template - bool CallFunctionVoid(JS::HandleValue val, const char* name, const T0& a0); - - /** - * Call the named property on the given object, with void return type and 2 arguments - */ - template - bool CallFunctionVoid(JS::HandleValue val, const char* name, const T0& a0, const T1& a1); - - /** - * Call the named property on the given object, with void return type and 3 arguments - */ - template - bool CallFunctionVoid(JS::HandleValue val, const char* name, const T0& a0, const T1& a1, const T2& a2); - JSObject* CreateCustomObject(const std::string & typeName) const; void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); @@ -443,8 +420,20 @@ // template // static JSNative callMethodConst; // - // template + // template // static size_t nargs(); + // + // template + // bool CallFunction(JS::HandleValue val, const char* name, R& ret, const T0&...) const; + // + // template + // bool CallFunction(JS::HandleValue val, const char* name, JS::Rooted* ret, const T0&...) const; + // + // template + // bool CallFunction(JS::HandleValue val, const char* name, JS::MutableHandle ret, const T0&...) const; + // + // template + // bool CallFunctionVoid(JS::HandleValue val, const char* name, const T0&...) const; }; // Implement those declared functions @@ -495,45 +484,6 @@ return val; } -template -bool ScriptInterface::CallFunctionVoid(JS::HandleValue val, const char* name, const T0& a0) -{ - JSContext* cx = GetContext(); - JSAutoRequest rq(cx); - JS::RootedValue jsRet(cx); - JS::AutoValueVector argv(cx); - argv.resize(1); - AssignOrToJSVal(cx, argv[0], a0); - return CallFunction_(val, name, argv, &jsRet); -} - -template -bool ScriptInterface::CallFunctionVoid(JS::HandleValue val, const char* name, const T0& a0, const T1& a1) -{ - JSContext* cx = GetContext(); - JSAutoRequest rq(cx); - JS::RootedValue jsRet(cx); - JS::AutoValueVector argv(cx); - argv.resize(2); - AssignOrToJSVal(cx, argv[0], a0); - AssignOrToJSVal(cx, argv[1], a1); - return CallFunction_(val, name, argv, &jsRet); -} - -template -bool ScriptInterface::CallFunctionVoid(JS::HandleValue val, const char* name, const T0& a0, const T1& a1, const T2& a2) -{ - JSContext* cx = GetContext(); - JSAutoRequest rq(cx); - JS::RootedValue jsRet(cx); - JS::AutoValueVector argv(cx); - argv.resize(3); - AssignOrToJSVal(cx, argv[0], a0); - AssignOrToJSVal(cx, argv[1], a1); - AssignOrToJSVal(cx, argv[2], a2); - return CallFunction_(val, name, argv, &jsRet); -} - template bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace) { Index: ps/trunk/source/scriptinterface/ScriptInterface.cpp =================================================================== --- ps/trunk/source/scriptinterface/ScriptInterface.cpp +++ ps/trunk/source/scriptinterface/ScriptInterface.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -562,14 +562,6 @@ return JS_NewObjectWithGivenProto(m->m_cx, it->second.m_Class, prototype); } -bool ScriptInterface::CallFunctionVoid(JS::HandleValue val, const char* name) -{ - JSAutoRequest rq(m->m_cx); - JS::RootedValue jsRet(m->m_cx); - return CallFunction_(val, name, JS::HandleValueArray::empty(), &jsRet); -} - - bool ScriptInterface::CallFunction_(JS::HandleValue val, const char* name, JS::HandleValueArray argv, JS::MutableHandleValue ret) const { JSAutoRequest rq(m->m_cx); Index: ps/trunk/source/scriptinterface/tests/test_ScriptConversions.h =================================================================== --- ps/trunk/source/scriptinterface/tests/test_ScriptConversions.h +++ ps/trunk/source/scriptinterface/tests/test_ScriptConversions.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -45,7 +45,7 @@ // since they might not be objects. So just use uneval. std::string source; JS::RootedValue global(cx, script.GetGlobalObject()); - TS_ASSERT(script.CallFunction(global, "uneval", v1, source)); + TS_ASSERT(script.CallFunction(global, "uneval", source, v1)); TS_ASSERT_STR_EQUALS(source, expected); } @@ -63,7 +63,7 @@ std::string source; JS::RootedValue global(cx, script.GetGlobalObject()); - TS_ASSERT(script.CallFunction(global, "uneval", v1, source)); + TS_ASSERT(script.CallFunction(global, "uneval", source, v1)); if (expected) TS_ASSERT_STR_EQUALS(source, expected); @@ -89,12 +89,12 @@ T r; JS::RootedValue r1(cx); - TS_ASSERT(script.CallFunction(u1, func.c_str(), v1, r)); + TS_ASSERT(script.CallFunction(u1, func.c_str(), r, v1)); ScriptInterface::ToJSVal(cx, &r1, r); std::string source; JS::RootedValue global(cx, script.GetGlobalObject()); - TS_ASSERT(script.CallFunction(global, "uneval", r1, source)); + TS_ASSERT(script.CallFunction(global, "uneval", source, r1)); TS_ASSERT_STR_EQUALS(source, expected); } Index: ps/trunk/source/scriptinterface/tests/test_ScriptInterface.h =================================================================== --- ps/trunk/source/scriptinterface/tests/test_ScriptInterface.h +++ ps/trunk/source/scriptinterface/tests/test_ScriptInterface.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -170,7 +170,7 @@ TS_ASSERT_EQUALS(4, nbr); // CallFunction const JS::RootedValue& parameter overload - script.CallFunction(val, "add", nbrVal, nbr); + script.CallFunction(val, "add", nbr, nbrVal); TS_ASSERT_EQUALS(7, nbr); // GetProperty JS::RootedValue* overload @@ -202,7 +202,7 @@ TS_ASSERT_EQUALS(4, nbr); // CallFunction const JS::HandleValue& parameter overload - script.CallFunction(val, "add", nbrVal, nbr); + script.CallFunction(val, "add", nbr, nbrVal); TS_ASSERT_EQUALS(7, nbr); // GetProperty JS::MutableHandleValue overload Index: ps/trunk/source/simulation2/components/ICmpAIInterface.cpp =================================================================== --- ps/trunk/source/simulation2/components/ICmpAIInterface.cpp +++ ps/trunk/source/simulation2/components/ICmpAIInterface.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -32,11 +32,11 @@ virtual void GetRepresentation(JS::MutableHandleValue ret) { - return m_Script.CallRef("GetRepresentation", ret); + m_Script.CallRef("GetRepresentation", ret); } virtual void GetFullRepresentation(JS::MutableHandleValue ret, bool flushEvents = false) { - return m_Script.CallRef("GetFullRepresentation",flushEvents, ret); + m_Script.CallRef("GetFullRepresentation", ret, flushEvents); } }; Index: ps/trunk/source/simulation2/components/ICmpDataTemplateManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/ICmpDataTemplateManager.cpp +++ ps/trunk/source/simulation2/components/ICmpDataTemplateManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ virtual void GetAllTechs(JS::MutableHandleValue ret) { - return m_Script.CallRef("GetAllTechs", ret); + m_Script.CallRef("GetAllTechs", ret); } }; Index: ps/trunk/source/simulation2/components/ICmpGuiInterface.cpp =================================================================== --- ps/trunk/source/simulation2/components/ICmpGuiInterface.cpp +++ ps/trunk/source/simulation2/components/ICmpGuiInterface.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ virtual void ScriptCall(int player, const std::wstring& cmd, JS::HandleValue data, JS::MutableHandleValue ret) { - m_Script.CallRef("ScriptCall", player, cmd, data, ret); + m_Script.CallRef("ScriptCall", ret, player, cmd, data); } }; Index: ps/trunk/source/simulation2/scripting/ScriptComponent.h =================================================================== --- ps/trunk/source/simulation2/scripting/ScriptComponent.h +++ ps/trunk/source/simulation2/scripting/ScriptComponent.h @@ -22,10 +22,6 @@ #include "ps/CLogger.h" -#include -#include -#include - class CSimContext; class CParamNode; class ISerializer; @@ -33,6 +29,7 @@ class CComponentTypeScript { + NONCOPYABLE(CComponentTypeScript); public: CComponentTypeScript(ScriptInterface& scriptInterface, JS::HandleValue instance); @@ -45,43 +42,30 @@ void Serialize(ISerializer& serialize); void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize, entity_id_t ent); - // Use Boost.PP to define: - // template R Call(const char* funcname) const; - // template R Call(const char* funcname, const T0& a0) const; - // ... - // template void CallRef(const char* funcname, R ret) const; - // template void CallRef(const char* funcname, const T0& a0, R ret) const; - // ... - // void CallVoid(const char* funcname) const; - // template void CallVoid(const char* funcname, const T0& a0) const; - // ... - -// CallRef is mainly used for returning script values with correct stack rooting. -#define OVERLOADS(z, i, data) \ - template \ - R Call(const char* funcname BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a)) const \ - { \ - R ret; \ - if (m_ScriptInterface.CallFunction(m_Instance, funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \ - return ret; \ - LOGERROR("Error calling component script function %s", funcname); \ - return R(); \ - } \ - template \ - void CallRef(const char* funcname BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a), R ret) const \ - { \ - if (!m_ScriptInterface.CallFunction(m_Instance, funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \ - LOGERROR("Error calling component script function %s", funcname); \ - } \ - BOOST_PP_IF(i, template<, ) BOOST_PP_ENUM_PARAMS(i, typename T) BOOST_PP_IF(i, >, ) \ - void CallVoid(const char* funcname BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a)) const \ - { \ - if (m_ScriptInterface.CallFunctionVoid(m_Instance, funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a))) \ - return; \ - LOGERROR("Error calling component script function %s", funcname); \ + template + R Call(const char* funcname, const Ts&... params) const + { + R ret; + if (m_ScriptInterface.CallFunction(m_Instance, funcname, ret, params...)) + return ret; + LOGERROR("Error calling component script function %s", funcname); + return R(); + } + + // CallRef is mainly used for returning script values with correct stack rooting. + template + void CallRef(const char* funcname, R ret, const Ts&... params) const + { + if (!m_ScriptInterface.CallFunction(m_Instance, funcname, ret, params...)) + LOGERROR("Error calling component script function %s", funcname); + } + + template + void CallVoid(const char* funcname, const Ts&... params) const + { + if (!m_ScriptInterface.CallFunctionVoid(m_Instance, funcname, params...)) + LOGERROR("Error calling component script function %s", funcname); } -BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) -#undef OVERLOADS private: ScriptInterface& m_ScriptInterface; @@ -89,8 +73,6 @@ bool m_HasCustomSerialize; bool m_HasCustomDeserialize; bool m_HasNullSerialize; - - NONCOPYABLE(CComponentTypeScript); }; #endif // INCLUDED_SCRIPTCOMPONENT