Changeset View
Changeset View
Standalone View
Standalone View
source/scriptinterface/ScriptInterface.h
Show All 15 Lines | |||||
*/ | */ | ||||
#ifndef INCLUDED_SCRIPTINTERFACE | #ifndef INCLUDED_SCRIPTINTERFACE | ||||
#define INCLUDED_SCRIPTINTERFACE | #define INCLUDED_SCRIPTINTERFACE | ||||
#include "lib/file/vfs/vfs_path.h" | #include "lib/file/vfs/vfs_path.h" | ||||
#include "maths/Fixed.h" | #include "maths/Fixed.h" | ||||
#include "ScriptTypes.h" | #include "ScriptTypes.h" | ||||
#include "ScriptExceptions.h" | |||||
vladislavbelov: Wrong order and useless empty line. | |||||
#include "ps/Errors.h" | #include "ps/Errors.h" | ||||
#include <boost/random/linear_congruential.hpp> | #include <boost/random/linear_congruential.hpp> | ||||
#include <map> | #include <map> | ||||
ERROR_GROUP(Scripting); | ERROR_GROUP(Scripting); | ||||
ERROR_TYPE(Scripting, SetupFailed); | ERROR_TYPE(Scripting, SetupFailed); | ||||
ERROR_SUBGROUP(Scripting, LoadFile); | ERROR_SUBGROUP(Scripting, LoadFile); | ||||
ERROR_TYPE(Scripting_LoadFile, OpenFailed); | ERROR_TYPE(Scripting_LoadFile, OpenFailed); | ||||
Show All 9 Lines | |||||
ERROR_TYPE(Scripting_DefineType, AlreadyExists); | ERROR_TYPE(Scripting_DefineType, AlreadyExists); | ||||
ERROR_TYPE(Scripting_DefineType, CreationFailed); | ERROR_TYPE(Scripting_DefineType, CreationFailed); | ||||
// Set the maximum number of function arguments that can be handled | // Set the maximum number of function arguments that can be handled | ||||
// (This should be as small as possible (for compiler efficiency), | // (This should be as small as possible (for compiler efficiency), | ||||
// but as large as necessary for all wrapped functions) | // but as large as necessary for all wrapped functions) | ||||
#define SCRIPT_INTERFACE_MAX_ARGS 8 | #define SCRIPT_INTERFACE_MAX_ARGS 8 | ||||
class ScriptInterface; | |||||
struct ScriptInterface_impl; | struct ScriptInterface_impl; | ||||
class ScriptContext; | class ScriptContext; | ||||
// Using a global object for the context is a workaround until Simulation, AI, etc, | // Using a global object for the context is a workaround until Simulation, AI, etc, | ||||
// use their own threads and also their own contexts. | // use their own threads and also their own contexts. | ||||
extern thread_local shared_ptr<ScriptContext> g_ScriptContext; | extern thread_local shared_ptr<ScriptContext> g_ScriptContext; | ||||
/** | |||||
* RAII structure which encapsulates an access to the context and compartment of a ScriptInterface. | |||||
* This struct provides: | |||||
* - a pointer to the context, while acting like JSAutoRequest | |||||
* - a pointer to the global object of the compartment, while acting like JSAutoCompartment | |||||
* | |||||
* This way, getting and using those pointers is safe with respect to the GC | |||||
* and to the separation of compartments. | |||||
*/ | |||||
struct ScriptRequest | |||||
Done Inline ActionsHad to be moved away for inclusion purposes. wraitii: Had to be moved away for inclusion purposes. | |||||
vladislavbelovUnsubmitted Not Done Inline ActionsIt should be class. vladislavbelov: It should be `class`. | |||||
{ | |||||
ScriptRequest() = delete; | |||||
ScriptRequest(const ScriptRequest& rq) = delete; | |||||
ScriptRequest& operator=(const ScriptRequest& rq) = delete; | |||||
ScriptRequest(const ScriptInterface& scriptInterface); | |||||
ScriptRequest(const ScriptInterface* scriptInterface) : ScriptRequest(*scriptInterface) {} | |||||
ScriptRequest(shared_ptr<ScriptInterface> scriptInterface) : ScriptRequest(*scriptInterface) {} | |||||
~ScriptRequest(); | |||||
JS::Value globalValue() const; | |||||
JSContext* cx; | |||||
JSObject* glob; | |||||
private: | |||||
JSCompartment* m_formerCompartment; | |||||
}; | |||||
/** | /** | ||||
* Abstraction around a SpiderMonkey JSCompartment. | * Abstraction around a SpiderMonkey JSCompartment. | ||||
* | * | ||||
* Thread-safety: | * Thread-safety: | ||||
* - May be used in non-main threads. | * - May be used in non-main threads. | ||||
* - Each ScriptInterface must be created, used, and destroyed, all in a single thread | * - Each ScriptInterface must be created, used, and destroyed, all in a single thread | ||||
* (it must never be shared between threads). | * (it must never be shared between threads). | ||||
*/ | */ | ||||
class ScriptInterface | class ScriptInterface | ||||
{ | { | ||||
NONCOPYABLE(ScriptInterface); | NONCOPYABLE(ScriptInterface); | ||||
friend struct ScriptRequest; | |||||
public: | public: | ||||
/** | /** | ||||
* Constructor. | * Constructor. | ||||
* @param nativeScopeName Name of global object that functions (via RegisterFunction) will | * @param nativeScopeName Name of global object that functions (via RegisterFunction) will | ||||
* be placed into, as a scoping mechanism; typically "Engine" | * be placed into, as a scoping mechanism; typically "Engine" | ||||
* @param debugName Name of this interface for CScriptStats purposes. | * @param debugName Name of this interface for CScriptStats purposes. | ||||
* @param context ScriptContext to use when initializing this interface. | * @param context ScriptContext to use when initializing this interface. | ||||
Show All 10 Lines | public: | ||||
void SetCallbackData(void* pCBData); | void SetCallbackData(void* pCBData); | ||||
static CmptPrivate* GetScriptInterfaceAndCBData(JSContext* cx); | static CmptPrivate* GetScriptInterfaceAndCBData(JSContext* cx); | ||||
JSRuntime* GetJSRuntime() const; | JSRuntime* GetJSRuntime() const; | ||||
shared_ptr<ScriptContext> GetContext() const; | shared_ptr<ScriptContext> GetContext() const; | ||||
/** | /** | ||||
* RAII structure which encapsulates an access to the context and compartment of a ScriptInterface. | |||||
* This struct provides: | |||||
* - a pointer to the context, while acting like JSAutoRequest | |||||
* - a pointer to the global object of the compartment, while acting like JSAutoCompartment | |||||
* | |||||
* This way, getting and using those pointers is safe with respect to the GC | |||||
* and to the separation of compartments. | |||||
*/ | |||||
struct Request | |||||
{ | |||||
Request() = delete; | |||||
Request(const Request& rq) = delete; | |||||
Request& operator=(const Request& rq) = delete; | |||||
Request(const ScriptInterface& scriptInterface); | |||||
Request(const ScriptInterface* scriptInterface) : Request(*scriptInterface) {} | |||||
Request(shared_ptr<ScriptInterface> scriptInterface) : Request(*scriptInterface) {} | |||||
Request(const CmptPrivate* cmptPrivate) : Request(cmptPrivate->pScriptInterface) {} | |||||
~Request(); | |||||
JS::Value globalValue() const; | |||||
JSContext* cx; | |||||
JSObject* glob; | |||||
private: | |||||
JSCompartment* m_formerCompartment; | |||||
}; | |||||
friend struct Request; | |||||
/** | |||||
* Load global scripts that most script interfaces need, | * Load global scripts that most script interfaces need, | ||||
* located in the /globalscripts directory. VFS must be initialized. | * located in the /globalscripts directory. VFS must be initialized. | ||||
*/ | */ | ||||
bool LoadGlobalScripts(); | bool LoadGlobalScripts(); | ||||
/** | /** | ||||
* Replace the default JS random number geenrator with a seeded, network-sync'd one. | * Replace the default JS random number geenrator with a seeded, network-sync'd one. | ||||
*/ | */ | ||||
Show All 11 Lines | public: | ||||
void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); | ||||
/** | /** | ||||
* Sets the given value to a new plain JS::Object, converts the arguments to JS::Values and sets them as properties. | * Sets the given value to a new plain JS::Object, converts the arguments to JS::Values and sets them as properties. | ||||
* This is static so that callers like ToJSVal can use it with the JSContext directly instead of having to obtain the instance using GetScriptInterfaceAndCBData. | * This is static so that callers like ToJSVal can use it with the JSContext directly instead of having to obtain the instance using GetScriptInterfaceAndCBData. | ||||
* Can throw an exception. | * Can throw an exception. | ||||
*/ | */ | ||||
template<typename... Args> | template<typename... Args> | ||||
static bool CreateObject(const Request& rq, JS::MutableHandleValue objectValue, Args const&... args) | static bool CreateObject(const ScriptRequest& rq, JS::MutableHandleValue objectValue, Args const&... args) | ||||
{ | { | ||||
JS::RootedObject obj(rq.cx); | JS::RootedObject obj(rq.cx); | ||||
if (!CreateObject_(rq, &obj, args...)) | if (!CreateObject_(rq, &obj, args...)) | ||||
return false; | return false; | ||||
objectValue.setObject(*obj); | objectValue.setObject(*obj); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Sets the given value to a new JS object or Null Value in case of out-of-memory. | * Sets the given value to a new JS object or Null Value in case of out-of-memory. | ||||
*/ | */ | ||||
static void CreateArray(const Request& rq, JS::MutableHandleValue objectValue, size_t length = 0); | static void CreateArray(const ScriptRequest& rq, JS::MutableHandleValue objectValue, size_t length = 0); | ||||
/** | /** | ||||
* Set the named property on the global object. | * Set the named property on the global object. | ||||
* Optionally makes it {ReadOnly, DontEnum}. We do not allow to make it DontDelete, so that it can be hotloaded | * Optionally makes it {ReadOnly, DontEnum}. We do not allow to make it DontDelete, so that it can be hotloaded | ||||
* by deleting it and re-creating it, which is done by setting @p replace to true. | * by deleting it and re-creating it, which is done by setting @p replace to true. | ||||
*/ | */ | ||||
template<typename T> | template<typename T> | ||||
bool SetGlobal(const char* name, const T& value, bool replace = false, bool constant = true, bool enumerate = true); | bool SetGlobal(const char* name, const T& value, bool replace = false, bool constant = true, bool enumerate = true); | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | public: | ||||
void ReadJSONFile(const VfsPath& path, JS::MutableHandleValue out) const; | void ReadJSONFile(const VfsPath& path, JS::MutableHandleValue out) const; | ||||
/** | /** | ||||
* Stringify to a JSON string, UTF-8 encoded. Returns an empty string on error. | * Stringify to a JSON string, UTF-8 encoded. Returns an empty string on error. | ||||
*/ | */ | ||||
std::string StringifyJSON(JS::MutableHandleValue obj, bool indent = true) const; | std::string StringifyJSON(JS::MutableHandleValue obj, bool indent = true) const; | ||||
/** | /** | ||||
* Report the given error message through the JS error reporting mechanism, | |||||
* and throw a JS exception. (Callers can check IsPendingException, and must | |||||
* return false in that case to propagate the exception.) | |||||
*/ | |||||
void ReportError(const char* msg) const; | |||||
/** | |||||
* Load and execute the given script in a new function scope. | * Load and execute the given script in a new function scope. | ||||
* @param filename Name for debugging purposes (not used to load the file) | * @param filename Name for debugging purposes (not used to load the file) | ||||
* @param code JS code to execute | * @param code JS code to execute | ||||
* @return true on successful compilation and execution; false otherwise | * @return true on successful compilation and execution; false otherwise | ||||
*/ | */ | ||||
bool LoadScript(const VfsPath& filename, const std::string& code) const; | bool LoadScript(const VfsPath& filename, const std::string& code) const; | ||||
/** | /** | ||||
Show All 16 Lines | public: | ||||
* Complex values (functions, XML, etc) won't be cloned correctly, but basic | * Complex values (functions, XML, etc) won't be cloned correctly, but basic | ||||
* types and cyclic references should be fine. | * types and cyclic references should be fine. | ||||
*/ | */ | ||||
JS::Value CloneValueFromOtherCompartment(const ScriptInterface& otherCompartment, JS::HandleValue val) const; | JS::Value CloneValueFromOtherCompartment(const ScriptInterface& otherCompartment, JS::HandleValue val) const; | ||||
/** | /** | ||||
* Convert a JS::Value to a C++ type. (This might trigger GC.) | * Convert a JS::Value to a C++ type. (This might trigger GC.) | ||||
*/ | */ | ||||
template<typename T> static bool FromJSVal(const Request& rq, const JS::HandleValue val, T& ret); | template<typename T> static bool FromJSVal(const ScriptRequest& rq, const JS::HandleValue val, T& ret); | ||||
/** | /** | ||||
* Convert a C++ type to a JS::Value. (This might trigger GC. The return | * Convert a C++ type to a JS::Value. (This might trigger GC. The return | ||||
* value must be rooted if you don't want it to be collected.) | * value must be rooted if you don't want it to be collected.) | ||||
* NOTE: We are passing the JS::Value by reference instead of returning it by value. | * NOTE: We are passing the JS::Value by reference instead of returning it by value. | ||||
* The reason is a memory corruption problem that appears to be caused by a bug in Visual Studio. | * The reason is a memory corruption problem that appears to be caused by a bug in Visual Studio. | ||||
* Details here: http://www.wildfiregames.com/forum/index.php?showtopic=17289&p=285921 | * Details here: http://www.wildfiregames.com/forum/index.php?showtopic=17289&p=285921 | ||||
*/ | */ | ||||
template<typename T> static void ToJSVal(const Request& rq, JS::MutableHandleValue ret, T const& val); | template<typename T> static void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, T const& val); | ||||
/** | /** | ||||
* Convert a named property of an object to a C++ type. | * Convert a named property of an object to a C++ type. | ||||
*/ | */ | ||||
template<typename T> static bool FromJSProperty(const Request& rq, const JS::HandleValue val, const char* name, T& ret, bool strict = false); | template<typename T> static bool FromJSProperty(const ScriptRequest& rq, const JS::HandleValue val, const char* name, T& ret, bool strict = false); | ||||
/** | /** | ||||
* MathRandom (this function) calls the random number generator assigned to this ScriptInterface instance and | * MathRandom (this function) calls the random number generator assigned to this ScriptInterface instance and | ||||
* returns the generated number. | * returns the generated number. | ||||
* Math_random (with underscore, not this function) is a global function, but different random number generators can be | * Math_random (with underscore, not this function) is a global function, but different random number generators can be | ||||
* stored per ScriptInterface. It calls MathRandom of the current ScriptInterface instance. | * stored per ScriptInterface. It calls MathRandom of the current ScriptInterface instance. | ||||
*/ | */ | ||||
bool MathRandom(double& nbr); | bool MathRandom(double& nbr); | ||||
Show All 17 Lines | public: | ||||
shared_ptr<StructuredClone> WriteStructuredClone(JS::HandleValue v) const; | shared_ptr<StructuredClone> WriteStructuredClone(JS::HandleValue v) const; | ||||
void ReadStructuredClone(const shared_ptr<StructuredClone>& ptr, JS::MutableHandleValue ret) const; | void ReadStructuredClone(const shared_ptr<StructuredClone>& ptr, JS::MutableHandleValue ret) const; | ||||
/** | /** | ||||
* Retrieve the private data field of a JSObject that is an instance of the given JSClass. | * Retrieve the private data field of a JSObject that is an instance of the given JSClass. | ||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
static T* GetPrivate(const Request& rq, JS::HandleObject thisobj, JSClass* jsClass) | static T* GetPrivate(const ScriptRequest& rq, JS::HandleObject thisobj, JSClass* jsClass) | ||||
{ | { | ||||
T* value = static_cast<T*>(JS_GetInstancePrivate(rq.cx, thisobj, jsClass, nullptr)); | T* value = static_cast<T*>(JS_GetInstancePrivate(rq.cx, thisobj, jsClass, nullptr)); | ||||
if (value == nullptr && !JS_IsExceptionPending(rq.cx)) | |||||
JS_ReportError(rq.cx, "Private data of the given object is null!"); | if (value == nullptr) | ||||
ScriptException::Raise(rq, "Private data of the given object is null!"); | |||||
return value; | return value; | ||||
} | } | ||||
/** | /** | ||||
* Retrieve the private data field of a JS Object that is an instance of the given JSClass. | * Retrieve the private data field of a JS Object that is an instance of the given JSClass. | ||||
* If an error occurs, GetPrivate will report it with the according stack. | * If an error occurs, GetPrivate will report it with the according stack. | ||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
static T* GetPrivate(const Request& rq, JS::CallArgs& callArgs, JSClass* jsClass) | static T* GetPrivate(const ScriptRequest& rq, JS::CallArgs& callArgs, JSClass* jsClass) | ||||
{ | { | ||||
if (!callArgs.thisv().isObject()) | if (!callArgs.thisv().isObject()) | ||||
{ | { | ||||
JS_ReportError(rq.cx, "Cannot retrieve private JS class data because from a non-object value!"); | ScriptException::Raise(rq, "Cannot retrieve private JS class data because from a non-object value!"); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
JS::RootedObject thisObj(rq.cx, &callArgs.thisv().toObject()); | JS::RootedObject thisObj(rq.cx, &callArgs.thisv().toObject()); | ||||
T* value = static_cast<T*>(JS_GetInstancePrivate(rq.cx, thisObj, jsClass, &callArgs)); | T* value = static_cast<T*>(JS_GetInstancePrivate(rq.cx, thisObj, jsClass, &callArgs)); | ||||
if (value == nullptr && !JS_IsExceptionPending(rq.cx)) | |||||
JS_ReportError(rq.cx, "Private data of the given object is null!"); | if (value == nullptr) | ||||
ScriptException::Raise(rq, "Private data of the given object is null!"); | |||||
return value; | return value; | ||||
} | } | ||||
/** | /** | ||||
* Converts |a| if needed and assigns it to |handle|. | * 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 | * 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 | * 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). | * 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 | * 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". | * because "conversions" from JS::HandleValue to JS::MutableHandleValue are unusual and should not happen "by accident". | ||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
static void AssignOrToJSVal(const Request& rq, JS::MutableHandleValue handle, const T& a); | static void AssignOrToJSVal(const ScriptRequest& rq, JS::MutableHandleValue handle, const T& a); | ||||
/** | /** | ||||
* The same as AssignOrToJSVal, but also allows JS::Value for T. | * The same as AssignOrToJSVal, but also allows JS::Value for T. | ||||
* In most cases it's not safe to use the plain (unrooted) JS::Value type, but this can happen quite | * In most cases it's not safe to use the plain (unrooted) JS::Value type, but this can happen quite | ||||
* easily with template functions. The idea is that the linker prints an error if AssignOrToJSVal is | * easily with template functions. The idea is that the linker prints an error if AssignOrToJSVal is | ||||
* used with JS::Value. If the specialization for JS::Value should be allowed, you can use this | * used with JS::Value. If the specialization for JS::Value should be allowed, you can use this | ||||
* "unrooted" version of AssignOrToJSVal. | * "unrooted" version of AssignOrToJSVal. | ||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
static void AssignOrToJSValUnrooted(const Request& rq, JS::MutableHandleValue handle, const T& a) | static void AssignOrToJSValUnrooted(const ScriptRequest& rq, JS::MutableHandleValue handle, const T& a) | ||||
{ | { | ||||
AssignOrToJSVal(rq, handle, a); | AssignOrToJSVal(rq, handle, a); | ||||
} | } | ||||
/** | /** | ||||
* Converts |val| to T if needed or just returns it if it's a handle. | * Converts |val| to T if needed or just returns it if it's a handle. | ||||
* This is meant for use in other templates where we want to use the same code for JS::HandleValue and | * This is meant for use in other templates where we want to use the same code for JS::HandleValue and | ||||
* other types. | * other types. | ||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
static T AssignOrFromJSVal(const Request& rq, const JS::HandleValue& val, bool& ret); | static T AssignOrFromJSVal(const ScriptRequest& rq, const JS::HandleValue& val, bool& ret); | ||||
private: | private: | ||||
static bool CreateObject_(const Request& rq, JS::MutableHandleObject obj); | static bool CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject obj); | ||||
template<typename T, typename... Args> | template<typename T, typename... Args> | ||||
static bool CreateObject_(const Request& rq, JS::MutableHandleObject obj, const char* propertyName, const T& propertyValue, Args const&... args) | static bool CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject obj, const char* propertyName, const T& propertyValue, Args const&... args) | ||||
{ | { | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
AssignOrToJSVal(rq, &val, propertyValue); | AssignOrToJSVal(rq, &val, propertyValue); | ||||
return CreateObject_(rq, obj, args...) && JS_DefineProperty(rq.cx, obj, propertyName, val, JSPROP_ENUMERATE); | return CreateObject_(rq, obj, args...) && JS_DefineProperty(rq.cx, obj, propertyName, val, JSPROP_ENUMERATE); | ||||
} | } | ||||
bool CallFunction_(JS::HandleValue val, const char* name, JS::HandleValueArray argv, JS::MutableHandleValue ret) const; | bool CallFunction_(JS::HandleValue val, const char* name, JS::HandleValueArray argv, JS::MutableHandleValue ret) const; | ||||
bool Eval_(const char* code, JS::MutableHandleValue ret) const; | bool Eval_(const char* code, JS::MutableHandleValue ret) const; | ||||
bool Eval_(const wchar_t* code, JS::MutableHandleValue ret) const; | bool Eval_(const wchar_t* code, JS::MutableHandleValue ret) const; | ||||
bool SetGlobal_(const char* name, JS::HandleValue value, bool replace, bool constant, bool enumerate); | bool SetGlobal_(const char* name, JS::HandleValue value, bool replace, bool constant, bool enumerate); | ||||
bool SetProperty_(JS::HandleValue obj, const char* name, JS::HandleValue value, bool constant, bool enumerate) const; | bool SetProperty_(JS::HandleValue obj, const char* name, JS::HandleValue value, bool constant, bool enumerate) const; | ||||
bool SetProperty_(JS::HandleValue obj, const wchar_t* name, JS::HandleValue value, bool constant, bool enumerate) const; | bool SetProperty_(JS::HandleValue obj, const wchar_t* name, JS::HandleValue value, bool constant, bool enumerate) const; | ||||
bool SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) const; | bool SetPropertyInt_(JS::HandleValue obj, int name, JS::HandleValue value, bool constant, bool enumerate) const; | ||||
bool GetProperty_(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) const; | bool GetProperty_(JS::HandleValue obj, const char* name, JS::MutableHandleValue out) const; | ||||
bool GetPropertyInt_(JS::HandleValue obj, int name, JS::MutableHandleValue value) const; | bool GetPropertyInt_(JS::HandleValue obj, int name, JS::MutableHandleValue value) const; | ||||
static bool IsExceptionPending(const Request& rq); | |||||
struct CustomType | struct CustomType | ||||
{ | { | ||||
JS::PersistentRootedObject m_Prototype; | JS::PersistentRootedObject m_Prototype; | ||||
JSClass* m_Class; | JSClass* m_Class; | ||||
JSNative m_Constructor; | JSNative m_Constructor; | ||||
}; | }; | ||||
void Register(const char* name, JSNative fptr, size_t nargs) const; | void Register(const char* name, JSNative fptr, size_t nargs) const; | ||||
Show All 37 Lines | public: | ||||
// template <T0...> | // template <T0...> | ||||
// bool CallFunctionVoid(JS::HandleValue val, const char* name, const T0&...) const; | // bool CallFunctionVoid(JS::HandleValue val, const char* name, const T0&...) const; | ||||
}; | }; | ||||
// Implement those declared functions | // Implement those declared functions | ||||
#include "NativeWrapperDefns.h" | #include "NativeWrapperDefns.h" | ||||
template<typename T> | template<typename T> | ||||
inline void ScriptInterface::AssignOrToJSVal(const Request& rq, JS::MutableHandleValue handle, const T& a) | inline void ScriptInterface::AssignOrToJSVal(const ScriptRequest& rq, JS::MutableHandleValue handle, const T& a) | ||||
{ | { | ||||
ToJSVal(rq, handle, a); | ToJSVal(rq, handle, a); | ||||
} | } | ||||
template<> | template<> | ||||
inline void ScriptInterface::AssignOrToJSVal<JS::PersistentRootedValue>(const Request& UNUSED(rq), JS::MutableHandleValue handle, const JS::PersistentRootedValue& a) | inline void ScriptInterface::AssignOrToJSVal<JS::PersistentRootedValue>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::PersistentRootedValue& a) | ||||
{ | { | ||||
handle.set(a); | handle.set(a); | ||||
} | } | ||||
template<> | template<> | ||||
inline void ScriptInterface::AssignOrToJSVal<JS::Heap<JS::Value> >(const Request& UNUSED(rq), JS::MutableHandleValue handle, const JS::Heap<JS::Value>& a) | inline void ScriptInterface::AssignOrToJSVal<JS::Heap<JS::Value> >(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::Heap<JS::Value>& a) | ||||
{ | { | ||||
handle.set(a); | handle.set(a); | ||||
} | } | ||||
template<> | template<> | ||||
inline void ScriptInterface::AssignOrToJSVal<JS::RootedValue>(const Request& UNUSED(rq), JS::MutableHandleValue handle, const JS::RootedValue& a) | inline void ScriptInterface::AssignOrToJSVal<JS::RootedValue>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::RootedValue& a) | ||||
{ | { | ||||
handle.set(a); | handle.set(a); | ||||
} | } | ||||
template <> | template <> | ||||
inline void ScriptInterface::AssignOrToJSVal<JS::HandleValue>(const Request& UNUSED(rq), JS::MutableHandleValue handle, const JS::HandleValue& a) | inline void ScriptInterface::AssignOrToJSVal<JS::HandleValue>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::HandleValue& a) | ||||
{ | { | ||||
handle.set(a); | handle.set(a); | ||||
} | } | ||||
template <> | template <> | ||||
inline void ScriptInterface::AssignOrToJSValUnrooted<JS::Value>(const Request& UNUSED(rq), JS::MutableHandleValue handle, const JS::Value& a) | inline void ScriptInterface::AssignOrToJSValUnrooted<JS::Value>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::Value& a) | ||||
{ | { | ||||
handle.set(a); | handle.set(a); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
inline T ScriptInterface::AssignOrFromJSVal(const Request& rq, const JS::HandleValue& val, bool& ret) | inline T ScriptInterface::AssignOrFromJSVal(const ScriptRequest& rq, const JS::HandleValue& val, bool& ret) | ||||
{ | { | ||||
T retVal; | T retVal; | ||||
ret = FromJSVal(rq, val, retVal); | ret = FromJSVal(rq, val, retVal); | ||||
return retVal; | return retVal; | ||||
} | } | ||||
template<> | template<> | ||||
inline JS::HandleValue ScriptInterface::AssignOrFromJSVal<JS::HandleValue>(const Request& UNUSED(rq), const JS::HandleValue& val, bool& ret) | inline JS::HandleValue ScriptInterface::AssignOrFromJSVal<JS::HandleValue>(const ScriptRequest& UNUSED(rq), const JS::HandleValue& val, bool& ret) | ||||
{ | { | ||||
ret = true; | ret = true; | ||||
return val; | return val; | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace, bool constant, bool enumerate) | bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace, bool constant, bool enumerate) | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
AssignOrToJSVal(rq, &val, value); | AssignOrToJSVal(rq, &val, value); | ||||
return SetGlobal_(name, val, replace, constant, enumerate); | return SetGlobal_(name, val, replace, constant, enumerate); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
bool ScriptInterface::SetProperty(JS::HandleValue obj, const char* name, const T& value, bool constant, bool enumerate) const | bool ScriptInterface::SetProperty(JS::HandleValue obj, const char* name, const T& value, bool constant, bool enumerate) const | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
AssignOrToJSVal(rq, &val, value); | AssignOrToJSVal(rq, &val, value); | ||||
return SetProperty_(obj, name, val, constant, enumerate); | return SetProperty_(obj, name, val, constant, enumerate); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
bool ScriptInterface::SetProperty(JS::HandleValue obj, const wchar_t* name, const T& value, bool constant, bool enumerate) const | bool ScriptInterface::SetProperty(JS::HandleValue obj, const wchar_t* name, const T& value, bool constant, bool enumerate) const | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
AssignOrToJSVal(rq, &val, value); | AssignOrToJSVal(rq, &val, value); | ||||
return SetProperty_(obj, name, val, constant, enumerate); | return SetProperty_(obj, name, val, constant, enumerate); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
bool ScriptInterface::SetPropertyInt(JS::HandleValue obj, int name, const T& value, bool constant, bool enumerate) const | bool ScriptInterface::SetPropertyInt(JS::HandleValue obj, int name, const T& value, bool constant, bool enumerate) const | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
AssignOrToJSVal(rq, &val, value); | AssignOrToJSVal(rq, &val, value); | ||||
return SetPropertyInt_(obj, name, val, constant, enumerate); | return SetPropertyInt_(obj, name, val, constant, enumerate); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, T& out) const | bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, T& out) const | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
if (!GetProperty_(obj, name, &val)) | if (!GetProperty_(obj, name, &val)) | ||||
return false; | return false; | ||||
return FromJSVal(rq, val, out); | return FromJSVal(rq, val, out); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
bool ScriptInterface::GetPropertyInt(JS::HandleValue obj, int name, T& out) const | bool ScriptInterface::GetPropertyInt(JS::HandleValue obj, int name, T& out) const | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue val(rq.cx); | JS::RootedValue val(rq.cx); | ||||
if (!GetPropertyInt_(obj, name, &val)) | if (!GetPropertyInt_(obj, name, &val)) | ||||
return false; | return false; | ||||
return FromJSVal(rq, val, out); | return FromJSVal(rq, val, out); | ||||
} | } | ||||
template<typename CHAR> | template<typename CHAR> | ||||
bool ScriptInterface::Eval(const CHAR* code, JS::MutableHandleValue ret) const | bool ScriptInterface::Eval(const CHAR* code, JS::MutableHandleValue ret) const | ||||
{ | { | ||||
if (!Eval_(code, ret)) | if (!Eval_(code, ret)) | ||||
return false; | return false; | ||||
return true; | return true; | ||||
} | } | ||||
template<typename T, typename CHAR> | template<typename T, typename CHAR> | ||||
bool ScriptInterface::Eval(const CHAR* code, T& ret) const | bool ScriptInterface::Eval(const CHAR* code, T& ret) const | ||||
{ | { | ||||
Request rq(this); | ScriptRequest rq(this); | ||||
JS::RootedValue rval(rq.cx); | JS::RootedValue rval(rq.cx); | ||||
if (!Eval_(code, &rval)) | if (!Eval_(code, &rval)) | ||||
return false; | return false; | ||||
return FromJSVal(rq, rval, ret); | return FromJSVal(rq, rval, ret); | ||||
} | } | ||||
#endif // INCLUDED_SCRIPTINTERFACE | #endif // INCLUDED_SCRIPTINTERFACE |
Wildfire Games · Phabricator
Wrong order and useless empty line.