mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
Refactor all usage of RegisterFunction to ScriptFunction::Register
- Replace ScriptInterface::RegisterFunction with
ScriptFunction::Register
- Mostly removing unused cmpPrivate*
- Some usage introduces specific getters (mapgenerator, AIWorker,
XmppClient,...)
- Several passthrough functions are simply removed in favour of calling
the original, reducing duplication
- Make use of ScriptRequest/ScriptInterface capabilities where
relevant.
- Make JSI_* headers only expose necessary functions, lightening them
considerably and reducing duplication
- Reuse namespaces in JSI_* implementations directly, reducing visual
noise there
Follows f3aedf88a6
Differential Revision: https://code.wildfiregames.com/D3626
This was SVN commit r24983.
This commit is contained in:
@@ -56,16 +56,6 @@ template <typename T> struct MaybeRef;
|
||||
#define T0_TAIL_MAYBE_REF(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL_MAYBE_REF, T) // ", const T0&, T1"
|
||||
#define A0_TAIL(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_TAIL, a) // ", a0, a1"
|
||||
|
||||
// Define RegisterFunction<TR, T0..., f>
|
||||
#define OVERLOADS(z, i, data) \
|
||||
template <typename R, TYPENAME_T0_HEAD(z,i) R (*fptr) ( ScriptInterface::CmptPrivate* T0_TAIL_MAYBE_REF(z,i) )> \
|
||||
void RegisterFunction(const char* name) const \
|
||||
{ \
|
||||
Register(name, call<R T0_TAIL(z,i), fptr>, nargs<T0(z,i)>()); \
|
||||
}
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
|
||||
// JSFastNative-compatible function that wraps the function identified in the template argument list
|
||||
// (Definition comes later, since it depends on some things we haven't defined yet)
|
||||
#define OVERLOADS(z, i, data) \
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "FunctionWrapper.h"
|
||||
#include "ScriptContext.h"
|
||||
#include "ScriptExtraHeaders.h"
|
||||
#include "ScriptInterface.h"
|
||||
@@ -55,7 +56,6 @@ struct ScriptInterface_impl
|
||||
{
|
||||
ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context);
|
||||
~ScriptInterface_impl();
|
||||
void Register(const char* name, JSNative fptr, uint nargs) const;
|
||||
|
||||
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted
|
||||
// members have to be called before the context destructor.
|
||||
@@ -176,107 +176,77 @@ bool error(JSContext* cx, uint argc, JS::Value* vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deepcopy(JSContext* cx, uint argc, JS::Value* vp)
|
||||
JS::Value deepcopy(const ScriptRequest& rq, JS::HandleValue val)
|
||||
{
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
if (args.length() < 1)
|
||||
if (val.isNullOrUndefined())
|
||||
{
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
ScriptException::Raise(rq, "deepcopy requires one argument.");
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
JS::RootedValue ret(cx);
|
||||
if (!JS_StructuredClone(rq.cx, args[0], &ret, NULL, NULL))
|
||||
return false;
|
||||
|
||||
args.rval().set(ret);
|
||||
return true;
|
||||
JS::RootedValue ret(rq.cx);
|
||||
if (!JS_StructuredClone(rq.cx, val, &ret, NULL, NULL))
|
||||
{
|
||||
ScriptException::Raise(rq, "deepcopy StructureClone copy failed.");
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool deepfreeze(JSContext* cx, uint argc, JS::Value* vp)
|
||||
JS::Value deepfreeze(const ScriptInterface& scriptInterface, JS::HandleValue val)
|
||||
{
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
|
||||
if (args.length() != 1 || !args.get(0).isObject())
|
||||
ScriptRequest rq(scriptInterface);
|
||||
if (!val.isObject())
|
||||
{
|
||||
ScriptException::Raise(rq, "deepfreeze requires exactly one object as an argument.");
|
||||
return false;
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->FreezeObject(args.get(0), true);
|
||||
args.rval().set(args.get(0));
|
||||
return true;
|
||||
scriptInterface.FreezeObject(val, true);
|
||||
return val;
|
||||
}
|
||||
|
||||
bool ProfileStart(JSContext* cx, uint argc, JS::Value* vp)
|
||||
void ProfileStart(const std::string& regionName)
|
||||
{
|
||||
const char* name = "(ProfileStart)";
|
||||
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
if (args.length() >= 1)
|
||||
{
|
||||
std::string str;
|
||||
if (!ScriptInterface::FromJSVal(rq, args[0], str))
|
||||
return false;
|
||||
typedef boost::flyweight<
|
||||
std::string,
|
||||
boost::flyweights::no_tracking,
|
||||
boost::flyweights::no_locking
|
||||
> StringFlyweight;
|
||||
|
||||
typedef boost::flyweight<
|
||||
std::string,
|
||||
boost::flyweights::no_tracking,
|
||||
boost::flyweights::no_locking
|
||||
> StringFlyweight;
|
||||
|
||||
name = StringFlyweight(str).get().c_str();
|
||||
}
|
||||
if (!regionName.empty())
|
||||
name = StringFlyweight(regionName).get().c_str();
|
||||
|
||||
if (CProfileManager::IsInitialised() && Threading::IsMainThread())
|
||||
g_Profiler.StartScript(name);
|
||||
|
||||
g_Profiler2.RecordRegionEnter(name);
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProfileStop(JSContext* UNUSED(cx), uint argc, JS::Value* vp)
|
||||
void ProfileStop()
|
||||
{
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
if (CProfileManager::IsInitialised() && Threading::IsMainThread())
|
||||
g_Profiler.Stop();
|
||||
|
||||
g_Profiler2.RecordRegionLeave();
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProfileAttribute(JSContext* cx, uint argc, JS::Value* vp)
|
||||
void ProfileAttribute(const std::string& attr)
|
||||
{
|
||||
const char* name = "(ProfileAttribute)";
|
||||
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
if (args.length() >= 1)
|
||||
{
|
||||
std::string str;
|
||||
if (!ScriptInterface::FromJSVal(rq, args[0], str))
|
||||
return false;
|
||||
typedef boost::flyweight<
|
||||
std::string,
|
||||
boost::flyweights::no_tracking,
|
||||
boost::flyweights::no_locking
|
||||
> StringFlyweight;
|
||||
|
||||
typedef boost::flyweight<
|
||||
std::string,
|
||||
boost::flyweights::no_tracking,
|
||||
boost::flyweights::no_locking
|
||||
> StringFlyweight;
|
||||
|
||||
name = StringFlyweight(str).get().c_str();
|
||||
}
|
||||
if (!attr.empty())
|
||||
name = StringFlyweight(attr).get().c_str();
|
||||
|
||||
g_Profiler2.RecordAttribute("%s", name);
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Math override functions:
|
||||
@@ -336,18 +306,19 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh
|
||||
|
||||
JS_DefineProperty(m_cx, m_glob, "global", m_glob, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
||||
m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
||||
// These first 4 actually use CallArgs & thus don't use ScriptFunction
|
||||
JS_DefineFunction(m_cx, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(m_cx, m_glob, "clone", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(m_cx, m_glob, "deepfreeze", ::deepfreeze, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
ScriptFunction::Register<deepcopy>(m_cx, m_glob, "clone");
|
||||
ScriptFunction::Register<deepfreeze>(m_cx, m_glob, "deepfreeze");
|
||||
|
||||
Register("ProfileStart", ::ProfileStart, 1);
|
||||
Register("ProfileStop", ::ProfileStop, 0);
|
||||
Register("ProfileAttribute", ::ProfileAttribute, 1);
|
||||
m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
||||
ScriptFunction::Register<&ProfileStart>(m_cx, m_nativeScope, "ProfileStart");
|
||||
ScriptFunction::Register<&ProfileStop>(m_cx, m_nativeScope, "ProfileStop");
|
||||
ScriptFunction::Register<&ProfileAttribute>(m_cx, m_nativeScope, "ProfileAttribute");
|
||||
|
||||
m_context->RegisterRealm(JS::GetObjectRealmOrNull(m_glob));
|
||||
}
|
||||
@@ -357,13 +328,6 @@ ScriptInterface_impl::~ScriptInterface_impl()
|
||||
m_context->UnRegisterRealm(JS::GetObjectRealmOrNull(m_glob));
|
||||
}
|
||||
|
||||
void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs) const
|
||||
{
|
||||
JSAutoRealm autoRealm(m_cx, m_glob);
|
||||
JS::RootedObject nativeScope(m_cx, m_nativeScope);
|
||||
JS::RootedFunction func(m_cx, JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT));
|
||||
}
|
||||
|
||||
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptContext>& context) :
|
||||
m(std::make_unique<ScriptInterface_impl>(nativeScopeName, context))
|
||||
{
|
||||
@@ -441,11 +405,6 @@ bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) const
|
||||
{
|
||||
m->Register(name, fptr, (uint)nargs);
|
||||
}
|
||||
|
||||
JSContext* ScriptInterface::GetGeneralJSContext() const
|
||||
{
|
||||
return m->m_context->GetGeneralJSContext();
|
||||
|
||||
@@ -34,7 +34,6 @@ ERROR_TYPE(Scripting_LoadFile, OpenFailed);
|
||||
ERROR_TYPE(Scripting_LoadFile, EvalErrors);
|
||||
|
||||
ERROR_TYPE(Scripting, CallFunctionFailed);
|
||||
ERROR_TYPE(Scripting, RegisterFunctionFailed);
|
||||
ERROR_TYPE(Scripting, DefineConstantFailed);
|
||||
ERROR_TYPE(Scripting, CreateObjectFailed);
|
||||
ERROR_TYPE(Scripting, TypeDoesNotExist);
|
||||
@@ -105,7 +104,7 @@ public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param nativeScopeName Name of global object that functions (via RegisterFunction) will
|
||||
* @param nativeScopeName Name of global object that functions (via ScriptFunction::Register) will
|
||||
* be placed into, as a scoping mechanism; typically "Engine"
|
||||
* @param debugName Name of this interface for CScriptStats purposes.
|
||||
* @param context ScriptContext to use when initializing this interface.
|
||||
@@ -455,7 +454,6 @@ private:
|
||||
JSClass* m_Class;
|
||||
JSNative m_Constructor;
|
||||
};
|
||||
void Register(const char* name, JSNative fptr, size_t nargs) const;
|
||||
|
||||
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted
|
||||
// members have to be called before the custom destructor of ScriptInterface_impl.
|
||||
@@ -470,9 +468,6 @@ public:
|
||||
// This declares:
|
||||
//
|
||||
// template <R, T0..., TR (*fptr) (void* cbdata, T0...)>
|
||||
// void RegisterFunction(const char* functionName) const;
|
||||
//
|
||||
// template <R, T0..., TR (*fptr) (void* cbdata, T0...)>
|
||||
// static JSNative call;
|
||||
//
|
||||
// template <R, T0..., JSClass*, TC, TR (TC:*fptr) (T0...)>
|
||||
|
||||
Reference in New Issue
Block a user