Use JSFastNative API in more places, for improved compatibility with future SpiderMonkey versions.
Remove some unnecessary script-exposed functions, and move some more into the Engine namespace. This was SVN commit r8428.
This commit is contained in:
parent
55741aed44
commit
c0a7a36f7a
@ -497,27 +497,3 @@ void CMapWriter::WriteTrigger(XMLWriter_File& xml_file_, const MapTrigger& trigg
|
||||
} //Effects' scope
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RewriteAllMaps
|
||||
void CMapWriter::RewriteAllMaps(CTerrain* pTerrain,
|
||||
WaterManager* pWaterMan, SkyManager* pSkyMan,
|
||||
CLightEnv* pLightEnv, CGameView* pGameView, CCinemaManager* pCinema,
|
||||
CTriggerManager* pTrigMan, CSimulation2* pSimulation2)
|
||||
{
|
||||
VfsPaths pathnames;
|
||||
(void)fs_util::GetPathnames(g_VFS, L"maps/scenarios", L"*.pmp", pathnames);
|
||||
for (size_t i = 0; i < pathnames.size(); i++)
|
||||
{
|
||||
CMapReader* reader = new CMapReader;
|
||||
LDR_BeginRegistering();
|
||||
reader->LoadMap(pathnames[i], pTerrain, pWaterMan, pSkyMan, pLightEnv, pGameView, pCinema, pTrigMan, pSimulation2, -1);
|
||||
LDR_EndRegistering();
|
||||
LDR_NonprogressiveLoad();
|
||||
|
||||
CStrW newPathname(pathnames[i].string());
|
||||
newPathname.Replace(L"scenarios/", L"scenarios/new/");
|
||||
CMapWriter writer;
|
||||
writer.SaveMap(newPathname, pTerrain, pWaterMan, pSkyMan, pLightEnv, pGameView->GetCamera(), pCinema, pSimulation2);
|
||||
}
|
||||
}
|
||||
|
@ -48,13 +48,6 @@ public:
|
||||
CLightEnv* pLightEnv, CCamera* pCamera,
|
||||
CCinemaManager* pCinema, CSimulation2* pSimulation2);
|
||||
|
||||
// RewriteAllMaps: for use during development: load/save all maps, to
|
||||
// update them to the newest format.
|
||||
static void RewriteAllMaps(CTerrain* pTerrain, WaterManager* pWaterMan,
|
||||
SkyManager* pSkyMan, CLightEnv* pLightEnv, CGameView* pGameView,
|
||||
CCinemaManager* pCinema, CTriggerManager* pTrigMan,
|
||||
CSimulation2* pSimulation2);
|
||||
|
||||
private:
|
||||
// PackMap: pack the current world into a raw data stream
|
||||
void PackMap(CFilePacker& packer, CTerrain* pTerrain);
|
||||
|
@ -23,14 +23,17 @@
|
||||
#include "graphics/GameView.h"
|
||||
#include "graphics/MapReader.h"
|
||||
#include "gui/GUIManager.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
#include "maths/FixedVector3D.h"
|
||||
#include "network/NetClient.h"
|
||||
#include "network/NetServer.h"
|
||||
#include "network/NetTurnManager.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CConsole.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Overlay.h"
|
||||
#include "ps/Pyrogenesis.h"
|
||||
#include "ps/GameSetup/Atlas.h"
|
||||
#include "ps/GameSetup/Config.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
@ -322,6 +325,47 @@ void CameraFollow(void* UNUSED(cbdata), entity_id_t entityid)
|
||||
g_Game->GetView()->CameraFollow(entityid);
|
||||
}
|
||||
|
||||
|
||||
void SetSimRate(void* UNUSED(cbdata), float rate)
|
||||
{
|
||||
g_Game->SetSimRate(rate);
|
||||
}
|
||||
|
||||
void SetTurnLength(void* UNUSED(cbdata), int length)
|
||||
{
|
||||
if (g_NetServer)
|
||||
g_NetServer->SetTurnLength(length);
|
||||
else
|
||||
LOGERROR(L"Only network host can change turn length");
|
||||
}
|
||||
|
||||
// Focus the game camera on a given position.
|
||||
void SetCameraTarget(void* UNUSED(cbdata), float x, float y, float z)
|
||||
{
|
||||
g_Game->GetView()->ResetCameraTarget(CVector3D(x, y, z));
|
||||
}
|
||||
|
||||
// Deliberately cause the game to crash.
|
||||
// Currently implemented via access violation (read of address 0).
|
||||
// Useful for testing the crashlog/stack trace code.
|
||||
int Crash(void* UNUSED(cbdata))
|
||||
{
|
||||
MICROLOG(L"Crashing at user's request.");
|
||||
return *(int*)0;
|
||||
}
|
||||
|
||||
// Force a JS garbage collection cycle to take place immediately.
|
||||
// Writes an indication of how long this took to the console.
|
||||
void ForceGC(void* cbdata)
|
||||
{
|
||||
CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
|
||||
|
||||
double time = timer_Time();
|
||||
JS_GC(guiManager->GetScriptInterface().GetContext());
|
||||
time = timer_Time() - time;
|
||||
g_Console->InsertMessage(L"Garbage collection completed in: %f", time);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
@ -362,4 +406,11 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
scriptInterface.RegisterFunction<CScriptVal, std::wstring, &LoadMapData>("LoadMapData");
|
||||
scriptInterface.RegisterFunction<void, bool, &SetRevealMap>("SetRevealMap");
|
||||
scriptInterface.RegisterFunction<void, entity_id_t, &CameraFollow>("CameraFollow");
|
||||
|
||||
// Development/debugging functions
|
||||
scriptInterface.RegisterFunction<void, float, &SetSimRate>("SetSimRate");
|
||||
scriptInterface.RegisterFunction<void, int, &SetTurnLength>("SetTurnLength");
|
||||
scriptInterface.RegisterFunction<void, float, float, float, &SetCameraTarget>("SetCameraTarget");
|
||||
scriptInterface.RegisterFunction<int, &Crash>("Crash");
|
||||
scriptInterface.RegisterFunction<void, &ForceGC>("ForceGC");
|
||||
}
|
||||
|
@ -154,7 +154,6 @@ public:
|
||||
|
||||
class CProfileSample
|
||||
{
|
||||
static std::map<CStrW, char*> evMap;
|
||||
public:
|
||||
CProfileSample( const char* name )
|
||||
{
|
||||
@ -168,6 +167,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CProfileSampleScript
|
||||
{
|
||||
public:
|
||||
CProfileSampleScript( const char* name )
|
||||
{
|
||||
if (CProfileManager::IsInitialised())
|
||||
g_Profiler.StartScript( name );
|
||||
}
|
||||
~CProfileSampleScript()
|
||||
{
|
||||
if (CProfileManager::IsInitialised())
|
||||
g_Profiler.Stop();
|
||||
}
|
||||
};
|
||||
|
||||
// Put a PROFILE( xyz ) block at the start of all code to be profiled.
|
||||
// Profile blocks last until the end of the containing scope.
|
||||
#define PROFILE( name ) CProfileSample __profile( name )
|
||||
|
@ -58,7 +58,6 @@ CWorld::CWorld(CGame *pGame):
|
||||
m_pGame(pGame),
|
||||
m_Terrain(new CTerrain()),
|
||||
m_UnitManager(new CUnitManager()),
|
||||
m_LOSManager(NULL),
|
||||
m_TerritoryManager(NULL)
|
||||
{
|
||||
}
|
||||
@ -105,18 +104,3 @@ CWorld::~CWorld()
|
||||
delete m_Terrain;
|
||||
delete m_UnitManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the world.
|
||||
* Provided for JS _rewritemaps function.
|
||||
*
|
||||
**/
|
||||
void CWorld::RewriteMap()
|
||||
{
|
||||
CMapWriter::RewriteAllMaps(m_Terrain,
|
||||
g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(),
|
||||
&g_LightEnv, m_pGame->GetView(),
|
||||
m_pGame->GetView()->GetCinema(), NULL,
|
||||
m_pGame->GetSimulation2());
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ ERROR_TYPE(Game_World, MapLoadFailed);
|
||||
|
||||
class CGame;
|
||||
class CUnitManager;
|
||||
class CLOSManager;
|
||||
class CTerritoryManager;
|
||||
class CTerrain;
|
||||
class CStrW;
|
||||
@ -61,10 +60,6 @@ class CWorld
|
||||
* pointer to the CUnitManager that holds all the units in the world.
|
||||
**/
|
||||
CUnitManager *m_UnitManager;
|
||||
/**
|
||||
* pointer to the CLOSManager that holds the visibility matrix for the world.
|
||||
**/
|
||||
CLOSManager *m_LOSManager;
|
||||
/**
|
||||
* pointer to the CTerritoryManager that holds territory matrix for the world.
|
||||
**/
|
||||
@ -79,9 +74,6 @@ public:
|
||||
*/
|
||||
void RegisterInit(const CStrW& mapFile, int playerID);
|
||||
|
||||
// provided for JS _rewritemaps function
|
||||
void RewriteMap();
|
||||
|
||||
/**
|
||||
* Get the pointer to the terrain object.
|
||||
*
|
||||
@ -97,13 +89,6 @@ public:
|
||||
**/
|
||||
inline CUnitManager &GetUnitManager()
|
||||
{ return *m_UnitManager; }
|
||||
/**
|
||||
* Get the pointer to the LOS manager object.
|
||||
*
|
||||
* @return CLOSManager * the value of m_LOSManager.
|
||||
**/
|
||||
inline CLOSManager *GetLOSManager()
|
||||
{ return m_LOSManager; }
|
||||
/**
|
||||
* Get the pointer to the territory manager object.
|
||||
*
|
||||
|
@ -54,9 +54,7 @@
|
||||
#include "ps/scripting/JSInterface_Console.h"
|
||||
#include "ps/scripting/JSInterface_VFS.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/SkyManager.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation/LOSManager.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
|
||||
#define LOG_CATEGORY L"script"
|
||||
@ -70,67 +68,10 @@
|
||||
// JSBool accessor(JSContext* cx, JSObject* globalObject, jsval id, jsval* vp);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Output
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Write values to the log file.
|
||||
// params: any number of any type.
|
||||
// returns:
|
||||
// notes:
|
||||
// - Each argument is converted to a string and then written to the log.
|
||||
// - Output is in NORMAL style (see LOG).
|
||||
JSBool WriteLog(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_PARAMS(1);
|
||||
|
||||
CStrW logMessage;
|
||||
|
||||
for (int i = 0; i < (int)argc; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CStrW arg = g_ScriptingHost.ValueToUCString( argv[i] );
|
||||
logMessage += arg;
|
||||
}
|
||||
catch( PSERROR_Scripting_ConversionFailed )
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
LOG(CLogger::Normal, LOG_CATEGORY, L"%ls", logMessage.c_str());
|
||||
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Timer
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Set the simulation rate scalar-time becomes time * SimRate.
|
||||
// Params: rate [float] : sets SimRate
|
||||
JSBool SetSimRate(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_PARAMS(1);
|
||||
|
||||
g_Game->SetSimRate( ToPrimitive<float>(argv[0]) );
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool SetTurnLength(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_PARAMS(1);
|
||||
|
||||
if (g_NetServer)
|
||||
g_NetServer->SetTurnLength(ToPrimitive<unsigned int>(argv[0]));
|
||||
else
|
||||
LOGERROR(L"Only network host can change turn length");
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -214,87 +155,6 @@ JSBool EndGame(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internationalization
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// these remain here instead of in the i18n tree because they are
|
||||
// really related to the engine's use of them, as opposed to i18n itself.
|
||||
// contrariwise, translate() cannot be moved here because that would
|
||||
// make i18n dependent on this code and therefore harder to reuse.
|
||||
|
||||
// Replaces the current language (locale) with a new one.
|
||||
// params: language id [string] as in I18n::LoadLanguage
|
||||
// returns:
|
||||
JSBool LoadLanguage(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_PARAMS(1);
|
||||
|
||||
CStr lang = g_ScriptingHost.ValueToString(argv[0]);
|
||||
I18n::LoadLanguage(lang);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Return identifier of the current language (locale) in use.
|
||||
// params:
|
||||
// returns: language id [string] as in I18n::LoadLanguage
|
||||
JSBool GetLanguageID(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_NO_PARAMS();
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
JSString* s = JS_NewStringCopyZ(cx, I18n::CurrentLanguageName());
|
||||
if (!s)
|
||||
{
|
||||
JS_ReportError(cx, "Error creating string");
|
||||
return JS_FALSE;
|
||||
}
|
||||
*rval = STRING_TO_JSVAL(s);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debug
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Deliberately cause the game to crash.
|
||||
// params:
|
||||
// returns:
|
||||
// notes:
|
||||
// - currently implemented via access violation (read of address 0)
|
||||
// - useful for testing the crashlog/stack trace code.
|
||||
JSBool ProvokeCrash(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_NO_PARAMS();
|
||||
|
||||
MICROLOG(L"Crashing at user's request.");
|
||||
return *(JSBool*)0;
|
||||
}
|
||||
|
||||
|
||||
// Force a JS garbage collection cycle to take place immediately.
|
||||
// params:
|
||||
// returns: true [bool]
|
||||
// notes:
|
||||
// - writes an indication of how long this took to the console.
|
||||
JSBool ForceGarbageCollection(JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
JSU_REQUIRE_NO_PARAMS();
|
||||
|
||||
double time = timer_Time();
|
||||
JS_GC(cx);
|
||||
time = timer_Time() - time;
|
||||
g_Console->InsertMessage(L"Garbage collection completed in: %f", time);
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Misc. Engine Interface
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -360,26 +220,6 @@ JSBool SetCursor( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool GetCursorName( JSContext* UNUSED(cx), JSObject*, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval )
|
||||
{
|
||||
*rval = ToJSVal(g_CursorName);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Trigger a rewrite of all maps.
|
||||
// params:
|
||||
// returns:
|
||||
// notes:
|
||||
// - Usefulness is unclear. If you need it, consider renaming this and updating the docs.
|
||||
JSBool _RewriteMaps( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
JSU_REQUIRE_NO_PARAMS();
|
||||
|
||||
g_Game->GetWorld()->RewriteMap();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Change the LOD bias.
|
||||
// params: LOD bias [float]
|
||||
// returns:
|
||||
@ -395,26 +235,6 @@ JSBool _LodBias( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval
|
||||
}
|
||||
|
||||
|
||||
// Focus the game camera on a given position.
|
||||
// params: target position vector [CVector3D]
|
||||
// returns: success [bool]
|
||||
JSBool SetCameraTarget( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
JSU_REQUIRE_PARAMS(1);
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
CVector3D* target = ToNative<CVector3D>( argv[0] );
|
||||
if(!target)
|
||||
{
|
||||
JS_ReportError( cx, "Invalid camera target" );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
g_Game->GetView()->ResetCameraTarget( *target );
|
||||
|
||||
*rval = JSVAL_TRUE;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
JSBool GetGUIObjectByName(JSContext* cx, JSObject* UNUSED(obj), uintN UNUSED(argc), jsval* argv, jsval* rval)
|
||||
{
|
||||
try
|
||||
@ -509,15 +329,6 @@ JSBool DumpHeaps(JSContext* UNUSED(cx), JSObject* UNUSED(globalObject), uintN UN
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Toggles drawing the sky
|
||||
JSBool ToggleSky( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
JSU_REQUIRE_NO_PARAMS();
|
||||
g_Renderer.GetSkyManager()->m_RenderSky = !g_Renderer.GetSkyManager()->m_RenderSky;
|
||||
*rval = JSVAL_VOID;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Is the game paused?
|
||||
@ -558,47 +369,6 @@ JSBool SetPaused( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsv
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Reveal map
|
||||
JSBool RevealMap( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
JSU_REQUIRE_MAX_PARAMS(1);
|
||||
|
||||
int newValue;
|
||||
if(argc == 0)
|
||||
newValue = LOS_SETTING_ALL_VISIBLE;
|
||||
else if(!ToPrimitive( g_ScriptingHost.GetContext(), argv[0], newValue ) || newValue > 2)
|
||||
{
|
||||
JS_ReportError( cx, "Invalid argument (should be 0, 1 or 2)" );
|
||||
*rval = JSVAL_VOID;
|
||||
return( JS_FALSE );
|
||||
}
|
||||
|
||||
g_Game->GetWorld()->GetLOSManager()->m_LOSSetting = (ELOSSetting)newValue;
|
||||
*rval = JSVAL_VOID;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
* isGameRunning
|
||||
* @return bool
|
||||
*/
|
||||
JSBool isGameRunning( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
JSU_REQUIRE_NO_PARAMS();
|
||||
|
||||
if (g_Game && g_Game->IsGameStarted())
|
||||
{
|
||||
*rval = JSVAL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rval = JSVAL_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// function table
|
||||
@ -616,19 +386,6 @@ JSBool isGameRunning( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc,
|
||||
|
||||
JSFunctionSpec ScriptFunctionTable[] =
|
||||
{
|
||||
// Console
|
||||
JS_FUNC("writeConsole", JSI_Console::writeConsole, 1) // external
|
||||
|
||||
// Camera
|
||||
JS_FUNC("setCameraTarget", SetCameraTarget, 1)
|
||||
|
||||
// Sky
|
||||
JS_FUNC("toggleSky", ToggleSky, 0)
|
||||
|
||||
// Timer
|
||||
JS_FUNC("setSimRate", SetSimRate, 1)
|
||||
JS_FUNC("setTurnLength", SetTurnLength, 1)
|
||||
|
||||
// Profiling
|
||||
JS_FUNC("startXTimer", StartJsTimer, 1)
|
||||
JS_FUNC("stopXTimer", StopJsTimer, 1)
|
||||
@ -644,29 +401,14 @@ JSFunctionSpec ScriptFunctionTable[] =
|
||||
JS_FUNC("readFileLines", JSI_VFS::ReadFileLines, 1)
|
||||
JS_FUNC("archiveBuilderCancel", JSI_VFS::ArchiveBuilderCancel, 1)
|
||||
|
||||
// Internationalization
|
||||
JS_FUNC("loadLanguage", LoadLanguage, 1)
|
||||
JS_FUNC("getLanguageID", GetLanguageID, 0)
|
||||
// note: i18n/ScriptInterface.cpp registers translate() itself.
|
||||
// rationale: see implementation section above.
|
||||
|
||||
// Debug
|
||||
JS_FUNC("crash", ProvokeCrash, 0)
|
||||
JS_FUNC("forceGC", ForceGarbageCollection, 0)
|
||||
JS_FUNC("revealMap", RevealMap, 1)
|
||||
|
||||
// Misc. Engine Interface
|
||||
JS_FUNC("writeLog", WriteLog, 1)
|
||||
JS_FUNC("exit", ExitProgram, 0)
|
||||
JS_FUNC("isPaused", IsPaused, 0)
|
||||
JS_FUNC("setPaused", SetPaused, 1)
|
||||
JS_FUNC("vmem", WriteVideoMemToConsole, 0)
|
||||
JS_FUNC("_rewriteMaps", _RewriteMaps, 0)
|
||||
JS_FUNC("_lodBias", _LodBias, 0)
|
||||
JS_FUNC("setCursor", SetCursor, 1)
|
||||
JS_FUNC("getCursorName", GetCursorName, 0)
|
||||
JS_FUNC("getFPS", GetFps, 0)
|
||||
JS_FUNC("isGameRunning", isGameRunning, 0)
|
||||
JS_FUNC("getGUIObjectByName", GetGUIObjectByName, 1)
|
||||
|
||||
// Miscellany
|
||||
|
@ -100,18 +100,6 @@ void ScriptingHost::RunScript(const VfsPath& pathname, JSObject* globalObject)
|
||||
throw PSERROR_Scripting_LoadFile_EvalErrors();
|
||||
}
|
||||
|
||||
jsval ScriptingHost::CallFunction(const std::string & functionName, jsval * params, int numParams)
|
||||
{
|
||||
jsval result;
|
||||
|
||||
JSBool ok = JS_CallFunctionName(m_Context, m_GlobalObject, functionName.c_str(), numParams, params, &result);
|
||||
|
||||
if (ok == JS_FALSE)
|
||||
throw PSERROR_Scripting_CallFunctionFailed();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
jsval ScriptingHost::ExecuteScript(const CStrW& script, const CStrW& calledFrom, JSObject* contextObject )
|
||||
{
|
||||
jsval rval;
|
||||
@ -124,18 +112,6 @@ jsval ScriptingHost::ExecuteScript(const CStrW& script, const CStrW& calledFrom,
|
||||
return rval;
|
||||
}
|
||||
|
||||
void ScriptingHost::DefineConstant(const std::string & name, int value)
|
||||
{
|
||||
// First remove this constant if it already exists
|
||||
JS_DeleteProperty(m_Context, m_GlobalObject, name.c_str());
|
||||
|
||||
JSBool ok = JS_DefineProperty( m_Context, m_GlobalObject, name.c_str(), INT_TO_JSVAL(value),
|
||||
NULL, NULL, JSPROP_READONLY);
|
||||
|
||||
if (ok == JS_FALSE)
|
||||
throw PSERROR_Scripting_DefineConstantFailed();
|
||||
}
|
||||
|
||||
void ScriptingHost::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
|
||||
{
|
||||
std::string typeName = clasp->name;
|
||||
@ -246,8 +222,3 @@ CStrW ScriptingHost::ValueToUCString( const jsval value )
|
||||
size_t length=JS_GetStringLength(string);
|
||||
return std::wstring(strptr, strptr+length);
|
||||
}
|
||||
|
||||
jsval ScriptingHost::UCStringToValue( const CStrW& str )
|
||||
{
|
||||
return STRING_TO_JSVAL(JS_NewUCStringCopyZ(m_Context, str.utf16().c_str()));
|
||||
}
|
||||
|
@ -97,12 +97,8 @@ public:
|
||||
void RunScript(const VfsPath& filename, JSObject* globalObject = 0);
|
||||
|
||||
|
||||
jsval CallFunction(const std::string & functionName, jsval * params, int numParams);
|
||||
|
||||
jsval ExecuteScript(const CStrW& script, const CStrW& calledFrom = L"Console", JSObject* contextObject = NULL );
|
||||
|
||||
void DefineConstant(const std::string & name, int value);
|
||||
|
||||
void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN nargs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
|
||||
|
||||
JSObject * CreateCustomObject(const std::string & typeName);
|
||||
@ -117,7 +113,6 @@ public:
|
||||
|
||||
std::string ValueToString(const jsval value);
|
||||
CStrW ValueToUCString(const jsval value);
|
||||
jsval UCStringToValue(const CStrW& str);
|
||||
};
|
||||
|
||||
#define g_ScriptingHost ScriptingHost::GetSingleton()
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define NUMBERED_LIST_BALANCED(z, i, data) BOOST_PP_COMMA_IF(i) data##i
|
||||
// Some other things
|
||||
#define TYPED_ARGS(z, i, data) , T##i a##i
|
||||
#define CONVERT_ARG(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal<T##i>(cx, argv[i], a##i)) return JS_FALSE;
|
||||
#define CONVERT_ARG(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal<T##i>(cx, i < argc ? JS_ARGV(cx, vp)[i] : JSVAL_VOID, a##i)) return JS_FALSE;
|
||||
|
||||
// List-generating macros, named roughly after their first list item
|
||||
#define TYPENAME_T0_HEAD(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_HEAD, typename T) // "typename T0, typename T1, "
|
||||
@ -47,18 +47,18 @@
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
|
||||
// JSNative-compatible function that wraps the function identified in the template argument list
|
||||
// JSFastNative-compatible function that wraps the function identified in the template argument list
|
||||
// (Definition comes later, since it depends on some things we haven't defined yet)
|
||||
#define OVERLOADS(z, i, data) \
|
||||
template <typename R, TYPENAME_T0_HEAD(z,i) R (*fptr) ( void* T0_TAIL(z,i) )> \
|
||||
static JSBool call(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
|
||||
static JSBool call(JSContext* cx, uintN argc, jsval* vp);
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
|
||||
// Similar, for class methods
|
||||
#define OVERLOADS(z, i, data) \
|
||||
template <typename R, TYPENAME_T0_HEAD(z,i) JSClass* CLS, typename TC, R (TC::*fptr) ( T0(z,i) )> \
|
||||
static JSBool callMethod(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
|
||||
static JSBool callMethod(JSContext* cx, uintN argc, jsval* vp);
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
|
||||
|
@ -71,15 +71,27 @@ struct ScriptInterface_NativeMethodWrapper<void, TC> {
|
||||
#undef OVERLOADS
|
||||
};
|
||||
|
||||
// Fast natives don't trigger the hook we use for profiling, so explicitly
|
||||
// notify the profiler when these functions are being called
|
||||
#if ENABLE_SCRIPT_PROFILING
|
||||
#define SCRIPT_PROFILE \
|
||||
debug_assert(JSVAL_IS_OBJECT(JS_CALLEE(cx, vp)) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)))); \
|
||||
const char* name = JS_GetFunctionName(JS_ValueToFunction(cx, JS_CALLEE(cx, vp))); /* native function so ValueToFunction is safe; this makes unsafe lifetime assumptions */ \
|
||||
CProfileSampleScript profile(name);
|
||||
#else
|
||||
#define SCRIPT_PROFILE
|
||||
#endif
|
||||
|
||||
|
||||
// JSNative-compatible function that wraps the function identified in the template argument list
|
||||
// JSFastNative-compatible function that wraps the function identified in the template argument list
|
||||
#define OVERLOADS(z, i, data) \
|
||||
template <typename R, TYPENAME_T0_HEAD(z,i) R (*fptr) ( void* T0_TAIL(z,i) )> \
|
||||
JSBool ScriptInterface::call(JSContext* cx, JSObject* /*obj*/, uintN /*argc*/, jsval* argv, jsval* rval) { \
|
||||
(void)argv; /* avoid 'unused parameter' warnings */ \
|
||||
JSBool ScriptInterface::call(JSContext* cx, uintN argc, jsval* vp) { \
|
||||
UNUSED2(argc); \
|
||||
SCRIPT_PROFILE \
|
||||
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
|
||||
ScriptInterface_NativeWrapper<R>::call(cx, *rval, fptr A0_TAIL(z,i)); \
|
||||
jsval rval = JSVAL_VOID; \
|
||||
ScriptInterface_NativeWrapper<R>::call(cx, rval, fptr A0_TAIL(z,i)); \
|
||||
JS_SET_RVAL(cx, vp, rval); \
|
||||
return (ScriptInterface::IsExceptionPending(cx) ? JS_FALSE : JS_TRUE); \
|
||||
}
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
@ -88,19 +100,23 @@ BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
// Same idea but for methods
|
||||
#define OVERLOADS(z, i, data) \
|
||||
template <typename R, TYPENAME_T0_HEAD(z,i) JSClass* CLS, typename TC, R (TC::*fptr) ( T0(z,i) )> \
|
||||
JSBool ScriptInterface::callMethod(JSContext* cx, JSObject* obj, uintN /*argc*/, jsval* argv, jsval* rval) { \
|
||||
(void)argv; /* avoid 'unused parameter' warnings */ \
|
||||
if (ScriptInterface::GetClass(cx, obj) != CLS) return JS_FALSE; \
|
||||
TC* c = static_cast<TC*>(ScriptInterface::GetPrivate(cx, obj)); \
|
||||
JSBool ScriptInterface::callMethod(JSContext* cx, uintN argc, jsval* vp) { \
|
||||
UNUSED2(argc); \
|
||||
SCRIPT_PROFILE \
|
||||
if (ScriptInterface::GetClass(cx, JS_THIS_OBJECT(cx, vp)) != CLS) return JS_FALSE; \
|
||||
TC* c = static_cast<TC*>(ScriptInterface::GetPrivate(cx, JS_THIS_OBJECT(cx, vp))); \
|
||||
if (! c) return JS_FALSE; \
|
||||
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
|
||||
ScriptInterface_NativeMethodWrapper<R, TC>::call(cx, *rval, c, fptr A0_TAIL(z,i)); \
|
||||
jsval rval = JSVAL_VOID; \
|
||||
ScriptInterface_NativeMethodWrapper<R, TC>::call(cx, rval, c, fptr A0_TAIL(z,i)); \
|
||||
JS_SET_RVAL(cx, vp, rval); \
|
||||
return (ScriptInterface::IsExceptionPending(cx) ? JS_FALSE : JS_TRUE); \
|
||||
}
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
|
||||
// Clean up our mess
|
||||
#undef SCRIPT_PROFILE
|
||||
#undef NUMBERED_LIST_HEAD
|
||||
#undef NUMBERED_LIST_TAIL
|
||||
#undef NUMBERED_LIST_BALANCED
|
||||
|
@ -39,12 +39,6 @@
|
||||
const int RUNTIME_SIZE = 16 * 1024 * 1024; // TODO: how much memory is needed?
|
||||
const int STACK_CHUNK_SIZE = 8192;
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define ENABLE_SCRIPT_PROFILING 0
|
||||
#else
|
||||
#define ENABLE_SCRIPT_PROFILING 1
|
||||
#endif
|
||||
|
||||
#if ENABLE_SCRIPT_PROFILING
|
||||
#include "js/jsdbgapi.h"
|
||||
#endif
|
||||
@ -55,7 +49,7 @@ struct ScriptInterface_impl
|
||||
{
|
||||
ScriptInterface_impl(const char* nativeScopeName, JSContext* cx);
|
||||
~ScriptInterface_impl();
|
||||
void Register(const char* name, JSNative fptr, uintN nargs);
|
||||
void Register(const char* name, JSFastNative fptr, uintN nargs);
|
||||
|
||||
JSRuntime* m_rt; // NULL if m_cx is shared; non-NULL if we own m_cx
|
||||
JSContext* m_cx;
|
||||
@ -314,9 +308,9 @@ ScriptInterface_impl::~ScriptInterface_impl()
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptInterface_impl::Register(const char* name, JSNative fptr, uintN nargs)
|
||||
void ScriptInterface_impl::Register(const char* name, JSFastNative fptr, uintN nargs)
|
||||
{
|
||||
JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(m_cx, m_nativeScope, name, reinterpret_cast<JSNative>(fptr), nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_FAST_NATIVE);
|
||||
}
|
||||
|
||||
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName) :
|
||||
@ -367,7 +361,7 @@ void ScriptInterface::ReplaceNondeterministicFunctions(boost::rand48& rng)
|
||||
JS_SetReservedSlot(m->m_cx, JS_GetFunctionObject(random), 0, PRIVATE_TO_JSVAL(&rng));
|
||||
}
|
||||
|
||||
void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs)
|
||||
void ScriptInterface::Register(const char* name, JSFastNative fptr, size_t nargs)
|
||||
{
|
||||
m->Register(name, fptr, (uintN)nargs);
|
||||
}
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include "ScriptTypes.h"
|
||||
#include "ScriptVal.h"
|
||||
|
||||
#include "js/jsapi.h"
|
||||
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/utf16string.h"
|
||||
|
||||
class AutoGCRooter;
|
||||
@ -40,6 +43,12 @@ namespace boost { class rand48; }
|
||||
// but as large as necessary for all wrapped functions)
|
||||
#define SCRIPT_INTERFACE_MAX_ARGS 6
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define ENABLE_SCRIPT_PROFILING 0
|
||||
#else
|
||||
#define ENABLE_SCRIPT_PROFILING 1
|
||||
#endif
|
||||
|
||||
struct ScriptInterface_impl;
|
||||
class ScriptInterface
|
||||
{
|
||||
@ -241,7 +250,7 @@ private:
|
||||
static JSClass* GetClass(JSContext* cx, JSObject* obj);
|
||||
static void* GetPrivate(JSContext* cx, JSObject* obj);
|
||||
|
||||
void Register(const char* name, JSNative fptr, size_t nargs);
|
||||
void Register(const char* name, JSFastNative fptr, size_t nargs);
|
||||
std::auto_ptr<ScriptInterface_impl> m;
|
||||
|
||||
// The nasty macro/template bits are split into a separate file so you don't have to look at them
|
||||
@ -253,10 +262,10 @@ public:
|
||||
// void RegisterFunction(const char* functionName);
|
||||
//
|
||||
// template <R, T0..., TR (*fptr) (void* cbdata, T0...)>
|
||||
// static JSNative call;
|
||||
// static JSFastNative call;
|
||||
//
|
||||
// template <R, T0..., JSClass*, TC, TR (TC:*fptr) (T0...)>
|
||||
// static JSNative callMethod;
|
||||
// static JSFastNative callMethod;
|
||||
//
|
||||
// template <dummy, T0...>
|
||||
// static size_t nargs();
|
||||
|
@ -45,38 +45,38 @@
|
||||
|
||||
#define DEFINE_INTERFACE_METHOD_0(scriptname, rettype, classname, methodname) \
|
||||
{ scriptname, \
|
||||
ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, \
|
||||
reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>)), \
|
||||
0, \
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT, 0 },
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
|
||||
|
||||
#define DEFINE_INTERFACE_METHOD_1(scriptname, rettype, classname, methodname, arg1) \
|
||||
{ scriptname, \
|
||||
ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, \
|
||||
reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>)), \
|
||||
1, \
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT, 0 },
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
|
||||
|
||||
#define DEFINE_INTERFACE_METHOD_2(scriptname, rettype, classname, methodname, arg1, arg2) \
|
||||
{ scriptname, \
|
||||
ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, \
|
||||
reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>)), \
|
||||
2, \
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT, 0 },
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
|
||||
|
||||
#define DEFINE_INTERFACE_METHOD_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \
|
||||
{ scriptname, \
|
||||
ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, \
|
||||
reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>)), \
|
||||
3, \
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT, 0 },
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
|
||||
|
||||
#define DEFINE_INTERFACE_METHOD_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \
|
||||
{ scriptname, \
|
||||
ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, \
|
||||
reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>)), \
|
||||
4, \
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT, 0 },
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
|
||||
|
||||
#define DEFINE_INTERFACE_METHOD_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \
|
||||
{ scriptname, \
|
||||
ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, \
|
||||
reinterpret_cast<JSNative>(static_cast<JSFastNative>(ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>)), \
|
||||
5, \
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT, 0 },
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSFUN_FAST_NATIVE, 0 },
|
||||
|
||||
#endif // INCLUDED_INTERFACE_SCRIPTED
|
||||
|
Loading…
Reference in New Issue
Block a user