Ticket #622: js-upgrade-wip.diff
File js-upgrade-wip.diff, 142.1 KB (added by , 14 years ago) |
---|
-
binaries/data/mods/_test.sim/simulation/components/test-entityid.js
diff -r 6b3ac7e864ba binaries/data/mods/_test.sim/simulation/components/test-entityid.js
a b 2 2 3 3 TestScript1A.prototype.GetX = function() { 4 4 // Test that .entity is readonly 5 delete this.entity; 6 this.entity = -1; 5 try { 6 delete this.entity; 7 Engine.TS_FAIL("Missed exception"); 8 } catch (e) { } 9 try { 10 this.entity = -1; 11 Engine.TS_FAIL("Missed exception"); 12 } catch (e) { } 7 13 8 14 // and return the value 9 15 return this.entity; -
binaries/data/mods/_test.sim/simulation/components/test-serialize.js
diff -r 6b3ac7e864ba binaries/data/mods/_test.sim/simulation/components/test-serialize.js
a b 19 19 20 20 TestScript1_entity.prototype.GetX = function() { 21 21 // Test that .entity is readonly 22 delete this.entity; 23 this.entity = -1; 22 try { 23 delete this.entity; 24 Engine.TS_FAIL("Missed exception"); 25 } catch (e) { } 26 try { 27 this.entity = -1; 28 Engine.TS_FAIL("Missed exception"); 29 } catch (e) { } 24 30 25 31 // and return the value 26 32 return this.entity; -
deleted file source/graphics/scripting/JSInterface_Camera.cpp
diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_Camera.cpp
+ - 1 /* Copyright (C) 2009 Wildfire Games.2 * This file is part of 0 A.D.3 *4 * 0 A.D. is free software: you can redistribute it and/or modify5 * it under the terms of the GNU General Public License as published by6 * the Free Software Foundation, either version 2 of the License, or7 * (at your option) any later version.8 *9 * 0 A.D. is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12 * GNU General Public License for more details.13 *14 * You should have received a copy of the GNU General Public License15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.16 */17 18 #include "precompiled.h"19 20 #include "JSInterface_Camera.h"21 22 #include "scripting/JSConversions.h"23 #include "maths/scripting/JSInterface_Vector3D.h"24 #include "graphics/Camera.h"25 #include "maths/Vector3D.h"26 #include "maths/Matrix3D.h"27 #include "maths/MathUtil.h"28 #include "graphics/Terrain.h"29 #include "ps/Game.h"30 #include "graphics/GameView.h"31 32 33 JSClass JSI_Camera::JSI_class = {34 "Camera", JSCLASS_HAS_PRIVATE,35 JS_PropertyStub, JS_PropertyStub,36 JSI_Camera::getProperty, JSI_Camera::setProperty,37 JS_EnumerateStub, JS_ResolveStub,38 JS_ConvertStub, JSI_Camera::finalize,39 NULL, NULL, NULL, NULL40 };41 42 JSPropertySpec JSI_Camera::JSI_props[] =43 {44 { "position", JSI_Camera::vector_position, JSPROP_ENUMERATE },45 { "orientation", JSI_Camera::vector_orientation, JSPROP_ENUMERATE },46 { "up", JSI_Camera::vector_up, JSPROP_ENUMERATE },47 { 0 },48 };49 50 JSFunctionSpec JSI_Camera::JSI_methods[] =51 {52 { "lookAt", JSI_Camera::lookAt, 2, 0, 0 },53 { "getFocus", JSI_Camera::getFocus, 0, 0, 0 },54 { 0 }55 };56 57 void JSI_Camera::init()58 {59 g_ScriptingHost.DefineCustomObjectType( &JSI_class, JSI_Camera::construct, 0, JSI_props, JSI_methods, NULL, NULL );60 }61 62 JSI_Camera::Camera_Info::Camera_Info()63 {64 Initialise();65 }66 67 JSI_Camera::Camera_Info::Camera_Info( const CVector3D& Position )68 {69 CMatrix3D Orient;70 Orient.SetXRotation( DEGTORAD( 30 ) );71 Orient.RotateY( DEGTORAD( -45 ) );72 Orient.Translate( Position );73 74 Initialise( (const CMatrix3D&)Orient );75 }76 77 JSI_Camera::Camera_Info::Camera_Info( const CVector3D& Position, const CVector3D& Orientation )78 {79 Initialise();80 m_Data->LookAlong( Position, Orientation, CVector3D( 0.0f, 1.0f, 0.0f ) );81 }82 83 JSI_Camera::Camera_Info::Camera_Info( const CVector3D& Position, const CVector3D& Orientation, const CVector3D& Up )84 {85 Initialise();86 m_Data->LookAlong( Position, Orientation, Up );87 }88 89 JSI_Camera::Camera_Info::Camera_Info( const CMatrix3D& Orientation )90 {91 Initialise( Orientation );92 }93 94 JSI_Camera::Camera_Info::Camera_Info( CCamera* Reference )95 {96 m_Data = Reference;97 m_EngineOwned = true;98 }99 100 JSI_Camera::Camera_Info::~Camera_Info()101 {102 if( !m_EngineOwned )103 delete( m_Data );104 }105 106 void JSI_Camera::Camera_Info::Initialise()107 {108 CMatrix3D Orient;109 Orient.SetXRotation( DEGTORAD( 30 ) );110 Orient.RotateY( DEGTORAD( -45 ) );111 Orient.Translate( 100, 150, -100 );112 113 Initialise( (const CMatrix3D&)Orient );114 }115 116 void JSI_Camera::Camera_Info::Initialise( const CMatrix3D& Orientation )117 {118 m_Data = new CCamera();119 m_EngineOwned = false;120 121 m_Data->LookAlong( Orientation.GetTranslation(), Orientation.GetIn(), Orientation.GetUp() );122 }123 124 void JSI_Camera::Camera_Info::Freshen()125 {126 m_sv_Position = m_Data->m_Orientation.GetTranslation();127 m_sv_Orientation = m_Data->m_Orientation.GetIn();128 m_sv_Up = m_Data->m_Orientation.GetUp();129 }130 131 void JSI_Camera::Camera_Info::Update()132 {133 m_Data->LookAlong( m_sv_Position, m_sv_Orientation, m_sv_Up );134 }135 136 void JSI_Camera::Camera_Info::FreshenTarget()137 {138 m_sv_Target = m_Data->GetFocus();139 }140 141 JSBool JSI_Camera::getCamera( JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )142 {143 if( g_Game && g_Game->GetView()->GetCamera() )144 {145 JSObject* camera = JS_NewObject( cx, &JSI_Camera::JSI_class, NULL, NULL );146 JS_SetPrivate( cx, camera, new Camera_Info( g_Game->GetView()->GetCamera() ) );147 *vp = OBJECT_TO_JSVAL( camera );148 }149 else150 {151 *vp = JSVAL_NULL;152 }153 return( JS_TRUE );154 }155 156 JSBool JSI_Camera::setCamera( JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp )157 {158 JSObject* camera = JSVAL_TO_OBJECT( *vp );159 Camera_Info* cameraInfo;160 if( !JSVAL_IS_OBJECT( *vp ) || NULL == ( cameraInfo = (Camera_Info*)JS_GetInstancePrivate( cx, camera, &JSI_Camera::JSI_class, NULL ) ) )161 {162 JS_ReportError( cx, "[Camera] Invalid object" );163 }164 else165 {166 g_Game->GetView()->GetCamera()->m_Orientation = cameraInfo->m_Data->m_Orientation;167 }168 return( JS_TRUE );169 }170 171 JSBool JSI_Camera::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )172 {173 if( !JSVAL_IS_INT( id ) )174 return( JS_TRUE );175 176 Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );177 if( !cameraInfo )178 {179 JS_ReportError( cx, "[Camera] Invalid Reference" );180 return( JS_TRUE );181 }182 183 CVector3D* d;184 185 switch( ToPrimitive<int>( id ) )186 {187 case vector_position: d = &cameraInfo->m_sv_Position; break;188 case vector_orientation: d = &cameraInfo->m_sv_Orientation; break;189 case vector_up: d = &cameraInfo->m_sv_Up; break;190 default: return( JS_TRUE );191 }192 193 JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );194 JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( d, cameraInfo, ( void( IPropertyOwner::* )() )&Camera_Info::Update, ( void( IPropertyOwner::* )() )&Camera_Info::Freshen ) );195 *vp = OBJECT_TO_JSVAL( vector3d );196 return( JS_TRUE );197 }198 199 JSBool JSI_Camera::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )200 {201 if( !JSVAL_IS_INT( id ) )202 return( JS_TRUE );203 204 Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );205 if( !cameraInfo )206 {207 JS_ReportError( cx, "[Camera] Invalid reference" );208 return( JS_TRUE );209 }210 211 JSObject* vector3d = JSVAL_TO_OBJECT( *vp );212 JSI_Vector3D::Vector3D_Info* v = NULL;213 214 if( JSVAL_IS_OBJECT( *vp ) && NULL != ( v = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( g_ScriptingHost.getContext(), vector3d, &JSI_Vector3D::JSI_class, NULL ) ) )215 {216 cameraInfo->Freshen();217 218 switch( ToPrimitive<int>( id ) )219 {220 case vector_position: cameraInfo->m_sv_Position = *( v->vector ); break;221 case vector_orientation: cameraInfo->m_sv_Orientation = *( v->vector ); break;222 case vector_up: cameraInfo->m_sv_Up = *( v->vector ); break;223 }224 225 cameraInfo->Update();226 }227 228 return( JS_TRUE );229 }230 231 #define GETVECTOR( jv ) ( ( JSVAL_IS_OBJECT( jv ) && NULL != ( v = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( g_ScriptingHost.getContext(), JSVAL_TO_OBJECT( jv ), &JSI_Vector3D::JSI_class, NULL ) ) ) ? *(v->vector) : CVector3D() )232 233 234 JSBool JSI_Camera::lookAt( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )235 {236 JSI_Vector3D::Vector3D_Info* v = NULL;237 Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );238 239 JSU_REQUIRE_PARAM_RANGE(2, 3);240 241 cameraInfo->m_sv_Position = GETVECTOR( argv[0] );242 cameraInfo->m_sv_Orientation = GETVECTOR( argv[1] ) - cameraInfo->m_sv_Position;243 cameraInfo->m_sv_Orientation.Normalize();244 245 if( argc == 2 )246 {247 cameraInfo->m_sv_Up = CVector3D( 0.0f, 1.0f, 0.0f );248 }249 else if( argc == 3 )250 {251 cameraInfo->m_sv_Up = GETVECTOR( argv[2] );252 }253 254 cameraInfo->Update();255 256 *rval = JSVAL_TRUE;257 return( JS_TRUE );258 }259 260 JSBool JSI_Camera::getFocus( JSContext* cx, JSObject* obj,261 uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )262 {263 // Largely copied from the equivalent method in CCamera264 265 Camera_Info* cameraInfo = (Camera_Info*)JS_GetPrivate( cx, obj );266 267 JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );268 JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( &( cameraInfo->m_sv_Target ), cameraInfo, NULL, ( void( IPropertyOwner::* )() )&Camera_Info::FreshenTarget ) );269 *rval = OBJECT_TO_JSVAL( vector3d );270 return( JS_TRUE );271 }272 273 JSBool JSI_Camera::construct( JSContext* cx, JSObject* UNUSED(obj),274 uintN argc, jsval* argv, jsval* rval )275 {276 JSI_Vector3D::Vector3D_Info* v = NULL;277 278 JSObject* camera = JS_NewObject( cx, &JSI_Camera::JSI_class, NULL, NULL );279 280 JSU_REQUIRE_MAX_PARAMS(3);281 Camera_Info* camera_info = 0;282 switch(argc)283 {284 case 0:285 camera_info = new Camera_Info();286 break;287 case 1:288 camera_info = new Camera_Info( GETVECTOR( argv[0] ) );289 break;290 case 2:291 camera_info = new Camera_Info( GETVECTOR( argv[0] ), GETVECTOR( argv[1] ) );292 break;293 case 3:294 camera_info = new Camera_Info( GETVECTOR( argv[0] ), GETVECTOR( argv[1] ), GETVECTOR( argv[2] ) );295 break;296 NODEFAULT;297 }298 299 #undef GET_VECTOR300 301 JS_SetPrivate( cx, camera, camera_info );302 *rval = OBJECT_TO_JSVAL( camera );303 return( JS_TRUE );304 }305 306 void JSI_Camera::finalize( JSContext* cx, JSObject* obj )307 {308 delete( (Camera_Info*)JS_GetPrivate( cx, obj ) );309 }310 -
deleted file source/graphics/scripting/JSInterface_Camera.h
diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_Camera.h
+ - 1 /* Copyright (C) 2009 Wildfire Games.2 * This file is part of 0 A.D.3 *4 * 0 A.D. is free software: you can redistribute it and/or modify5 * it under the terms of the GNU General Public License as published by6 * the Free Software Foundation, either version 2 of the License, or7 * (at your option) any later version.8 *9 * 0 A.D. is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12 * GNU General Public License for more details.13 *14 * You should have received a copy of the GNU General Public License15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.16 */17 18 // JSInterface_Camera.h19 //20 // A JavaScript wrapper around a camera object.21 //22 // Usage: When manipulating objects of type 'Camera' in JavaScript23 24 #include "scripting/ScriptingHost.h"25 26 #include "maths/Vector3D.h"27 #include "graphics/Camera.h"28 #include "graphics/HFTracer.h"29 30 #ifndef INCLUDED_JSI_CAMERA31 #define INCLUDED_JSI_CAMERA32 33 namespace JSI_Camera34 {35 enum36 {37 vector_position,38 vector_orientation,39 vector_up40 };41 42 enum43 {44 lookat45 };46 47 struct Camera_Info : public IPropertyOwner48 {49 CCamera* m_Data;50 bool m_EngineOwned;51 CVector3D m_sv_Position;52 CVector3D m_sv_Orientation;53 CVector3D m_sv_Up;54 CVector3D m_sv_Target;55 56 Camera_Info(); // Create a camera set to the initial view57 58 Camera_Info( const CVector3D& Position );59 Camera_Info( const CVector3D& Position, const CVector3D& Orientation );60 Camera_Info( const CVector3D& Position, const CVector3D& Orientation, const CVector3D& Up );61 Camera_Info( const CMatrix3D& Orientation );62 Camera_Info( CCamera* copy );63 64 void Initialise();65 void Initialise( const CMatrix3D& Orientation );66 67 void Freshen();68 void Update();69 void FreshenTarget();70 71 ~Camera_Info();72 /*73 74 Camera_Info( const CVector3D& _position );75 Camera_Info( const CVector3D& _position, const CVector3D& _orientation );76 Camera_Info( const CVector3D& _position, const CVector3D& _orientation, const CVector3D& _up );77 Camera_Info( CCamera* _copy );78 void update();79 80 */81 };82 extern JSClass JSI_class;83 extern JSPropertySpec JSI_props[];84 extern JSFunctionSpec JSI_methods[];85 86 JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );87 JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );88 89 JSBool getCamera( JSContext* cx, JSObject* obj, jsval id, jsval* vp );90 JSBool setCamera( JSContext* cx, JSObject* obj, jsval id, jsval* vp );91 92 JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );93 void finalize( JSContext* cx, JSObject* obj );94 95 JSBool lookAt( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );96 JSBool getFocus( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );97 98 void init();99 }100 101 #endif -
deleted file source/graphics/scripting/JSInterface_LightEnv.cpp
diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_LightEnv.cpp
+ - 1 /* Copyright (C) 2009 Wildfire Games.2 * This file is part of 0 A.D.3 *4 * 0 A.D. is free software: you can redistribute it and/or modify5 * it under the terms of the GNU General Public License as published by6 * the Free Software Foundation, either version 2 of the License, or7 * (at your option) any later version.8 *9 * 0 A.D. is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12 * GNU General Public License for more details.13 *14 * You should have received a copy of the GNU General Public License15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.16 */17 18 /*19 * Provide the LightEnv object type for JavaScript20 */21 22 #include "precompiled.h"23 24 #include "maths/scripting/JSInterface_Vector3D.h"25 26 #include "graphics/scripting/JSInterface_LightEnv.h"27 #include "graphics/LightEnv.h"28 29 #include "ps/World.h"30 31 #include "scripting/JSConversions.h"32 33 34 namespace JSI_LightEnv {35 36 namespace {37 38 extern JSClass JSI_class;39 40 /**41 * This enumeration is used to index properties with the JavaScript implementation.42 */43 enum44 {45 lightenv_elevation,46 lightenv_rotation,47 lightenv_terrainShadowTransparency,48 lightenv_sun,49 lightenv_terrainAmbient,50 lightenv_unitsAmbient51 };52 53 ///////////////////////////////////////////////////////////////////////////////////////////////54 // LightEnv_Info, the private structure that holds data for individual LightEnv objects55 56 struct LightEnv_Info : public IPropertyOwner57 {58 CLightEnv* m_Data;59 bool m_EngineOwned;60 61 // Create a new LightEnv that will only be used by JavaScript62 LightEnv_Info()63 {64 m_Data = new CLightEnv;65 m_EngineOwned = false;66 }67 68 // Use the given CLightEnv from the engine. The caller must guarantee that69 // the copy object will not be deleted.70 LightEnv_Info(CLightEnv* copy)71 {72 m_Data = copy;73 m_EngineOwned = true;74 }75 76 ~LightEnv_Info()77 {78 if (!m_EngineOwned)79 delete m_Data;80 }81 };82 83 84 ///////////////////////////////////////////////////////////////////////////////////////////////85 // Construction and finalization of LightEnvs86 87 /**88 * construct: the LightEnv constructor has been called from JavaScript, so create a new89 * LightEnv object90 */91 JSBool construct(JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)92 {93 JSObject* lightenv = JS_NewObject(cx, &JSI_class, NULL, NULL);94 95 JSU_REQUIRE_NO_PARAMS();96 97 JS_SetPrivate(cx, lightenv, new LightEnv_Info);98 *rval = OBJECT_TO_JSVAL(lightenv);99 return JS_TRUE;100 }101 102 /**103 * finalize: callback from the JS engine to indicate we should free our private data104 */105 void finalize(JSContext* cx, JSObject* obj)106 {107 delete (LightEnv_Info*)JS_GetPrivate(cx, obj);108 }109 110 111 ///////////////////////////////////////////////////////////////////////////////////////////////112 // Accessing properties of a LightEnv object113 114 // Can't use ToJSVal here because we need live updates from the vectors115 JSBool getVectorProperty(JSContext* cx, LightEnv_Info* lightenvInfo, CVector3D* vec, jsval* vp)116 {117 JSObject* vector3d = JS_NewObject(cx, &JSI_Vector3D::JSI_class, NULL, NULL);118 JS_SetPrivate(cx, vector3d, new JSI_Vector3D::Vector3D_Info(vec, lightenvInfo));119 *vp = OBJECT_TO_JSVAL(vector3d);120 return JS_TRUE;121 }122 123 124 JSBool getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)125 {126 if (!JSVAL_IS_INT(id))127 return JS_TRUE ;128 129 LightEnv_Info* lightenvInfo = (LightEnv_Info*)JS_GetPrivate(cx, obj);130 if (!lightenvInfo)131 {132 JS_ReportError(cx, "[LightEnv] Invalid Reference");133 return JS_TRUE;134 }135 136 CLightEnv* lightenv = lightenvInfo->m_Data;137 138 switch(ToPrimitive<int>(id)) {139 case lightenv_elevation: *vp = ToJSVal(lightenv->GetElevation()); break;140 case lightenv_rotation: *vp = ToJSVal(lightenv->GetRotation()); break;141 case lightenv_terrainShadowTransparency: *vp = ToJSVal(lightenv->GetTerrainShadowTransparency()); break;142 case lightenv_sun: return getVectorProperty(cx, lightenvInfo, &lightenv->m_SunColor, vp);143 case lightenv_terrainAmbient: return getVectorProperty(cx, lightenvInfo, &lightenv->m_TerrainAmbientColor, vp);144 case lightenv_unitsAmbient: return getVectorProperty(cx, lightenvInfo, &lightenv->m_UnitsAmbientColor, vp);145 default: break;146 }147 148 return JS_TRUE;149 }150 151 152 JSBool setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp)153 {154 if (!JSVAL_IS_INT(id))155 return( JS_TRUE );156 157 LightEnv_Info* lightenvInfo = (LightEnv_Info*)JS_GetPrivate(cx, obj);158 if (!lightenvInfo)159 {160 JS_ReportError(cx, "[LightEnv] Invalid reference");161 return JS_TRUE;162 }163 164 CLightEnv* lightenv = lightenvInfo->m_Data;165 166 switch(ToPrimitive<int>(id)) {167 case lightenv_elevation: lightenv->SetElevation(ToPrimitive<float>(*vp)); break;168 case lightenv_rotation: lightenv->SetRotation(ToPrimitive<float>(*vp)); break;169 case lightenv_terrainShadowTransparency: lightenv->SetTerrainShadowTransparency(ToPrimitive<float>(*vp)); break;170 case lightenv_sun: lightenv->m_SunColor = ToPrimitive<CVector3D>(*vp); break;171 case lightenv_terrainAmbient: lightenv->m_TerrainAmbientColor = ToPrimitive<CVector3D>(*vp); break;172 case lightenv_unitsAmbient: lightenv->m_UnitsAmbientColor = ToPrimitive<CVector3D>(*vp); break;173 default: break;174 }175 176 return JS_TRUE;177 }178 179 180 181 ///////////////////////////////////////////////////////////////////////////////////////////////182 // Registration of LightEnv class with JavaScript183 184 JSClass JSI_class = {185 "LightEnv", JSCLASS_HAS_PRIVATE,186 JS_PropertyStub, JS_PropertyStub,187 getProperty, setProperty,188 JS_EnumerateStub, JS_ResolveStub,189 JS_ConvertStub, finalize,190 NULL, NULL, NULL, NULL191 };192 193 JSPropertySpec JSI_props[] =194 {195 { "elevation", lightenv_elevation, JSPROP_ENUMERATE },196 { "rotation", lightenv_rotation, JSPROP_ENUMERATE },197 { "terrainShadowTransparency", lightenv_terrainShadowTransparency, JSPROP_ENUMERATE },198 { "sun", lightenv_sun, JSPROP_ENUMERATE },199 { "terrainAmbient", lightenv_terrainAmbient, JSPROP_ENUMERATE },200 { "unitsAmbient", lightenv_unitsAmbient, JSPROP_ENUMERATE },201 { 0 },202 };203 204 JSFunctionSpec JSI_methods[] =205 {206 { 0 }207 };208 209 } // anonymous namespace210 211 /**212 * init: called by GameSetup to register the LightEnv class with the JS engine.213 */214 void init()215 {216 g_ScriptingHost.DefineCustomObjectType( &JSI_class, construct, 0, JSI_props, JSI_methods, NULL, NULL );217 }218 219 220 ///////////////////////////////////////////////////////////////////////////////////////////////221 // Accessing the global lightenv222 223 JSBool getLightEnv(JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp)224 {225 JSObject* lightenv = JS_NewObject(cx, &JSI_class, NULL, NULL);226 JS_SetPrivate(cx, lightenv, new LightEnv_Info(&g_LightEnv));227 *vp = OBJECT_TO_JSVAL(lightenv);228 return JS_TRUE;229 }230 231 JSBool setLightEnv(JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp)232 {233 JSObject* lightenv = JSVAL_TO_OBJECT(*vp);234 LightEnv_Info* lightenvInfo;235 236 if (!JSVAL_IS_OBJECT(*vp) || NULL == (lightenvInfo = (LightEnv_Info*)JS_GetInstancePrivate(cx, lightenv, &JSI_class, NULL)))237 {238 JS_ReportError( cx, "[LightEnv] Invalid object" );239 }240 else241 {242 g_LightEnv = *lightenvInfo->m_Data;243 }244 245 return JS_TRUE;246 }247 248 } // namespace JSI_LightEnv249 250 -
deleted file source/graphics/scripting/JSInterface_LightEnv.h
diff -r 6b3ac7e864ba source/graphics/scripting/JSInterface_LightEnv.h
+ - 1 /* Copyright (C) 2009 Wildfire Games.2 * This file is part of 0 A.D.3 *4 * 0 A.D. is free software: you can redistribute it and/or modify5 * it under the terms of the GNU General Public License as published by6 * the Free Software Foundation, either version 2 of the License, or7 * (at your option) any later version.8 *9 * 0 A.D. is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12 * GNU General Public License for more details.13 *14 * You should have received a copy of the GNU General Public License15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.16 */17 18 /*19 * Provide the LightEnv object type for JavaScript20 */21 22 #ifndef INCLUDED_JSI_LIGHTENV23 #define INCLUDED_JSI_LIGHTENV24 25 #include "scripting/ScriptingHost.h"26 27 namespace JSI_LightEnv28 {29 void init();30 JSBool getLightEnv( JSContext* cx, JSObject* obj, jsval id, jsval* vp );31 JSBool setLightEnv( JSContext* cx, JSObject* obj, jsval id, jsval* vp );32 }33 34 #endif -
source/gui/CGUI.cpp
diff -r 6b3ac7e864ba source/gui/CGUI.cpp
a b 326 326 &IGUIObject::ScriptEvent, EventName.LowerCase()); 327 327 } 328 328 329 330 // Class needed for constructor 331 static JSClass global_class = { 332 "global", JSCLASS_GLOBAL_FLAGS, 333 JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, 334 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, 335 NULL, NULL, NULL, NULL, 336 NULL, NULL, NULL, NULL 337 }; 338 329 339 //------------------------------------------------------------------- 330 340 // Constructor / Destructor 331 341 //------------------------------------------------------------------- … … 334 344 m_BaseObject = new CGUIDummyObject; 335 345 m_BaseObject->SetGUI(this); 336 346 337 // Construct the parent object for all GUI JavaScript things 338 m_ScriptObject = JS_NewObject(g_ScriptingHost.getContext(), NULL, g_ScriptingHost.GetGlobalObject(), NULL); 339 debug_assert(m_ScriptObject != NULL); // How should it handle errors? 340 JS_AddRoot(g_ScriptingHost.getContext(), &m_ScriptObject); 347 // Construct the root object for all GUI JavaScript things 348 // (We need an object with no parent, so functions defined by scripts get 349 // put onto this object and not its parent. In the current version of SpiderMonkey 350 // that means it must be a global object. Then we adjust its prototype so it 351 // can still read standard properties from the context's standard global object.) 352 m_ScriptObject = JS_NewGlobalObject(g_ScriptingHost.getContext(), &global_class); 353 JS_AddObjectRoot(g_ScriptingHost.getContext(), &m_ScriptObject); 354 355 JS_SetPrototype(g_ScriptingHost.getContext(), m_ScriptObject, g_ScriptingHost.GetGlobalObject()); 341 356 } 342 357 343 358 CGUI::~CGUI() … … 350 365 if (m_ScriptObject) 351 366 { 352 367 // Let it be garbage-collected 353 JS_Remove Root(g_ScriptingHost.getContext(), &m_ScriptObject);368 JS_RemoveObjectRoot(g_ScriptingHost.getContext(), &m_ScriptObject); 354 369 } 355 370 } 356 371 -
source/gui/GUIManager.cpp
diff -r 6b3ac7e864ba source/gui/GUIManager.cpp
a b 48 48 return g_GUI->HandleEvent(ev); 49 49 } 50 50 51 CGUIManager::SGUIPage::SGUIPage()52 {53 JS_AddNamedRoot(g_ScriptingHost.GetContext(), &initData, "SGUIPage initData");54 }55 56 CGUIManager::SGUIPage::SGUIPage(const SGUIPage& page)57 {58 *this = page;59 JS_AddNamedRoot(g_ScriptingHost.GetContext(), &initData, "SGUIPage initData copy");60 }61 62 CGUIManager::SGUIPage::~SGUIPage()63 {64 JS_RemoveRoot(g_ScriptingHost.GetContext(), &initData);65 }66 67 51 CGUIManager::CGUIManager(ScriptInterface& scriptInterface) : 68 52 m_ScriptInterface(scriptInterface) 69 53 { … … 90 74 { 91 75 m_PageStack.push_back(SGUIPage()); 92 76 m_PageStack.back().name = pageName; 93 m_PageStack.back().initData = initData;77 m_PageStack.back().initData = CScriptValRooted(m_ScriptInterface.GetContext(), initData); 94 78 LoadPage(m_PageStack.back()); 95 79 } 96 80 -
source/gui/GUIManager.h
diff -r 6b3ac7e864ba source/gui/GUIManager.h
a b 135 135 private: 136 136 struct SGUIPage 137 137 { 138 SGUIPage();139 SGUIPage(const SGUIPage&);140 ~SGUIPage();141 142 138 CStrW name; 143 139 std::set<VfsPath> inputs; // for hotloading 144 140 145 141 JSContext* cx; 146 CScriptVal initData; // data to be passed to the init() function142 CScriptValRooted initData; // data to be passed to the init() function 147 143 148 144 shared_ptr<CGUI> gui; // the actual GUI page 149 145 }; -
source/gui/IGUIObject.cpp
diff -r 6b3ac7e864ba source/gui/IGUIObject.cpp
a b 90 90 std::map<CStr, JSObject**>::iterator it; 91 91 for (it = m_ScriptHandlers.begin(); it != m_ScriptHandlers.end(); ++it) 92 92 { 93 JS_Remove Root(g_ScriptingHost.getContext(), it->second);93 JS_RemoveObjectRoot(g_ScriptingHost.getContext(), it->second); 94 94 delete it->second; 95 95 } 96 96 } 97 97 98 98 if (m_JSObject) 99 JS_Remove Root(g_ScriptingHost.getContext(), &m_JSObject);99 JS_RemoveObjectRoot(g_ScriptingHost.getContext(), &m_JSObject); 100 100 } 101 101 102 102 //------------------------------------------------------------------- … … 488 488 { 489 489 JSObject** obj = new JSObject*; 490 490 *obj = Function; 491 JS_Add Root(g_ScriptingHost.getContext(), obj);491 JS_AddObjectRoot(g_ScriptingHost.getContext(), obj); 492 492 493 493 if (m_ScriptHandlers[Action]) 494 494 { 495 JS_Remove Root(g_ScriptingHost.getContext(), m_ScriptHandlers[Action]);495 JS_RemoveObjectRoot(g_ScriptingHost.getContext(), m_ScriptHandlers[Action]); 496 496 delete m_ScriptHandlers[Action]; 497 497 } 498 498 m_ScriptHandlers[Action] = obj; … … 504 504 if (it == m_ScriptHandlers.end()) 505 505 return; 506 506 507 // PRIVATE_TO_JSVAL assumes two-byte alignment,508 // so make sure that's always true509 debug_assert(! ((jsval)this & JSVAL_INT));510 511 507 // The IGUIObject needs to be stored inside the script's object 512 508 jsval guiObject = PRIVATE_TO_JSVAL(this); 513 509 … … 517 513 518 514 // TODO: why don't we use GetJSObject here? 519 515 520 // Prevent it from being garbage-collected before it's passed into the function521 JS_AddRoot(g_ScriptingHost.getContext(), &jsGuiObject);522 523 516 // Set up the 'mouse' parameter 524 517 jsval mouseParams[3]; 525 518 mouseParams[0] = INT_TO_JSVAL(m_pGUI->m_MousePos.x); … … 528 521 JSObject* mouseObj = JS_ConstructObjectWithArguments(g_ScriptingHost.getContext(), &JSI_GUIMouse::JSI_class, m_pGUI->m_ScriptObject, NULL, 3, mouseParams); 529 522 debug_assert(mouseObj); // TODO: Handle errors 530 523 531 // Don't garbage collect the mouse532 JS_AddRoot(g_ScriptingHost.getContext(), &mouseObj);533 534 524 jsval paramData[] = { OBJECT_TO_JSVAL(mouseObj) }; 535 525 536 526 jsval result; … … 539 529 { 540 530 JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%s\"", Action.c_str()); 541 531 } 542 543 // Allow the temporary parameters to be garbage-collected544 JS_RemoveRoot(g_ScriptingHost.getContext(), &mouseObj);545 JS_RemoveRoot(g_ScriptingHost.getContext(), &jsGuiObject);546 532 } 547 533 548 534 void IGUIObject::ScriptEvent(const CStr& Action, const CScriptValRooted& Argument) … … 571 557 if (! m_JSObject) 572 558 { 573 559 m_JSObject = JS_NewObject(g_ScriptingHost.getContext(), &JSI_IGUIObject::JSI_class, NULL, NULL); 574 JS_Add Root(g_ScriptingHost.getContext(), &m_JSObject);560 JS_AddObjectRoot(g_ScriptingHost.getContext(), &m_JSObject); 575 561 JS_SetPrivate(g_ScriptingHost.getContext(), m_JSObject, this); 576 562 } 577 563 return m_JSObject; -
source/gui/IGUIObject.h
diff -r 6b3ac7e864ba source/gui/IGUIObject.h
a b 145 145 friend class GUITooltip; 146 146 147 147 // Allow getProperty to access things like GetParent() 148 friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, js valid, jsval* vp);149 friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, js valid, jsval* vp);148 friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 149 friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 150 150 151 151 public: 152 152 IGUIObject(); -
source/gui/scripting/JSInterface_GUITypes.cpp
diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_GUITypes.cpp
a b 45 45 46 46 JSFunctionSpec JSI_GUISize::JSI_methods[] = 47 47 { 48 { "toString", JSI_GUISize::toString, 0, 0 , 0},48 { "toString", JSI_GUISize::toString, 0, 0 }, 49 49 { 0 } 50 50 }; 51 51 52 JSBool JSI_GUISize::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))52 JSBool JSI_GUISize::construct(JSContext* cx, uintN argc, jsval* vp) 53 53 { 54 JSObject* obj = JS_NewObject(cx, &JSI_GUISize::JSI_class, NULL, NULL); 55 54 56 if (argc == 8) 55 57 { 56 JS_SetProperty(cx, obj, "left", & argv[0]);57 JS_SetProperty(cx, obj, "top", & argv[1]);58 JS_SetProperty(cx, obj, "right", & argv[2]);59 JS_SetProperty(cx, obj, "bottom", & argv[3]);60 JS_SetProperty(cx, obj, "rleft", & argv[4]);61 JS_SetProperty(cx, obj, "rtop", & argv[5]);62 JS_SetProperty(cx, obj, "rright", & argv[6]);63 JS_SetProperty(cx, obj, "rbottom", & argv[7]);58 JS_SetProperty(cx, obj, "left", &JS_ARGV(cx, vp)[0]); 59 JS_SetProperty(cx, obj, "top", &JS_ARGV(cx, vp)[1]); 60 JS_SetProperty(cx, obj, "right", &JS_ARGV(cx, vp)[2]); 61 JS_SetProperty(cx, obj, "bottom", &JS_ARGV(cx, vp)[3]); 62 JS_SetProperty(cx, obj, "rleft", &JS_ARGV(cx, vp)[4]); 63 JS_SetProperty(cx, obj, "rtop", &JS_ARGV(cx, vp)[5]); 64 JS_SetProperty(cx, obj, "rright", &JS_ARGV(cx, vp)[6]); 65 JS_SetProperty(cx, obj, "rbottom", &JS_ARGV(cx, vp)[7]); 64 66 } 65 67 else if (argc == 4) 66 68 { 67 69 jsval zero = JSVAL_ZERO; 68 JS_SetProperty(cx, obj, "left", & argv[0]);69 JS_SetProperty(cx, obj, "top", & argv[1]);70 JS_SetProperty(cx, obj, "right", & argv[2]);71 JS_SetProperty(cx, obj, "bottom", & argv[3]);70 JS_SetProperty(cx, obj, "left", &JS_ARGV(cx, vp)[0]); 71 JS_SetProperty(cx, obj, "top", &JS_ARGV(cx, vp)[1]); 72 JS_SetProperty(cx, obj, "right", &JS_ARGV(cx, vp)[2]); 73 JS_SetProperty(cx, obj, "bottom", &JS_ARGV(cx, vp)[3]); 72 74 JS_SetProperty(cx, obj, "rleft", &zero); 73 75 JS_SetProperty(cx, obj, "rtop", &zero); 74 76 JS_SetProperty(cx, obj, "rright", &zero); … … 87 89 JS_SetProperty(cx, obj, "rbottom", &zero); 88 90 } 89 91 92 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); 90 93 return JS_TRUE; 91 94 } 92 95 … … 99 102 return CStr(per)+CStr("%")+( pix == 0.0 ? CStr() : pix > 0.0 ? CStr("+")+CStr(pix) : CStr(pix) ); 100 103 } 101 104 102 JSBool JSI_GUISize::toString(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)105 JSBool JSI_GUISize::toString(JSContext* cx, uintN argc, jsval* vp) 103 106 { 107 UNUSED2(argc); 108 104 109 CStr buffer; 105 110 106 111 try 107 112 { 108 #define SIDE(side) buffer += ToPercentString(g_ScriptingHost.GetObjectProperty_Double( obj, #side), g_ScriptingHost.GetObjectProperty_Double(obj, "r"#side));113 #define SIDE(side) buffer += ToPercentString(g_ScriptingHost.GetObjectProperty_Double(JS_THIS_OBJECT(cx, vp), #side), g_ScriptingHost.GetObjectProperty_Double(JS_THIS_OBJECT(cx, vp), "r"#side)); 109 114 SIDE(left); 110 115 buffer += " "; 111 116 SIDE(top); … … 117 122 } 118 123 catch (PSERROR_Scripting_ConversionFailed) 119 124 { 120 *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "<Error converting value to numbers>"));125 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "<Error converting value to numbers>"))); 121 126 return JS_TRUE; 122 127 } 123 128 124 *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer.c_str()));129 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer.c_str()))); 125 130 return JS_TRUE; 126 131 } 127 132 … … 149 154 150 155 JSFunctionSpec JSI_GUIColor::JSI_methods[] = 151 156 { 152 { "toString", JSI_GUIColor::toString, 0, 0 , 0},157 { "toString", JSI_GUIColor::toString, 0, 0 }, 153 158 { 0 } 154 159 }; 155 160 156 JSBool JSI_GUIColor::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))161 JSBool JSI_GUIColor::construct(JSContext* cx, uintN argc, jsval* vp) 157 162 { 163 JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL); 164 158 165 if (argc == 4) 159 166 { 160 JS_SetProperty(cx, obj, "r", & argv[0]);161 JS_SetProperty(cx, obj, "g", & argv[1]);162 JS_SetProperty(cx, obj, "b", & argv[2]);163 JS_SetProperty(cx, obj, "a", & argv[3]);167 JS_SetProperty(cx, obj, "r", &JS_ARGV(cx, vp)[0]); 168 JS_SetProperty(cx, obj, "g", &JS_ARGV(cx, vp)[1]); 169 JS_SetProperty(cx, obj, "b", &JS_ARGV(cx, vp)[2]); 170 JS_SetProperty(cx, obj, "a", &JS_ARGV(cx, vp)[3]); 164 171 } 165 172 else 166 173 { 167 174 // Nice magenta: 168 jsval r = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0)); 169 JS_SetProperty(cx, obj, "r", &r); 170 jsval g = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 0.0)); 171 JS_SetProperty(cx, obj, "g", &g); 172 jsval b = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0)); 173 JS_SetProperty(cx, obj, "b", &b); 174 jsval a = DOUBLE_TO_JSVAL(JS_NewDouble(cx, 1.0)); 175 JS_SetProperty(cx, obj, "a", &a); 175 jsval c; 176 if (!JS_NewNumberValue(cx, 1.0, &c)) 177 return JS_FALSE; 178 JS_SetProperty(cx, obj, "r", &c); 179 JS_SetProperty(cx, obj, "b", &c); 180 JS_SetProperty(cx, obj, "a", &c); 181 if (!JS_NewNumberValue(cx, 0.0, &c)) 182 return JS_FALSE; 183 JS_SetProperty(cx, obj, "g", &c); 176 184 } 185 186 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); 177 187 return JS_TRUE; 178 188 } 179 189 180 JSBool JSI_GUIColor::toString(JSContext* cx, JSObject* obj, 181 uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval) 190 JSBool JSI_GUIColor::toString(JSContext* cx, uintN argc, jsval* vp) 182 191 { 192 UNUSED2(argc); 193 194 jsdouble r, g, b, a; 195 if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "r"), &r)) return JS_FALSE; 196 if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "g"), &g)) return JS_FALSE; 197 if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "b"), &b)) return JS_FALSE; 198 if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "a"), &a)) return JS_FALSE; 199 183 200 char buffer[256]; 184 201 // Convert to integers, to be compatible with the GUI's string SetSetting 185 202 snprintf(buffer, 256, "%d %d %d %d", 186 (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "r"))),187 (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "g"))),188 (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "b"))),189 (int)( 255.0 * *JSVAL_TO_DOUBLE(g_ScriptingHost.GetObjectProperty(obj, "a"))));190 *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));203 (int)(255.0 * r), 204 (int)(255.0 * g), 205 (int)(255.0 * b), 206 (int)(255.0 * a)); 207 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer))); 191 208 return JS_TRUE; 192 209 } 193 210 … … 213 230 214 231 JSFunctionSpec JSI_GUIMouse::JSI_methods[] = 215 232 { 216 { "toString", JSI_GUIMouse::toString, 0, 0 , 0},233 { "toString", JSI_GUIMouse::toString, 0, 0 }, 217 234 { 0 } 218 235 }; 219 236 220 JSBool JSI_GUIMouse::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))237 JSBool JSI_GUIMouse::construct(JSContext* cx, uintN argc, jsval* vp) 221 238 { 239 JSObject* obj = JS_NewObject(cx, &JSI_GUIMouse::JSI_class, NULL, NULL); 240 222 241 if (argc == 3) 223 242 { 224 JS_SetProperty(cx, obj, "x", & argv[0]);225 JS_SetProperty(cx, obj, "y", & argv[1]);226 JS_SetProperty(cx, obj, "buttons", & argv[2]);243 JS_SetProperty(cx, obj, "x", &JS_ARGV(cx, vp)[0]); 244 JS_SetProperty(cx, obj, "y", &JS_ARGV(cx, vp)[1]); 245 JS_SetProperty(cx, obj, "buttons", &JS_ARGV(cx, vp)[2]); 227 246 } 228 247 else 229 248 { … … 232 251 JS_SetProperty(cx, obj, "y", &zero); 233 252 JS_SetProperty(cx, obj, "buttons", &zero); 234 253 } 254 255 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); 235 256 return JS_TRUE; 236 257 } 237 258 238 JSBool JSI_GUIMouse::toString(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)259 JSBool JSI_GUIMouse::toString(JSContext* cx, uintN argc, jsval* vp) 239 260 { 261 UNUSED2(argc); 262 263 int32 x, y, buttons; 264 if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "x"), &x)) return JS_FALSE; 265 if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "y"), &y)) return JS_FALSE; 266 if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "buttons"), &buttons)) return JS_FALSE; 267 240 268 char buffer[256]; 241 snprintf(buffer, 256, "%d %d %d", 242 JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "x")), 243 JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "y")), 244 JSVAL_TO_INT(g_ScriptingHost.GetObjectProperty(obj, "buttons")) ); 245 *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)); 269 snprintf(buffer, 256, "%d %d %d", x, y, buttons); 270 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer))); 246 271 return JS_TRUE; 247 272 } 248 273 -
source/gui/scripting/JSInterface_GUITypes.h
diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_GUITypes.h
a b 26 26 extern JSClass JSI_class; \ 27 27 extern JSPropertySpec JSI_props[]; \ 28 28 extern JSFunctionSpec JSI_methods[]; \ 29 JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); \30 JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); \29 JSBool construct(JSContext* cx, uintN argc, jsval* vp); \ 30 JSBool toString(JSContext* cx, uintN argc, jsval* vp); \ 31 31 } 32 32 33 33 GUISTDTYPE(Size) -
source/gui/scripting/JSInterface_IGUIObject.cpp
diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_IGUIObject.cpp
a b 46 46 47 47 JSFunctionSpec JSI_IGUIObject::JSI_methods[] = 48 48 { 49 { "toString", JSI_IGUIObject::toString, 0, 0 , 0},50 { "focus", JSI_IGUIObject::focus, 0, 0 , 0},51 { "blur", JSI_IGUIObject::blur, 0, 0 , 0},49 { "toString", JSI_IGUIObject::toString, 0, 0 }, 50 { "focus", JSI_IGUIObject::focus, 0, 0 }, 51 { "blur", JSI_IGUIObject::blur, 0, 0 }, 52 52 { 0 } 53 53 }; 54 54 55 JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, js valid, jsval* vp)55 JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) 56 56 { 57 CStr propName = JS_GetStringBytes(JS_ValueToString(cx, id)); 57 IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL); 58 if (!e) 59 return JS_FALSE; 60 61 jsval idval; 62 if (!JS_IdToValue(cx, id, &idval)) 63 return JS_FALSE; 64 65 CStr propName = g_ScriptingHost.ValueToString(idval); 58 66 59 67 // Skip some things which are known to be functions rather than properties. 60 68 // ("constructor" *must* be here, else it'll try to GetSettingType before … … 69 77 ) 70 78 return JS_TRUE; 71 79 72 IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj);73 74 80 // Use onWhatever to access event handlers 75 81 if (propName.Left(2) == "on") 76 82 { … … 143 149 float value; 144 150 GUI<float>::GetSetting(e, propName, value); 145 151 // Create a garbage-collectable double 146 *vp = DOUBLE_TO_JSVAL(JS_NewDouble(cx, value) ); 147 break; 152 return JS_NewNumberValue(cx, value, vp); 148 153 } 149 154 150 155 case GUIST_CColor: … … 154 159 JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL); 155 160 *vp = OBJECT_TO_JSVAL(obj); // root it 156 161 162 jsval c; 157 163 // Attempt to minimise ugliness through macrosity 158 #define P(x) jsval x = DOUBLE_TO_JSVAL(JS_NewDouble(cx, colour.x)); JS_SetProperty(cx, obj, #x, &x)164 #define P(x) if (!JS_NewNumberValue(cx, colour.x, &c)) return JS_FALSE; JS_SetProperty(cx, obj, #x, &c) 159 165 P(r); 160 166 P(g); 161 167 P(b); … … 286 292 } 287 293 } 288 294 289 JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, js valid, jsval* vp)295 JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) 290 296 { 291 IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj); 292 CStr propName = g_ScriptingHost.ValueToString(id); 297 IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL); 298 if (!e) 299 return JS_FALSE; 300 301 jsval idval; 302 if (!JS_IdToValue(cx, id, &idval)) 303 return JS_FALSE; 304 305 CStr propName = g_ScriptingHost.ValueToString(idval); 306 293 307 if (propName == "name") 294 308 { 295 309 CStr propValue = JS_GetStringBytes(JS_ValueToString(cx, *vp)); … … 549 563 } 550 564 551 565 552 JSBool JSI_IGUIObject::construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))566 JSBool JSI_IGUIObject::construct(JSContext* cx, uintN argc, jsval* vp) 553 567 { 554 568 if (argc == 0) 555 569 { … … 557 571 return JS_FALSE; 558 572 } 559 573 560 debug_assert(argc == 1);574 JSObject* obj = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL); 561 575 562 576 // Store the IGUIObject in the JS object's 'private' area 563 IGUIObject* guiObject = (IGUIObject*)JSVAL_TO_PRIVATE( argv[0]);577 IGUIObject* guiObject = (IGUIObject*)JSVAL_TO_PRIVATE(JS_ARGV(cx, vp)[0]); 564 578 JS_SetPrivate(cx, obj, guiObject); 565 579 580 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); 566 581 return JS_TRUE; 567 582 } 568 583 … … 571 586 g_ScriptingHost.DefineCustomObjectType(&JSI_class, construct, 1, JSI_props, JSI_methods, NULL, NULL); 572 587 } 573 588 574 JSBool JSI_IGUIObject::toString(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval)589 JSBool JSI_IGUIObject::toString(JSContext* cx, uintN argc, jsval* vp) 575 590 { 576 IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj ); 591 UNUSED2(argc); 592 593 IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); 594 if (!e) 595 return JS_FALSE; 577 596 578 597 char buffer[256]; 579 598 snprintf(buffer, 256, "[GUIObject: %s]", e->GetName().c_str()); 580 599 buffer[255] = 0; 581 *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer));600 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer))); 582 601 return JS_TRUE; 583 602 } 584 603 585 JSBool JSI_IGUIObject::focus(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* UNUSED(rval))604 JSBool JSI_IGUIObject::focus(JSContext* cx, uintN argc, jsval* vp) 586 605 { 587 IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj ); 606 UNUSED2(argc); 607 608 IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); 609 if (!e) 610 return JS_FALSE; 588 611 589 612 e->GetGUI()->SetFocusedObject(e); 590 613 return JS_TRUE; 591 614 } 592 615 593 JSBool JSI_IGUIObject::blur(JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* UNUSED(rval))616 JSBool JSI_IGUIObject::blur(JSContext* cx, uintN argc, jsval* vp) 594 617 { 595 IGUIObject* e = (IGUIObject*)JS_GetPrivate( cx, obj ); 618 UNUSED2(argc); 619 620 IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); 621 if (!e) 622 return JS_FALSE; 596 623 597 624 e->GetGUI()->SetFocusedObject(NULL); 598 625 return JS_TRUE; -
source/gui/scripting/JSInterface_IGUIObject.h
diff -r 6b3ac7e864ba source/gui/scripting/JSInterface_IGUIObject.h
a b 25 25 extern JSClass JSI_class; 26 26 extern JSPropertySpec JSI_props[]; 27 27 extern JSFunctionSpec JSI_methods[]; 28 JSBool addProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp); 29 JSBool delProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp); 30 JSBool getProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp); 31 JSBool setProperty(JSContext* cx, JSObject* obj, jsval id, jsval* vp); 32 JSBool construct(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); 33 JSBool toString(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); 34 JSBool focus(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); 35 JSBool blur(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); 28 JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 29 JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 30 JSBool construct(JSContext* cx, uintN argc, jsval* vp); 31 JSBool toString(JSContext* cx, uintN argc, jsval* vp); 32 JSBool focus(JSContext* cx, uintN argc, jsval* vp); 33 JSBool blur(JSContext* cx, uintN argc, jsval* vp); 36 34 void init(); 37 35 } 38 36 -
source/maths/scripting/JSInterface_Vector3D.cpp
diff -r 6b3ac7e864ba source/maths/scripting/JSInterface_Vector3D.cpp
a b 21 21 #include "scripting/JSConversions.h" 22 22 #include "scripting/ScriptingHost.h" 23 23 24 namespace JSI_Vector3D25 {26 static CVector3D* GetVector( JSContext* cx, JSObject* obj );27 }28 29 24 JSClass JSI_Vector3D::JSI_class = { 30 25 "Vector3D", JSCLASS_HAS_PRIVATE, 31 26 JS_PropertyStub, JS_PropertyStub, … … 45 40 46 41 JSFunctionSpec JSI_Vector3D::JSI_methods[] = 47 42 { 48 { "toString", JSI_Vector3D::toString, 0, 0, 0 }, 49 { "add", JSI_Vector3D::add, 1, 0, 0 }, 50 { "subtract", JSI_Vector3D::subtract, 1, 0, 0 }, 51 { "minus", JSI_Vector3D::subtract, 1, 0, 0 }, 52 { "negate", JSI_Vector3D::negate, 1, 0, 0 }, 53 { "scale", JSI_Vector3D::scale, 1, 0, 0 }, 54 { "multiply", JSI_Vector3D::scale, 1, 0, 0 }, 55 { "divide", JSI_Vector3D::divide, 1, 0, 0 }, 56 { "dot", JSI_Vector3D::dot, 1, 0, 0 }, 57 { "cross", JSI_Vector3D::cross, 1, 0, 0 }, 58 { "length", JSI_Vector3D::length, 0, 0, 0 }, 59 { "normalize", JSI_Vector3D::normalize, 0, 0, 0 }, 43 { "toString", JSI_Vector3D::toString, 0, 0 }, 60 44 { 0 } 61 45 }; 62 46 63 47 void JSI_Vector3D::init() 64 48 { 65 g_ScriptingHost.DefineCustomObjectType( &JSI_class, JSI_Vector3D::construct, 0, JSI_props, JSI_methods, NULL, NULL);49 g_ScriptingHost.DefineCustomObjectType(&JSI_class, JSI_Vector3D::construct, 0, JSI_props, JSI_methods, NULL, NULL); 66 50 } 67 51 68 52 JSI_Vector3D::Vector3D_Info::Vector3D_Info() … … 71 55 vector = new CVector3D(); 72 56 } 73 57 74 JSI_Vector3D::Vector3D_Info::Vector3D_Info( float x, float y, float z)58 JSI_Vector3D::Vector3D_Info::Vector3D_Info(float x, float y, float z) 75 59 { 76 60 owner = NULL; 77 vector = new CVector3D( x, y, z);61 vector = new CVector3D(x, y, z); 78 62 } 79 63 80 JSI_Vector3D::Vector3D_Info::Vector3D_Info( const CVector3D& copy)64 JSI_Vector3D::Vector3D_Info::Vector3D_Info(const CVector3D& copy) 81 65 { 82 66 owner = NULL; 83 vector = new CVector3D( copy.X, copy.Y, copy.Z);67 vector = new CVector3D(copy.X, copy.Y, copy.Z); 84 68 } 85 69 86 JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner)70 JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner) 87 71 { 88 72 owner = _owner; 89 73 updateFn = NULL; … … 91 75 vector = attach; 92 76 } 93 77 94 JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void( IPropertyOwner::*_updateFn )(void))78 JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void)) 95 79 { 96 80 owner = _owner; 97 81 updateFn = _updateFn; … … 99 83 vector = attach; 100 84 } 101 85 102 JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void( IPropertyOwner::*_updateFn )(void), void( IPropertyOwner::*_freshenFn )(void) ) 86 JSI_Vector3D::Vector3D_Info::Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void), 87 void(IPropertyOwner::*_freshenFn)(void)) 103 88 { 104 89 owner = _owner; 105 90 updateFn = _updateFn; … … 109 94 110 95 JSI_Vector3D::Vector3D_Info::~Vector3D_Info() 111 96 { 112 if( !owner ) delete( vector ); 97 if (!owner) 98 delete (vector); 113 99 } 114 100 115 JSBool JSI_Vector3D::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp)101 JSBool JSI_Vector3D::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) 116 102 { 117 if ( !JSVAL_IS_INT( id ))118 return ( JS_TRUE );103 if (!JSID_IS_INT(id)) 104 return JS_TRUE; 119 105 120 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj ); 121 if( !vectorInfo ) 106 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, obj, &JSI_Vector3D::JSI_class, NULL); 107 if (!vectorInfo) 108 return JS_FALSE; 109 110 CVector3D* vectorData = vectorInfo->vector; 111 112 if (vectorInfo->owner && vectorInfo->freshenFn) 113 ((vectorInfo->owner)->*(vectorInfo->freshenFn))(); 114 115 switch (JSID_TO_INT(id)) 122 116 { 123 JS_ReportError( cx, "[Vector3D] Invalid reference" ); 124 return( JS_TRUE ); 117 case component_x: 118 return JS_NewNumberValue(cx, vectorData->X, vp); 119 case component_y: 120 return JS_NewNumberValue(cx, vectorData->Y, vp); 121 case component_z: 122 return JS_NewNumberValue(cx, vectorData->Z, vp); 125 123 } 126 124 127 CVector3D* vectorData = vectorInfo->vector; 125 return JS_FALSE; 126 } 128 127 129 if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )(); 130 131 switch( ToPrimitive<int>( id ) ) 128 JSBool JSI_Vector3D::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) 129 { 130 if (!JSID_IS_INT(id)) 131 return JS_TRUE; 132 133 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, obj, &JSI_Vector3D::JSI_class, NULL); 134 if (!vectorInfo) 135 return JS_FALSE; 136 137 CVector3D* vectorData = vectorInfo->vector; 138 139 if (vectorInfo->owner && vectorInfo->freshenFn) 140 ((vectorInfo->owner)->*(vectorInfo->freshenFn))(); 141 142 switch (JSID_TO_INT(id)) 132 143 { 133 case component_x: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->X ) ); return( JS_TRUE ); 134 case component_y: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->Y ) ); return( JS_TRUE ); 135 case component_z: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->Z ) ); return( JS_TRUE ); 144 case component_x: 145 vectorData->X = ToPrimitive<float> (*vp); 146 break; 147 case component_y: 148 vectorData->Y = ToPrimitive<float> (*vp); 149 break; 150 case component_z: 151 vectorData->Z = ToPrimitive<float> (*vp); 152 break; 136 153 } 137 154 138 return( JS_FALSE ); 155 if (vectorInfo->owner && vectorInfo->updateFn) 156 ((vectorInfo->owner)->*(vectorInfo->updateFn))(); 157 158 return JS_TRUE; 139 159 } 140 160 141 JSBool JSI_Vector3D:: setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp)161 JSBool JSI_Vector3D::construct(JSContext* cx, uintN argc, jsval* vp) 142 162 { 143 if( !JSVAL_IS_INT( id ) ) 144 return( JS_TRUE ); 163 JSObject* vector = JS_NewObject(cx, &JSI_Vector3D::JSI_class, NULL, NULL); 145 164 146 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj ); 147 if( !vectorInfo ) 165 if (argc == 0) 148 166 { 149 JS_ReportError( cx, "[Vector3D] Invalid reference" ); 150 return( JS_TRUE ); 151 } 152 CVector3D* vectorData = vectorInfo->vector; 153 154 if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )(); 155 156 switch( ToPrimitive<int>( id ) ) 157 { 158 case component_x: vectorData->X = ToPrimitive<float>( *vp ); break; 159 case component_y: vectorData->Y = ToPrimitive<float>( *vp ); break; 160 case component_z: vectorData->Z = ToPrimitive<float>( *vp ); break; 161 } 162 163 164 if( vectorInfo->owner && vectorInfo->updateFn ) ( (vectorInfo->owner)->*(vectorInfo->updateFn) )(); 165 166 return( JS_TRUE ); 167 } 168 169 JSBool JSI_Vector3D::construct( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval ) 170 { 171 JSObject* vector = JS_NewObject( cx, &JSI_Vector3D::JSI_class, NULL, NULL ); 172 173 if( argc == 0 ) 174 { 175 JS_SetPrivate( cx, vector, new Vector3D_Info() ); 176 *rval = OBJECT_TO_JSVAL( vector ); 177 return( JS_TRUE ); 167 JS_SetPrivate(cx, vector, new Vector3D_Info()); 168 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(vector)); 169 return JS_TRUE; 178 170 } 179 171 180 172 JSU_REQUIRE_PARAMS(3); 181 173 try 182 174 { 183 float x = ToPrimitive<float> ( argv[0]);184 float y = ToPrimitive<float> ( argv[1]);185 float z = ToPrimitive<float> ( argv[2]);186 JS_SetPrivate( cx, vector, new Vector3D_Info( x, y, z ));187 *rval = OBJECT_TO_JSVAL( vector);188 return ( JS_TRUE );175 float x = ToPrimitive<float> (JS_ARGV(cx, vp)[0]); 176 float y = ToPrimitive<float> (JS_ARGV(cx, vp)[1]); 177 float z = ToPrimitive<float> (JS_ARGV(cx, vp)[2]); 178 JS_SetPrivate(cx, vector, new Vector3D_Info(x, y, z)); 179 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(vector)); 180 return JS_TRUE; 189 181 } 190 182 catch (PSERROR_Scripting_ConversionFailed) 191 183 { 192 184 // Invalid input (i.e. can't be coerced into doubles) - fail 193 JS_ReportError( cx, "Invalid parameters to Vector3D constructor" ); 194 *rval = JSVAL_NULL; 195 return( JS_FALSE ); 185 JS_ReportError(cx, "Invalid parameters to Vector3D constructor"); 186 return JS_FALSE; 196 187 } 197 188 } 198 189 199 void JSI_Vector3D::finalize( JSContext* cx, JSObject* obj)190 void JSI_Vector3D::finalize(JSContext* cx, JSObject* obj) 200 191 { 201 delete ( (Vector3D_Info*)JS_GetPrivate( cx, obj ));192 delete ((Vector3D_Info*)JS_GetPrivate(cx, obj)); 202 193 } 203 194 204 JSBool JSI_Vector3D::toString( JSContext* cx, JSObject* obj, 205 uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval ) 195 JSBool JSI_Vector3D::toString(JSContext* cx, uintN argc, jsval* vp) 206 196 { 207 197 char buffer[256]; 208 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj ); 198 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_Vector3D::JSI_class, NULL); 199 if (!vectorInfo) 200 return JS_FALSE; 209 201 210 if( !vectorInfo ) return( JS_TRUE ); 202 if (vectorInfo->owner && vectorInfo->freshenFn) 203 ((vectorInfo->owner)->*(vectorInfo->freshenFn))(); 211 204 212 if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )(); 213 214 CVector3D* vectorData = vectorInfo->vector; 215 sprintf_s( buffer, ARRAY_SIZE(buffer), "[object Vector3D: ( %f, %f, %f )]", vectorData->X, vectorData->Y, vectorData->Z ); 216 *rval = STRING_TO_JSVAL( JS_NewStringCopyZ( cx, buffer ) ); 217 return( JS_TRUE ); 205 CVector3D* vectorData = vectorInfo->vector; 206 sprintf_s(buffer, ARRAY_SIZE(buffer), "[object Vector3D: ( %f, %f, %f )]", vectorData->X, vectorData->Y, vectorData->Z); 207 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer))); 208 return JS_TRUE; 218 209 } 219 220 CVector3D* JSI_Vector3D::GetVector( JSContext* cx, JSObject* obj )221 {222 Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetInstancePrivate( cx, obj, &JSI_class, NULL );223 if( !vectorInfo )224 {225 JS_ReportError( cx, "[Vector3D] Invalid reference" );226 return( NULL );227 }228 if( vectorInfo->owner && vectorInfo->freshenFn ) ( (vectorInfo->owner)->*(vectorInfo->freshenFn) )();229 return( vectorInfo->vector );230 }231 232 #define GET_VECTORS\233 CVector3D* a = GetVector( cx, obj );\234 if(!a)\235 return( JS_TRUE );\236 if( ( argc == 0 ) || !JSVAL_IS_OBJECT( argv[0] ) )\237 {\238 invalid_param:\239 JS_ReportError( cx, "[Vector3D] Invalid parameter" );\240 return( JS_TRUE );\241 }\242 CVector3D* b = GetVector( cx, JSVAL_TO_OBJECT( argv[0] ) );\243 if(!b)\244 goto invalid_param;245 246 #define GET_VECTOR_AND_FLOAT\247 CVector3D* v = GetVector( cx, obj );\248 if(!v)\249 return( JS_TRUE );\250 float f;\251 if( ( argc == 0 ) || !ToPrimitive( cx, argv[0], f ) )\252 {\253 JS_ReportError( cx, "Invalid parameter" );\254 return( JS_TRUE );\255 }256 257 258 JSBool JSI_Vector3D::add( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )259 {260 GET_VECTORS;261 262 JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );263 JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *a + *b ) );264 *rval = OBJECT_TO_JSVAL( vector3d );265 266 return( JS_TRUE );267 }268 269 JSBool JSI_Vector3D::subtract( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )270 {271 GET_VECTORS;272 273 JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );274 JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *a - *b ) );275 *rval = OBJECT_TO_JSVAL( vector3d );276 277 return( JS_TRUE );278 }279 280 JSBool JSI_Vector3D::negate( JSContext* cx, JSObject* obj,281 uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )282 {283 CVector3D* v = GetVector( cx, obj );284 if(!v)285 return( JS_TRUE );286 287 *rval = ToJSVal( -( *v ) );288 289 return( JS_TRUE );290 }291 292 JSBool JSI_Vector3D::scale( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )293 {294 GET_VECTOR_AND_FLOAT;295 296 JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );297 JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *v * f ) );298 *rval = OBJECT_TO_JSVAL( vector3d );299 300 return( JS_TRUE );301 }302 303 JSBool JSI_Vector3D::divide( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )304 {305 GET_VECTOR_AND_FLOAT;306 307 JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );308 JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *v * ( 1.0f / f ) ) );309 *rval = OBJECT_TO_JSVAL( vector3d );310 311 return( JS_TRUE );312 }313 314 JSBool JSI_Vector3D::dot( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )315 {316 GET_VECTORS;317 318 *rval = ToJSVal( a->Dot( *b ) );319 return( JS_TRUE );320 }321 322 JSBool JSI_Vector3D::cross( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )323 {324 GET_VECTORS;325 326 *rval = ToJSVal( a->Cross( *b ) );327 return( JS_TRUE );328 }329 330 JSBool JSI_Vector3D::length( JSContext* cx, JSObject* obj,331 uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )332 {333 CVector3D* v = GetVector( cx, obj );334 if(!v)335 return( JS_TRUE );336 337 *rval = ToJSVal( v->Length() );338 return( JS_TRUE );339 }340 341 JSBool JSI_Vector3D::normalize( JSContext* cx, JSObject* obj,342 uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )343 {344 CVector3D* v = GetVector( cx, obj );345 if(!v)346 return( JS_TRUE );347 348 CVector3D r( v->X, v->Y, v->Z );349 r.Normalize();350 351 *rval = ToJSVal( r );352 return( JS_TRUE );353 } -
source/maths/scripting/JSInterface_Vector3D.h
diff -r 6b3ac7e864ba source/maths/scripting/JSInterface_Vector3D.h
a b 36 36 component_y, 37 37 component_z 38 38 }; 39 JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 40 JSBool add( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 41 JSBool subtract( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 42 JSBool negate( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 43 JSBool scale( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 44 JSBool divide( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 45 JSBool dot( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 46 JSBool cross( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 47 JSBool length( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 48 JSBool normalize( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); 39 JSBool toString(JSContext* cx, uintN argc, jsval* vp); 49 40 50 41 struct Vector3D_Info 51 42 { 52 43 IPropertyOwner* owner; 53 void ( IPropertyOwner::*updateFn)();54 void ( IPropertyOwner::*freshenFn)();44 void (IPropertyOwner::*updateFn)(); 45 void (IPropertyOwner::*freshenFn)(); 55 46 CVector3D* vector; 56 47 Vector3D_Info(); 57 Vector3D_Info( float x, float y, float z);58 Vector3D_Info( const CVector3D& copy);59 Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner);60 Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void (IPropertyOwner::*_updateFn)(void));61 Vector3D_Info( CVector3D* attach, IPropertyOwner* _owner, void (IPropertyOwner::*_updateFn)(void), void (IPropertyOwner::*_freshenFn)(void));48 Vector3D_Info(float x, float y, float z); 49 Vector3D_Info(const CVector3D& copy); 50 Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner); 51 Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void)); 52 Vector3D_Info(CVector3D* attach, IPropertyOwner* _owner, void(IPropertyOwner::*_updateFn)(void), void(IPropertyOwner::*_freshenFn)(void)); 62 53 ~Vector3D_Info(); 63 54 }; 64 55 extern JSClass JSI_class; 65 56 extern JSPropertySpec JSI_props[]; 66 57 extern JSFunctionSpec JSI_methods[]; 67 58 68 JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp);69 JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp);70 void finalize( JSContext* cx, JSObject* obj);71 JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);72 59 JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 60 JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 61 void finalize(JSContext* cx, JSObject* obj); 62 JSBool construct(JSContext* cx, uintN argc, jsval* vp); 63 void init(); 73 64 } 74 65 75 66 #endif 76 77 -
source/ps/ConfigDB.cpp
diff -r 6b3ac7e864ba source/ps/ConfigDB.cpp
a b 35 35 36 36 namespace ConfigNamespace_JS 37 37 { 38 JSBool GetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) 38 JSBool GetProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) 39 { 40 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj); 41 if (cfgNs < 0 || cfgNs >= CFG_LAST) 42 return JS_FALSE; 43 44 jsval idval; 45 if (!JS_IdToValue(cx, id, &idval)) 46 return JS_FALSE; 47 48 CStr propName = g_ScriptingHost.ValueToString(idval); 49 CConfigValue *val = g_ConfigDB.GetValue(cfgNs, propName); 50 if (val) 51 { 52 JSString *js_str = JS_NewStringCopyN(cx, val->m_String.c_str(), val->m_String.size()); 53 *vp = STRING_TO_JSVAL(js_str); 54 } 55 return JS_TRUE; 56 } 57 58 JSBool SetProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp) 39 59 { 40 60 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj); 41 61 if (cfgNs < 0 || cfgNs >= CFG_LAST) 42 62 return JS_FALSE; 43 63 44 CStr propName = g_ScriptingHost.ValueToString(id); 45 CConfigValue *val=g_ConfigDB.GetValue(cfgNs, propName); 46 if (val) 47 { 48 JSString *js_str=JS_NewStringCopyN(cx, val->m_String.c_str(), val->m_String.size()); 49 *vp = STRING_TO_JSVAL(js_str); 50 } 51 return JS_TRUE; 52 } 53 54 JSBool SetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) 55 { 56 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj); 57 if (cfgNs < 0 || cfgNs >= CFG_LAST) 64 jsval idval; 65 if (!JS_IdToValue(cx, id, &idval)) 58 66 return JS_FALSE; 59 67 60 CStr propName = g_ScriptingHost.ValueToString(id );61 CConfigValue *val =g_ConfigDB.CreateValue(cfgNs, propName);68 CStr propName = g_ScriptingHost.ValueToString(idval); 69 CConfigValue *val = g_ConfigDB.CreateValue(cfgNs, propName); 62 70 char *str; 63 71 if (JS_ConvertArguments(cx, 1, vp, "s", &str)) 64 72 { 65 val->m_String =str;73 val->m_String = str; 66 74 return JS_TRUE; 67 75 } 68 76 else … … 77 85 JS_ConvertStub, JS_FinalizeStub 78 86 }; 79 87 80 JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* UNUSED(argv), jsval* rval)88 JSBool Construct(JSContext* cx, uintN argc, jsval* vp) 81 89 { 82 if (argc != 0) 83 return JS_FALSE; 90 UNUSED2(argc); 84 91 85 JSObject *newObj =JS_NewObject(cx, &Class, NULL, obj);86 *rval=OBJECT_TO_JSVAL(newObj);92 JSObject *newObj = JS_NewObject(cx, &Class, NULL, NULL); 93 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObj)); 87 94 return JS_TRUE; 88 95 } 89 96 … … 92 99 JS_SetPrivate(cx, obj, (void *)((uintptr_t)cfgNs << 1)); // JS requires bottom bit = 0 93 100 } 94 101 95 JSBool WriteFile( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)102 JSBool WriteFile(JSContext* cx, uintN argc, jsval* vp) 96 103 { 97 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);104 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp)); 98 105 if (cfgNs < 0 || cfgNs >= CFG_LAST) 99 106 return JS_FALSE; 100 107 … … 103 110 104 111 JSBool useVFS; 105 112 char *path; 106 if (JS_ConvertArguments(cx, 2, argv, "bs", &useVFS, &path))113 if (JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "bs", &useVFS, &path)) 107 114 { 108 JSBool res =g_ConfigDB.WriteFile(cfgNs, useVFS?true:false, CStrW(path));109 *rval = BOOLEAN_TO_JSVAL(res);115 JSBool res = g_ConfigDB.WriteFile(cfgNs, useVFS ? true : false, CStrW(path)); 116 JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(res)); 110 117 return JS_TRUE; 111 118 } 112 119 else 113 120 return JS_FALSE; 114 121 } 115 122 116 JSBool Reload( JSContext* cx, JSObject* obj, uintN argc, jsval* UNUSED(argv), jsval* rval)123 JSBool Reload(JSContext* cx, uintN argc, jsval* vp) 117 124 { 118 125 if (argc != 0) 119 126 return JS_FALSE; 120 127 121 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);128 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp)); 122 129 if (cfgNs < 0 || cfgNs >= CFG_LAST) 123 130 return JS_FALSE; 124 131 125 JSBool ret =g_ConfigDB.Reload(cfgNs);126 *rval = BOOLEAN_TO_JSVAL(ret);132 JSBool ret = g_ConfigDB.Reload(cfgNs); 133 JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(ret)); 127 134 return JS_TRUE; 128 135 } 129 136 130 JSBool SetFile( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))137 JSBool SetFile(JSContext* cx, uintN argc, jsval* vp) 131 138 { 132 139 if (argc != 0) 133 140 return JS_FALSE; 134 141 135 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);142 EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp)); 136 143 if (cfgNs < 0 || cfgNs >= CFG_LAST) 137 144 return JS_FALSE; 138 145 139 146 JSBool useVFS; 140 147 char *path; 141 if (JS_ConvertArguments(cx, 2, argv, "bs", &useVFS, &path))148 if (JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "bs", &useVFS, &path)) 142 149 { 143 g_ConfigDB.SetConfigFile(cfgNs, useVFS?true:false, CStrW(path)); 150 g_ConfigDB.SetConfigFile(cfgNs, useVFS ? true : false, CStrW(path)); 151 JS_SET_RVAL(cx, vp, JSVAL_VOID); 144 152 return JS_TRUE; 145 153 } 146 154 else … … 148 156 } 149 157 150 158 JSFunctionSpec Funcs[] = { 151 { "writeFile", WriteFile, 2, 0 , 0},152 { "reload", Reload, 0, 0 , 0},153 { "setFile", SetFile, 2, 0 , 0},159 { "writeFile", WriteFile, 2, 0 }, 160 { "reload", Reload, 0, 0 }, 161 { "setFile", SetFile, 2, 0 }, 154 162 {0} 155 163 }; 156 164 }; … … 173 181 {0} 174 182 }; 175 183 176 JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* UNUSED(argv), jsval* rval)184 JSBool Construct(JSContext* cx, uintN argc, jsval* vp) 177 185 { 178 if (argc != 0) 179 return JS_FALSE; 186 UNUSED2(argc); 180 187 181 JSObject *newObj =JS_NewObject(cx, &Class, NULL, obj);182 *rval=OBJECT_TO_JSVAL(newObj);188 JSObject *newObj = JS_NewObject(cx, &Class, NULL, NULL); 189 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObj)); 183 190 184 191 int flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT; 185 192 #define cfg_ns(_propname, _enum) STMT (\ … … 204 211 { 205 212 g_ScriptingHost.DefineCustomObjectType(&ConfigDB_JS::Class, ConfigDB_JS::Construct, 0, ConfigDB_JS::Props, ConfigDB_JS::Funcs, NULL, NULL); 206 213 g_ScriptingHost.DefineCustomObjectType(&ConfigNamespace_JS::Class, ConfigNamespace_JS::Construct, 0, NULL, ConfigNamespace_JS::Funcs, NULL, NULL); 207 JSObject *js_ConfigDB =g_ScriptingHost.CreateCustomObject("ConfigDB");214 JSObject *js_ConfigDB = g_ScriptingHost.CreateCustomObject("ConfigDB"); 208 215 g_ScriptingHost.SetGlobal("g_ConfigDB", OBJECT_TO_JSVAL(js_ConfigDB)); 209 216 } 210 217 211 218 CConfigValue *CConfigDB::GetValue(EConfigNamespace ns, const CStr& name) 212 219 { 213 CConfigValueSet* values = GetValues( ns, name ); 214 if( !values ) return( NULL ); 215 return &( (*values)[0] ); 220 CConfigValueSet* values = GetValues(ns, name); 221 if (!values) 222 return (NULL); 223 return &((*values)[0]); 216 224 } 217 225 218 226 CConfigValueSet *CConfigDB::GetValues(EConfigNamespace ns, const CStr& name) … … 223 231 return NULL; 224 232 } 225 233 226 TConfigMap::iterator it = m_Map[CFG_COMMAND].find( name);227 if ( it != m_Map[CFG_COMMAND].end())228 return &( it->second);234 TConfigMap::iterator it = m_Map[CFG_COMMAND].find(name); 235 if (it != m_Map[CFG_COMMAND].end()) 236 return &(it->second); 229 237 230 for ( int search_ns = ns; search_ns >= 0; search_ns--)238 for (int search_ns = ns; search_ns >= 0; search_ns--) 231 239 { 232 240 TConfigMap::iterator it = m_Map[search_ns].find(name); 233 241 if (it != m_Map[search_ns].end()) 234 return &( it->second);242 return &(it->second); 235 243 } 236 244 237 return ( NULL );245 return NULL; 238 246 } 239 247 240 248 std::vector<std::pair<CStr, CConfigValueSet> > CConfigDB::GetValuesWithPrefix(EConfigNamespace ns, const CStr& prefix) -
source/ps/GameSetup/GameSetup.cpp
diff -r 6b3ac7e864ba source/ps/GameSetup/GameSetup.cpp
a b 76 76 77 77 #include "maths/scripting/JSInterface_Vector3D.h" 78 78 79 #include "graphics/scripting/JSInterface_Camera.h"80 #include "graphics/scripting/JSInterface_LightEnv.h"81 82 79 #include "ps/scripting/JSInterface_Console.h" 83 80 84 81 #include "gui/GUI.h" … … 304 301 JSI_Vector3D::init(); 305 302 306 303 // graphics 307 JSI_Camera::init();308 JSI_LightEnv::init();309 304 CGameView::ScriptingInit(); 310 305 311 306 // renderer -
source/ps/scripting/JSInterface_Console.cpp
diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_Console.cpp
a b 1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2010 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 40 40 41 41 JSFunctionSpec JSI_Console::JSI_methods[] = 42 42 { 43 { "write", JSI_Console::writeConsole, 1, 0 , 0},43 { "write", JSI_Console::writeConsole, 1, 0 }, 44 44 { 0 }, 45 45 }; 46 46 47 JSBool JSI_Console::getProperty( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval id, jsval* vp)47 JSBool JSI_Console::getProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp) 48 48 { 49 if ( !JSVAL_IS_INT( id ))50 return ( JS_TRUE );49 if (!JSID_IS_INT(id)) 50 return JS_TRUE; 51 51 52 int i = JS VAL_TO_INT( id);52 int i = JSID_TO_INT(id); 53 53 54 switch ( i)54 switch (i) 55 55 { 56 56 case console_visible: 57 *vp = BOOLEAN_TO_JSVAL( g_Console->IsActive() ); return( JS_TRUE ); 57 *vp = BOOLEAN_TO_JSVAL(g_Console->IsActive()); 58 return JS_TRUE; 58 59 default: 59 *vp = JSVAL_NULL; return( JS_TRUE ); 60 } 60 *vp = JSVAL_NULL; 61 return JS_TRUE; 62 } 61 63 } 62 64 63 JSBool JSI_Console::setProperty( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval id, jsval* vp)65 JSBool JSI_Console::setProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp) 64 66 { 65 if ( !JSVAL_IS_INT( id ))66 return ( JS_TRUE );67 if (!JSID_IS_INT(id)) 68 return JS_TRUE; 67 69 68 int i = JS VAL_TO_INT( id);70 int i = JSID_TO_INT(id); 69 71 70 switch ( i)72 switch (i) 71 73 { 72 74 case console_visible: 73 75 try 74 76 { 75 g_Console->SetVisible( ToPrimitive<bool>( *vp ));76 return ( JS_TRUE );77 g_Console->SetVisible(ToPrimitive<bool> (*vp)); 78 return JS_TRUE; 77 79 } 78 catch (PSERROR_Scripting_ConversionFailed )80 catch (PSERROR_Scripting_ConversionFailed ) 79 81 { 80 return ( JS_TRUE );82 return JS_TRUE; 81 83 } 82 84 default: 83 return ( JS_TRUE );84 } 85 return JS_TRUE; 86 } 85 87 } 86 88 87 89 void JSI_Console::init() 88 90 { 89 g_ScriptingHost.DefineCustomObjectType( &JSI_class, NULL, 0, JSI_props, JSI_methods, NULL, NULL);91 g_ScriptingHost.DefineCustomObjectType(&JSI_class, NULL, 0, JSI_props, JSI_methods, NULL, NULL); 90 92 } 91 93 92 JSBool JSI_Console::getConsole( JSContext* cx, JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp)94 JSBool JSI_Console::getConsole(JSContext* cx, JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp) 93 95 { 94 JSObject* console = JS_NewObject( cx, &JSI_Console::JSI_class, NULL, NULL);95 *vp = OBJECT_TO_JSVAL( console);96 return ( JS_TRUE );96 JSObject* console = JS_NewObject(cx, &JSI_Console::JSI_class, NULL, NULL); 97 *vp = OBJECT_TO_JSVAL(console); 98 return JS_TRUE; 97 99 } 98 100 99 JSBool JSI_Console::writeConsole( JSContext* UNUSED(context), JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* UNUSED(rval))101 JSBool JSI_Console::writeConsole(JSContext* cx, uintN argc, jsval* vp) 100 102 { 101 debug_assert( argc >= 1 ); 103 UNUSED2(cx); 104 102 105 CStrW output; 103 for ( unsigned int i = 0; i < argc; i++)106 for (uintN i = 0; i < argc; i++) 104 107 { 105 108 try 106 109 { 107 CStrW arg = g_ScriptingHost.ValueToUCString( argv[i]);110 CStrW arg = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[i]); 108 111 output += arg; 109 112 } 110 catch (PSERROR_Scripting_ConversionFailed )113 catch (PSERROR_Scripting_ConversionFailed ) 111 114 { 112 115 } 113 116 } 114 117 115 118 // TODO: What if the console has been destroyed already? 116 119 if (g_Console) 117 g_Console->InsertMessage( L"%ls", output.c_str());120 g_Console->InsertMessage(L"%ls", output.c_str()); 118 121 119 return( JS_TRUE ); 122 JS_SET_RVAL(cx, vp, JSVAL_VOID); 123 return JS_TRUE; 120 124 } -
source/ps/scripting/JSInterface_Console.h
diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_Console.h
a b 34 34 extern JSPropertySpec JSI_props[]; 35 35 extern JSFunctionSpec JSI_methods[]; 36 36 37 JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp);38 JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp);37 JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 38 JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); 39 39 40 JSBool getConsole( JSContext* context, JSObject* obj, jsval id, jsval* vp);40 JSBool getConsole(JSContext* context, JSObject* obj, jsid id, jsval* vp); 41 41 42 42 void init(); 43 43 44 JSBool writeConsole( JSContext* context, JSObject* obj, uintN argc, jsval* argv, jsval* rval);44 JSBool writeConsole(JSContext* cx, uintN argc, jsval* vp); 45 45 } 46 46 47 47 #endif -
source/ps/scripting/JSInterface_VFS.cpp
diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_VFS.cpp
a b 29 29 // shared error handling code 30 30 #define JS_CHECK_FILE_ERR(err)\ 31 31 /* this is liable to happen often, so don't complain */\ 32 if (err == ERR::VFS_FILE_NOT_FOUND)\32 if (err == ERR::VFS_FILE_NOT_FOUND)\ 33 33 {\ 34 *rval = JSVAL_NULL;\35 return ( JS_TRUE );\34 JS_SET_RVAL(cx, vp, JSVAL_NULL);\ 35 return JS_TRUE;\ 36 36 }\ 37 37 /* unknown failure. we return an error (akin to an exception in JS) that 38 38 stops the script to make sure this error is noticed. */\ 39 else if (err < 0)\40 return ( JS_FALSE );\39 else if (err < 0)\ 40 return JS_FALSE;\ 41 41 /* else: success */ 42 42 43 43 … … 54 54 : cx(cx_) 55 55 { 56 56 filename_array = JS_NewArrayObject(cx, 0, NULL); 57 JS_Add Root(cx, &filename_array);57 JS_AddObjectRoot(cx, &filename_array); 58 58 cur_idx = 0; 59 59 } 60 60 61 61 ~BuildDirEntListState() 62 62 { 63 JS_Remove Root(cx, &filename_array);63 JS_RemoveObjectRoot(cx, &filename_array); 64 64 } 65 65 }; 66 66 … … 85 85 // 86 86 // note: full pathnames of each file/subdirectory are returned, 87 87 // ready for use as a "filename" for the other functions. 88 JSBool JSI_VFS::BuildDirEntList( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)88 JSBool JSI_VFS::BuildDirEntList(JSContext* cx, uintN argc, jsval* vp) 89 89 { 90 90 // 91 91 // get arguments 92 92 // 93 93 94 debug_assert( argc >= 1 ); 94 JSU_REQUIRE_MIN_PARAMS(1); 95 95 96 CStr path; 96 if ( !ToPrimitive<CStr>( cx, argv[0], path ))97 return ( JS_FALSE );97 if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], path)) 98 return JS_FALSE; 98 99 99 100 CStrW filter_str = L""; 100 if (argc >= 2)101 if (argc >= 2) 101 102 { 102 if ( !ToPrimitive<CStrW>( cx, argv[1], filter_str ))103 return ( JS_FALSE );103 if (!ToPrimitive<CStrW> (cx, JS_ARGV(cx, vp)[1], filter_str)) 104 return JS_FALSE; 104 105 } 105 106 // convert to const wchar_t*; if there's no filter, pass 0 for speed 106 107 // (interpreted as: "accept all files without comparing"). 107 108 const wchar_t* filter = 0; 108 if (!filter_str.empty())109 if (!filter_str.empty()) 109 110 filter = filter_str.c_str(); 110 111 111 112 bool recursive = false; 112 if (argc >= 3)113 if (argc >= 3) 113 114 { 114 if ( !ToPrimitive<bool>( cx, argv[2], recursive ))115 return ( JS_FALSE );115 if (!ToPrimitive<bool> (cx, JS_ARGV(cx, vp)[2], recursive)) 116 return JS_FALSE; 116 117 } 117 int flags = recursive ? fs_util::DIR_RECURSIVE : 0;118 int flags = recursive ? fs_util::DIR_RECURSIVE : 0; 118 119 119 120 120 121 // build array in the callback function 121 122 BuildDirEntListState state(cx); 122 123 fs_util::ForEachFile(g_VFS, CStrW(path), BuildDirEntListCB, (uintptr_t)&state, filter, flags); 123 124 124 *rval = OBJECT_TO_JSVAL( state.filename_array);125 return ( JS_TRUE );125 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(state.filename_array)); 126 return JS_TRUE; 126 127 } 127 128 128 129 … … 130 131 // 131 132 // mtime = getFileMTime(filename); 132 133 // filename: VFS filename (may include path) 133 JSBool JSI_VFS::GetFileMTime( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)134 JSBool JSI_VFS::GetFileMTime(JSContext* cx, uintN argc, jsval* vp) 134 135 { 135 debug_assert( argc >= 1 ); 136 JSU_REQUIRE_MIN_PARAMS(1); 137 136 138 CStr filename; 137 if ( !ToPrimitive<CStr>( cx, argv[0], filename ))138 return ( JS_FALSE );139 if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename)) 140 return JS_FALSE; 139 141 140 142 FileInfo fileInfo; 141 143 LibError err = g_VFS->GetFileInfo(CStrW(filename), &fileInfo); 142 JS_CHECK_FILE_ERR( err);144 JS_CHECK_FILE_ERR(err); 143 145 144 *rval = ToJSVal( (double)fileInfo.MTime());145 return ( JS_TRUE );146 JS_SET_RVAL(cx, vp, ToJSVal((double)fileInfo.MTime())); 147 return JS_TRUE; 146 148 } 147 149 148 150 … … 150 152 // 151 153 // size = getFileSize(filename); 152 154 // filename: VFS filename (may include path) 153 JSBool JSI_VFS::GetFileSize( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)155 JSBool JSI_VFS::GetFileSize(JSContext* cx, uintN argc, jsval* vp) 154 156 { 155 debug_assert( argc >= 1 ); 157 JSU_REQUIRE_MIN_PARAMS(1); 158 156 159 CStr filename; 157 if ( !ToPrimitive<CStr>( cx, argv[0], filename ))158 return ( JS_FALSE );160 if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename)) 161 return JS_FALSE; 159 162 160 163 FileInfo fileInfo; 161 164 LibError err = g_VFS->GetFileInfo(CStrW(filename), &fileInfo); 162 165 JS_CHECK_FILE_ERR(err); 163 166 164 *rval = ToJSVal( (unsigned)fileInfo.Size());165 return ( JS_TRUE );167 JS_SET_RVAL(cx, vp, ToJSVal( (unsigned)fileInfo.Size() )); 168 return JS_TRUE; 166 169 } 167 170 168 171 … … 170 173 // 171 174 // contents = readFile(filename); 172 175 // filename: VFS filename (may include path) 173 JSBool JSI_VFS::ReadFile( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)176 JSBool JSI_VFS::ReadFile(JSContext* cx, uintN argc, jsval* vp) 174 177 { 175 debug_assert( argc >= 1 ); 178 JSU_REQUIRE_MIN_PARAMS(1); 179 176 180 CStr filename; 177 if ( !ToPrimitive<CStr>( cx, argv[0], filename ))178 return ( JS_FALSE );181 if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename)) 182 return JS_FALSE; 179 183 180 shared_ptr<u8> buf; size_t size; 181 LibError err = g_VFS->LoadFile( CStrW(filename), buf, size ); 184 shared_ptr<u8> buf; 185 size_t size; 186 LibError err = g_VFS->LoadFile(CStrW(filename), buf, size); 182 187 JS_CHECK_FILE_ERR( err ); 183 188 184 CStr contents( (const char*)buf.get(), size);189 CStr contents((const char*)buf.get(), size); 185 190 186 191 // Fix CRLF line endings. (This function will only ever be used on text files.) 187 192 contents.Replace("\r\n", "\n"); 188 193 189 194 // Decode as UTF-8 190 *rval = ToJSVal( contents.FromUTF8());191 return ( JS_TRUE );195 JS_SET_RVAL(cx, vp, ToJSVal( contents.FromUTF8() )); 196 return JS_TRUE; 192 197 } 193 198 194 199 … … 196 201 // 197 202 // lines = readFileLines(filename); 198 203 // filename: VFS filename (may include path) 199 JSBool JSI_VFS::ReadFileLines( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)204 JSBool JSI_VFS::ReadFileLines(JSContext* cx, uintN argc, jsval* vp) 200 205 { 201 debug_assert( argc >= 1 ); 206 JSU_REQUIRE_MIN_PARAMS(1); 207 202 208 CStr filename; 203 if ( !ToPrimitive<CStr>( cx, argv[0], filename ))204 return ( JS_FALSE);209 if (!ToPrimitive<CStr> (cx, JS_ARGV(cx, vp)[0], filename)) 210 return (JS_FALSE); 205 211 206 212 // 207 213 // read file 208 214 // 209 215 210 shared_ptr<u8> buf; size_t size; 211 LibError err = g_VFS->LoadFile( CStrW(filename), buf, size ); 216 shared_ptr<u8> buf; 217 size_t size; 218 LibError err = g_VFS->LoadFile(CStrW(filename), buf, size); 212 219 JS_CHECK_FILE_ERR( err ); 213 220 214 CStr contents( (const char*)buf.get(), size);221 CStr contents((const char*)buf.get(), size); 215 222 216 223 // Fix CRLF line endings. (This function will only ever be used on text files.) 217 224 contents.Replace("\r\n", "\n"); … … 220 227 // split into array of strings (one per line) 221 228 // 222 229 223 std::stringstream ss( contents);230 std::stringstream ss(contents); 224 231 225 JSObject* line_array = JS_NewArrayObject( cx, 0, NULL ); 226 JS_AddRoot(cx, &line_array); 232 JSObject* line_array = JS_NewArrayObject(cx, 0, NULL); 227 233 228 234 std::string line; 229 235 int cur_line = 0; 230 while ( std::getline( ss, line ))236 while (std::getline(ss, line)) 231 237 { 232 238 // Decode each line as UTF-8 233 jsval val = ToJSVal( CStr( line ).FromUTF8());234 JS_SetElement( cx, line_array, cur_line++, &val);239 jsval val = ToJSVal(CStr(line).FromUTF8()); 240 JS_SetElement(cx, line_array, cur_line++, &val); 235 241 } 236 242 237 JS_RemoveRoot(cx, &line_array); 238 239 *rval = OBJECT_TO_JSVAL( line_array ); 240 return( JS_TRUE ); 243 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL( line_array )); 244 return JS_TRUE ; 241 245 } 242 246 243 247 244 248 // vfs_optimizer 245 249 246 JSBool JSI_VFS::ArchiveBuilderCancel(JSContext* UNUSED(cx), JSObject* UNUSED(obj), uintN argc, jsval* UNUSED(argv), jsval* UNUSED(rval))250 JSBool JSI_VFS::ArchiveBuilderCancel(JSContext* cx, uintN argc, jsval* vp) 247 251 { 248 debug_assert( argc == 0 ); 252 UNUSED2(cx); 253 UNUSED2(argc); 254 249 255 // vfs_opt_auto_build_cancel(); 250 return( JS_TRUE ); 256 257 JS_SET_RVAL(cx, vp, JSVAL_VOID); 258 return JS_TRUE; 251 259 } -
source/ps/scripting/JSInterface_VFS.h
diff -r 6b3ac7e864ba source/ps/scripting/JSInterface_VFS.h
a b 38 38 // 39 39 // note: full pathnames of each file/subdirectory are returned, 40 40 // ready for use as a "filename" for the other functions. 41 JSBool BuildDirEntList( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);41 JSBool BuildDirEntList(JSContext* cx, uintN argc, jsval* vp); 42 42 43 43 // Return time [seconds since 1970] of the last modification to the specified file. 44 44 // 45 45 // mtime = getFileMTime(filename); 46 46 // filename: VFS filename (may include path) 47 JSBool GetFileMTime( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);47 JSBool GetFileMTime(JSContext* cx, uintN argc, jsval* vp); 48 48 49 49 // Return current size of file. 50 50 // 51 51 // size = getFileSize(filename); 52 52 // filename: VFS filename (may include path) 53 JSBool GetFileSize( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);53 JSBool GetFileSize(JSContext* cx, uintN argc, jsval* vp); 54 54 55 55 // Return file contents in a string. 56 56 // 57 57 // contents = readFile(filename); 58 58 // filename: VFS filename (may include path) 59 JSBool ReadFile( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);59 JSBool ReadFile(JSContext* cx, uintN argc, jsval* vp); 60 60 61 61 // Return file contents as an array of lines. 62 62 // 63 63 // lines = readFileLines(filename); 64 64 // filename: VFS filename (may include path) 65 JSBool ReadFileLines( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);65 JSBool ReadFileLines(JSContext* cx, uintN argc, jsval* vp); 66 66 67 67 // Abort the current archive build operation (no-op if not currently active). 68 68 // 69 69 // archiveBuilderCancel(); 70 JSBool ArchiveBuilderCancel(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);70 JSBool ArchiveBuilderCancel(JSContext* cx, uintN argc, jsval* vp); 71 71 } 72 72 73 73 #endif -
source/scripting/JSConversions.cpp
diff -r 6b3ac7e864ba source/scripting/JSConversions.cpp
a b 180 180 181 181 template<> jsval ToJSVal<double>( const double& Native ) 182 182 { 183 return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) ); 183 jsval val = JSVAL_VOID; 184 JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); 185 return val; 184 186 } 185 187 186 188 template<> jsval ToJSVal<double>( double& Native ) 187 189 { 188 return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) ); 190 jsval val = JSVAL_VOID; 191 JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); 192 return val; 189 193 } 190 194 191 195 template<> bool ToPrimitive<double>( JSContext* cx, jsval v, double& Storage ) … … 200 204 201 205 template<> jsval ToJSVal<float>( const float& Native ) 202 206 { 203 return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) ); 207 jsval val = JSVAL_VOID; 208 JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); 209 return val; 204 210 } 205 211 206 212 template<> jsval ToJSVal<float>( float& Native ) 207 213 { 208 return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), Native ) ) ); 214 jsval val = JSVAL_VOID; 215 JS_NewNumberValue( g_ScriptingHost.getContext(), Native, &val ); 216 return val; 209 217 } 210 218 211 219 template<> bool ToPrimitive<float>( JSContext* cx, jsval v, float& Storage ) … … 304 312 stringParser.InputTaskType( "string", "_$value_" ); 305 313 CParserLine result; 306 314 result.ParseString( stringParser, CStr(Native) ); 307 bool boolResult; int intResult; float floatResult; 315 bool boolResult; 316 float floatResult; 308 317 309 318 if( result.GetArgFloat( 0, floatResult ) ) 310 {311 if( floatResult == floor( floatResult ) )312 {313 intResult = (int)floatResult;314 if( INT_FITS_IN_JSVAL( intResult ) )315 return( ToJSVal( intResult ) );316 }317 319 return( ToJSVal( floatResult ) ); 318 } 320 319 321 if( result.GetArgBool( 0, boolResult ) ) 320 322 return( BOOLEAN_TO_JSVAL( boolResult ) ); 321 323 -
source/scripting/JSUtil.cpp
diff -r 6b3ac7e864ba source/scripting/JSUtil.cpp
a b 19 19 20 20 #include "SpiderMonkey.h" 21 21 22 jsval jsu_report_param_error(JSContext* cx, jsval* rval)22 JSBool jsu_report_param_error(JSContext* cx, jsval* vp) 23 23 { 24 24 JS_ReportError(cx, "Invalid parameter(s) or count"); 25 25 26 if (rval)27 *rval = JSVAL_NULL;26 if (vp) 27 JS_SET_RVAL(cx, vp, JSVAL_NULL); 28 28 29 29 // yes, we had an error, but returning JS_FALSE would cause SpiderMonkey 30 30 // to abort. that would be hard to debug. -
source/scripting/JSUtil.h
diff -r 6b3ac7e864ba source/scripting/JSUtil.h
a b 17 17 18 18 // included from SpiderMonkey.h 19 19 20 extern jsval jsu_report_param_error(JSContext* cx, jsval* rval);20 extern JSBool jsu_report_param_error(JSContext* cx, jsval* vp); 21 21 22 22 23 23 // consistent argc checking for normal function wrappers: reports an … … 25 25 // .. require exact number (most common case) 26 26 #define JSU_REQUIRE_PARAMS(exact_number)\ 27 27 if(argc != exact_number)\ 28 return jsu_report_param_error(cx, rval);28 return jsu_report_param_error(cx, vp); 29 29 // .. require 0 params (avoids L4 warning "unused argv param") 30 30 #define JSU_REQUIRE_NO_PARAMS()\ 31 UNUSED2(argv);\32 31 if(argc != 0)\ 33 return jsu_report_param_error(cx, rval);32 return jsu_report_param_error(cx, vp); 34 33 // .. require a certain range (e.g. due to optional params) 35 34 #define JSU_REQUIRE_PARAM_RANGE(min_number, max_number)\ 36 35 if(!(min_number <= argc && argc <= max_number))\ 37 return jsu_report_param_error(cx, rval);36 return jsu_report_param_error(cx, vp); 38 37 // .. require at most a certain count 39 38 #define JSU_REQUIRE_MAX_PARAMS(max_number)\ 40 39 if(argc > max_number)\ 41 return jsu_report_param_error(cx, rval);40 return jsu_report_param_error(cx, vp); 42 41 // .. require at least a certain count (rarely needed) 43 42 #define JSU_REQUIRE_MIN_PARAMS(min_number)\ 44 43 if(argc < min_number)\ 45 return jsu_report_param_error(cx, rval);44 return jsu_report_param_error(cx, vp); 46 45 47 46 // same as JSU_REQUIRE_PARAMS, but used from C++ functions that are 48 47 // a bit further removed from SpiderMonkey, i.e. return a -
source/scripting/ScriptGlue.cpp
diff -r 6b3ac7e864ba source/scripting/ScriptGlue.cpp
a b 31 31 #include "graphics/MapWriter.h" 32 32 #include "graphics/Unit.h" 33 33 #include "graphics/UnitManager.h" 34 #include "graphics/scripting/JSInterface_Camera.h"35 #include "graphics/scripting/JSInterface_LightEnv.h"36 34 #include "gui/GUIManager.h" 37 35 #include "gui/IGUIObject.h" 38 36 #include "lib/frequency_filter.h" … … 109 107 js_timer_clients[0].sum.SetToZero(); 110 108 } 111 109 112 JSBool StartJsTimer(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)110 JSBool StartJsTimer(JSContext* cx, uintN argc, jsval* vp) 113 111 { 114 112 ONCE(InitJsTimers()); 115 113 116 114 JSU_REQUIRE_PARAMS(1); 117 size_t slot = ToPrimitive<size_t>( argv[0]);115 size_t slot = ToPrimitive<size_t>(JS_ARGV(cx, vp)[0]); 118 116 if (slot >= MAX_JS_TIMERS) 119 117 return JS_FALSE; 120 118 121 119 js_start_times[slot].SetFromTimer(); 120 121 JS_SET_RVAL(cx, vp, JSVAL_VOID); 122 122 return JS_TRUE; 123 123 } 124 124 125 125 126 JSBool StopJsTimer(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)126 JSBool StopJsTimer(JSContext* cx, uintN argc, jsval* vp) 127 127 { 128 128 JSU_REQUIRE_PARAMS(1); 129 size_t slot = ToPrimitive<size_t>( argv[0]);129 size_t slot = ToPrimitive<size_t>(JS_ARGV(cx, vp)[0]); 130 130 if (slot >= MAX_JS_TIMERS) 131 131 return JS_FALSE; 132 132 … … 135 135 now.Subtract(js_timer_overhead); 136 136 BillingPolicy_Default()(&js_timer_clients[slot], js_start_times[slot], now); 137 137 js_start_times[slot].SetToZero(); 138 139 JS_SET_RVAL(cx, vp, JSVAL_VOID); 138 140 return JS_TRUE; 139 141 } 140 142 … … 146 148 // Immediately ends the current game (if any). 147 149 // params: 148 150 // returns: 149 JSBool EndGame(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)151 JSBool EndGame(JSContext* cx, uintN argc, jsval* vp) 150 152 { 151 153 JSU_REQUIRE_NO_PARAMS(); 152 154 153 155 EndGame(); 156 157 JS_SET_RVAL(cx, vp, JSVAL_VOID); 154 158 return JS_TRUE; 155 159 } 156 160 … … 164 168 // notes: 165 169 // - This value is recalculated once a frame. We take special care to 166 170 // filter it, so it is both accurate and free of jitter. 167 JSBool GetFps( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)171 JSBool GetFps(JSContext* cx, uintN argc, jsval* vp) 168 172 { 169 173 JSU_REQUIRE_NO_PARAMS(); 170 174 int freq = 0; 171 175 if (g_frequencyFilter) 172 176 freq = g_frequencyFilter->StableFrequency(); 173 *rval = INT_TO_JSVAL(freq);177 JS_SET_RVAL(cx, vp, INT_TO_JSVAL(freq)); 174 178 return JS_TRUE; 175 179 } 176 180 … … 181 185 // notes: 182 186 // - Exit happens after the current main loop iteration ends 183 187 // (since this only sets a flag telling it to end) 184 JSBool ExitProgram( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)188 JSBool ExitProgram(JSContext* cx, uintN argc, jsval* vp) 185 189 { 186 190 JSU_REQUIRE_NO_PARAMS(); 187 191 188 192 kill_mainloop(); 189 return JS_TRUE;190 }191 193 192 193 // Write an indication of total video RAM to console. 194 // params: 195 // returns: 196 // notes: 197 // - May not be supported on all platforms. 198 // - Only a rough approximation; do not base low-level decisions 199 // ("should I allocate one more texture?") on this. 200 JSBool WriteVideoMemToConsole( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval ) 201 { 202 JSU_REQUIRE_NO_PARAMS(); 203 204 const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); 205 g_Console->InsertMessage(L"VRAM: total %d", videoInfo->video_mem); 194 JS_SET_RVAL(cx, vp, JSVAL_VOID); 206 195 return JS_TRUE; 207 196 } 208 197 … … 212 201 // returns: 213 202 // notes: 214 203 // - Cursors are stored in "art\textures\cursors" 215 JSBool SetCursor( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)204 JSBool SetCursor(JSContext* cx, uintN argc, jsval* vp) 216 205 { 217 206 JSU_REQUIRE_PARAMS(1); 218 g_CursorName = g_ScriptingHost.ValueToUCString(argv[0]); 207 g_CursorName = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[0]); 208 209 JS_SET_RVAL(cx, vp, JSVAL_VOID); 219 210 return JS_TRUE; 220 211 } 221 212 222 // Change the LOD bias. 223 // params: LOD bias [float] 224 // returns: 225 // notes: 226 // - value is as required by GL_TEXTURE_LOD_BIAS. 227 // - useful for adjusting image "sharpness" (since it affects which mipmap level is chosen) 228 JSBool _LodBias( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval ) 213 JSBool GetGUIObjectByName(JSContext* cx, uintN argc, jsval* vp) 229 214 { 230 215 JSU_REQUIRE_PARAMS(1); 231 216 232 g_Renderer.SetOptionFloat(CRenderer::OPT_LODBIAS, ToPrimitive<float>(argv[0]));233 return JS_TRUE;234 }235 236 237 JSBool GetGUIObjectByName(JSContext* cx, JSObject* UNUSED(obj), uintN UNUSED(argc), jsval* argv, jsval* rval)238 {239 217 try 240 218 { 241 CStr name = ToPrimitive<CStr>(cx, argv[0]);219 CStr name = ToPrimitive<CStr>(cx, JS_ARGV(cx, vp)[0]); 242 220 IGUIObject* guiObj = g_GUI->FindObjectByName(name); 243 221 if (guiObj) 244 *rval = OBJECT_TO_JSVAL(guiObj->GetJSObject());222 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(guiObj->GetJSObject())); 245 223 else 246 *rval = JSVAL_NULL;224 JS_SET_RVAL(cx, vp, JSVAL_NULL); 247 225 return JS_TRUE; 248 226 } 249 227 catch (PSERROR_Scripting&) … … 270 248 // lib/svn_revision.cpp. it is useful to know when attempting to 271 249 // reproduce bugs (the main EXE and PDB should be temporarily reverted to 272 250 // that revision so that they match user-submitted crashdumps). 273 JSBool GetBuildTimestamp( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)251 JSBool GetBuildTimestamp(JSContext* cx, uintN argc, jsval* vp) 274 252 { 275 253 JSU_REQUIRE_MAX_PARAMS(1); 276 254 277 255 char buf[200]; 278 256 279 257 // see function documentation 280 const int mode = argc? JSVAL_TO_INT( argv[0]) : -1;258 const int mode = argc? JSVAL_TO_INT(JS_ARGV(cx, vp)[0]) : -1; 281 259 switch(mode) 282 260 { 283 261 case -1: … … 294 272 break; 295 273 } 296 274 297 *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf));275 JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf))); 298 276 return JS_TRUE; 299 277 } 300 278 … … 311 289 } 312 290 #endif 313 291 314 JSBool DumpHeaps(JSContext* UNUSED(cx), JSObject* UNUSED(globalObject), uintN UNUSED(argc), jsval* UNUSED(argv), jsval* UNUSED(rval))292 JSBool DumpHeaps(JSContext* cx, uintN argc, jsval* vp) 315 293 { 294 UNUSED2(cx); 295 UNUSED2(argc); 296 316 297 #ifdef DEBUG 317 298 static int i = 0; 318 299 … … 325 306 #else 326 307 debug_warn(L"DumpHeaps only available in DEBUG mode"); 327 308 #endif 309 310 JS_SET_RVAL(cx, vp, JSVAL_VOID); 328 311 return JS_TRUE; 329 312 } 330 313 331 314 //----------------------------------------------------------------------------- 332 315 333 316 // Is the game paused? 334 JSBool IsPaused( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval)317 JSBool IsPaused(JSContext* cx, uintN argc, jsval* vp) 335 318 { 336 319 JSU_REQUIRE_NO_PARAMS(); 337 320 338 if ( !g_Game)321 if (!g_Game) 339 322 { 340 JS_ReportError( cx, "Game is not started");323 JS_ReportError(cx, "Game is not started"); 341 324 return JS_FALSE; 342 325 } 343 326 344 *rval = g_Game->m_Paused ? JSVAL_TRUE : JSVAL_FALSE;345 return JS_TRUE 327 JS_SET_RVAL(cx, vp, g_Game->m_Paused ? JSVAL_TRUE : JSVAL_FALSE); 328 return JS_TRUE; 346 329 } 347 330 348 331 // Pause/unpause the game 349 JSBool SetPaused( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval)332 JSBool SetPaused(JSContext* cx, uintN argc, jsval* vp) 350 333 { 351 334 JSU_REQUIRE_PARAMS( 1 ); 352 335 353 if ( !g_Game)336 if (!g_Game) 354 337 { 355 JS_ReportError( cx, "Game is not started");338 JS_ReportError(cx, "Game is not started"); 356 339 return JS_FALSE; 357 340 } 358 341 359 342 try 360 343 { 361 g_Game->m_Paused = ToPrimitive<bool> ( argv[0]);344 g_Game->m_Paused = ToPrimitive<bool> (JS_ARGV(cx, vp)[0]); 362 345 } 363 catch ( PSERROR_Scripting_ConversionFailed)346 catch (PSERROR_Scripting_ConversionFailed) 364 347 { 365 JS_ReportError( cx, "Invalid parameter to SetPaused");348 JS_ReportError(cx, "Invalid parameter to SetPaused"); 366 349 } 367 350 368 return JS_TRUE; 351 JS_SET_RVAL(cx, vp, JSVAL_VOID); 352 return JS_TRUE; 369 353 } 370 354 371 355 … … 381 365 // - Extra (reserved for future use, always zero) 382 366 // 383 367 // we simplify this a bit with a macro: 384 #define JS_FUNC(script_name, cpp_function, min_params) { script_name, cpp_function, min_params, 0 , 0},368 #define JS_FUNC(script_name, cpp_function, min_params) { script_name, cpp_function, min_params, 0 }, 385 369 386 370 JSFunctionSpec ScriptFunctionTable[] = 387 371 { … … 404 388 JS_FUNC("exit", ExitProgram, 0) 405 389 JS_FUNC("isPaused", IsPaused, 0) 406 390 JS_FUNC("setPaused", SetPaused, 1) 407 JS_FUNC("vmem", WriteVideoMemToConsole, 0)408 JS_FUNC("_lodBias", _LodBias, 0)409 391 JS_FUNC("setCursor", SetCursor, 1) 410 392 JS_FUNC("getFPS", GetFps, 0) 411 393 JS_FUNC("getGUIObjectByName", GetGUIObjectByName, 1) … … 415 397 JS_FUNC("dumpHeaps", DumpHeaps, 0) 416 398 417 399 // end of table marker 418 {0 , 0, 0, 0, 0}400 {0} 419 401 }; 420 402 #undef JS_FUNC 421 403 … … 424 406 // property accessors 425 407 //----------------------------------------------------------------------------- 426 408 427 JSBool GetGameView( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp)409 JSBool GetGameView(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp) 428 410 { 429 411 if (g_Game) 430 *vp = OBJECT_TO_JSVAL( g_Game->GetView()->GetScript());412 *vp = OBJECT_TO_JSVAL(g_Game->GetView()->GetScript()); 431 413 else 432 414 *vp = JSVAL_NULL; 433 return ( JS_TRUE );415 return JS_TRUE; 434 416 } 435 417 436 437 JSBool GetRenderer( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp ) 418 JSBool GetRenderer(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp) 438 419 { 439 420 if (CRenderer::IsInitialised()) 440 *vp = OBJECT_TO_JSVAL( g_Renderer.GetScript());421 *vp = OBJECT_TO_JSVAL(g_Renderer.GetScript()); 441 422 else 442 423 *vp = JSVAL_NULL; 443 return ( JS_TRUE );424 return JS_TRUE; 444 425 } 445 426 446 427 … … 455 436 456 437 JSPropertySpec ScriptGlobalTable[] = 457 438 { 458 { "camera" , GLOBAL_CAMERA, JSPROP_PERMANENT, JSI_Camera::getCamera, JSI_Camera::setCamera },459 439 { "console" , GLOBAL_CONSOLE, JSPROP_PERMANENT|JSPROP_READONLY, JSI_Console::getConsole, 0 }, 460 { "lightenv" , GLOBAL_LIGHTENV, JSPROP_PERMANENT, JSI_LightEnv::getLightEnv, JSI_LightEnv::setLightEnv },461 440 { "gameView" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetGameView, 0 }, 462 441 { "renderer" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetRenderer, 0 }, 463 442 -
source/scripting/ScriptableObject.h
diff -r 6b3ac7e864ba source/scripting/ScriptableObject.h
a b 155 155 void Root() 156 156 { 157 157 if( JSVAL_IS_GCTHING( m_Data ) ) 158 JS_AddNamed Root( g_ScriptingHost.GetContext(), (void*)&m_Data, "ScriptableObjectProperty" );158 JS_AddNamedValueRoot( g_ScriptingHost.GetContext(), &m_Data, "ScriptableObjectProperty" ); 159 159 } 160 160 void Uproot() 161 161 { 162 162 if( JSVAL_IS_GCTHING( m_Data )) 163 JS_Remove Root( g_ScriptingHost.GetContext(), (void*)&m_Data );163 JS_RemoveValueRoot( g_ScriptingHost.GetContext(), &m_Data ); 164 164 } 165 165 jsval Get( JSContext* UNUSED(cx), IJSObject* UNUSED(object)) 166 166 { … … 179 179 template<typename T, bool ReadOnly, typename RType, RType (T::*NativeFunction)( JSContext* cx, uintN argc, jsval* argv )> class CNativeFunction 180 180 { 181 181 public: 182 static JSBool JSFunction( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)182 static JSBool JSFunction( JSContext* cx, uintN argc, jsval* vp ) 183 183 { 184 T* Native = ToNative<T>( cx, obj);184 T* Native = ToNative<T>( cx, JS_THIS_OBJECT( cx, vp ) ); 185 185 if( !Native ) 186 return( JS_ TRUE );186 return( JS_FALSE ); 187 187 188 *rval = ToJSVal<RType>( (Native->*NativeFunction)( cx, argc, argv) );189 188 jsval rval = ToJSVal<RType>( (Native->*NativeFunction)( cx, argc, JS_ARGV(cx, vp) ) ); 189 JS_SET_RVAL( cx, vp, rval ); 190 190 return( JS_TRUE ); 191 191 } 192 192 }; … … 196 196 class CNativeFunction<T, ReadOnly, void, NativeFunction> 197 197 { 198 198 public: 199 static JSBool JSFunction( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval))199 static JSBool JSFunction( JSContext* cx, uintN argc, jsval* vp ) 200 200 { 201 T* Native = ToNative<T>( cx, obj);201 T* Native = ToNative<T>( cx, JS_THIS_OBJECT( cx, vp ) ); 202 202 if( !Native ) 203 return( JS_ TRUE );203 return( JS_FALSE ); 204 204 205 (Native->*NativeFunction)( cx, argc, argv);205 (Native->*NativeFunction)( cx, argc, JS_ARGV(cx, vp) ); 206 206 207 JS_SET_RVAL( cx, vp, JSVAL_VOID ); 207 208 return( JS_TRUE ); 208 209 } 209 210 }; … … 328 329 template<typename ReturnType, ReturnType (T::*NativeFunction)( JSContext* cx, uintN argc, jsval* argv )> 329 330 static void AddMethod( const char* Name, uintN MinArgs ) 330 331 { 331 JSFunctionSpec FnInfo = { Name, CNativeFunction<T, ReadOnly, ReturnType, NativeFunction>::JSFunction, (uint8)MinArgs, 0 , 0};332 JSFunctionSpec FnInfo = { Name, CNativeFunction<T, ReadOnly, ReturnType, NativeFunction>::JSFunction, (uint8)MinArgs, 0 }; 332 333 m_Methods.push_back( FnInfo ); 333 334 } 334 335 template<typename PropType> static void AddProperty( const CStrW& PropertyName, PropType T::*Native, bool PropReadOnly = ReadOnly ) … … 373 374 { 374 375 m_JS = JS_NewObject( g_ScriptingHost.GetContext(), &JSI_class, NULL, NULL ); 375 376 if( m_EngineOwned ) 376 JS_AddNamed Root( g_ScriptingHost.GetContext(), (void*)&m_JS, JSI_class.name );377 JS_AddNamedObjectRoot( g_ScriptingHost.GetContext(), &m_JS, JSI_class.name ); 377 378 378 379 JS_SetPrivate( g_ScriptingHost.GetContext(), m_JS, (T*)this ); 379 380 } … … 384 385 { 385 386 JS_SetPrivate( g_ScriptingHost.GetContext(), m_JS, NULL ); 386 387 if( m_EngineOwned ) 387 JS_Remove Root( g_ScriptingHost.GetContext(), &m_JS );388 JS_RemoveObjectRoot( g_ScriptingHost.GetContext(), &m_JS ); 388 389 m_JS = NULL; 389 390 } 390 391 } … … 393 394 // Functions and data that must be provided to JavaScript 394 395 // 395 396 private: 396 static JSBool JSGetProperty( JSContext* cx, JSObject* obj, js valid, jsval* vp )397 static JSBool JSGetProperty( JSContext* cx, JSObject* obj, jsid id, jsval* vp ) 397 398 { 398 399 T* Instance = ToNative<T>( cx, obj ); 399 400 if( !Instance ) 400 401 return( JS_TRUE ); 401 402 402 CStrW PropName = g_ScriptingHost.ValueToUCString( id ); 403 jsval idval; 404 if( !JS_IdToValue( cx, id, &idval ) ) 405 return( JS_FALSE ); 406 407 CStrW PropName = g_ScriptingHost.ValueToUCString( idval ); 403 408 404 409 if( !Instance->GetProperty( cx, PropName, vp ) ) 405 410 return( JS_TRUE ); 406 411 407 412 return( JS_TRUE ); 408 413 } 409 static JSBool JSSetProperty( JSContext* cx, JSObject* obj, js valid, jsval* vp )414 static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsid id, jsval* vp ) 410 415 { 411 416 T* Instance = ToNative<T>( cx, obj ); 412 417 if( !Instance ) 413 418 return( JS_TRUE ); 414 419 415 CStrW PropName = g_ScriptingHost.ValueToUCString( id ); 420 jsval idval; 421 if( !JS_IdToValue( cx, id, &idval ) ) 422 return( JS_FALSE ); 423 424 CStrW PropName = g_ScriptingHost.ValueToUCString( idval ); 416 425 417 426 Instance->SetProperty( cx, PropName, vp ); 418 427 -
source/scripting/ScriptingHost.cpp
diff -r 6b3ac7e864ba source/scripting/ScriptingHost.cpp
a b 168 168 169 169 void ScriptingHost::SetObjectProperty_Double(JSObject* object, const char* propertyName, double value) 170 170 { 171 js double* d = JS_NewDouble(m_Context, value);172 if (! d)171 jsval v; 172 if (! JS_NewNumberValue(m_Context, value, &v)) 173 173 throw PSERROR_Scripting_ConversionFailed(); 174 174 175 jsval v = DOUBLE_TO_JSVAL(d);176 177 175 if (! JS_SetProperty(m_Context, object, propertyName, &v)) 178 176 throw PSERROR_Scripting_ConversionFailed(); 179 177 } -
source/scripting/SpiderMonkey.h
diff -r 6b3ac7e864ba source/scripting/SpiderMonkey.h
a b 45 45 46 46 #include <js/jsapi.h> 47 47 48 #ifndef NDEBUG49 // Used by ScriptingHost::jshook_{script,function}50 # include <js/jsdbgapi.h>51 #endif52 53 48 // include any further required headers here 54 49 55 50 #include "JSUtil.h" -
source/scriptinterface/AutoRooters.cpp
diff -r 6b3ac7e864ba source/scriptinterface/AutoRooters.cpp
a b 47 47 { 48 48 JS_CALL_VALUE_TRACER(trc, m_Vals[i], "AutoGCRooter val"); 49 49 } 50 51 for (size_t i = 0; i < m_IdArrays.size(); ++i) 52 { 53 for (jsint j = 0; j < m_IdArrays[i]->length; ++j) 54 { 55 jsval val = JSVAL_VOID; 56 JS_IdToValue(m_ScriptInterface.GetContext(), m_IdArrays[i]->vector[j], &val); 57 JS_CALL_VALUE_TRACER(trc, val, "AutoGCRooter id array"); 58 } 59 } 60 50 61 } -
source/scriptinterface/AutoRooters.h
diff -r 6b3ac7e864ba source/scriptinterface/AutoRooters.h
a b 22 22 23 23 #include "js/jsapi.h" 24 24 25 // Exception-safety and GC-safety wrapper for JSIdArray26 // (TODO: it'd be nicer to use the existing js::AutoIdArray but currently that27 // requires a load of semi-private SpiderMonkey headers that cause a load of compile warnings)28 class IdArrayWrapper29 {30 JSContext* m_cx;31 JSIdArray* m_ida;32 public:33 IdArrayWrapper(JSContext* cx, JSIdArray* ida) :34 m_cx(cx), m_ida(ida)35 {36 for (jsint i = 0; i < m_ida->length; ++i)37 if (!JS_AddRoot(m_cx, &m_ida->vector[i]))38 debug_warn(L"JS_AddRoot failed");39 }40 ~IdArrayWrapper()41 {42 for (jsint i = 0; i < m_ida->length; ++i)43 if (!JS_RemoveRoot(m_cx, &m_ida->vector[i]))44 debug_warn(L"JS_RemoveRoot failed");45 JS_DestroyIdArray(m_cx, m_ida);46 }47 };48 49 25 /** 50 26 * Helper for rooting large groups of script values. 51 27 * Construct this object, push values into it, and they will all be rooted until this … … 61 37 62 38 void Push(JSObject* obj) { m_Objects.push_back(obj); } 63 39 void Push(jsval val) { m_Vals.push_back(val); } 40 void Push(JSIdArray* ida) { m_IdArrays.push_back(ida); } 64 41 65 42 void Trace(JSTracer* trc); 66 43 private: … … 69 46 70 47 std::vector<JSObject*> m_Objects; 71 48 std::vector<jsval> m_Vals; 49 std::vector<JSIdArray*> m_IdArrays; 72 50 // TODO: add vectors of other value types 73 51 }; 74 52 -
source/scriptinterface/ScriptConversions.cpp
diff -r 6b3ac7e864ba source/scriptinterface/ScriptConversions.cpp
a b 139 139 return rval; 140 140 } 141 141 142 template<> jsval ScriptInterface::ToJSVal<i32>(JSContext* cx, const i32& val)142 template<> jsval ScriptInterface::ToJSVal<i32>(JSContext* UNUSED(cx), const i32& val) 143 143 { 144 if (INT_FITS_IN_JSVAL(val)) 145 return INT_TO_JSVAL(val); 146 jsval rval = JSVAL_VOID; 147 JS_NewNumberValue(cx, val, &rval); // ignore return value 148 return rval; 144 cassert(JSVAL_INT_BITS == 32); 145 return INT_TO_JSVAL(val); 149 146 } 150 147 151 148 template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* cx, const u32& val) … … 201 198 JSObject* obj = JS_NewArrayObject(cx, 0, NULL); 202 199 if (!obj) 203 200 return JSVAL_VOID; 204 JS_AddRoot(cx, &obj);205 201 for (size_t i = 0; i < val.size(); ++i) 206 202 { 207 203 jsval el = ScriptInterface::ToJSVal<T>(cx, val[i]); 208 204 JS_SetElement(cx, obj, (jsint)i, &el); 209 205 } 210 JS_RemoveRoot(cx, &obj);211 206 return OBJECT_TO_JSVAL(obj); 212 207 } 213 208 -
source/scriptinterface/ScriptInterface.cpp
diff -r 6b3ac7e864ba source/scriptinterface/ScriptInterface.cpp
a b 39 39 const int RUNTIME_SIZE = 16 * 1024 * 1024; // TODO: how much memory is needed? 40 40 const int STACK_CHUNK_SIZE = 8192; 41 41 42 #define signbit(x) ((x) < 0.0 ? true : false) // XXX 43 42 44 #if ENABLE_SCRIPT_PROFILING 43 45 #include "js/jsdbgapi.h" 44 46 #endif … … 49 51 { 50 52 ScriptInterface_impl(const char* nativeScopeName, JSContext* cx); 51 53 ~ScriptInterface_impl(); 52 void Register(const char* name, JS FastNative fptr, uintN nargs);54 void Register(const char* name, JSNative fptr, uintN nargs); 53 55 54 56 JSRuntime* m_rt; // NULL if m_cx is shared; non-NULL if we own m_cx 55 57 JSContext* m_cx; … … 286 288 // Threadsafe SpiderMonkey requires that we have a request before doing anything much 287 289 JS_BeginRequest(m_cx); 288 290 289 m_glob = JS_New Object(m_cx, &global_class, NULL, NULL);291 m_glob = JS_NewGlobalObject(m_cx, &global_class); 290 292 ok = JS_InitStandardClasses(m_cx, m_glob); 291 293 292 294 JS_DefineProperty(m_cx, m_glob, "global", OBJECT_TO_JSVAL(m_glob), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY … … 296 298 m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY 297 299 | JSPROP_PERMANENT); 298 300 299 JS_DefineFunction(m_cx, m_glob, "print", (JSNative)::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);300 JS_DefineFunction(m_cx, m_glob, "log", (JSNative)::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);301 JS_DefineFunction(m_cx, m_glob, "warn", (JSNative)::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);302 JS_DefineFunction(m_cx, m_glob, "error", (JSNative)::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);301 JS_DefineFunction(m_cx, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); 302 JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); 303 JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); 304 JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); 303 305 } 304 306 305 307 ScriptInterface_impl::~ScriptInterface_impl() … … 312 314 } 313 315 } 314 316 315 void ScriptInterface_impl::Register(const char* name, JS FastNative fptr, uintN nargs)317 void ScriptInterface_impl::Register(const char* name, JSNative fptr, uintN nargs) 316 318 { 317 JS_DefineFunction(m_cx, m_nativeScope, name, reinterpret_cast<JSNative>(fptr), nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);319 JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); 318 320 } 319 321 320 322 ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName) : … … 361 363 return; 362 364 } 363 365 364 JSFunction* random = JS_DefineFunction(m->m_cx, JSVAL_TO_OBJECT(math), "random", (JSNative)Math_random, 0,365 JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);366 JSFunction* random = JS_DefineFunction(m->m_cx, JSVAL_TO_OBJECT(math), "random", Math_random, 0, 367 JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); 366 368 if (!random) 367 369 { 368 370 LOGERROR(L"ReplaceNondeterministicFunctions: failed to replace Math.random"); … … 372 374 JS_SetReservedSlot(m->m_cx, JS_GetFunctionObject(random), 0, PRIVATE_TO_JSVAL(&rng)); 373 375 } 374 376 375 void ScriptInterface::Register(const char* name, JS FastNative fptr, size_t nargs)377 void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) 376 378 { 377 379 m->Register(name, fptr, (uintN)nargs); 378 380 } … … 387 389 return m->m_rt; 388 390 } 389 391 390 bool ScriptInterface::AddRoot(void* ptr, const char* name)391 {392 return JS_AddNamedRoot(m->m_cx, ptr, name) ? true : false;393 }394 395 bool ScriptInterface::RemoveRoot(void* ptr)396 {397 return JS_RemoveRoot(m->m_cx, ptr) ? true : false;398 }399 400 392 AutoGCRooter* ScriptInterface::ReplaceAutoGCRooter(AutoGCRooter* rooter) 401 393 { 402 394 debug_assert(m->m_rt); // this class must own the runtime, else the rooter won't work … … 494 486 JSObject* obj; 495 487 if (!JS_ValueToObject(m->m_cx, val, &obj) || obj == NULL) 496 488 return false; 497 JS_AddRoot(m->m_cx, &obj);498 489 499 490 // Check that the named function actually exists, to avoid ugly JS error reports 500 491 // when calling an undefined value 501 492 JSBool found; 502 493 if (!JS_HasProperty(m->m_cx, obj, name, &found) || !found) 503 {504 JS_RemoveRoot(m->m_cx, &obj);505 494 return false; 506 }507 495 508 496 JSBool ok = JS_CallFunctionName(m->m_cx, obj, name, (uintN)argc, argv, &ret); 509 JS_RemoveRoot(m->m_cx, &obj);510 497 511 498 return ok ? true : false; 512 499 } … … 638 625 if (!func) 639 626 return false; 640 627 641 JS_AddRoot(m->m_cx, &func); // TODO: do we need to root this?642 628 jsval scriptRval; 643 629 JSBool ok = JS_CallFunction(m->m_cx, NULL, func, 0, NULL, &scriptRval); 644 JS_RemoveRoot(m->m_cx, &func);645 630 646 631 return ok ? true : false; 647 632 } … … 782 767 { 783 768 public: 784 769 ValueCloner(ScriptInterface& from, ScriptInterface& to) : 785 cxFrom(from.GetContext()), cxTo(to.GetContext()), m_RooterFrom(from), m_RooterTo(to)770 scriptInterfaceFrom(from), cxFrom(from.GetContext()), cxTo(to.GetContext()), m_RooterFrom(from), m_RooterTo(to) 786 771 { 787 772 } 788 773 … … 792 777 if (!JSVAL_IS_GCTHING(val) || JSVAL_IS_NULL(val)) 793 778 return val; 794 779 795 std::map< jsval, jsval>::iterator it = m_Mapping.find(val);780 std::map<void*, jsval>::iterator it = m_Mapping.find(JSVAL_TO_GCTHING(val)); 796 781 if (it != m_Mapping.end()) 797 782 return it->second; 798 783 … … 811 796 if (JSVAL_IS_DOUBLE(val)) 812 797 { 813 798 jsval rval; 814 CLONE_REQUIRE(JS_NewNumberValue(cxTo, *JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue"); 815 m_Mapping[val] = rval; 799 CLONE_REQUIRE(JS_NewNumberValue(cxTo, JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue"); 816 800 m_RooterTo.Push(rval); 817 801 return rval; 818 802 } … … 822 806 JSString* str = JS_NewUCStringCopyN(cxTo, JS_GetStringChars(JSVAL_TO_STRING(val)), JS_GetStringLength(JSVAL_TO_STRING(val))); 823 807 CLONE_REQUIRE(str, L"JS_NewUCStringCopyN"); 824 808 jsval rval = STRING_TO_JSVAL(str); 825 m_Mapping[ val] = rval;809 m_Mapping[JSVAL_TO_GCTHING(val)] = rval; 826 810 m_RooterTo.Push(rval); 827 811 return rval; 828 812 } … … 843 827 CLONE_REQUIRE(newObj, L"JS_NewObject"); 844 828 } 845 829 846 m_Mapping[ val] = OBJECT_TO_JSVAL(newObj);830 m_Mapping[JSVAL_TO_GCTHING(val)] = OBJECT_TO_JSVAL(newObj); 847 831 m_RooterTo.Push(newObj); 848 832 849 833 JSIdArray* ida = JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val)); 850 834 CLONE_REQUIRE(ida, L"JS_Enumerate"); 851 835 852 IdArrayWrapper idaWrapper(cxFrom, ida); 836 AutoGCRooter idaRooter(scriptInterfaceFrom); 837 idaRooter.Push(ida); 853 838 854 839 for (jsint i = 0; i < ida->length; ++i) 855 840 { … … 880 865 return OBJECT_TO_JSVAL(newObj); 881 866 } 882 867 868 ScriptInterface& scriptInterfaceFrom; 883 869 JSContext* cxFrom; 884 870 JSContext* cxTo; 885 std::map< jsval, jsval> m_Mapping;871 std::map<void*, jsval> m_Mapping; 886 872 AutoGCRooter m_RooterFrom; 887 873 AutoGCRooter m_RooterTo; 888 874 }; -
source/scriptinterface/ScriptInterface.h
diff -r 6b3ac7e864ba source/scriptinterface/ScriptInterface.h
a b 223 223 */ 224 224 template<typename T> static jsval ToJSVal(JSContext* cx, T const& val); 225 225 226 bool AddRoot(void* ptr, const char* name);227 bool RemoveRoot(void* ptr);228 229 226 AutoGCRooter* ReplaceAutoGCRooter(AutoGCRooter* rooter); 230 227 231 228 /** … … 264 261 static JSClass* GetClass(JSContext* cx, JSObject* obj); 265 262 static void* GetPrivate(JSContext* cx, JSObject* obj); 266 263 267 void Register(const char* name, JS FastNative fptr, size_t nargs);264 void Register(const char* name, JSNative fptr, size_t nargs); 268 265 std::auto_ptr<ScriptInterface_impl> m; 269 266 270 267 // The nasty macro/template bits are split into a separate file so you don't have to look at them … … 276 273 // void RegisterFunction(const char* functionName); 277 274 // 278 275 // template <R, T0..., TR (*fptr) (void* cbdata, T0...)> 279 // static JS FastNative call;276 // static JSNative call; 280 277 // 281 278 // template <R, T0..., JSClass*, TC, TR (TC:*fptr) (T0...)> 282 // static JS FastNative callMethod;279 // static JSNative callMethod; 283 280 // 284 281 // template <dummy, T0...> 285 282 // static size_t nargs(); -
source/scriptinterface/ScriptTypes.h
diff -r 6b3ac7e864ba source/scriptinterface/ScriptTypes.h
a b 25 25 #endif 26 26 // (we don't support XP_OS2 or XP_BEOS) 27 27 28 #include "js/jspubtd.h" 29 #include "js/jsversion.h" 28 //#include "js/jspubtd.h" 29 //#include "js/jsversion.h" 30 31 #include "js/jsapi.h" 30 32 31 33 #if JS_VERSION != 185 32 34 #error Your compiler is trying to use an incorrect version of the SpiderMonkey library. -
source/scriptinterface/ScriptVal.cpp
diff -r 6b3ac7e864ba source/scriptinterface/ScriptVal.cpp
a b 24 24 struct Unrooter 25 25 { 26 26 Unrooter(JSContext* cx) : cx(cx) { } 27 void operator()(jsval* p) { JS_Remove Root(cx, p); delete p; }27 void operator()(jsval* p) { JS_RemoveValueRoot(cx, p); delete p; } 28 28 JSContext* cx; 29 29 }; 30 30 31 31 CScriptValRooted::CScriptValRooted(JSContext* cx, jsval val) 32 32 { 33 33 jsval* p = new jsval(val); 34 JS_AddNamed Root(cx, p, "CScriptValRooted");34 JS_AddNamedValueRoot(cx, p, "CScriptValRooted"); 35 35 m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx)); 36 36 } 37 37 38 38 CScriptValRooted::CScriptValRooted(JSContext* cx, CScriptVal val) 39 39 { 40 40 jsval* p = new jsval(val.get()); 41 JS_AddNamed Root(cx, p, "CScriptValRooted");41 JS_AddNamedValueRoot(cx, p, "CScriptValRooted"); 42 42 m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx)); 43 43 } 44 44 45 jsval CScriptValRooted::get() const 45 const jsval& CScriptValRooted::get() const 46 { 47 if (!m_Val) 48 return JSVAL_VOID; 49 return *m_Val; 50 } 51 52 jsval& CScriptValRooted::get() 46 53 { 47 54 if (!m_Val) 48 55 return JSVAL_VOID; -
source/scriptinterface/ScriptVal.h
diff -r 6b3ac7e864ba source/scriptinterface/ScriptVal.h
a b 29 29 class CScriptVal 30 30 { 31 31 public: 32 CScriptVal() : m_Val( 0) { }32 CScriptVal() : m_Val(JSVAL_VOID) { } 33 33 CScriptVal(jsval val) : m_Val(val) { } 34 34 35 jsvalget() const { return m_Val; }35 const jsval& get() const { return m_Val; } 36 36 37 37 private: 38 38 jsval m_Val; … … 45 45 CScriptValRooted(JSContext* cx, jsval val); 46 46 CScriptValRooted(JSContext* cx, CScriptVal val); 47 47 48 jsval get() const; 48 const jsval& get() const; 49 jsval& get(); 49 50 50 51 bool undefined() const; 51 52 -
source/scriptinterface/tests/test_ScriptConversions.h
diff -r 6b3ac7e864ba source/scriptinterface/tests/test_ScriptConversions.h
a b 34 34 JSContext* cx = script.GetContext(); 35 35 36 36 jsval v1 = ScriptInterface::ToJSVal(cx, value); 37 JS_AddRoot(cx, &v1);38 37 39 38 // We want to convert values to strings, but can't just call toSource() on them 40 39 // since they might not be objects. So just use uneval. … … 42 41 TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source)); 43 42 44 43 TS_ASSERT_STR_EQUALS(source, expected); 45 46 JS_RemoveRoot(cx, &v1);47 44 } 48 45 49 46 template <typename T> … … 53 50 JSContext* cx = script.GetContext(); 54 51 55 52 jsval v1 = ScriptInterface::ToJSVal(cx, value); 56 JS_AddRoot(cx, &v1);57 53 58 54 std::string source; 59 55 TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source)); … … 64 60 T v2 = T(); 65 61 TS_ASSERT(ScriptInterface::FromJSVal(script.GetContext(), v1, v2)); 66 62 TS_ASSERT_EQUALS(value, v2); 67 68 JS_RemoveRoot(cx, &v1);69 63 } 70 64 71 65 public: … … 132 126 133 127 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 0))); 134 128 135 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 1073741822))); // JSVAL_INT_MAX-1 136 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 1073741823))); // JSVAL_INT_MAX 137 TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<i32>(cx, 1073741824))); // JSVAL_INT_MAX+1 138 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -1073741823))); // JSVAL_INT_MIN+1 139 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -1073741824))); // JSVAL_INT_MIN 140 TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<i32>(cx, -1073741825))); // JSVAL_INT_MIN-1 129 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 2147483646))); // JSVAL_INT_MAX-1 130 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, 2147483647))); // JSVAL_INT_MAX 131 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -2147483647))); // JSVAL_INT_MIN+1 132 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<i32>(cx, -2147483648))); // JSVAL_INT_MIN 141 133 142 134 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 0))); 143 135 144 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 1073741822))); // JSVAL_INT_MAX-1145 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 1073741823))); // JSVAL_INT_MAX146 TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<u32>(cx, 1073741824))); // JSVAL_INT_MAX+1136 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 2147483646))); // JSVAL_INT_MAX-1 137 TS_ASSERT(JSVAL_IS_INT(ScriptInterface::ToJSVal<u32>(cx, 2147483647))); // JSVAL_INT_MAX 138 TS_ASSERT(JSVAL_IS_DOUBLE(ScriptInterface::ToJSVal<u32>(cx, 2147483648))); // JSVAL_INT_MAX+1 147 139 } 148 140 149 141 void test_nonfinite() -
source/scriptinterface/tests/test_ScriptInterface.h
diff -r 6b3ac7e864ba source/scriptinterface/tests/test_ScriptInterface.h
a b 136 136 TS_ASSERT(script.Eval(input.c_str(), val)); 137 137 138 138 std::string stringified = script.StringifyJSON(val.get()); 139 TS_ASSERT_STR_EQUALS(stringified, "{\n \"x\": 1,\n \"z\":[2,\n \"3\xE2\x98\xBA\xEF\xBF\xBD\"\n ],\n \"y\":true\n}");139 TS_ASSERT_STR_EQUALS(stringified, "{\n \"x\": 1,\n \"z\": [\n 2,\n \"3\xE2\x98\xBA\xEF\xBF\xBD\"\n ],\n \"y\": true\n}"); 140 140 141 141 val = script.ParseJSON(stringified); 142 142 TS_ASSERT_WSTR_EQUALS(script.ToString(val.get()), L"({x:1, z:[2, \"3\\u263A\\uFFFD\"], y:true})"); -
source/simulation2/scripting/EngineScriptConversions.cpp
diff -r 6b3ac7e864ba source/simulation2/scripting/EngineScriptConversions.cpp
a b 37 37 38 38 // If this is a scripted component, just return the JS object directly 39 39 jsval instance = val->GetJSInstance(); 40 if ( instance)40 if (!JSVAL_IS_NULL(instance)) 41 41 return instance; 42 42 43 43 // Otherwise we need to construct a wrapper object -
source/simulation2/scripting/ScriptComponent.cpp
diff -r 6b3ac7e864ba source/simulation2/scripting/ScriptComponent.cpp
a b 23 23 #include "simulation2/serialization/IDeserializer.h" 24 24 25 25 CComponentTypeScript::CComponentTypeScript(ScriptInterface& scriptInterface, jsval instance) : 26 m_ScriptInterface(scriptInterface), m_Instance( instance)26 m_ScriptInterface(scriptInterface), m_Instance(CScriptValRooted(scriptInterface.GetContext(), instance)) 27 27 { 28 debug_assert(instance);29 m_ScriptInterface.AddRoot(&m_Instance, "CComponentTypeScript.m_Instance");30 31 28 // Cache the property detection for efficiency 32 m_HasCustomSerialize = m_ScriptInterface.HasProperty(m_Instance, "Serialize"); 33 } 34 35 CComponentTypeScript::~CComponentTypeScript() 36 { 37 m_ScriptInterface.RemoveRoot(&m_Instance); 29 m_HasCustomSerialize = m_ScriptInterface.HasProperty(m_Instance.get(), "Serialize"); 38 30 } 39 31 40 32 void CComponentTypeScript::Init(const CSimContext& UNUSED(context), const CParamNode& paramNode, entity_id_t ent) 41 33 { 42 m_ScriptInterface.SetProperty(m_Instance , "entity", (int)ent, true);43 m_ScriptInterface.SetProperty(m_Instance , "template", paramNode, true);44 m_ScriptInterface.CallFunctionVoid(m_Instance , "Init");34 m_ScriptInterface.SetProperty(m_Instance.get(), "entity", (int)ent, true); 35 m_ScriptInterface.SetProperty(m_Instance.get(), "template", paramNode, true); 36 m_ScriptInterface.CallFunctionVoid(m_Instance.get(), "Init"); 45 37 } 46 38 47 39 void CComponentTypeScript::Deinit(const CSimContext& UNUSED(context)) 48 40 { 49 m_ScriptInterface.CallFunctionVoid(m_Instance , "Deinit");41 m_ScriptInterface.CallFunctionVoid(m_Instance.get(), "Deinit"); 50 42 } 51 43 52 44 void CComponentTypeScript::HandleMessage(const CSimContext& UNUSED(context), const CMessage& msg, bool global) … … 55 47 56 48 CScriptVal msgVal = msg.ToJSValCached(m_ScriptInterface); 57 49 58 if (!m_ScriptInterface.CallFunctionVoid(m_Instance , name, msgVal))50 if (!m_ScriptInterface.CallFunctionVoid(m_Instance.get(), name, msgVal)) 59 51 LOGERROR(L"Script message handler %hs failed", name); 60 52 } 61 53 … … 66 58 if (m_HasCustomSerialize) 67 59 { 68 60 CScriptValRooted val; 69 if (!m_ScriptInterface.CallFunction(m_Instance , "Serialize", val))61 if (!m_ScriptInterface.CallFunction(m_Instance.get(), "Serialize", val)) 70 62 LOGERROR(L"Script Serialize call failed"); 71 63 serialize.ScriptVal("object", val); 72 64 } 73 65 else 74 66 { 75 serialize.ScriptVal("object", m_Instance );67 serialize.ScriptVal("object", m_Instance.get()); 76 68 } 77 69 } 78 70 … … 82 74 83 75 // Use ScriptObjectAppend so we don't lose the carefully-constructed 84 76 // prototype/parent of this object 85 deserialize.ScriptObjectAppend("object", m_Instance );77 deserialize.ScriptObjectAppend("object", m_Instance.get()); 86 78 87 m_ScriptInterface.SetProperty(m_Instance , "entity", (int)ent, true);88 m_ScriptInterface.SetProperty(m_Instance , "template", paramNode, true);79 m_ScriptInterface.SetProperty(m_Instance.get(), "entity", (int)ent, true); 80 m_ScriptInterface.SetProperty(m_Instance.get(), "template", paramNode, true); 89 81 } -
source/simulation2/scripting/ScriptComponent.h
diff -r 6b3ac7e864ba source/simulation2/scripting/ScriptComponent.h
a b 35 35 { 36 36 public: 37 37 CComponentTypeScript(ScriptInterface& scriptInterface, jsval instance); 38 ~CComponentTypeScript();39 38 40 jsval GetInstance() const { return m_Instance ; }39 jsval GetInstance() const { return m_Instance.get(); } 41 40 42 41 void Init(const CSimContext& context, const CParamNode& paramNode, entity_id_t ent); 43 42 void Deinit(const CSimContext& context); … … 58 57 R Call(const char* funcname BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a)) \ 59 58 { \ 60 59 R ret; \ 61 if (m_ScriptInterface.CallFunction(m_Instance , funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \60 if (m_ScriptInterface.CallFunction(m_Instance.get(), funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \ 62 61 return ret; \ 63 62 LOGERROR(L"Error calling component script function %hs", funcname); \ 64 63 return R(); \ … … 66 65 BOOST_PP_IF(i, template<, ) BOOST_PP_ENUM_PARAMS(i, typename T) BOOST_PP_IF(i, >, ) \ 67 66 void CallVoid(const char* funcname BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(i, const T, &a)) \ 68 67 { \ 69 if (m_ScriptInterface.CallFunctionVoid(m_Instance , funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a))) \68 if (m_ScriptInterface.CallFunctionVoid(m_Instance.get(), funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a))) \ 70 69 return; \ 71 70 LOGERROR(L"Error calling component script function %hs", funcname); \ 72 71 } … … 75 74 76 75 private: 77 76 ScriptInterface& m_ScriptInterface; 78 jsvalm_Instance;77 CScriptValRooted m_Instance; 79 78 bool m_HasCustomSerialize; 80 79 81 80 NONCOPYABLE(CComponentTypeScript); -
source/simulation2/serialization/BinarySerializer.cpp
diff -r 6b3ac7e864ba source/simulation2/serialization/BinarySerializer.cpp
a b 32 32 # pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) 33 33 #endif 34 34 35 #include "js/jsobj.h"35 //#include "js/jsobj.h" 36 36 37 37 #if MSC_VERSION 38 38 # pragma warning(pop) … … 100 100 101 101 // Find all properties (ordered by insertion time) 102 102 103 // JS_Enumerate is a bit slow (lots of memory allocation), so do the enumeration manually104 // (based on the code from JS_Enumerate, using the probably less stable JSObject API):105 //106 // Correction: Actually array_enumerate returns an incorrect num_properties so we can't107 // trust it and have to iterate over all ids before we know how many there are, so108 // actually this probably isn't any faster than JS_Enumerate. Also it's less compatible109 // with future JSAPI updates. This probably wasn't a great idea.110 111 103 // (Note that we don't do any rooting, because we assume nothing is going to trigger GC. 112 104 // I'm not absolute certain that's necessarily a valid assumption.) 113 105 114 jsval iter_state, num_properties; 115 if (!obj->enumerate(cx, JSENUMERATE_INIT, &iter_state, &num_properties)) 116 throw PSERROR_Serialize_ScriptError("enumerate INIT failed"); 117 debug_assert(JSVAL_IS_INT(num_properties)); 118 debug_assert(JSVAL_TO_INT(num_properties) >= 0); 106 JSIdArray* ida = JS_Enumerate(cx, obj); 107 if (!ida) 108 throw PSERROR_Serialize_ScriptError("JS_Enumerate failed"); 119 109 120 std::vector<jsid> ids; 121 ids.reserve(JSVAL_TO_INT(num_properties)); 110 m_Serializer.NumberU32_Unbounded("num props", (uint32_t)ida->length); 122 111 123 while (true)112 for (jsint i = 0; i < ida->length; ++i) 124 113 { 125 jsval id; 126 if (!obj->enumerate(cx, JSENUMERATE_NEXT, &iter_state, &id)) 127 throw PSERROR_Serialize_ScriptError("enumerate NEXT failed"); 128 129 if (JSVAL_IS_NULL(iter_state)) 130 break; 131 132 ids.push_back(id); 133 } 134 135 m_Serializer.NumberU32_Unbounded("num props", (uint32_t)ids.size()); 136 137 for (size_t i = 0; i < ids.size(); ++i) 138 { 139 jsval id = ids[i]; 114 jsid id = ida->vector[i]; 140 115 141 116 jsval idval, propval; 142 117 … … 183 158 { 184 159 debug_assert(JSVAL_IS_DOUBLE(val)); 185 160 m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE); 186 jsdouble* dbl = JSVAL_TO_DOUBLE(val); 187 m_Serializer.NumberDouble_Unbounded("value", *dbl); 161 m_Serializer.NumberDouble_Unbounded("value", JSVAL_TO_DOUBLE(val)); 188 162 } 189 163 break; 190 164 } -
source/simulation2/serialization/StdDeserializer.cpp
diff -r 6b3ac7e864ba source/simulation2/serialization/StdDeserializer.cpp
a b 46 46 { 47 47 std::pair<std::map<u32, JSObject*>::iterator, bool> it = m_ScriptBackrefs.insert(std::make_pair((u32)m_ScriptBackrefs.size()+1, obj)); 48 48 debug_assert(it.second); 49 if (!JS_Add Root(m_ScriptInterface.GetContext(), (void*)&it.first->second))49 if (!JS_AddObjectRoot(m_ScriptInterface.GetContext(), &it.first->second)) 50 50 throw PSERROR_Deserialize_ScriptError("JS_AddRoot failed"); 51 51 } 52 52 … … 63 63 std::map<u32, JSObject*>::iterator it = m_ScriptBackrefs.begin(); 64 64 for (; it != m_ScriptBackrefs.end(); ++it) 65 65 { 66 if (!JS_Remove Root(m_ScriptInterface.GetContext(), (void*)&it->second))66 if (!JS_RemoveObjectRoot(m_ScriptInterface.GetContext(), &it->second)) 67 67 throw PSERROR_Deserialize_ScriptError("JS_RemoveRoot failed"); 68 68 } 69 69 m_ScriptBackrefs.clear(); -
source/simulation2/system/ComponentManager.cpp
diff -r 6b3ac7e864ba source/simulation2/system/ComponentManager.cpp
a b 100 100 CComponentManager::~CComponentManager() 101 101 { 102 102 ResetState(); 103 104 // Release GC roots105 std::map<ComponentTypeId, ComponentType>::iterator it = m_ComponentTypesById.begin();106 for (; it != m_ComponentTypesById.end(); ++it)107 if (it->second.type == CT_Script)108 m_ScriptInterface.RemoveRoot(&it->second.ctor);109 103 } 110 104 111 105 void CComponentManager::LoadComponentTypes() … … 194 188 } 195 189 } 196 190 197 // Clean up the old component type 198 componentManager->m_ScriptInterface.RemoveRoot(&componentManager->m_ComponentTypesById[cid].ctor); 199 200 // Remove its old message subscriptions 191 // Remove the old component type's message subscriptions 201 192 std::map<MessageTypeId, std::vector<ComponentTypeId> >::iterator it; 202 193 for (it = componentManager->m_LocalMessageSubscriptions.begin(); it != componentManager->m_LocalMessageSubscriptions.end(); ++it) 203 194 { … … 228 219 } 229 220 230 221 // Construct a new ComponentType, using the wrapper's alloc functions 231 ComponentType ct = { CT_Script, iid, ctWrapper.alloc, ctWrapper.dealloc, cname, schema, ctor.get() }; 222 ComponentType ct = { 223 CT_Script, 224 iid, 225 ctWrapper.alloc, 226 ctWrapper.dealloc, 227 cname, 228 schema, 229 CScriptValRooted(componentManager->m_ScriptInterface.GetContext(), ctor) 230 }; 232 231 componentManager->m_ComponentTypesById[cid] = ct; 233 232 234 233 componentManager->m_CurrentComponent = cid; // needed by Subscribe 235 234 236 // Stop the ctor getting GCed237 componentManager->m_ScriptInterface.AddRoot(&componentManager->m_ComponentTypesById[cid].ctor, "ComponentType ctor");238 // TODO: check carefully that roots will never get leaked etc239 240 235 241 236 // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages: 242 237 … … 285 280 for (; eit != comps.end(); ++eit) 286 281 { 287 282 jsval instance = eit->second->GetJSInstance(); 288 if ( instance)283 if (!JSVAL_IS_NULL(instance)) 289 284 componentManager->m_ScriptInterface.SetPrototype(instance, proto.get()); 290 285 } 291 286 } … … 458 453 void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, 459 454 const char* name, const std::string& schema) 460 455 { 461 ComponentType c = { CT_Native, iid, alloc, dealloc, name, schema, 0};456 ComponentType c = { CT_Native, iid, alloc, dealloc, name, schema, CScriptValRooted() }; 462 457 m_ComponentTypesById.insert(std::make_pair(cid, c)); 463 458 m_ComponentTypeIdsByName[name] = cid; 464 459 } … … 466 461 void CComponentManager::RegisterComponentTypeScriptWrapper(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, 467 462 DeallocFunc dealloc, const char* name, const std::string& schema) 468 463 { 469 ComponentType c = { CT_ScriptWrapper, iid, alloc, dealloc, name, schema, 0};464 ComponentType c = { CT_ScriptWrapper, iid, alloc, dealloc, name, schema, CScriptValRooted() }; 470 465 m_ComponentTypesById.insert(std::make_pair(cid, c)); 471 466 m_ComponentTypeIdsByName[name] = cid; 472 467 // TODO: merge with RegisterComponentType … … 584 579 std::map<entity_id_t, IComponent*>& emap2 = m_ComponentsByTypeId[cid]; 585 580 586 581 // If this is a scripted component, construct the appropriate JS object first 587 jsval obj = 0;582 jsval obj = JSVAL_NULL; 588 583 if (ct.type == CT_Script) 589 584 { 590 obj = m_ScriptInterface.CallConstructor(ct.ctor );591 if ( !obj)585 obj = m_ScriptInterface.CallConstructor(ct.ctor.get()); 586 if (JSVAL_IS_VOID(obj)) 592 587 { 593 588 LOGERROR(L"Script component constructor failed"); 594 589 return NULL; -
source/simulation2/system/ComponentManager.h
diff -r 6b3ac7e864ba source/simulation2/system/ComponentManager.h
a b 66 66 DeallocFunc dealloc; 67 67 std::string name; 68 68 std::string schema; // RelaxNG fragment 69 jsvalctor; // only valid if type == CT_Script69 CScriptValRooted ctor; // only valid if type == CT_Script 70 70 }; 71 71 72 72 public: -
source/simulation2/system/IComponent.cpp
diff -r 6b3ac7e864ba source/simulation2/system/IComponent.cpp
a b 40 40 41 41 jsval IComponent::GetJSInstance() const 42 42 { 43 return 0;43 return JSVAL_NULL; 44 44 } -
source/simulation2/system/InterfaceScripted.h
diff -r 6b3ac7e864ba source/simulation2/system/InterfaceScripted.h
a b 45 45 46 46 #define DEFINE_INTERFACE_METHOD_0(scriptname, rettype, classname, methodname) \ 47 47 { scriptname, \ 48 reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>)), \48 ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, \ 49 49 0, \ 50 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT |JSFUN_FAST_NATIVE, 0},50 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT }, 51 51 52 52 #define DEFINE_INTERFACE_METHOD_1(scriptname, rettype, classname, methodname, arg1) \ 53 53 { scriptname, \ 54 reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>)), \54 ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, \ 55 55 1, \ 56 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT |JSFUN_FAST_NATIVE, 0},56 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT }, 57 57 58 58 #define DEFINE_INTERFACE_METHOD_2(scriptname, rettype, classname, methodname, arg1, arg2) \ 59 59 { scriptname, \ 60 reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>)), \60 ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, \ 61 61 2, \ 62 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT |JSFUN_FAST_NATIVE, 0},62 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT }, 63 63 64 64 #define DEFINE_INTERFACE_METHOD_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \ 65 65 { scriptname, \ 66 reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>)), \66 ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, \ 67 67 3, \ 68 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT |JSFUN_FAST_NATIVE, 0},68 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT }, 69 69 70 70 #define DEFINE_INTERFACE_METHOD_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \ 71 71 { scriptname, \ 72 reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>)), \72 ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, \ 73 73 4, \ 74 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT |JSFUN_FAST_NATIVE, 0},74 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT }, 75 75 76 76 #define DEFINE_INTERFACE_METHOD_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \ 77 77 { scriptname, \ 78 reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>)), \78 ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, \ 79 79 5, \ 80 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT |JSFUN_FAST_NATIVE, 0},80 JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT }, 81 81 82 82 #endif // INCLUDED_INTERFACE_SCRIPTED -
source/simulation2/tests/test_ComponentManager.h
diff -r 6b3ac7e864ba source/simulation2/tests/test_ComponentManager.h
a b 325 325 { 326 326 CSimContext context; 327 327 CComponentManager man(context); 328 ScriptTestSetup(man.m_ScriptInterface); 328 329 man.LoadComponentTypes(); 329 330 TS_ASSERT(man.LoadScript(L"simulation/components/test-entityid.js")); 330 331 … … 334 335 man.AddComponent(ent1, man.LookupCID("TestScript1A"), noParam); 335 336 man.AddComponent(ent2, man.LookupCID("TestScript1A"), noParam); 336 337 337 TestLogger log;338 338 TS_ASSERT_EQUALS(static_cast<ICmpTest1*> (man.QueryInterface(ent1, IID_Test1))->GetX(), (int)ent1); 339 339 TS_ASSERT_EQUALS(static_cast<ICmpTest1*> (man.QueryInterface(ent2, IID_Test1))->GetX(), (int)ent2); 340 TS_ASSERT_WSTR_CONTAINS(log.GetOutput(), L"this.entity is read-only");341 340 } 342 341 343 342 void test_script_QueryInterface() … … 632 631 { 633 632 CSimContext context; 634 633 CComponentManager man(context); 634 ScriptTestSetup(man.m_ScriptInterface); 635 635 man.LoadComponentTypes(); 636 636 TS_ASSERT(man.LoadScript(L"simulation/components/test-serialize.js")); 637 637 -
source/simulation2/tests/test_Serializer.h
diff -r 6b3ac7e864ba source/simulation2/tests/test_Serializer.h
a b 372 372 const char stream[] = "\x02" // SCRIPT_TYPE_ARRAY 373 373 "\x04\0\0\0" // num props 374 374 "\x01\0\0\0" "0\0" // "0" 375 "\x05" "\ x00\0\0\xC0" // SCRIPT_TYPE_INT -1073741824(JS_INT_MIN)375 "\x05" "\0\0\0\x80" // SCRIPT_TYPE_INT -2147483648 (JS_INT_MIN) 376 376 "\x01\0\0\0" "1\0" // "1" 377 "\x06" "\0\0\x 40\0\0\0\xD0\xC1" // SCRIPT_TYPE_DOUBLE -1073741825(JS_INT_MIN-1)377 "\x06" "\0\0\x20\0\0\0\xE0\xC1" // SCRIPT_TYPE_DOUBLE -2147483649 (JS_INT_MIN-1) 378 378 "\x01\0\0\0" "2\0" // "2" 379 "\x05" "\xFF\xFF\xFF\x 3F" // SCRIPT_TYPE_INT 1073741823379 "\x05" "\xFF\xFF\xFF\x7F" // SCRIPT_TYPE_INT 2147483647 (JS_INT_MAX) 380 380 "\x01\0\0\0" "3\0" // "3" 381 "\x06" "\0\0\0\0\0\0\x D0\x41" // SCRIPT_TYPE_DOUBLE 1073741824381 "\x06" "\0\0\0\0\0\0\xE0\x41" // SCRIPT_TYPE_DOUBLE 2147483648 (JS_INT_MAX+1) 382 382 ; 383 383 384 helper_script_roundtrip("numbers", "[- 1073741824, -1073741825, 1.073741823e+9, 1073741824]",385 "[- 1073741824, -1073741825, 1073741823, 1073741824]", sizeof(stream) - 1, stream);384 helper_script_roundtrip("numbers", "[-2147483648, -2147483649, 2.147483647e+9, 2147483648]", 385 "[-2147483648, -2147483649, 2147483647, 2147483648]", sizeof(stream) - 1, stream); 386 386 } 387 387 388 388 void test_script_exceptions() -
source/sound/JSI_Sound.cpp
diff -r 6b3ac7e864ba source/sound/JSI_Sound.cpp
a b 28 28 { 29 29 m_Handle = snd_open(g_VFS, pathname); 30 30 31 // special-case to avoid throwing exceptions if quickstart has32 // disabled sound: set a flag queried by Construct; the object will33 // then immediately be freed.34 if (m_Handle == ERR::AGAIN)31 // if open failed, we still have to return a valid non-null object to 32 // the script, so just reset the handle to 0 so all subsequent method 33 // calls will do nothing 34 if (m_Handle < 0) 35 35 { 36 m_ SoundDisabled = true;36 m_Handle = 0; 37 37 return; 38 38 } 39 m_SoundDisabled = false;40 41 // if open failed, raise an exception - it's the only way to42 // report errors, since we're in the ctor and don't want to move43 // the open call elsewhere (by requiring an explicit open() call).44 if (m_Handle < 0)45 throw std::exception(); // caught by JSI_Sound::Construct.46 39 47 40 (void)snd_set_pos(m_Handle, 0,0,0, true); 48 41 } … … 190 183 return "[object Sound: " + CStr(h_filename(m_Handle).string()) + "]"; 191 184 } 192 185 193 JSBool JSI_Sound::Construct(JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)186 JSBool JSI_Sound::Construct(JSContext* cx, uintN argc, jsval* vp) 194 187 { 195 debug_assert(argc >= 1); // FIXME 188 JSU_REQUIRE_MIN_PARAMS(1); 189 196 190 CStrW filename; 197 if (! ToPrimitive<CStrW>(cx, argv[0], filename))191 if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename)) 198 192 return JS_FALSE; 199 193 200 try 201 { 202 JSI_Sound* newObject = new JSI_Sound(filename); 203 204 // somewhat of a hack to avoid throwing exceptions if 205 // sound was disabled due to quickstart. see JSI_Sound(). 206 if (newObject->m_SoundDisabled) 207 { 208 delete newObject; 209 *rval = JSVAL_NULL; 210 return JS_TRUE; 211 } 212 213 newObject->m_EngineOwned = false; 214 *rval = OBJECT_TO_JSVAL(newObject->GetScript()); 215 } 216 catch (std::exception) 217 { 218 // failed, but this can happen easily enough that we don't want to 219 // return JS_FALSE (since that stops the script). 220 *rval = JSVAL_NULL; 221 } 194 JSI_Sound* newObject = new JSI_Sound(filename); 195 newObject->m_EngineOwned = false; 196 JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript())); 222 197 223 198 return JS_TRUE; 224 199 } -
source/sound/JSI_Sound.h
diff -r 6b3ac7e864ba source/sound/JSI_Sound.h
a b 48 48 49 49 // Script-bound functions 50 50 51 CStr ToString( JSContext* cx, uintN argc, jsval* argv);51 CStr ToString(JSContext* cx, uintN argc, jsval* argv); 52 52 53 53 // start playing the sound (one-shot). 54 54 // it will automatically be freed when done. 55 bool Play( JSContext* cx, uintN argc, jsval* argv);55 bool Play(JSContext* cx, uintN argc, jsval* argv); 56 56 57 57 // request the sound be played until free() is called. returns immediately. 58 bool Loop( JSContext* cx, uintN argc, jsval* argv);58 bool Loop(JSContext* cx, uintN argc, jsval* argv); 59 59 60 60 // stop sound if currently playing and free resources. 61 61 // doesn't need to be called unless played via loop() - 62 62 // sounds are freed automatically when done playing. 63 bool Free( JSContext* cx, uintN argc, jsval* argv);63 bool Free(JSContext* cx, uintN argc, jsval* argv); 64 64 65 bool SetGain( JSContext* cx, uintN argc, jsval* argv);65 bool SetGain(JSContext* cx, uintN argc, jsval* argv); 66 66 67 bool SetPitch( JSContext* cx, uintN argc, jsval* argv);67 bool SetPitch(JSContext* cx, uintN argc, jsval* argv); 68 68 69 bool SetPosition( JSContext* cx, uintN argc, jsval* argv);69 bool SetPosition(JSContext* cx, uintN argc, jsval* argv); 70 70 71 bool Fade ( JSContext* cx, uintN argc, jsval* argv);71 bool Fade(JSContext* cx, uintN argc, jsval* argv); 72 72 73 static JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);73 static JSBool Construct(JSContext* cx, uintN argc, jsval* vp); 74 74 75 75 static void ScriptingInit(); 76 77 private:78 bool m_SoundDisabled; // see constructor and JSI_Sound::Construct79 76 }; 80 77 81 78 #endif // #ifndef INCLUDED_JSI_SOUND