From 20ed5b118c8343b59cefbbe5d4963efbcfeedf48 Mon Sep 17 00:00:00 2001 From: Yves Date: Sun, 20 Oct 2013 17:13:53 +0000 Subject: [PATCH] Unify script conversions and remove JSInterface_Vector3D. Because it was historically grown, we have some duplicated code for converting script types to native types. This patch removes the file JSConversions.cpp and moves some code to ScriptConversions.cpp. The places using JSConversions.cpp are changed to use the ScriptInterface's conversion functions in ScriptConversions.cpp. I also removed JSInterface_Vector3D because it had additional requirements to the conversion code that no other code has and because it's currently not used. I think it doesn't make sense to maintain code just because it could possibly be used again later. Closes #2213 Refs #1886 This was SVN commit r14036. --- .../maths/scripting/JSInterface_Vector3D.cpp | 209 ------------- source/maths/scripting/JSInterface_Vector3D.h | 69 ---- source/ps/GameSetup/GameSetup.cpp | 4 - source/ps/scripting/JSInterface_VFS.cpp | 26 +- source/scripting/JSConversions.cpp | 294 ------------------ source/scripting/JSConversions.h | 193 ------------ source/scripting/ScriptGlue.cpp | 13 +- source/scriptinterface/DebuggingServer.cpp | 1 - source/scriptinterface/ScriptConversions.cpp | 86 ++++- 9 files changed, 104 insertions(+), 791 deletions(-) delete mode 100644 source/maths/scripting/JSInterface_Vector3D.cpp delete mode 100644 source/maths/scripting/JSInterface_Vector3D.h delete mode 100644 source/scripting/JSConversions.cpp delete mode 100644 source/scripting/JSConversions.h diff --git a/source/maths/scripting/JSInterface_Vector3D.cpp b/source/maths/scripting/JSInterface_Vector3D.cpp deleted file mode 100644 index 986c04d0c4..0000000000 --- a/source/maths/scripting/JSInterface_Vector3D.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* Copyright (C) 2013 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "JSInterface_Vector3D.h" -#include "scripting/JSConversions.h" -#include "scripting/ScriptingHost.h" - -JSClass JSI_Vector3D::JSI_class = { - "Vector3D", JSCLASS_HAS_PRIVATE, - JS_PropertyStub, JS_PropertyStub, - JSI_Vector3D::getProperty, JSI_Vector3D::setProperty, - JS_EnumerateStub, JS_ResolveStub, - JS_ConvertStub, JSI_Vector3D::finalize, - NULL, NULL, NULL, NULL -}; - -JSPropertySpec JSI_Vector3D::JSI_props[] = -{ - { "x", JSI_Vector3D::component_x, JSPROP_ENUMERATE }, - { "y", JSI_Vector3D::component_y, JSPROP_ENUMERATE }, - { "z", JSI_Vector3D::component_z, JSPROP_ENUMERATE }, - { 0 } -}; - -JSFunctionSpec JSI_Vector3D::JSI_methods[] = -{ - { "toString", JSI_Vector3D::toString, 0, 0 }, - { 0 } -}; - -void JSI_Vector3D::init() -{ - g_ScriptingHost.DefineCustomObjectType(&JSI_class, JSI_Vector3D::construct, 0, JSI_props, JSI_methods, NULL, NULL); -} - -JSI_Vector3D::Vector3D_Info::Vector3D_Info() -{ - owner = NULL; - vector = new CVector3D(); -} - -JSI_Vector3D::Vector3D_Info::Vector3D_Info(float x, float y, float z) -{ - owner = NULL; - vector = new CVector3D(x, y, z); -} - -JSI_Vector3D::Vector3D_Info::Vector3D_Info(const CVector3D& copy) -{ - owner = NULL; - vector = new CVector3D(copy.X, copy.Y, copy.Z); -} - -JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner) -{ - owner = _owner; - updateFn = NULL; - freshenFn = NULL; - vector = attach; -} - -JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void)) -{ - owner = _owner; - updateFn = _updateFn; - freshenFn = NULL; - vector = attach; -} - -JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void), - void(IPropertyOwner::*_freshenFn)(void)) -{ - owner = _owner; - updateFn = _updateFn; - freshenFn = _freshenFn; - vector = attach; -} - -JSI_Vector3D::Vector3D_Info::~Vector3D_Info() -{ - if (!owner) - delete (vector); -} - -JSBool JSI_Vector3D::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) -{ - if (!JSID_IS_INT(id)) - return JS_TRUE; - - Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, obj, &JSI_Vector3D::JSI_class, NULL); - if (!vectorInfo) - return JS_FALSE; - - CVector3D* vectorData = vectorInfo->vector; - - if (vectorInfo->owner && vectorInfo->freshenFn) - ((vectorInfo->owner)->*(vectorInfo->freshenFn))(); - - switch (JSID_TO_INT(id)) - { - case component_x: - return JS_NewNumberValue(cx, vectorData->X, vp); - case component_y: - return JS_NewNumberValue(cx, vectorData->Y, vp); - case component_z: - return JS_NewNumberValue(cx, vectorData->Z, vp); - } - - return JS_FALSE; -} - -JSBool JSI_Vector3D::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp) -{ - if (!JSID_IS_INT(id)) - return JS_TRUE; - - Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, obj, &JSI_Vector3D::JSI_class, NULL); - if (!vectorInfo) - return JS_FALSE; - - CVector3D* vectorData = vectorInfo->vector; - - if (vectorInfo->owner && vectorInfo->freshenFn) - ((vectorInfo->owner)->*(vectorInfo->freshenFn))(); - - switch (JSID_TO_INT(id)) - { - case component_x: - vectorData->X = ToPrimitive (*vp); - break; - case component_y: - vectorData->Y = ToPrimitive (*vp); - break; - case component_z: - vectorData->Z = ToPrimitive (*vp); - break; - } - - if (vectorInfo->owner && vectorInfo->updateFn) - ((vectorInfo->owner)->*(vectorInfo->updateFn))(); - - return JS_TRUE; -} - -JSBool JSI_Vector3D::construct(JSContext* cx, uintN argc, jsval* vp) -{ - JSObject* vector = JS_NewObject(cx, &JSI_Vector3D::JSI_class, NULL, NULL); - - if (argc == 0) - { - JS_SetPrivate(cx, vector, new Vector3D_Info()); - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(vector)); - return JS_TRUE; - } - - JSU_REQUIRE_PARAMS(3); - try - { - float x = ToPrimitive (JS_ARGV(cx, vp)[0]); - float y = ToPrimitive (JS_ARGV(cx, vp)[1]); - float z = ToPrimitive (JS_ARGV(cx, vp)[2]); - JS_SetPrivate(cx, vector, new Vector3D_Info(x, y, z)); - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(vector)); - return JS_TRUE; - } - catch (PSERROR_Scripting_ConversionFailed&) - { - // Invalid input (i.e. can't be coerced into doubles) - fail - JS_ReportError(cx, "Invalid parameters to Vector3D constructor"); - return JS_FALSE; - } -} - -void JSI_Vector3D::finalize(JSContext* cx, JSObject* obj) -{ - delete ((Vector3D_Info*)JS_GetPrivate(cx, obj)); -} - -JSBool JSI_Vector3D::toString(JSContext* cx, uintN UNUSED(argc), jsval* vp) -{ - char buffer[256]; - Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_Vector3D::JSI_class, NULL); - if (!vectorInfo) - return JS_FALSE; - - if (vectorInfo->owner && vectorInfo->freshenFn) - ((vectorInfo->owner)->*(vectorInfo->freshenFn))(); - - CVector3D* vectorData = vectorInfo->vector; - sprintf_s(buffer, ARRAY_SIZE(buffer), "[object Vector3D: ( %f, %f, %f )]", vectorData->X, vectorData->Y, vectorData->Z); - JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer))); - return JS_TRUE; -} diff --git a/source/maths/scripting/JSInterface_Vector3D.h b/source/maths/scripting/JSInterface_Vector3D.h deleted file mode 100644 index 29a6d8c70b..0000000000 --- a/source/maths/scripting/JSInterface_Vector3D.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2013 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// JSInterface_Entity.h -// -// -// A JavaScript class representing a Pyrogenesis CVector3D object. -// -// Usage: Used when manipulating objects of class 'Vector3D' in JavaScript. - -#include "scripting/ScriptingHost.h" -#include "maths/Vector3D.h" - -#ifndef INCLUDED_JSI_VECTOR3 -#define INCLUDED_JSI_VECTOR3 - -namespace JSI_Vector3D -{ - enum - { - component_x, - component_y, - component_z - }; - JSBool toString(JSContext* cx, uintN argc, jsval* vp); - - struct Vector3D_Info - { - NONCOPYABLE(Vector3D_Info); - public: - - IPropertyOwner* owner; - void (IPropertyOwner::*updateFn)(); - void (IPropertyOwner::*freshenFn)(); - CVector3D* vector; - Vector3D_Info(); - Vector3D_Info(float x, float y, float z); - Vector3D_Info(const CVector3D& copy); - Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner); - Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void)); - Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void), void(IPropertyOwner::*_freshenFn)(void)); - ~Vector3D_Info(); - }; - extern JSClass JSI_class; - extern JSPropertySpec JSI_props[]; - extern JSFunctionSpec JSI_methods[]; - - JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); - JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp); - void finalize(JSContext* cx, JSObject* obj); - JSBool construct(JSContext* cx, uintN argc, jsval* vp); - void init(); -} - -#endif diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index ba0fc8df3e..13a180523d 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -48,7 +48,6 @@ #include "gui/scripting/JSInterface_GUITypes.h" #include "gui/scripting/ScriptFunctions.h" #include "maths/MathUtil.h" -#include "maths/scripting/JSInterface_Vector3D.h" #include "network/NetServer.h" #include "network/NetClient.h" @@ -318,9 +317,6 @@ void Render() static void RegisterJavascriptInterfaces() { - // maths - JSI_Vector3D::init(); - // GUI CGUI::ScriptingInit(); diff --git a/source/ps/scripting/JSInterface_VFS.cpp b/source/ps/scripting/JSInterface_VFS.cpp index 791484a180..877bb14263 100644 --- a/source/ps/scripting/JSInterface_VFS.cpp +++ b/source/ps/scripting/JSInterface_VFS.cpp @@ -23,7 +23,7 @@ #include "ps/Filesystem.h" //#include "lib/res/file/archive/vfs_optimizer.h" // ArchiveBuilderCancel #include "scripting/ScriptingHost.h" -#include "scripting/JSConversions.h" +#include "scriptinterface/ScriptInterface.h" #include "ps/scripting/JSInterface_VFS.h" #include "lib/file/vfs/vfs_util.h" @@ -70,7 +70,7 @@ static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED { BuildDirEntListState* s = (BuildDirEntListState*)cbData; - jsval val = ToJSVal( CStrW(pathname.string()) ); + jsval val = ScriptInterface::ToJSVal(s->cx, CStrW(pathname.string())); JS_SetElement(s->cx, s->filename_array, s->cur_idx++, &val); return INFO::OK; } @@ -95,13 +95,13 @@ JSBool JSI_VFS::BuildDirEntList(JSContext* cx, uintN argc, jsval* vp) JSU_REQUIRE_MIN_PARAMS(1); CStrW path; - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[0], path)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], path)) return JS_FALSE; CStrW filter_str = L""; if (argc >= 2) { - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[1], filter_str)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[1], filter_str)) return JS_FALSE; } // convert to const wchar_t*; if there's no filter, pass 0 for speed @@ -113,7 +113,7 @@ JSBool JSI_VFS::BuildDirEntList(JSContext* cx, uintN argc, jsval* vp) bool recursive = false; if (argc >= 3) { - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[2], recursive)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[2], recursive)) return JS_FALSE; } int flags = recursive ? vfs::DIR_RECURSIVE : 0; @@ -137,14 +137,14 @@ JSBool JSI_VFS::GetFileMTime(JSContext* cx, uintN argc, jsval* vp) JSU_REQUIRE_MIN_PARAMS(1); CStrW filename; - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[0], filename)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename)) return JS_FALSE; CFileInfo fileInfo; Status err = g_VFS->GetFileInfo(filename, &fileInfo); JS_CHECK_FILE_ERR(err); - JS_SET_RVAL(cx, vp, ToJSVal((double)fileInfo.MTime())); + JS_SET_RVAL(cx, vp, ScriptInterface::ToJSVal(cx, (double)fileInfo.MTime())); return JS_TRUE; } @@ -158,14 +158,14 @@ JSBool JSI_VFS::GetFileSize(JSContext* cx, uintN argc, jsval* vp) JSU_REQUIRE_MIN_PARAMS(1); CStrW filename; - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[0], filename)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename)) return JS_FALSE; CFileInfo fileInfo; Status err = g_VFS->GetFileInfo(filename, &fileInfo); JS_CHECK_FILE_ERR(err); - JS_SET_RVAL(cx, vp, ToJSVal( (unsigned)fileInfo.Size() )); + JS_SET_RVAL(cx, vp, ScriptInterface::ToJSVal(cx, (unsigned)fileInfo.Size())); return JS_TRUE; } @@ -179,7 +179,7 @@ JSBool JSI_VFS::ReadFile(JSContext* cx, uintN argc, jsval* vp) JSU_REQUIRE_MIN_PARAMS(1); CStrW filename; - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[0], filename)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename)) return JS_FALSE; // @@ -198,7 +198,7 @@ JSBool JSI_VFS::ReadFile(JSContext* cx, uintN argc, jsval* vp) contents.Replace("\r\n", "\n"); // Decode as UTF-8 - JS_SET_RVAL(cx, vp, ToJSVal( contents.FromUTF8() )); + JS_SET_RVAL(cx, vp, ScriptInterface::ToJSVal(cx, contents.FromUTF8())); return JS_TRUE; } @@ -212,7 +212,7 @@ JSBool JSI_VFS::ReadFileLines(JSContext* cx, uintN argc, jsval* vp) JSU_REQUIRE_MIN_PARAMS(1); CStrW filename; - if (!ToPrimitive (cx, JS_ARGV(cx, vp)[0], filename)) + if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename)) return (JS_FALSE); // @@ -243,7 +243,7 @@ JSBool JSI_VFS::ReadFileLines(JSContext* cx, uintN argc, jsval* vp) while (std::getline(ss, line)) { // Decode each line as UTF-8 - jsval val = ToJSVal(CStr(line).FromUTF8()); + jsval val = ScriptInterface::ToJSVal(cx, CStr(line).FromUTF8()); JS_SetElement(cx, line_array, cur_line++, &val); } diff --git a/source/scripting/JSConversions.cpp b/source/scripting/JSConversions.cpp deleted file mode 100644 index 09b6a0d00b..0000000000 --- a/source/scripting/JSConversions.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* Copyright (C) 2013 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "JSConversions.h" -#include "graphics/ObjectManager.h" -#include "maths/scripting/JSInterface_Vector3D.h" -#include "lib/sysdep/sysdep.h" // isfinite -#include "scriptinterface/ScriptInterface.h" -#include -#include - -// CVector3D - -template<> CVector3D* ToNative( JSContext* cx, JSObject* obj ) -{ - JSI_Vector3D::Vector3D_Info* v = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( cx, obj, &JSI_Vector3D::JSI_class, NULL ); - return( v ? v->vector : NULL ); -} - -template<> JSObject* ToScript( CVector3D* Native ) -{ - JSObject* Script = JS_NewObject( g_ScriptingHost.GetContext(), &JSI_Vector3D::JSI_class, NULL, NULL ); - JS_SetPrivate( g_ScriptingHost.GetContext(), Script, new JSI_Vector3D::Vector3D_Info( *Native ) ); - return( Script ); -} - -template<> jsval ToJSVal( const CVector3D& Native ) -{ - JSObject* Script = JS_NewObject( g_ScriptingHost.GetContext(), &JSI_Vector3D::JSI_class, NULL, NULL ); - JS_SetPrivate( g_ScriptingHost.GetContext(), Script, new JSI_Vector3D::Vector3D_Info( Native ) ); - return( OBJECT_TO_JSVAL( Script ) ); -} - -// int - -template<> jsval ToJSVal( const int& Native ) -{ - return( INT_TO_JSVAL( Native ) ); -} - -template<> jsval ToJSVal( int& Native ) -{ - return( INT_TO_JSVAL( Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, int& Storage ) -{ - JSBool ok = JS_ValueToInt32(cx, v, (int32*)&Storage); - return ok == JS_TRUE; -} - -// unsigned - -template<> jsval ToJSVal( const unsigned& Native ) -{ - return( INT_TO_JSVAL( Native ) ); -} - -template<> jsval ToJSVal( unsigned& Native ) -{ - return( INT_TO_JSVAL( Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, unsigned& Storage ) -{ - int temp; - if(!ToPrimitive(cx, v, temp)) - return false; - if(temp < 0) - return false; - Storage = (unsigned)temp; - return true; -} - -// long -template<> jsval ToJSVal( const long& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> jsval ToJSVal( long& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, long& Storage ) -{ - int32 tmp; - JSBool ok = JS_ValueToInt32(cx, v, &tmp); - Storage = (long)tmp; - return ok == JS_TRUE; -} - -// unsigned long -template<> jsval ToJSVal( const unsigned long& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> jsval ToJSVal( unsigned long& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, unsigned long& Storage ) -{ - int32 tmp; - JSBool ok = JS_ValueToInt32(cx, v, &tmp); - Storage = (unsigned long)tmp; - return ok == JS_TRUE; -} - -// see comment at declaration of specialization -#if !GCC_VERSION -#if ARCH_AMD64 - -template<> jsval ToJSVal( const size_t& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> jsval ToJSVal( size_t& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, size_t& Storage ) -{ - int temp; - if(!ToPrimitive(cx, v, temp)) - return false; - if(temp < 0) - return false; - Storage = (size_t)temp; - return true; -} - - -template<> jsval ToJSVal( const ssize_t& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> jsval ToJSVal( ssize_t& Native ) -{ - return( INT_TO_JSVAL( (int)Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, ssize_t& Storage ) -{ - int temp; - if(!ToPrimitive(cx, v, temp)) - return false; - if(temp < 0) - return false; - Storage = (ssize_t)temp; - return true; -} - -#endif // #if ARCH_AMD64 -#endif // #if !GCC_VERSION - -// double - -template<> jsval ToJSVal( const double& Native ) -{ - jsval val = JSVAL_VOID; - JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); - return val; -} - -template<> jsval ToJSVal( double& Native ) -{ - jsval val = JSVAL_VOID; - JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); - return val; -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, double& Storage ) -{ - JSBool ok = JS_ValueToNumber(cx, v, &Storage); - if (ok == JS_FALSE || !isfinite( Storage ) ) - return false; - return true; -} - -// float - -template<> jsval ToJSVal( const float& Native ) -{ - jsval val = JSVAL_VOID; - JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); - return val; -} - -template<> jsval ToJSVal( float& Native ) -{ - jsval val = JSVAL_VOID; - JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); - return val; -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, float& Storage ) -{ - double temp; - if(!ToPrimitive(cx, v, temp)) - return false; - Storage = (float)temp; - return true; -} - - -// bool - -template<> jsval ToJSVal( const bool& Native ) -{ - return( BOOLEAN_TO_JSVAL( Native ) ); -} - -template<> jsval ToJSVal( bool& Native ) -{ - return( BOOLEAN_TO_JSVAL( Native ) ); -} - -template<> bool ToPrimitive( JSContext* cx, jsval v, bool& Storage ) -{ - JSBool temp; - JSBool ok = JS_ValueToBoolean(cx, v, &temp); - if(ok == JS_FALSE) - return false; - Storage = (temp == JS_TRUE); - return true; -} - -// CStrW -template<> bool ToPrimitive( JSContext* UNUSED(cx), jsval v, CStrW& Storage ) -{ - try - { - Storage = g_ScriptingHost.ValueToUCString( v ); - } - catch( PSERROR_Scripting_ConversionFailed& ) - { - return( false ); - } - return( true ); -} - -template<> jsval ToJSVal( const CStrW& Native ) -{ - return( STRING_TO_JSVAL( JS_NewUCStringCopyZ( g_ScriptingHost.GetContext(), reinterpret_cast(Native.utf16().c_str()) ) ) ); -} - -template<> jsval ToJSVal( CStrW& Native ) -{ - return( STRING_TO_JSVAL( JS_NewUCStringCopyZ( g_ScriptingHost.GetContext(), reinterpret_cast(Native.utf16().c_str()) ) ) ); -} - -// CStr/CStr8 - -template<> bool ToPrimitive( JSContext* cx, jsval v, CStr8& Storage ) -{ - std::string str; - if (!ScriptInterface::FromJSVal(cx, v, str)) - return false; - Storage = str; - return true; -} - -template<> jsval ToJSVal( const CStr8& Native ) -{ - return( STRING_TO_JSVAL( JS_NewStringCopyZ( g_ScriptingHost.GetContext(), Native.c_str() ) ) ); -} - -template<> jsval ToJSVal( CStr8& Native ) -{ - return( STRING_TO_JSVAL( JS_NewStringCopyZ( g_ScriptingHost.GetContext(), Native.c_str() ) ) ); -} diff --git a/source/scripting/JSConversions.h b/source/scripting/JSConversions.h deleted file mode 100644 index 4865d31713..0000000000 --- a/source/scripting/JSConversions.h +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// A general system of converting between native objects and their JavaScript representations - -#ifndef INCLUDED_JSCONVERSIONS -#define INCLUDED_JSCONVERSIONS - -#include "scripting/ScriptingHost.h" - -class CStrW; -class CScriptObject; -class CObjectEntry; -class CVector3D; - -// ----- -// -// Defaults -// -// ----- - -template T* ToNative( JSContext* cx, JSObject* obj ) -{ - return( (T*)JS_GetInstancePrivate( cx, obj, &T::JSI_class, NULL ) ); -} - -template JSObject* ToScript( T* Native ) -{ - if( !Native ) - return( (JSObject*)NULL ); - return( Native->GetScript() ); -} - -template T* ToNative( jsval v ) -{ - if( !JSVAL_IS_OBJECT( v ) ) return( NULL ); - if( v == JSVAL_NULL ) return( NULL ); - return( ToNative( g_ScriptingHost.GetContext(), JSVAL_TO_OBJECT( v ) ) ); -} - -template bool ToPrimitive( JSContext* UNUSED(cx), jsval v, T& Storage ) -{ - T* Native = ToNative( v ); - if( !Native ) return( false ); - Storage = *Native; - return( true ); -} - -// Handle pointer-to-objects sensibly (by automatically dereferencing them one level) -template bool ToPrimitive( JSContext* UNUSED(cx), jsval v, T*& Storage ) -{ - T* Native = ToNative( v ); - if( !Native ) return( false ); - Storage = Native; - return( true ); -} - -// Throws PSERROR_Scripting_ConversionFailed on failure. -template inline T ToPrimitive( JSContext* cx, jsval v ) -{ - T Temp; - bool ok = ToPrimitive( cx, v, Temp ); - if( !ok ) throw PSERROR_Scripting_ConversionFailed(); - return( Temp ); -} - -// Throws PSERROR_Scripting_ConversionFailed on failure. -template inline T ToPrimitive( jsval v ) -{ - return( ToPrimitive( g_ScriptingHost.GetContext(), v ) ); -} - -template jsval ToJSVal( T& Native ) -{ - return( OBJECT_TO_JSVAL( ToScript( &Native ) ) ); -} - -template jsval ToJSVal( T*& Native ) -{ - return( OBJECT_TO_JSVAL( ToScript( Native ) ) ); -} - -template jsval ToJSVal( const T& Native ); - -// ----- -// -// Overrides -// -// ----- - -// CVector3D -template<> CVector3D* ToNative( JSContext* cx, JSObject* obj ); -template<> JSObject* ToScript( CVector3D* Native ); -template<> jsval ToJSVal( const CVector3D& Native ); - -// CObjectEntry -template<> bool ToPrimitive( JSContext* cx, jsval v, CObjectEntry*& Storage ); -template<> jsval ToJSVal( CObjectEntry*& Native ); - -// CScriptObject -template<> bool ToPrimitive( JSContext* cx, jsval v, CScriptObject& Storage ); -template<> jsval ToJSVal( CScriptObject& Native ); - -// int -template<> bool ToPrimitive( JSContext* cx, jsval v, int& Storage ); -template<> jsval ToJSVal( const int& Native ); -template<> jsval ToJSVal( int& Native ); - -// unsigned -template<> bool ToPrimitive( JSContext* cx, jsval v, unsigned& Storage ); -template<> jsval ToJSVal( const unsigned& Native ); -template<> jsval ToJSVal( unsigned& Native ); - -// long int -template<> bool ToPrimitive( JSContext* cx, jsval v, long& Storage ); -template<> jsval ToJSVal( const long& Native ); -template<> jsval ToJSVal( long& Native ); - -// unsigned long int -template<> bool ToPrimitive( JSContext* cx, jsval v, unsigned long& Storage ); -template<> jsval ToJSVal( const unsigned long& Native ); -template<> jsval ToJSVal( unsigned long& Native ); - -// (s)size_t are considered to be identical to (unsigned) int by GCC and -// their specializations would cause conflicts there. On x86_64 GCC, s/size_t -// is equivalent to (unsigned) long, but the same solution applies; use the -// long and unsigned long specializations instead of s/size_t. -#if !GCC_VERSION - -// for some reason, x64 MSC treats size_t as distinct from unsigned long: -#if ARCH_AMD64 - -// size_t -template<> bool ToPrimitive( JSContext* cx, jsval v, size_t& Storage ); -template<> jsval ToJSVal( const size_t& Native ); -template<> jsval ToJSVal( size_t& Native ); - -// ssize_t -template<> bool ToPrimitive( JSContext* cx, jsval v, ssize_t& Storage ); -template<> jsval ToJSVal( const ssize_t& Native ); -template<> jsval ToJSVal( ssize_t& Native ); - -#endif - -#endif - -// double -template<> bool ToPrimitive( JSContext* cx, jsval v, double& Storage ); -template<> jsval ToJSVal( const double& Native ); -template<> jsval ToJSVal( double& Native ); - -// float -template<> bool ToPrimitive( JSContext* cx, jsval v, float& Storage ); -template<> jsval ToJSVal( const float& Native ); -template<> jsval ToJSVal( float& Native ); - -// bool -template<> bool ToPrimitive( JSContext* cx, jsval v, bool& Storage ); -template<> jsval ToJSVal( const bool& Native ); -template<> jsval ToJSVal( bool& Native ); - -/* -// char* -template<> bool ToPrimitive( JSContext* cx, jsval v, char*& Storage ); -template<> jsval ToJSVal( const char* Native ); -template<> jsval ToJSVal( char* Native ); -*/ - -// CStrW -template<> bool ToPrimitive( JSContext* cx, jsval v, CStrW& Storage ); -template<> jsval ToJSVal( const CStrW& Native ); -template<> jsval ToJSVal( CStrW& Native ); - -// CStr(8) -template<> bool ToPrimitive( JSContext* cx, jsval v, CStr8& Storage ); -template<> jsval ToJSVal( const CStr8& Native ); -template<> jsval ToJSVal( CStr8& Native ); - -#endif diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index b2c73530bb..0a75439af1 100644 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -24,7 +24,6 @@ #include "precompiled.h" #include "ScriptGlue.h" -#include "JSConversions.h" #include "graphics/GameView.h" #include "graphics/LightEnv.h" @@ -37,7 +36,6 @@ #include "lib/svn_revision.h" #include "lib/timer.h" #include "lib/sysdep/sysdep.h" // sys_OpenFile -#include "maths/scripting/JSInterface_Vector3D.h" #include "network/NetServer.h" #include "ps/CConsole.h" #include "ps/CLogger.h" @@ -111,7 +109,8 @@ JSBool StartJsTimer(JSContext* cx, uintN argc, jsval* vp) ONCE(InitJsTimers()); JSU_REQUIRE_PARAMS(1); - size_t slot = ToPrimitive(JS_ARGV(cx, vp)[0]); + size_t slot; + ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], slot); if (slot >= MAX_JS_TIMERS) return JS_FALSE; @@ -125,7 +124,8 @@ JSBool StartJsTimer(JSContext* cx, uintN argc, jsval* vp) JSBool StopJsTimer(JSContext* cx, uintN argc, jsval* vp) { JSU_REQUIRE_PARAMS(1); - size_t slot = ToPrimitive(JS_ARGV(cx, vp)[0]); + size_t slot; + ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], slot); if (slot >= MAX_JS_TIMERS) return JS_FALSE; @@ -215,7 +215,8 @@ JSBool GetGUIObjectByName(JSContext* cx, uintN argc, jsval* vp) try { - CStr name = ToPrimitive(cx, JS_ARGV(cx, vp)[0]); + CStr name; + ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], name); IGUIObject* guiObj = g_GUI->FindObjectByName(name); if (guiObj) JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(guiObj->GetJSObject())); @@ -340,7 +341,7 @@ JSBool SetPaused(JSContext* cx, uintN argc, jsval* vp) try { - g_Game->m_Paused = ToPrimitive (JS_ARGV(cx, vp)[0]); + ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], g_Game->m_Paused); if ( g_SoundManager ) g_SoundManager->Pause(g_Game->m_Paused); diff --git a/source/scriptinterface/DebuggingServer.cpp b/source/scriptinterface/DebuggingServer.cpp index 1fe8f3f541..d729b85a06 100644 --- a/source/scriptinterface/DebuggingServer.cpp +++ b/source/scriptinterface/DebuggingServer.cpp @@ -21,7 +21,6 @@ #include "ThreadDebugger.h" #include "ps/CLogger.h" #include "ps/Filesystem.h" -#include "scripting/JSConversions.h" CDebuggingServer* g_DebuggingServer = NULL; diff --git a/source/scriptinterface/ScriptConversions.cpp b/source/scriptinterface/ScriptConversions.cpp index b7a22840f7..22e1cf52d1 100644 --- a/source/scriptinterface/ScriptConversions.cpp +++ b/source/scriptinterface/ScriptConversions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2013 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -100,6 +100,49 @@ template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, u8& out) return true; } +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, long& out) +{ + int32 tmp; + JSBool ok = JS_ValueToInt32(cx, v, &tmp); + out = (long)tmp; + return ok == JS_TRUE; +} + +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, unsigned long& out) +{ + int32 tmp; + JSBool ok = JS_ValueToInt32(cx, v, &tmp); + out = (unsigned long)tmp; + return ok == JS_TRUE; +} + +// see comment below (where the same preprocessor condition is used) +#if MSC_VERSION && ARCH_AMD64 + +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, size_t& out) +{ + int temp; + if(!FromJSVal(cx, v, temp)) + return false; + if(temp < 0) + return false; + out = (size_t)temp; + return true; +} + +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, ssize_t& out) +{ + int temp; + if(!FromJSVal(cx, v, temp)) + return false; + if(temp < 0) + return false; + out = (ssize_t)temp; + return true; +} + +#endif + // NOTE: we can't define a jsval specialisation, because that conflicts with integer types template<> bool ScriptInterface::FromJSVal(JSContext* UNUSED(cx), jsval v, CScriptVal& out) { @@ -150,6 +193,16 @@ template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, return true; } +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, CStr8& out) +{ + return ScriptInterface::FromJSVal(cx, v, static_cast(out)); +} + +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, CStrW& out) +{ + return ScriptInterface::FromJSVal(cx, v, static_cast(out)); +} + template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, Entity& out) { JSObject* obj; @@ -220,6 +273,35 @@ template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const u32& val) return rval; } +template<> jsval ScriptInterface::ToJSVal(JSContext* UNUSED(cx), const long& val) +{ + return INT_TO_JSVAL((int)val); +} + +template<> jsval ScriptInterface::ToJSVal(JSContext* UNUSED(cx), const unsigned long& val) +{ + return INT_TO_JSVAL((int)val); +} + +// (s)size_t are considered to be identical to (unsigned) int by GCC and +// their specializations would cause conflicts there. On x86_64 GCC, s/size_t +// is equivalent to (unsigned) long, but the same solution applies; use the +// long and unsigned long specializations instead of s/size_t. +// for some reason, x64 MSC treats size_t as distinct from unsigned long: +#if MSC_VERSION && ARCH_AMD64 + +template<> jsval ScriptInterface::ToJSVal(JSContext* UNUSED(cx), const size_t& val) +{ + return INT_TO_JSVAL((int)val); +} + +template<> jsval ScriptInterface::ToJSVal(JSContext* UNUSED(cx), const ssize_t& val) +{ + return INT_TO_JSVAL((int)val); +} + +#endif + // NOTE: we can't define a jsval specialisation, because that conflicts with integer types template<> jsval ScriptInterface::ToJSVal(JSContext* UNUSED(cx), const CScriptVal& val) { @@ -281,7 +363,7 @@ template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const CStr8& val template static jsval ToJSVal_vector(JSContext* cx, const std::vector& val) { - JSObject* obj = JS_NewArrayObject(cx, val.size(), NULL); + JSObject* obj = JS_NewArrayObject(cx, (jsint)val.size(), NULL); if (!obj) return JSVAL_VOID; for (size_t i = 0; i < val.size(); ++i)