2010-05-20 19:58:37 +02:00
|
|
|
/* Copyright (C) 2010 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
// This module defines the table of all functions callable from JS.
|
|
|
|
// it's required by the interpreter; we make use of the opportunity to
|
|
|
|
// document them all in one spot. we thus obviate having to dig through
|
|
|
|
// all the other headers. most of the functions are implemented here;
|
|
|
|
// as for the rest, we only link to their docs (duplication is bad).
|
|
|
|
|
2004-06-03 20:38:14 +02:00
|
|
|
#include "precompiled.h"
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
#include "ScriptGlue.h"
|
2006-06-04 01:02:37 +02:00
|
|
|
#include "JSConversions.h"
|
2007-02-10 04:09:52 +01:00
|
|
|
|
2006-06-04 01:02:37 +02:00
|
|
|
#include "graphics/GameView.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "graphics/LightEnv.h"
|
|
|
|
#include "graphics/MapWriter.h"
|
2007-02-10 04:09:52 +01:00
|
|
|
#include "graphics/Unit.h"
|
|
|
|
#include "graphics/UnitManager.h"
|
2010-07-20 01:01:58 +02:00
|
|
|
#include "gui/GUIManager.h"
|
|
|
|
#include "gui/IGUIObject.h"
|
2007-12-20 21:21:45 +01:00
|
|
|
#include "lib/frequency_filter.h"
|
2010-08-02 21:23:58 +02:00
|
|
|
#include "lib/svn_revision.h"
|
|
|
|
#include "lib/timer.h"
|
2011-03-23 14:36:20 +01:00
|
|
|
#include "lib/sysdep/sysdep.h" // sys_OpenFile
|
2006-06-04 01:02:37 +02:00
|
|
|
#include "maths/scripting/JSInterface_Vector3D.h"
|
2008-06-16 20:19:35 +02:00
|
|
|
#include "network/NetServer.h"
|
2006-06-04 01:02:37 +02:00
|
|
|
#include "ps/CConsole.h"
|
|
|
|
#include "ps/CLogger.h"
|
|
|
|
#include "ps/CStr.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/Game.h"
|
2008-01-03 23:07:18 +01:00
|
|
|
#include "ps/Globals.h" // g_frequencyFilter
|
2006-06-04 01:02:37 +02:00
|
|
|
#include "ps/GameSetup/GameSetup.h"
|
2007-02-10 04:09:52 +01:00
|
|
|
#include "ps/Hotkey.h"
|
|
|
|
#include "ps/ProfileViewer.h"
|
2010-05-20 20:09:23 +02:00
|
|
|
#include "ps/World.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/scripting/JSInterface_Console.h"
|
|
|
|
#include "ps/scripting/JSInterface_VFS.h"
|
2006-06-04 01:02:37 +02:00
|
|
|
#include "renderer/Renderer.h"
|
2010-01-09 20:20:14 +01:00
|
|
|
#include "scriptinterface/ScriptInterface.h"
|
2010-06-08 00:19:05 +02:00
|
|
|
#include "simulation2/Simulation2.h"
|
2006-03-31 05:30:34 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
// rationale: the function table is now at the end of the source file to
|
|
|
|
// avoid the need for forward declarations for every function.
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
// all normal function wrappers have the following signature:
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
// JSBool func(JSContext* cx, JSObject* globalObject, uintN argc, jsval* argv, jsval* rval);
|
2005-07-20 02:57:17 +02:00
|
|
|
// all property accessors have the following signature:
|
|
|
|
// JSBool accessor(JSContext* cx, JSObject* globalObject, jsval id, jsval* vp);
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2004-07-20 21:30:35 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Timer
|
|
|
|
//-----------------------------------------------------------------------------
|
2005-03-29 00:13:47 +02:00
|
|
|
|
2010-08-13 18:42:53 +02:00
|
|
|
|
2007-05-02 14:07:08 +02:00
|
|
|
// Script profiling functions: Begin timing a piece of code with StartJsTimer(num)
|
|
|
|
// and stop timing with StopJsTimer(num). The results will be printed to stdout
|
2006-07-30 02:24:04 +02:00
|
|
|
// when the game exits.
|
2005-12-18 08:33:16 +01:00
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
static const size_t MAX_JS_TIMERS = 20;
|
2007-05-02 14:07:08 +02:00
|
|
|
static TimerUnit js_start_times[MAX_JS_TIMERS];
|
|
|
|
static TimerUnit js_timer_overhead;
|
|
|
|
static TimerClient js_timer_clients[MAX_JS_TIMERS];
|
2009-11-03 22:46:35 +01:00
|
|
|
static wchar_t js_timer_descriptions_buf[MAX_JS_TIMERS * 12]; // depends on MAX_JS_TIMERS and format string below
|
2006-07-13 22:09:20 +02:00
|
|
|
|
2007-05-02 14:07:08 +02:00
|
|
|
static void InitJsTimers()
|
2006-07-13 22:09:20 +02:00
|
|
|
{
|
2009-11-03 22:46:35 +01:00
|
|
|
wchar_t* pos = js_timer_descriptions_buf;
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for(size_t i = 0; i < MAX_JS_TIMERS; i++)
|
2006-07-13 22:09:20 +02:00
|
|
|
{
|
2009-11-03 22:46:35 +01:00
|
|
|
const wchar_t* description = pos;
|
2009-11-03 23:27:25 +01:00
|
|
|
pos += swprintf_s(pos, 12, L"js_timer %d", (int)i)+1;
|
2008-01-07 21:03:19 +01:00
|
|
|
timer_AddClient(&js_timer_clients[i], description);
|
2006-07-13 22:09:20 +02:00
|
|
|
}
|
2006-07-13 23:04:06 +02:00
|
|
|
|
2006-07-14 16:00:00 +02:00
|
|
|
// call several times to get a good approximation of 'hot' performance.
|
|
|
|
// note: don't use a separate timer slot to warm up and then judge
|
|
|
|
// overhead from another: that causes worse results (probably some
|
|
|
|
// caching effects inside JS, but I don't entirely understand why).
|
2006-07-13 23:04:06 +02:00
|
|
|
static const char* calibration_script =
|
2006-07-14 16:00:00 +02:00
|
|
|
"startXTimer(0);\n"
|
|
|
|
"stopXTimer (0);\n"
|
2006-07-13 23:04:06 +02:00
|
|
|
"\n";
|
|
|
|
g_ScriptingHost.RunMemScript(calibration_script, strlen(calibration_script));
|
2008-01-07 21:03:19 +01:00
|
|
|
// slight hack: call RunMemScript twice because we can't average several
|
|
|
|
// TimerUnit values because there's no operator/. this way is better anyway
|
|
|
|
// because it hopefully avoids the one-time JS init overhead.
|
|
|
|
g_ScriptingHost.RunMemScript(calibration_script, strlen(calibration_script));
|
|
|
|
js_timer_overhead = js_timer_clients[0].sum;
|
|
|
|
js_timer_clients[0].sum.SetToZero();
|
2006-07-13 22:09:20 +02:00
|
|
|
}
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool StartJsTimer(JSContext* cx, uintN argc, jsval* vp)
|
2006-07-13 22:09:20 +02:00
|
|
|
{
|
2007-05-02 14:07:08 +02:00
|
|
|
ONCE(InitJsTimers());
|
2006-07-13 22:09:20 +02:00
|
|
|
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_PARAMS(1);
|
2010-11-17 00:00:52 +01:00
|
|
|
size_t slot = ToPrimitive<size_t>(JS_ARGV(cx, vp)[0]);
|
2007-05-02 14:07:08 +02:00
|
|
|
if (slot >= MAX_JS_TIMERS)
|
2006-11-07 22:03:13 +01:00
|
|
|
return JS_FALSE;
|
2006-07-13 22:09:20 +02:00
|
|
|
|
2008-01-07 21:03:19 +01:00
|
|
|
js_start_times[slot].SetFromTimer();
|
2010-11-17 00:00:52 +01:00
|
|
|
|
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
2006-11-07 22:03:13 +01:00
|
|
|
return JS_TRUE;
|
2006-07-13 22:09:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool StopJsTimer(JSContext* cx, uintN argc, jsval* vp)
|
2006-07-13 22:09:20 +02:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_PARAMS(1);
|
2010-11-17 00:00:52 +01:00
|
|
|
size_t slot = ToPrimitive<size_t>(JS_ARGV(cx, vp)[0]);
|
2007-05-02 14:07:08 +02:00
|
|
|
if (slot >= MAX_JS_TIMERS)
|
2006-11-07 22:03:13 +01:00
|
|
|
return JS_FALSE;
|
2006-07-13 22:09:20 +02:00
|
|
|
|
2008-01-07 21:03:19 +01:00
|
|
|
TimerUnit now;
|
|
|
|
now.SetFromTimer();
|
|
|
|
now.Subtract(js_timer_overhead);
|
2010-08-10 19:03:17 +02:00
|
|
|
BillingPolicy_Default()(&js_timer_clients[slot], js_start_times[slot], now);
|
2008-01-07 21:03:19 +01:00
|
|
|
js_start_times[slot].SetToZero();
|
2010-11-17 00:00:52 +01:00
|
|
|
|
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
2006-11-07 22:03:13 +01:00
|
|
|
return JS_TRUE;
|
2006-07-13 22:09:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Game Setup
|
|
|
|
//-----------------------------------------------------------------------------
|
2004-10-07 21:23:35 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
// Immediately ends the current game (if any).
|
|
|
|
// params:
|
|
|
|
// returns:
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool EndGame(JSContext* cx, uintN argc, jsval* vp)
|
2004-08-05 15:07:51 +02:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_NO_PARAMS();
|
2005-07-20 02:57:17 +02:00
|
|
|
|
2004-08-05 15:07:51 +02:00
|
|
|
EndGame();
|
2010-11-17 00:00:52 +01:00
|
|
|
|
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
2004-08-05 15:07:51 +02:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2004-07-31 14:45:30 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Misc. Engine Interface
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Return the global frames-per-second value.
|
|
|
|
// params:
|
|
|
|
// returns: FPS [int]
|
|
|
|
// notes:
|
|
|
|
// - This value is recalculated once a frame. We take special care to
|
|
|
|
// filter it, so it is both accurate and free of jitter.
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool GetFps(JSContext* cx, uintN argc, jsval* vp)
|
2005-07-20 02:57:17 +02:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_NO_PARAMS();
|
2010-06-30 23:41:04 +02:00
|
|
|
int freq = 0;
|
|
|
|
if (g_frequencyFilter)
|
|
|
|
freq = g_frequencyFilter->StableFrequency();
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(freq));
|
2004-07-09 14:44:12 +02:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2004-07-15 21:29:56 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// Cause the game to exit gracefully.
|
|
|
|
// params:
|
|
|
|
// returns:
|
|
|
|
// notes:
|
|
|
|
// - Exit happens after the current main loop iteration ends
|
|
|
|
// (since this only sets a flag telling it to end)
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool ExitProgram(JSContext* cx, uintN argc, jsval* vp)
|
2004-07-15 21:29:56 +02:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_NO_PARAMS();
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
kill_mainloop();
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
2004-08-14 13:21:29 +02:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2005-03-29 22:50:04 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// Change the mouse cursor.
|
|
|
|
// params: cursor name [string] (i.e. basename of definition file and texture)
|
|
|
|
// returns:
|
|
|
|
// notes:
|
|
|
|
// - Cursors are stored in "art\textures\cursors"
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool SetCursor(JSContext* cx, uintN argc, jsval* vp)
|
2005-07-20 02:57:17 +02:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_PARAMS(1);
|
2010-11-17 00:00:52 +01:00
|
|
|
g_CursorName = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[0]);
|
|
|
|
|
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
2005-07-20 02:57:17 +02:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
2007-05-02 14:07:08 +02:00
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool GetGUIObjectByName(JSContext* cx, uintN argc, jsval* vp)
|
2005-05-20 19:09:47 +02:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_PARAMS(1);
|
2005-07-20 02:57:17 +02:00
|
|
|
|
2010-07-20 01:01:58 +02:00
|
|
|
try
|
|
|
|
{
|
2010-11-17 00:00:52 +01:00
|
|
|
CStr name = ToPrimitive<CStr>(cx, JS_ARGV(cx, vp)[0]);
|
2010-07-20 01:01:58 +02:00
|
|
|
IGUIObject* guiObj = g_GUI->FindObjectByName(name);
|
|
|
|
if (guiObj)
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(guiObj->GetJSObject()));
|
2010-07-20 01:01:58 +02:00
|
|
|
else
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
2010-07-20 01:01:58 +02:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
catch (PSERROR_Scripting&)
|
|
|
|
{
|
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
}
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Miscellany
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Return the date/time at which the current executable was compiled.
|
2009-02-28 17:42:46 +01:00
|
|
|
// params: none (-> "date time (svn revision)") OR an integer specifying
|
|
|
|
// what to display: 0 for date, 1 for time, 2 for svn revision
|
|
|
|
// returns: string with the requested timestamp info
|
2005-07-20 02:57:17 +02:00
|
|
|
// notes:
|
|
|
|
// - Displayed on main menu screen; tells non-programmers which auto-build
|
|
|
|
// they are running. Could also be determined via .EXE file properties,
|
|
|
|
// but that's a bit more trouble.
|
|
|
|
// - To be exact, the date/time returned is when scriptglue.cpp was
|
2009-02-28 17:42:46 +01:00
|
|
|
// last compiled, but the auto-build does full rebuilds.
|
|
|
|
// - svn revision is generated by calling svnversion and cached in
|
|
|
|
// lib/svn_revision.cpp. it is useful to know when attempting to
|
|
|
|
// reproduce bugs (the main EXE and PDB should be temporarily reverted to
|
|
|
|
// that revision so that they match user-submitted crashdumps).
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool GetBuildTimestamp(JSContext* cx, uintN argc, jsval* vp)
|
2005-07-20 02:57:17 +02:00
|
|
|
{
|
2009-08-02 21:52:31 +02:00
|
|
|
JSU_REQUIRE_MAX_PARAMS(1);
|
2005-07-20 02:57:17 +02:00
|
|
|
|
2009-02-28 17:42:46 +01:00
|
|
|
char buf[200];
|
|
|
|
|
|
|
|
// see function documentation
|
2010-11-17 00:00:52 +01:00
|
|
|
const int mode = argc? JSVAL_TO_INT(JS_ARGV(cx, vp)[0]) : -1;
|
2009-02-28 17:42:46 +01:00
|
|
|
switch(mode)
|
|
|
|
{
|
|
|
|
case -1:
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, ARRAY_SIZE(buf), "%s %s (%ls)", __DATE__, __TIME__, svn_revision);
|
2009-02-28 17:42:46 +01:00
|
|
|
break;
|
|
|
|
case 0:
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, ARRAY_SIZE(buf), "%s", __DATE__);
|
2009-02-28 17:42:46 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, ARRAY_SIZE(buf), "%s", __TIME__);
|
2009-02-28 17:42:46 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2009-08-14 20:42:39 +02:00
|
|
|
sprintf_s(buf, ARRAY_SIZE(buf), "%ls", svn_revision);
|
2009-02-28 17:42:46 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf)));
|
2005-07-20 02:57:17 +02:00
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-11-14 19:18:04 +01:00
|
|
|
#if MOZJS_DEBUG_ABI
|
2011-03-21 20:54:08 +01:00
|
|
|
void DumpHeap(const char* basename, int idx, JSContext* cx)
|
2005-07-20 02:57:17 +02:00
|
|
|
{
|
2011-03-21 20:54:08 +01:00
|
|
|
char filename[64];
|
2011-03-21 22:06:08 +01:00
|
|
|
sprintf_s(filename, ARRAY_SIZE(filename), "%s.%03d.txt", basename, idx);
|
2011-03-23 14:36:20 +01:00
|
|
|
OsPath pathname = psLogDir() / filename;
|
|
|
|
FILE* f = sys_OpenFile(pathname, "w");
|
2011-04-30 15:01:45 +02:00
|
|
|
ENSURE(f);
|
2010-08-02 21:23:58 +02:00
|
|
|
JS_DumpHeap(cx, f, NULL, 0, NULL, (size_t)-1, NULL);
|
|
|
|
fclose(f);
|
2005-07-20 02:57:17 +02:00
|
|
|
}
|
2010-08-02 21:23:58 +02:00
|
|
|
#endif
|
2005-07-20 02:57:17 +02:00
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool DumpHeaps(JSContext* cx, uintN argc, jsval* vp)
|
2005-07-20 06:53:58 +02:00
|
|
|
{
|
2010-11-17 00:00:52 +01:00
|
|
|
UNUSED2(cx);
|
|
|
|
UNUSED2(argc);
|
|
|
|
|
2011-11-14 19:18:04 +01:00
|
|
|
#if MOZJS_DEBUG_ABI
|
2010-08-02 21:23:58 +02:00
|
|
|
static int i = 0;
|
2005-07-20 06:53:58 +02:00
|
|
|
|
2010-08-02 21:23:58 +02:00
|
|
|
if (ScriptingHost::IsInitialised())
|
|
|
|
DumpHeap("gui", i, g_ScriptingHost.GetContext());
|
|
|
|
if (g_Game)
|
|
|
|
DumpHeap("sim", i, g_Game->GetSimulation2()->GetScriptInterface().GetContext());
|
2005-07-20 06:53:58 +02:00
|
|
|
|
2010-08-02 21:23:58 +02:00
|
|
|
++i;
|
|
|
|
#else
|
|
|
|
debug_warn(L"DumpHeaps only available in DEBUG mode");
|
|
|
|
#endif
|
2010-11-17 00:00:52 +01:00
|
|
|
|
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
2010-08-02 21:23:58 +02:00
|
|
|
return JS_TRUE;
|
2007-02-10 04:09:52 +01:00
|
|
|
}
|
|
|
|
|
2007-05-02 14:07:08 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2006-01-02 04:07:29 +01:00
|
|
|
// Is the game paused?
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool IsPaused(JSContext* cx, uintN argc, jsval* vp)
|
2006-01-02 04:07:29 +01:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_NO_PARAMS();
|
2006-02-15 01:45:16 +01:00
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
if (!g_Game)
|
2006-01-23 04:56:48 +01:00
|
|
|
{
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_ReportError(cx, "Game is not started");
|
2006-01-23 04:56:48 +01:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, g_Game->m_Paused ? JSVAL_TRUE : JSVAL_FALSE);
|
|
|
|
return JS_TRUE;
|
2006-01-02 04:07:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Pause/unpause the game
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool SetPaused(JSContext* cx, uintN argc, jsval* vp)
|
2006-01-02 04:07:29 +01:00
|
|
|
{
|
2006-07-26 15:10:13 +02:00
|
|
|
JSU_REQUIRE_PARAMS( 1 );
|
2006-02-15 01:45:16 +01:00
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
if (!g_Game)
|
2006-01-23 04:56:48 +01:00
|
|
|
{
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_ReportError(cx, "Game is not started");
|
2006-01-23 04:56:48 +01:00
|
|
|
return JS_FALSE;
|
|
|
|
}
|
|
|
|
|
2006-02-15 01:45:16 +01:00
|
|
|
try
|
2006-01-02 04:07:29 +01:00
|
|
|
{
|
2010-11-17 00:00:52 +01:00
|
|
|
g_Game->m_Paused = ToPrimitive<bool> (JS_ARGV(cx, vp)[0]);
|
2006-02-15 01:45:16 +01:00
|
|
|
}
|
2010-11-17 00:00:52 +01:00
|
|
|
catch (PSERROR_Scripting_ConversionFailed)
|
2006-01-02 04:07:29 +01:00
|
|
|
{
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_ReportError(cx, "Invalid parameter to SetPaused");
|
2006-01-02 04:07:29 +01:00
|
|
|
}
|
2006-01-23 04:56:48 +01:00
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
|
|
|
return JS_TRUE;
|
2006-01-23 04:56:48 +01:00
|
|
|
}
|
|
|
|
|
2010-01-09 20:20:14 +01:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// function table
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// the JS interpreter expects the table to contain 5-tuples as follows:
|
|
|
|
// - name the function will be called as from script;
|
|
|
|
// - function which will be called;
|
|
|
|
// - number of arguments this function expects
|
|
|
|
// - Flags (deprecated, always zero)
|
|
|
|
// - Extra (reserved for future use, always zero)
|
|
|
|
//
|
|
|
|
// we simplify this a bit with a macro:
|
2010-11-17 00:00:52 +01:00
|
|
|
#define JS_FUNC(script_name, cpp_function, min_params) { script_name, cpp_function, min_params, 0 },
|
2005-07-20 02:57:17 +02:00
|
|
|
|
2006-01-07 02:04:26 +01:00
|
|
|
JSFunctionSpec ScriptFunctionTable[] =
|
2005-07-20 02:57:17 +02:00
|
|
|
{
|
2006-07-30 02:24:04 +02:00
|
|
|
// Profiling
|
2007-05-02 14:07:08 +02:00
|
|
|
JS_FUNC("startXTimer", StartJsTimer, 1)
|
|
|
|
JS_FUNC("stopXTimer", StopJsTimer, 1)
|
2006-07-13 22:09:20 +02:00
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
// Game Setup
|
2007-05-02 14:07:08 +02:00
|
|
|
JS_FUNC("endGame", EndGame, 0)
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// VFS (external)
|
2007-05-02 14:07:08 +02:00
|
|
|
JS_FUNC("buildDirEntList", JSI_VFS::BuildDirEntList, 1)
|
|
|
|
JS_FUNC("getFileMTime", JSI_VFS::GetFileMTime, 1)
|
|
|
|
JS_FUNC("getFileSize", JSI_VFS::GetFileSize, 1)
|
|
|
|
JS_FUNC("readFile", JSI_VFS::ReadFile, 1)
|
|
|
|
JS_FUNC("readFileLines", JSI_VFS::ReadFileLines, 1)
|
|
|
|
JS_FUNC("archiveBuilderCancel", JSI_VFS::ArchiveBuilderCancel, 1)
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// Misc. Engine Interface
|
2007-05-02 14:07:08 +02:00
|
|
|
JS_FUNC("exit", ExitProgram, 0)
|
|
|
|
JS_FUNC("isPaused", IsPaused, 0)
|
|
|
|
JS_FUNC("setPaused", SetPaused, 1)
|
|
|
|
JS_FUNC("setCursor", SetCursor, 1)
|
|
|
|
JS_FUNC("getFPS", GetFps, 0)
|
2010-07-20 01:01:58 +02:00
|
|
|
JS_FUNC("getGUIObjectByName", GetGUIObjectByName, 1)
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// Miscellany
|
2007-05-02 14:07:08 +02:00
|
|
|
JS_FUNC("buildTime", GetBuildTimestamp, 0)
|
2010-08-02 21:23:58 +02:00
|
|
|
JS_FUNC("dumpHeaps", DumpHeaps, 0)
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// end of table marker
|
2010-11-17 00:00:52 +01:00
|
|
|
{0}
|
2005-07-20 02:57:17 +02:00
|
|
|
};
|
|
|
|
#undef JS_FUNC
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// property accessors
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool GetGameView(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp)
|
2005-07-20 02:57:17 +02:00
|
|
|
{
|
|
|
|
if (g_Game)
|
2010-11-17 00:00:52 +01:00
|
|
|
*vp = OBJECT_TO_JSVAL(g_Game->GetView()->GetScript());
|
2005-07-20 02:57:17 +02:00
|
|
|
else
|
|
|
|
*vp = JSVAL_NULL;
|
2010-11-17 00:00:52 +01:00
|
|
|
return JS_TRUE;
|
2005-07-20 02:57:17 +02:00
|
|
|
}
|
|
|
|
|
2010-11-17 00:00:52 +01:00
|
|
|
JSBool GetRenderer(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp)
|
2005-10-10 16:15:28 +02:00
|
|
|
{
|
|
|
|
if (CRenderer::IsInitialised())
|
2010-11-17 00:00:52 +01:00
|
|
|
*vp = OBJECT_TO_JSVAL(g_Renderer.GetScript());
|
2005-10-10 16:15:28 +02:00
|
|
|
else
|
|
|
|
*vp = JSVAL_NULL;
|
2010-11-17 00:00:52 +01:00
|
|
|
return JS_TRUE;
|
2005-10-10 16:15:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-20 02:57:17 +02:00
|
|
|
enum ScriptGlobalTinyIDs
|
|
|
|
{
|
|
|
|
GLOBAL_SELECTION,
|
|
|
|
GLOBAL_GROUPSARRAY,
|
|
|
|
GLOBAL_CAMERA,
|
|
|
|
GLOBAL_CONSOLE,
|
2006-02-15 01:45:16 +01:00
|
|
|
GLOBAL_LIGHTENV
|
2005-07-20 02:57:17 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
JSPropertySpec ScriptGlobalTable[] =
|
|
|
|
{
|
2007-12-29 17:22:23 +01:00
|
|
|
{ "console" , GLOBAL_CONSOLE, JSPROP_PERMANENT|JSPROP_READONLY, JSI_Console::getConsole, 0 },
|
|
|
|
{ "gameView" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetGameView, 0 },
|
|
|
|
{ "renderer" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetRenderer, 0 },
|
2005-07-20 02:57:17 +02:00
|
|
|
|
|
|
|
// end of table marker
|
|
|
|
{ 0, 0, 0, 0, 0 },
|
|
|
|
};
|