18 #include "precompiled.h"
28 #define FAIL(msg) STMT(JS_ReportError(cx, msg); return false)
31 #define WARN_IF_NOT(c, v) STMT(if (!(c)) { JS_ReportWarning(cx, "Script value conversion check failed: %s (got type %s)", #c, JS_GetTypeName(cx, JS_TypeOfValue(cx, v))); })
33 template<>
bool ScriptInterface::FromJSVal<bool>(JSContext* cx, jsval v,
bool&
out)
37 if (!JS_ValueToBoolean(cx, v, &ret))
39 out = (ret ?
true :
false);
43 template<>
bool ScriptInterface::FromJSVal<float>(JSContext* cx, jsval v,
float&
out)
47 if (!JS_ValueToNumber(cx, v, &ret))
53 template<>
bool ScriptInterface::FromJSVal<double>(JSContext* cx, jsval v,
double&
out)
57 if (!JS_ValueToNumber(cx, v, &ret))
63 template<>
bool ScriptInterface::FromJSVal<i32>(JSContext* cx, jsval v,
i32&
out)
67 if (!JS_ValueToECMAInt32(cx, v, &ret))
73 template<>
bool ScriptInterface::FromJSVal<u32>(JSContext* cx, jsval v,
u32&
out)
77 if (!JS_ValueToECMAUint32(cx, v, &ret))
83 template<>
bool ScriptInterface::FromJSVal<u16>(JSContext* cx, jsval v,
u16&
out)
87 if (!JS_ValueToUint16(cx, v, &ret))
93 template<>
bool ScriptInterface::FromJSVal<u8>(JSContext* cx, jsval v,
u8&
out)
97 if (!JS_ValueToUint16(cx, v, &ret))
110 template<>
bool ScriptInterface::FromJSVal<CScriptValRooted>(JSContext* cx, jsval v,
CScriptValRooted&
out)
116 template<>
bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, jsval v, std::wstring&
out)
118 WARN_IF_NOT(JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v), v);
119 JSString* ret = JS_ValueToString(cx, v);
121 FAIL(
"Argument must be convertible to a string");
123 const jschar* ch = JS_GetStringCharsAndLength(cx, ret, &length);
125 FAIL(
"JS_GetStringsCharsAndLength failed");
126 out = std::wstring(ch, ch + length);
130 template<>
bool ScriptInterface::FromJSVal<Path>(JSContext* cx, jsval v,
Path&
out)
133 if (!FromJSVal(cx, v,
string))
139 template<>
bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, jsval v, std::string&
out)
141 WARN_IF_NOT(JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v), v);
142 JSString* ret = JS_ValueToString(cx, v);
144 FAIL(
"Argument must be convertible to a string");
145 char* ch = JS_EncodeString(cx, ret);
147 FAIL(
"JS_EncodeString failed");
148 out = std::string(ch, ch + JS_GetStringLength(ret));
153 template<>
bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, jsval v,
Entity&
out)
156 if (!JS_ValueToObject(cx, v, &obj) || obj == NULL)
157 FAIL(
"Argument must be an object");
159 jsval templateName, id, player, position, rotation;
162 if(!JS_GetProperty(cx, obj,
"player", &player) || !FromJSVal(cx, player,
out.playerID))
163 FAIL(
"Failed to read Entity.player property");
164 if (!JS_GetProperty(cx, obj,
"templateName", &templateName) || !FromJSVal(cx, templateName,
out.templateName))
165 FAIL(
"Failed to read Entity.templateName property");
166 if (!JS_GetProperty(cx, obj,
"id", &
id) || !FromJSVal(cx,
id,
out.entityID))
167 FAIL(
"Failed to read Entity.id property");
168 if (!JS_GetProperty(cx, obj,
"position", &position) || !FromJSVal(cx, position,
out.position))
169 FAIL(
"Failed to read Entity.position property");
170 if (!JS_GetProperty(cx, obj,
"rotation", &rotation) || !FromJSVal(cx, rotation,
out.rotation))
171 FAIL(
"Failed to read Entity.rotation property");
181 return val ? JSVAL_TRUE : JSVAL_FALSE;
186 jsval rval = JSVAL_VOID;
187 JS_NewNumberValue(cx, val, &rval);
193 jsval rval = JSVAL_VOID;
194 JS_NewNumberValue(cx, val, &rval);
198 template<> jsval ScriptInterface::ToJSVal<i32>(JSContext*
UNUSED(cx),
const i32& val)
201 return INT_TO_JSVAL(val);
204 template<> jsval ScriptInterface::ToJSVal<u16>(JSContext*
UNUSED(cx),
const u16& val)
206 return INT_TO_JSVAL(val);
209 template<> jsval ScriptInterface::ToJSVal<u8>(JSContext*
UNUSED(cx),
const u8& val)
211 return INT_TO_JSVAL(val);
214 template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* cx,
const u32& val)
216 if (val <= JSVAL_INT_MAX)
217 return INT_TO_JSVAL(val);
218 jsval rval = JSVAL_VOID;
219 JS_NewNumberValue(cx, val, &rval);
224 template<> jsval ScriptInterface::ToJSVal<CScriptVal>(JSContext*
UNUSED(cx),
const CScriptVal& val)
234 template<> jsval ScriptInterface::ToJSVal<std::wstring>(JSContext* cx,
const std::wstring& val)
237 JSString* str = JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar*> (utf16.c_str()), utf16.length());
239 return STRING_TO_JSVAL(str);
243 template<> jsval ScriptInterface::ToJSVal<Path>(JSContext* cx,
const Path& val)
245 return ToJSVal(cx, val.string());
248 template<> jsval ScriptInterface::ToJSVal<std::string>(JSContext* cx,
const std::string& val)
250 JSString* str = JS_NewStringCopyN(cx, val.c_str(), val.length());
252 return STRING_TO_JSVAL(str);
256 template<> jsval ScriptInterface::ToJSVal<const wchar_t*>(JSContext* cx,
const wchar_t*
const& val)
258 return ToJSVal(cx, std::wstring(val));
261 template<> jsval ScriptInterface::ToJSVal<const char*>(JSContext* cx,
const char*
const& val)
263 JSString* str = JS_NewStringCopyZ(cx, val);
265 return STRING_TO_JSVAL(str);
271 return ToJSVal(cx, static_cast<const std::wstring&>(val));
276 return ToJSVal(cx, static_cast<const std::string&>(val));
282 template<
typename T>
static jsval
ToJSVal_vector(JSContext* cx,
const std::vector<T>& val)
284 JSObject* obj = JS_NewArrayObject(cx, val.size(), NULL);
287 for (
size_t i = 0; i < val.size(); ++i)
289 jsval el = ScriptInterface::ToJSVal<T>(cx, val[i]);
290 JS_SetElement(cx, obj, (jsint)i, &el);
292 return OBJECT_TO_JSVAL(obj);
298 if (!JS_ValueToObject(cx, v, &obj) || obj == NULL || !(JS_IsArrayObject(cx, obj) || js_IsTypedArray(obj)))
299 FAIL(
"Argument must be an array");
301 if (!JS_GetArrayLength(cx, obj, &length))
302 FAIL(
"Failed to get array length");
304 for (jsuint i = 0; i < length; ++i)
307 if (!JS_GetElement(cx, obj, i, &el))
308 FAIL(
"Failed to read array element");
310 if (!ScriptInterface::FromJSVal<T>(cx, el, el2))
320 template<> jsval ScriptInterface::ToJSVal<std::vector<T> >(JSContext* cx, const std::vector<T>& val) \
322 return ToJSVal_vector(cx, val); \
324 template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, jsval v, std::vector<T>& out) \
326 return FromJSVal_vector(cx, v, out); \
343 template<>
bool ScriptInterface::FromJSVal<std::vector<Entity> >(JSContext* cx, jsval v, std::vector<Entity>&
out)
jsval ToJSVal< float >(const float &Native)
jsval ToJSVal< double >(const double &Native)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
static void out(const wchar_t *fmt,...)
#define WARN_IF_NOT(c, v)
A trivial wrapper around a jsval.
static bool FromJSVal_vector(JSContext *cx, jsval v, std::vector< T > &out)
static jsval ToJSVal_vector(JSContext *cx, const std::vector< T > &val)
jsval ToJSVal< CStrW >(const CStrW &Native)
#define T(string_literal)
jsval ToJSVal< CStr8 >(const CStr8 &Native)
std::basic_string< utf16_t, utf16_traits > utf16string
Abstraction around a SpiderMonkey JSContext.
#define cassert(expr)
Compile-time assertion.
jsval ToJSVal< bool >(const bool &Native)