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.
This commit is contained in:
Yves
2013-10-20 17:13:53 +00:00
parent a4cd90ddfc
commit 20ed5b118c
9 changed files with 104 additions and 791 deletions
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<float> (*vp);
break;
case component_y:
vectorData->Y = ToPrimitive<float> (*vp);
break;
case component_z:
vectorData->Z = ToPrimitive<float> (*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<float> (JS_ARGV(cx, vp)[0]);
float y = ToPrimitive<float> (JS_ARGV(cx, vp)[1]);
float z = ToPrimitive<float> (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;
}
@@ -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 <http://www.gnu.org/licenses/>.
*/
// 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
-4
View File
@@ -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();
+13 -13
View File
@@ -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<CStrW> (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<CStrW> (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<bool> (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<CStrW> (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<CStrW> (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<CStrW> (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<CStrW> (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);
}
-294
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <math.h>
#include <cfloat>
// CVector3D
template<> CVector3D* ToNative<CVector3D>( 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>( 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<CVector3D>( 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<int>( const int& Native )
{
return( INT_TO_JSVAL( Native ) );
}
template<> jsval ToJSVal<int>( int& Native )
{
return( INT_TO_JSVAL( Native ) );
}
template<> bool ToPrimitive<int>( JSContext* cx, jsval v, int& Storage )
{
JSBool ok = JS_ValueToInt32(cx, v, (int32*)&Storage);
return ok == JS_TRUE;
}
// unsigned
template<> jsval ToJSVal<unsigned>( const unsigned& Native )
{
return( INT_TO_JSVAL( Native ) );
}
template<> jsval ToJSVal<unsigned>( unsigned& Native )
{
return( INT_TO_JSVAL( Native ) );
}
template<> bool ToPrimitive<unsigned>( JSContext* cx, jsval v, unsigned& Storage )
{
int temp;
if(!ToPrimitive<int>(cx, v, temp))
return false;
if(temp < 0)
return false;
Storage = (unsigned)temp;
return true;
}
// long
template<> jsval ToJSVal<long>( const long& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> jsval ToJSVal<long>( long& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> bool ToPrimitive<long>( 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<unsigned long>( const unsigned long& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> jsval ToJSVal<unsigned long>( unsigned long& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> bool ToPrimitive<unsigned long>( 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<size_t>( const size_t& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> jsval ToJSVal<size_t>( size_t& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> bool ToPrimitive<size_t>( JSContext* cx, jsval v, size_t& Storage )
{
int temp;
if(!ToPrimitive<int>(cx, v, temp))
return false;
if(temp < 0)
return false;
Storage = (size_t)temp;
return true;
}
template<> jsval ToJSVal<ssize_t>( const ssize_t& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> jsval ToJSVal<ssize_t>( ssize_t& Native )
{
return( INT_TO_JSVAL( (int)Native ) );
}
template<> bool ToPrimitive<ssize_t>( JSContext* cx, jsval v, ssize_t& Storage )
{
int temp;
if(!ToPrimitive<int>(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<double>( const double& Native )
{
jsval val = JSVAL_VOID;
JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
return val;
}
template<> jsval ToJSVal<double>( double& Native )
{
jsval val = JSVAL_VOID;
JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
return val;
}
template<> bool ToPrimitive<double>( 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<float>( const float& Native )
{
jsval val = JSVAL_VOID;
JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
return val;
}
template<> jsval ToJSVal<float>( float& Native )
{
jsval val = JSVAL_VOID;
JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val );
return val;
}
template<> bool ToPrimitive<float>( JSContext* cx, jsval v, float& Storage )
{
double temp;
if(!ToPrimitive<double>(cx, v, temp))
return false;
Storage = (float)temp;
return true;
}
// bool
template<> jsval ToJSVal<bool>( const bool& Native )
{
return( BOOLEAN_TO_JSVAL( Native ) );
}
template<> jsval ToJSVal<bool>( bool& Native )
{
return( BOOLEAN_TO_JSVAL( Native ) );
}
template<> bool ToPrimitive<bool>( 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<CStrW>( JSContext* UNUSED(cx), jsval v, CStrW& Storage )
{
try
{
Storage = g_ScriptingHost.ValueToUCString( v );
}
catch( PSERROR_Scripting_ConversionFailed& )
{
return( false );
}
return( true );
}
template<> jsval ToJSVal<CStrW>( const CStrW& Native )
{
return( STRING_TO_JSVAL( JS_NewUCStringCopyZ( g_ScriptingHost.GetContext(), reinterpret_cast<const jschar*>(Native.utf16().c_str()) ) ) );
}
template<> jsval ToJSVal<CStrW>( CStrW& Native )
{
return( STRING_TO_JSVAL( JS_NewUCStringCopyZ( g_ScriptingHost.GetContext(), reinterpret_cast<const jschar*>(Native.utf16().c_str()) ) ) );
}
// CStr/CStr8
template<> bool ToPrimitive<CStr8>( JSContext* cx, jsval v, CStr8& Storage )
{
std::string str;
if (!ScriptInterface::FromJSVal(cx, v, str))
return false;
Storage = str;
return true;
}
template<> jsval ToJSVal<CStr8>( const CStr8& Native )
{
return( STRING_TO_JSVAL( JS_NewStringCopyZ( g_ScriptingHost.GetContext(), Native.c_str() ) ) );
}
template<> jsval ToJSVal<CStr8>( CStr8& Native )
{
return( STRING_TO_JSVAL( JS_NewStringCopyZ( g_ScriptingHost.GetContext(), Native.c_str() ) ) );
}
-193
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
// 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<typename T> T* ToNative( JSContext* cx, JSObject* obj )
{
return( (T*)JS_GetInstancePrivate( cx, obj, &T::JSI_class, NULL ) );
}
template<typename T> JSObject* ToScript( T* Native )
{
if( !Native )
return( (JSObject*)NULL );
return( Native->GetScript() );
}
template<typename T> T* ToNative( jsval v )
{
if( !JSVAL_IS_OBJECT( v ) ) return( NULL );
if( v == JSVAL_NULL ) return( NULL );
return( ToNative<T>( g_ScriptingHost.GetContext(), JSVAL_TO_OBJECT( v ) ) );
}
template<typename T> bool ToPrimitive( JSContext* UNUSED(cx), jsval v, T& Storage )
{
T* Native = ToNative<T>( v );
if( !Native ) return( false );
Storage = *Native;
return( true );
}
// Handle pointer-to-objects sensibly (by automatically dereferencing them one level)
template<typename T> bool ToPrimitive( JSContext* UNUSED(cx), jsval v, T*& Storage )
{
T* Native = ToNative<T>( v );
if( !Native ) return( false );
Storage = Native;
return( true );
}
// Throws PSERROR_Scripting_ConversionFailed on failure.
template<typename T> 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<typename T> inline T ToPrimitive( jsval v )
{
return( ToPrimitive<T>( g_ScriptingHost.GetContext(), v ) );
}
template<typename T> jsval ToJSVal( T& Native )
{
return( OBJECT_TO_JSVAL( ToScript<T>( &Native ) ) );
}
template<typename T> jsval ToJSVal( T*& Native )
{
return( OBJECT_TO_JSVAL( ToScript<T>( Native ) ) );
}
template<typename T> jsval ToJSVal( const T& Native );
// -----
//
// Overrides
//
// -----
// CVector3D
template<> CVector3D* ToNative<CVector3D>( JSContext* cx, JSObject* obj );
template<> JSObject* ToScript<CVector3D>( CVector3D* Native );
template<> jsval ToJSVal<CVector3D>( const CVector3D& Native );
// CObjectEntry
template<> bool ToPrimitive<CObjectEntry>( JSContext* cx, jsval v, CObjectEntry*& Storage );
template<> jsval ToJSVal<CObjectEntry>( CObjectEntry*& Native );
// CScriptObject
template<> bool ToPrimitive<CScriptObject>( JSContext* cx, jsval v, CScriptObject& Storage );
template<> jsval ToJSVal<CScriptObject>( CScriptObject& Native );
// int
template<> bool ToPrimitive<int>( JSContext* cx, jsval v, int& Storage );
template<> jsval ToJSVal<int>( const int& Native );
template<> jsval ToJSVal<int>( int& Native );
// unsigned
template<> bool ToPrimitive<unsigned>( JSContext* cx, jsval v, unsigned& Storage );
template<> jsval ToJSVal<unsigned>( const unsigned& Native );
template<> jsval ToJSVal<unsigned>( unsigned& Native );
// long int
template<> bool ToPrimitive<long>( JSContext* cx, jsval v, long& Storage );
template<> jsval ToJSVal<long>( const long& Native );
template<> jsval ToJSVal<long>( long& Native );
// unsigned long int
template<> bool ToPrimitive<unsigned long>( JSContext* cx, jsval v, unsigned long& Storage );
template<> jsval ToJSVal<unsigned long>( const unsigned long& Native );
template<> jsval ToJSVal<unsigned long>( 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<size_t>( JSContext* cx, jsval v, size_t& Storage );
template<> jsval ToJSVal<size_t>( const size_t& Native );
template<> jsval ToJSVal<size_t>( size_t& Native );
// ssize_t
template<> bool ToPrimitive<ssize_t>( JSContext* cx, jsval v, ssize_t& Storage );
template<> jsval ToJSVal<ssize_t>( const ssize_t& Native );
template<> jsval ToJSVal<ssize_t>( ssize_t& Native );
#endif
#endif
// double
template<> bool ToPrimitive<double>( JSContext* cx, jsval v, double& Storage );
template<> jsval ToJSVal<double>( const double& Native );
template<> jsval ToJSVal<double>( double& Native );
// float
template<> bool ToPrimitive<float>( JSContext* cx, jsval v, float& Storage );
template<> jsval ToJSVal<float>( const float& Native );
template<> jsval ToJSVal<float>( float& Native );
// bool
template<> bool ToPrimitive<bool>( JSContext* cx, jsval v, bool& Storage );
template<> jsval ToJSVal<bool>( const bool& Native );
template<> jsval ToJSVal<bool>( bool& Native );
/*
// char*
template<> bool ToPrimitive<char*>( JSContext* cx, jsval v, char*& Storage );
template<> jsval ToJSVal<char*>( const char* Native );
template<> jsval ToJSVal<char*>( char* Native );
*/
// CStrW
template<> bool ToPrimitive<CStrW>( JSContext* cx, jsval v, CStrW& Storage );
template<> jsval ToJSVal<CStrW>( const CStrW& Native );
template<> jsval ToJSVal<CStrW>( CStrW& Native );
// CStr(8)
template<> bool ToPrimitive<CStr8>( JSContext* cx, jsval v, CStr8& Storage );
template<> jsval ToJSVal<CStr8>( const CStr8& Native );
template<> jsval ToJSVal<CStr8>( CStr8& Native );
#endif
+7 -6
View File
@@ -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<size_t>(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<size_t>(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<CStr>(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<bool> (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);
@@ -21,7 +21,6 @@
#include "ThreadDebugger.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h"
#include "scripting/JSConversions.h"
CDebuggingServer* g_DebuggingServer = NULL;
+84 -2
View File
@@ -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<u8>(JSContext* cx, jsval v, u8& out)
return true;
}
template<> bool ScriptInterface::FromJSVal<long>(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<unsigned long>(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<size_t>(JSContext* cx, jsval v, size_t& out)
{
int temp;
if(!FromJSVal<int>(cx, v, temp))
return false;
if(temp < 0)
return false;
out = (size_t)temp;
return true;
}
template<> bool ScriptInterface::FromJSVal<ssize_t>(JSContext* cx, jsval v, ssize_t& out)
{
int temp;
if(!FromJSVal<int>(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<CScriptVal>(JSContext* UNUSED(cx), jsval v, CScriptVal& out)
{
@@ -150,6 +193,16 @@ template<> bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, jsval v,
return true;
}
template<> bool ScriptInterface::FromJSVal<CStr8>(JSContext* cx, jsval v, CStr8& out)
{
return ScriptInterface::FromJSVal(cx, v, static_cast<std::string&>(out));
}
template<> bool ScriptInterface::FromJSVal<CStrW>(JSContext* cx, jsval v, CStrW& out)
{
return ScriptInterface::FromJSVal(cx, v, static_cast<std::wstring&>(out));
}
template<> bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, jsval v, Entity& out)
{
JSObject* obj;
@@ -220,6 +273,35 @@ template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* cx, const u32& val)
return rval;
}
template<> jsval ScriptInterface::ToJSVal<long>(JSContext* UNUSED(cx), const long& val)
{
return INT_TO_JSVAL((int)val);
}
template<> jsval ScriptInterface::ToJSVal<unsigned long>(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<size_t>(JSContext* UNUSED(cx), const size_t& val)
{
return INT_TO_JSVAL((int)val);
}
template<> jsval ScriptInterface::ToJSVal<ssize_t>(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<CScriptVal>(JSContext* UNUSED(cx), const CScriptVal& val)
{
@@ -281,7 +363,7 @@ template<> jsval ScriptInterface::ToJSVal<CStr8>(JSContext* cx, const CStr8& val
template<typename T> static jsval ToJSVal_vector(JSContext* cx, const std::vector<T>& 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)