From 8286218cadce8e3263718da528f7705a9bca35cc Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Sun, 1 Aug 2010 20:56:34 +0000 Subject: [PATCH] Delete lots of obsolete unused script-interface code. Delete unused code from various other places. This was SVN commit r7839. --- source/graphics/Camera.cpp | 17 - source/graphics/Camera.h | 13 - source/graphics/GameView.cpp | 2 +- source/graphics/MapReader.cpp | 8 +- source/graphics/MapWriter.cpp | 21 +- source/graphics/MapWriter.h | 12 +- source/graphics/ObjectManager.h | 2 - source/graphics/Terrain.h | 1 - source/gui/MiniMap.cpp | 31 +- source/gui/MiniMap.h | 12 +- source/ps/CConsole.cpp | 1 - source/ps/Game.cpp | 70 -- source/ps/Game.h | 24 +- source/ps/GameSetup/GameSetup.cpp | 6 - source/ps/Vector2D.h | 131 -- source/ps/World.cpp | 4 +- source/ps/World.h | 2 - source/scripting/DOMEvent.cpp | 211 ---- source/scripting/DOMEvent.h | 152 --- source/scripting/EventTypes.h | 80 -- source/scripting/JSConversions.cpp | 14 - source/scripting/JSSerialization.h | 158 --- source/scripting/ScriptCustomTypes.cpp | 111 -- source/scripting/ScriptCustomTypes.h | 51 - source/scripting/ScriptGlue.cpp | 2 - source/scripting/ScriptObject.cpp | 143 --- source/scripting/ScriptObject.h | 73 -- source/scripting/ScriptableComplex.cpp | 62 - source/scripting/ScriptableComplex.h | 312 ----- source/scripting/ScriptableComplex.inl | 1105 ----------------- source/scripting/SynchedJSObject.cpp | 122 -- source/scripting/SynchedJSObject.h | 167 --- .../GameInterface/Handlers/MapHandlers.cpp | 2 +- 33 files changed, 24 insertions(+), 3098 deletions(-) delete mode 100644 source/ps/Vector2D.h delete mode 100644 source/scripting/DOMEvent.cpp delete mode 100644 source/scripting/DOMEvent.h delete mode 100644 source/scripting/EventTypes.h delete mode 100644 source/scripting/JSSerialization.h delete mode 100644 source/scripting/ScriptCustomTypes.cpp delete mode 100644 source/scripting/ScriptCustomTypes.h delete mode 100644 source/scripting/ScriptObject.cpp delete mode 100644 source/scripting/ScriptObject.h delete mode 100644 source/scripting/ScriptableComplex.cpp delete mode 100644 source/scripting/ScriptableComplex.h delete mode 100644 source/scripting/ScriptableComplex.inl delete mode 100644 source/scripting/SynchedJSObject.cpp delete mode 100644 source/scripting/SynchedJSObject.h diff --git a/source/graphics/Camera.cpp b/source/graphics/Camera.cpp index 417eec170c..cbe356ac2a 100644 --- a/source/graphics/Camera.cpp +++ b/source/graphics/Camera.cpp @@ -161,21 +161,6 @@ void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const pts[3].Z=dist; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// GetFrustumPoints: calculate and return the position of the 8 points of the frustum in world space -void CCamera::GetFrustumPoints(CVector3D pts[8]) const -{ - // get camera space points for near and far planes - CVector3D cpts[8]; - GetCameraPlanePoints(m_NearPlane,pts); - GetCameraPlanePoints(m_FarPlane,pts+4); - - // transform to world space - for (int i=0;i<8;i++) { - m_Orientation.Transform(cpts[i],pts[i]); - } -} - void CCamera::BuildCameraRay( int px, int py, CVector3D& origin, CVector3D& dir ) { CVector3D cPts[4]; @@ -401,5 +386,3 @@ void CCamera::Render(int intermediates) const glEnd(); } } - - diff --git a/source/graphics/Camera.h b/source/graphics/Camera.h index 2455e393b4..8b2562943f 100644 --- a/source/graphics/Camera.h +++ b/source/graphics/Camera.h @@ -26,8 +26,6 @@ #include "Frustum.h" #include "maths/Matrix3D.h" -extern int g_mouse_x, g_mouse_y; - // view port struct SViewPort { @@ -45,7 +43,6 @@ class CCamera ~CCamera (); // Methods for projection - void SetProjection (CMatrix3D *proj) { m_ProjMat = *proj; } void SetProjection (float nearp, float farp, float fov); void SetProjectionTile (int tiles, int tile_x, int tile_y); CMatrix3D& GetProjection () { return m_ProjMat; } @@ -65,9 +62,6 @@ class CCamera float GetFarPlane() const { return m_FarPlane; } float GetFOV() const { return m_FOV; } - // calculate and return the position of the 8 points of the frustum in world space - void GetFrustumPoints(CVector3D pts[8]) const; - // return four points in camera space at given distance from camera void GetCameraPlanePoints(float dist,CVector3D pts[4]) const; @@ -76,11 +70,6 @@ class CCamera // BuildCameraRay: calculate origin and ray direction of a ray through // the pixel (px,py) on the screen void BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir); - // BuildCameraRay: as previous, using global mouse position - void BuildCameraRay(CVector3D& origin, CVector3D& dir) - { - BuildCameraRay(g_mouse_x, g_mouse_y, origin, dir); - } // General helpers that seem to fit here @@ -90,8 +79,6 @@ class CCamera // Get the point on the terrain corresponding to pixel (px,py) (or the mouse coordinates) // The aboveWater parameter determines whether we want to stop at the water plane or also get underwater points CVector3D GetWorldCoordinates(int px, int py, bool aboveWater=false); - CVector3D GetWorldCoordinates(bool aboveWater=false) - { return GetWorldCoordinates(g_mouse_x, g_mouse_y, aboveWater); } // Get the point on the plane at height h corresponding to pixel (px,py) CVector3D GetWorldCoordinates(int px, int py, float h); // Get the point on the terrain the camera is pointing towards diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index d3515f7ddd..c036c8ca68 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -479,7 +479,7 @@ void CGameView::ResetCameraOrientation() void CGameView::RotateAboutTarget() { - m->CameraPivot = m->ViewCamera.GetWorldCoordinates(true); + m->CameraPivot = m->ViewCamera.GetWorldCoordinates(g_mouse_x, g_mouse_y, true); } void CGameView::Update(float DeltaTime) diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index edb04591be..82d4737086 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -21,19 +21,13 @@ #include "graphics/Camera.h" #include "graphics/CinemaTrack.h" -#include "graphics/GameView.h" -#include "graphics/Model.h" -#include "graphics/ObjectManager.h" #include "graphics/Patch.h" #include "graphics/Terrain.h" #include "graphics/TextureEntry.h" #include "graphics/TextureManager.h" -#include "graphics/Unit.h" -#include "graphics/UnitManager.h" #include "lib/timer.h" #include "maths/MathUtil.h" #include "ps/CLogger.h" -#include "ps/Game.h" #include "ps/Loader.h" #include "ps/LoaderThunks.h" #include "ps/XML/Xeromyces.h" @@ -781,7 +775,7 @@ void CXMLReader::ReadCinema(XMBElement parent) m_MapReader.pCinema->SetAllPaths(pathList); } -void CXMLReader::ReadTriggers(XMBElement parent) +void CXMLReader::ReadTriggers(XMBElement UNUSED(parent)) { // MapTriggerGroup rootGroup( L"Triggers", L"" ); // if (m_MapReader.pTrigMan) diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index f2a6700d16..e88178b5ad 100644 --- a/source/graphics/MapWriter.cpp +++ b/source/graphics/MapWriter.cpp @@ -22,20 +22,13 @@ #include "LightEnv.h" #include "MapReader.h" #include "MapWriter.h" -#include "Model.h" -#include "ObjectBase.h" -#include "ObjectEntry.h" -#include "ObjectManager.h" #include "Patch.h" #include "Terrain.h" #include "TextureEntry.h" #include "TextureManager.h" -#include "Unit.h" -#include "UnitManager.h" #include "maths/MathUtil.h" #include "maths/NUSpline.h" -#include "ps/Game.h" #include "ps/Loader.h" #include "ps/Filesystem.h" #include "ps/XML/XMLWriter.h" @@ -56,7 +49,7 @@ CMapWriter::CMapWriter() /////////////////////////////////////////////////////////////////////////////////////////////////// // SaveMap: try to save the current map to the given file void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain, - CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, + WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, CSimulation2* pSimulation2) { @@ -69,7 +62,7 @@ void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain, packer.Write(pathname); VfsPath pathnameXML = fs::change_extension(pathname, L".xml"); - WriteXML(pathnameXML, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); + WriteXML(pathnameXML, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -175,7 +168,7 @@ void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain* pTerrain) packer.PackRaw(&tiles[0],sizeof(STileDesc)*tiles.size()); } void CMapWriter::WriteXML(const VfsPath& filename, - CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, + WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, CSimulation2* pSimulation2) { @@ -285,7 +278,7 @@ void CMapWriter::WriteXML(const VfsPath& filename, { XML_Element("Entities"); - CSimulation2& sim = *g_Game->GetSimulation2(); + CSimulation2& sim = *pSimulation2; CmpPtr cmpTemplateManager(sim, SYSTEM_ENTITY); debug_assert(!cmpTemplateManager.null()); @@ -495,10 +488,10 @@ void CMapWriter::WriteTrigger(XMLWriter_File& xml_file_, const MapTrigger& trigg /////////////////////////////////////////////////////////////////////////////////////////////////// // RewriteAllMaps -void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan, +void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, - CTriggerManager* pTrigMan, CSimulation2* pSimulation2, CEntityManager* pEntityMan) + CTriggerManager* pTrigMan, CSimulation2* pSimulation2) { VfsPaths pathnames; (void)fs_util::GetPathnames(g_VFS, L"maps/scenarios", L"*.pmp", pathnames); @@ -513,6 +506,6 @@ void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan, CStrW newPathname(pathnames[i].string()); newPathname.Replace(L"scenarios/", L"scenarios/new/"); CMapWriter writer; - writer.SaveMap(newPathname, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); + writer.SaveMap(newPathname, pTerrain, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); } } diff --git a/source/graphics/MapWriter.h b/source/graphics/MapWriter.h index 8dbec33288..8c0b79326b 100644 --- a/source/graphics/MapWriter.h +++ b/source/graphics/MapWriter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -27,14 +27,12 @@ class CLightEnv; class CTerrain; -class CUnitManager; class CCamera; class CCinemaManager; class CTriggerManager; class WaterManager; class SkyManager; class CSimulation2; -class CEntityManager; struct MapTrigger; struct MapTriggerGroup; class XMLWriter_File; @@ -45,17 +43,17 @@ public: // constructor CMapWriter(); // SaveMap: try to save the current map to the given file - void SaveMap(const VfsPath& pathname, CTerrain* pTerr, CUnitManager* pUnitMan, + void SaveMap(const VfsPath& pathname, CTerrain* pTerr, WaterManager* pWaterMan, SkyManager* pSkyMan, 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, CUnitManager* pUnitMan, WaterManager* pWaterMan, + static void RewriteAllMaps(CTerrain* pTerrain, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, CTriggerManager* pTrigMan, - CSimulation2* pSimulation2, CEntityManager* pEntityMan); + CSimulation2* pSimulation2); private: // PackMap: pack the current world into a raw data stream @@ -69,7 +67,7 @@ private: std::vector& tileIndices); // WriteXML: output some other data (entities, etc) in XML format - void WriteXML(const VfsPath& pathname, CUnitManager* pUnitMan, WaterManager* pWaterMan, + void WriteXML(const VfsPath& pathname, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, CSimulation2* pSimulation2); // void WriteTriggerGroup(XMLWriter_File& xml_file_, const MapTriggerGroup& group, diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index 0391b061e4..851fe8be1b 100644 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -25,8 +25,6 @@ #include "ps/CStr.h" #include "lib/file/vfs/vfs_path.h" -class CEntityTemplate; -class CMatrix3D; class CMeshManager; class CObjectBase; class CObjectEntry; diff --git a/source/graphics/Terrain.h b/source/graphics/Terrain.h index 466b3c3466..641eb52559 100644 --- a/source/graphics/Terrain.h +++ b/source/graphics/Terrain.h @@ -22,7 +22,6 @@ #ifndef INCLUDED_TERRAIN #define INCLUDED_TERRAIN -#include "ps/Vector2D.h" #include "maths/Vector3D.h" #include "maths/Fixed.h" #include "graphics/SColor.h" diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index e50e381ce9..18d3d1f700 100644 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -26,8 +26,6 @@ #include "graphics/Terrain.h" #include "graphics/TextureEntry.h" #include "graphics/TextureManager.h" -#include "graphics/Unit.h" -#include "graphics/UnitManager.h" #include "lib/ogl.h" #include "lib/external_libraries/sdl.h" #include "lib/bits.h" @@ -44,13 +42,6 @@ bool g_TerrainModified = false; bool g_GameRestarted = false; -// used by GetMapSpaceCoords (precalculated as an optimization). -// this was formerly access via inline asm, which required it to be -// static data instead of a class member. that is no longer the case, -// but we leave it because this is slightly more efficient. -static float m_scaleX, m_scaleY; - - static unsigned int ScaleColor(unsigned int color, float x) { unsigned int r = unsigned(float(color & 0xff) * x); @@ -61,7 +52,7 @@ static unsigned int ScaleColor(unsigned int color, float x) CMiniMap::CMiniMap() : m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), - m_LOSTexture(0), m_LOSData(0), m_UnitManager(0) + m_LOSTexture(0), m_LOSData(0) { AddSetting(GUIST_CColor, "fov_wedge_color"); AddSetting(GUIST_CStr, "tooltip"); @@ -256,15 +247,11 @@ void CMiniMap::Draw() // Set our globals in case they hadn't been set before m_Camera = g_Game->GetView()->GetCamera(); m_Terrain = g_Game->GetWorld()->GetTerrain(); - m_UnitManager = &g_Game->GetWorld()->GetUnitManager(); m_Width = (u32)(m_CachedActualSize.right - m_CachedActualSize.left); m_Height = (u32)(m_CachedActualSize.bottom - m_CachedActualSize.top); m_MapSize = m_Terrain->GetVerticesPerSide(); m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize); - m_scaleX = float(m_Width) / float(m_MapSize - 1); - m_scaleY = float(m_Height) / float(m_MapSize - 1); - if(!m_TerrainTexture || g_GameRestarted) CreateTextures(); @@ -394,8 +381,8 @@ void CMiniMap::Draw() // (~70msec/frame on a GF4 rendering a thousand points) glPointSize(3.f); - float sx = m_scaleX / CELL_SIZE; - float sy = m_scaleY / CELL_SIZE; + float sx = (float)m_Width / ((m_MapSize - 1) * CELL_SIZE); + float sy = (float)m_Height / ((m_MapSize - 1) * CELL_SIZE); CSimulation2* sim = g_Game->GetSimulation2(); const CSimulation2::InterfaceList& ents = sim->GetEntitiesWithInterface(IID_Minimap); @@ -569,13 +556,3 @@ void CMiniMap::Destroy() delete[] m_TerrainData; m_TerrainData = 0; delete[] m_LOSData; m_LOSData = 0; } - -CVector2D CMiniMap::GetMapSpaceCoords(CVector3D worldPos) -{ - float x = rintf(worldPos.X / CELL_SIZE); - float y = rintf(worldPos.Z / CELL_SIZE); - // Entity's Z coordinate is really its longitudinal coordinate on the terrain - - // Calculate map space scale - return CVector2D(x * m_scaleX, y * m_scaleY); -} diff --git a/source/gui/MiniMap.h b/source/gui/MiniMap.h index 6d489b52b3..751cd4e5a5 100644 --- a/source/gui/MiniMap.h +++ b/source/gui/MiniMap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,11 +20,8 @@ #include "gui/GUI.h" -class CVector2D; -class CVector3D; class CCamera; class CTerrain; -class CUnitManager; extern bool g_TerrainModified; @@ -55,16 +52,9 @@ protected: void FireWorldClickEvent(int button, int clicks); - // calculate the relative heightmap space coordinates - // for a units world position - CVector2D GetMapSpaceCoords(CVector3D worldPos); - // the terrain we are mini-mapping const CTerrain* m_Terrain; - // the unit manager with unit positions - const CUnitManager* m_UnitManager; - // not const: camera is moved by clicking on minimap CCamera* m_Camera; diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp index b987d3599c..bdb8148b0c 100644 --- a/source/ps/CConsole.cpp +++ b/source/ps/CConsole.cpp @@ -37,7 +37,6 @@ #include "ps/Hotkey.h" #include "ps/Pyrogenesis.h" #include "scripting/ScriptingHost.h" -#include "scripting/ScriptableComplex.inl" #define LOG_CATEGORY L"Console" diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 65f7dad6db..484555aee7 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -230,76 +230,6 @@ void CGame::Interpolate(float frameLength) m_TurnManager->Interpolate(frameLength); } - -/** - * Test player statistics and update game status as required. - * - **/ -/* -void CGame::UpdateGameStatus() -{ - bool EOG_lose = true; - bool EOG_win = true; - CPlayer *local = GetLocalPlayer(); - - for (int i=0; iGetEntityManager().GetHandle(i); - if ( !handle ) - continue; - CPlayer *tmpPlayer = handle->m_entity->GetPlayer(); - - //Are we still alive? - if ( local == tmpPlayer && handle->m_entity->m_extant ) - { - EOG_lose = false; - if (EOG_win == false) - break; - } - //Are they still alive? - else if ( handle->m_entity->m_extant ) - { - EOG_win = false; - if (EOG_lose == false) - break; - } - } - if (EOG_lose && EOG_win) - GameStatus = EOG_SPECIAL_DRAW; - else if (EOG_win) - GameStatus = EOG_WIN; - else if (EOG_lose) - GameStatus = EOG_LOSE; - else - GameStatus = EOG_NEUTRAL; -}*/ - -/** - * End of game console message creation. - * - **/ -void CGame::EndGame() -{ - g_Console->InsertMessage( L"It's the end of the game as we know it!"); - switch (GameStatus) - { - case EOG_DRAW: - g_Console->InsertMessage( L"A diplomatic draw ain't so bad, eh?"); - break; - case EOG_SPECIAL_DRAW: - g_Console->InsertMessage( L"Amazingly, you managed to draw from dieing at the same time as your opponent...you have my respect."); - break; - case EOG_LOSE: - g_Console->InsertMessage( L"My condolences on your loss."); - break; - case EOG_WIN: - g_Console->InsertMessage( L"Thou art victorious!"); - break; - default: - break; - } -} - static CColor BrokenColor(0.3f, 0.3f, 0.3f, 1.0f); CColor CGame::GetPlayerColour(int player) const { diff --git a/source/ps/Game.h b/source/ps/Game.h index 1f7d01a7bb..fcc8f59081 100644 --- a/source/ps/Game.h +++ b/source/ps/Game.h @@ -66,18 +66,6 @@ class CGame int m_PlayerID; - /** - * enumerated values for game status. - **/ - enum EOG - { - EOG_NEUTRAL, /// Game is in progress - EOG_DRAW, /// Game is over as a Draw by means of agreement of civilizations - EOG_SPECIAL_DRAW, /// Game is over by players dying at the same time...? - EOG_LOSE, /// Game is over, local player loses - EOG_WIN /// Game is over, local player wins - } GameStatus; - CNetTurnManager* m_TurnManager; public: @@ -105,9 +93,6 @@ public: void Interpolate(float frameLength); - void UpdateGameStatus(); - void EndGame(); - int GetPlayerID(); void SetPlayerID(int playerID); @@ -130,6 +115,7 @@ public: **/ inline CWorld *GetWorld() { return m_World; } + /** * Get the pointer to the game view object. * @@ -137,6 +123,7 @@ public: **/ inline CGameView *GetView() { return m_GameView; } + /** * Get the pointer to the simulation2 object. * @@ -155,13 +142,6 @@ public: **/ inline void SetSimRate(float simRate) { m_SimRate = std::max(simRate, 0.0f); } - /** - * Get the simulation scale multiplier. - * - * @return float value of m_SimRate. - **/ - inline float GetSimRate() const - { return m_SimRate; } /** * Replace the current turn manager. diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 88a68b83f7..2ab27c1541 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -65,11 +65,8 @@ #include "simulation2/Simulation2.h" -#include "scripting/ScriptableComplex.inl" #include "scripting/ScriptingHost.h" #include "scripting/ScriptGlue.h" -#include "scripting/DOMEvent.h" -#include "scripting/ScriptableComplex.h" #include "scriptinterface/ScriptInterface.h" @@ -314,9 +311,6 @@ static void RegisterJavascriptInterfaces() // sound JSI_Sound::ScriptingInit(); - // scripting - CScriptEvent::ScriptingInit(); - // ps JSI_Console::init(); diff --git a/source/ps/Vector2D.h b/source/ps/Vector2D.h deleted file mode 100644 index e38f348c93..0000000000 --- a/source/ps/Vector2D.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// Vector2D.h -// -// 2-dimensional vector class, primarily for use by simulation code. - -#ifndef INCLUDED_VECTOR2D -#define INCLUDED_VECTOR2D - -#include -#include "maths/Vector3D.h" - -class CVector2D -{ -public: - float x; - float y; - inline CVector2D() { x = 0.0f; y = 0.0f; } - inline CVector2D( float _x, float _y ) - { - x = _x; y = _y; - } - inline CVector2D( const CVector3D& v3 ) // This is done an awful lot. - { - x = v3.X; y = v3.Z; - } - inline operator CVector3D() const - { - return( CVector3D( x, 0, y ) ); - } - inline bool operator==( const CVector2D& rhs ) const - { - return( x == rhs.x && y == rhs.y ); - } - static inline float Dot( const CVector2D& u, const CVector2D& v ) - { - return( u.x * v.x + u.y * v.y ); - } - static inline float betadot( const CVector2D& u, const CVector2D& v ) - { - // Beta-dot product. I have no idea if that's its correct name - // but use of it tends to simplify collision formulae. - // At the moment I think all of my code uses separate vectors - // and dots them together, though. - return( u.x * v.y - u.y * v.x ); - } - inline CVector2D beta() const - { - return( CVector2D( y, -x ) ); - } - inline float Dot( const CVector2D& u ) const - { - return( Dot( *this, u ) ); - } - inline float betadot( const CVector2D& u ) const - { - return( betadot( *this, u ) ); - } - inline CVector2D operator+( const CVector2D& u ) const - { - return( CVector2D( x + u.x, y + u.y ) ); - } - inline CVector2D operator-( const CVector2D& u ) const - { - return( CVector2D( x - u.x, y - u.y ) ); - } - inline CVector2D& operator+=( const CVector2D& u ) - { - x += u.x; y += u.y; - return( *this ); - } - inline CVector2D& operator-=( const CVector2D& u ) - { - x -= u.x; y -= u.y; - return( *this ); - } - inline CVector2D operator*( const float scale ) const - { - return( CVector2D( x * scale, y * scale ) ); - } - inline CVector2D operator/( const float scale ) const - { - return( CVector2D( x / scale, y / scale ) ); - } - inline CVector2D& operator*=( const float scale ) - { - x *= scale; y *= scale; - return( *this ); - } - inline CVector2D& operator/=( const float scale ) - { - x /= scale; y /= scale; - return( *this ); - } - inline float Length() const - { - return( sqrt( x * x + y * y ) ); - } - inline float length2() const - { - return( x * x + y * y ); - } - CVector2D Normalize() const - { - float l = Length(); - if( l < 0.00001 ) return( CVector2D( 1.0f, 0.0f ) ); - l = 1 / l; - return( CVector2D( x * l, y * l ) ); - } - inline bool within( const float dist ) const - { - return( ( x * x + y * y ) <= ( dist * dist ) ); - } -}; - -#endif diff --git a/source/ps/World.cpp b/source/ps/World.cpp index fa5c6d8d4a..d91595625c 100644 --- a/source/ps/World.cpp +++ b/source/ps/World.cpp @@ -115,9 +115,9 @@ CWorld::~CWorld() **/ void CWorld::RewriteMap() { - CMapWriter::RewriteAllMaps(m_Terrain, m_UnitManager, + CMapWriter::RewriteAllMaps(m_Terrain, g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(), &g_LightEnv, m_pGame->GetView()->GetCamera(), m_pGame->GetView()->GetCinema(), NULL, - m_pGame->GetSimulation2(), NULL); + m_pGame->GetSimulation2()); } diff --git a/source/ps/World.h b/source/ps/World.h index 41fe3bfcc5..0b91ec95e5 100644 --- a/source/ps/World.h +++ b/source/ps/World.h @@ -35,8 +35,6 @@ ERROR_TYPE(Game_World, MapLoadFailed); class CGame; class CUnitManager; -class CEntityManager; -class CProjectileManager; class CLOSManager; class CTerritoryManager; class CTerrain; diff --git a/source/scripting/DOMEvent.cpp b/source/scripting/DOMEvent.cpp deleted file mode 100644 index a8b0dd5e62..0000000000 --- a/source/scripting/DOMEvent.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" -#include "DOMEvent.h" -#include "lib/timer.h" -#include "ps/Profile.h" -#include "ScriptObject.h" - -IEventTarget::~IEventTarget() -{ - HandlerMap::iterator it; - for( it = m_Handlers_name.begin(); it != m_Handlers_name.end(); it++ ) - delete( it->second ); -} - -bool IEventTarget::_DispatchEvent( CScriptEvent* evt, IEventTarget* target ) -{ - PROFILE_START( "_DispatchEvent" ); - - // TODO: Deal correctly with multiple handlers - - if( before && before->_DispatchEvent( evt, target ) ) - { - return( true ); // Stop propagation. - } - - evt->m_CurrentTarget = this; - - HandlerList::const_iterator it; - const HandlerList &handlers=m_Handlers_id[evt->m_TypeCode]; - for( it = handlers.begin(); it != handlers.end(); it++ ) - { - DOMEventHandler id = *it; - if( id && id->DispatchEvent( GetScriptExecContext( target ), evt ) ) - { - return( true ); - } - } - - HandlerRange range = m_Handlers_name.equal_range( evt->m_Type ); - HandlerMap::iterator itm; - for( itm = range.first; itm != range.second; itm++ ) - { - DOMEventHandler id = itm->second; - if( id && id->DispatchEvent( GetScriptExecContext( target ), evt ) ) - { - return( true ); - } - } - - if( after && after->_DispatchEvent( evt, target ) ) - { - return( true ); // Stop propagation. - } - - return( false ); - - PROFILE_END( "_DispatchEvent" ); -} - -// Dispatch an event to its handler. -// returns: whether the event arrived (i.e. wasn't cancelled) [bool] -bool IEventTarget::DispatchEvent( CScriptEvent* evt ) -{ - const char* data; - PROFILE_START( "intern string" ); - data = g_Profiler.InternString( "script: " + (CStr8)evt->m_Type ); - PROFILE_END( "intern string" ); - g_Profiler.StartScript( data ); - evt->m_Target = this; - _DispatchEvent( evt, this ); - g_Profiler.Stop(); - return( !evt->m_Cancelled ); -} - -bool IEventTarget::AddHandler( size_t TypeCode, DOMEventHandler handler ) -{ - HandlerList::iterator it; - for( it = m_Handlers_id[TypeCode].begin(); it != m_Handlers_id[TypeCode].end(); it++ ) - if( **it == *handler ) return( false ); - m_Handlers_id[TypeCode].push_back( handler ); - return( true ); -} - -bool IEventTarget::AddHandler( const CStrW& TypeString, DOMEventHandler handler ) -{ - HandlerMap::iterator it; - HandlerRange range = m_Handlers_name.equal_range( TypeString ); - for( it = range.first; it != range.second; it++ ) - if( *( it->second ) == *handler ) return( false ); - m_Handlers_name.insert( HandlerMap::value_type( TypeString, handler ) ); - return( true ); -} - -bool IEventTarget::RemoveHandler( size_t TypeCode, DOMEventHandler handler ) -{ - HandlerList::iterator it; - for( it = m_Handlers_id[TypeCode].begin(); it != m_Handlers_id[TypeCode].end(); it++ ) - if( **it == *handler ) - { - m_Handlers_id[TypeCode].erase( it ); - return( true ); - } - - return( false ); -} - -bool IEventTarget::RemoveHandler( const CStrW& TypeString, DOMEventHandler handler ) -{ - HandlerMap::iterator it; - HandlerRange range = m_Handlers_name.equal_range( TypeString ); - for( it = range.first; it != range.second; it++ ) - if( *( it->second ) == *handler ) - { - delete( it->second ); - m_Handlers_name.erase( it ); - return( true ); - } - - return( false ); -} - -bool IEventTarget::AddHandlerJS( JSContext* UNUSED(cx), uintN argc, jsval* argv ) -{ - debug_assert( argc >= 2 ); - DOMEventHandler handler = new CScriptObject( argv[1] ); - if( !handler->Defined() ) - { - delete( handler ); - return( false ); - } - if( !AddHandler( ToPrimitive( argv[0] ), handler ) ) - { - delete( handler ); - return( false ); - } - return( true ); -} - -bool IEventTarget::RemoveHandlerJS( JSContext* UNUSED(cx), uintN argc, jsval* argv ) -{ - debug_assert( argc >= 2 ); - DOMEventHandler handler = new CScriptObject( argv[1] ); - if( !handler->Defined() ) - { - delete( handler ); - return( false ); - } - if( !RemoveHandler( ToPrimitive( argv[0] ), handler ) ) - { - delete( handler ); - return( false ); - } - delete( handler ); - return( true ); -} - -CScriptEvent::CScriptEvent( const CStrW& Type, size_t TypeCode, bool Cancelable, bool Blockable ) -{ - m_Type = Type; m_TypeCode = TypeCode; - m_Cancelable = Cancelable; m_Cancelled = false; - m_Blockable = Blockable; m_Blocked = false; - m_Timestamp = (size_t)( timer_Time() * 1000.0 ); -} - -void CScriptEvent::ScriptingInit() -{ - AddMethod( "toString", 0 ); - AddMethod( "preventDefault", 0 ); - AddMethod( "cancel", 0 ); - AddMethod( "stopPropagation", 0 ); - - AddProperty( L"type", &CScriptEvent::m_Type, true ); - AddProperty( L"cancelable", &CScriptEvent::m_Cancelable, true ); - AddProperty( L"blockable", &CScriptEvent::m_Blockable, true ); - AddProperty( L"timestamp", &CScriptEvent::m_Timestamp, true ); - - CJSObject::ScriptingInit( "Event" ); -} - -void CScriptEvent::PreventDefault( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) -{ - if( m_Cancelable ) - m_Cancelled = true; -} - -void CScriptEvent::StopPropagation( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) -{ - if( m_Blockable ) - m_Blocked = true; -} - -CStr CScriptEvent::ToString( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) -{ - return "[object Event: " + CStr(m_Type) + "]"; -} diff --git a/source/scripting/DOMEvent.h b/source/scripting/DOMEvent.h deleted file mode 100644 index e14623f5ae..0000000000 --- a/source/scripting/DOMEvent.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// DOM-style event object - -// Note: Cancellable [UK]? Cancelable [US]? DOM says one l, OED says 2. -// JS interface uses 1. - -// Entity and e.g. projectile classes derive from this and use it for -// sending/receiving events. - -#ifndef INCLUDED_DOMEVENT -#define INCLUDED_DOMEVENT - -#include "ScriptableObject.h" -#include "EventTypes.h" // for EVENT_LAST - -class CScriptObject; -class CScriptEvent; - -typedef CScriptObject* DOMEventHandler; - -class IEventTarget -{ - // Return 'true' if we should stop propagating. - bool _DispatchEvent( CScriptEvent* evt, IEventTarget* target ); - - // Events dispatched to this object are sent here before being processed. - IEventTarget* before; - // Events dispatched to this object are sent here after being processed. - IEventTarget* after; - - typedef std::vector HandlerList; - HandlerList m_Handlers_id[EVENT_LAST]; - typedef STL_HASH_MULTIMAP HandlerMap; - HandlerMap m_Handlers_name; - typedef std::pair HandlerRange; -public: - IEventTarget() - { - before = NULL; - after = NULL; - } - virtual ~IEventTarget(); - // Set target that will receive each event after it is processed. - // unused - inline void SetPriorObject( IEventTarget* obj ) - { - before = obj; - } - // Set target that will receive each event after it is processed. - // used by Entity and EntityTemplate. - inline void SetNextObject( IEventTarget* obj ) - { - after = obj; - } - - // Register a handler for the given event type. - // Returns false if the handler was already present - bool AddHandler( size_t TypeCode, DOMEventHandler handler ); - bool AddHandler( const CStrW& TypeString, DOMEventHandler handler ); - // Remove a previously registered handler for the specified event. - // Returns false if the handler was not present - bool RemoveHandler( size_t TypeCode, DOMEventHandler handler ); - bool RemoveHandler( const CStrW& TypeString, DOMEventHandler handler ); - - // called by ScriptGlue.cpp for add|RemoveGlobalHandler - bool AddHandlerJS( JSContext* cx, uintN argc, jsval* argv ); - bool RemoveHandlerJS( JSContext* cx, uintN argc, jsval* argv ); - - // Return the JSObject* we'd like to be the 'this' object - // when executing the handler. The argument is the object - // to which the event is targeted. - // It is passed to CScriptObject::DispatchEvent. - virtual JSObject* GetScriptExecContext( IEventTarget* target ) = 0; - - // Dispatch an event to its handler. - // returns: whether the event arrived (i.e. wasn't cancelled) [bool] - bool DispatchEvent( CScriptEvent* evt ); -}; - -class CScriptEvent : public CJSObject -{ -public: - enum EPhaseType - { - CAPTURING_PHASE = 1, - AT_TARGET = 2, - BUBBLING_PHASE = 3 - }; - - // Target (currently unused) - IEventTarget* m_Target; - - // Listening object currently being processed (currently unused) - IEventTarget* m_CurrentTarget; - - // Phase type (currently unused) - // EPhaseType m_EventPhase; - - // Can bubble? (currently unused) - // bool m_Bubbles; - - // Can be cancelled (default actions prevented) - bool m_Cancelable; - - // Can be blocked (prevented from propogating along the handler chain) - bool m_Blockable; - - // Timestamp (milliseconds since epoch (start of game?)) - size_t m_Timestamp; - - // Event type string - CStrW m_Type; - - // Type code (to speed lookups) - size_t m_TypeCode; - - // Has been cancelled? - bool m_Cancelled; - - // Has it been blocked (won't be sent to any more handlers) - bool m_Blocked; - -// -- - - CStr ToString( JSContext* cx, uintN argc, jsval* argv ); - void PreventDefault( JSContext* cx, uintN argc, jsval* argv ); - void StopPropagation( JSContext* cx, uintN argc, jsval* argv ); - -public: - CScriptEvent( const CStrW& Type, size_t TypeCode = ~size_t(0), bool Cancelable = true, bool Blockable = true ); - static void ScriptingInit(); -}; - -#endif - - diff --git a/source/scripting/EventTypes.h b/source/scripting/EventTypes.h deleted file mode 100644 index 5f1ff2c8af..0000000000 --- a/source/scripting/EventTypes.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// EventTypes.h -// Fairly game-specific event declarations for use with DOMEvent. -// Creates unique (for the current target) names for each event. -// DOMEvent currently uses a preallocated array of EVENT_LAST elements, -// so these must be consecutive integers starting with 0. - -#ifndef INCLUDED_EVENTTYPES -#define INCLUDED_EVENTTYPES - -enum EEventType -{ - // Entity events - EVENT_INITIALIZE = 0, - EVENT_DEATH, - EVENT_TICK, - EVENT_CONTACT_ACTION, - EVENT_TARGET_EXHAUSTED, - EVENT_START_CONSTRUCTION, - EVENT_START_PRODUCTION, - EVENT_CANCEL_PRODUCTION, - EVENT_FINISH_PRODUCTION, - EVENT_TARGET_CHANGED, - EVENT_PREPARE_ORDER, - EVENT_ORDER_TRANSITION, - EVENT_NOTIFICATION, - EVENT_FORMATION, - EVENT_IDLE, - EVENT_LAST, - - // Projectile events - EVENT_IMPACT = 0, - EVENT_MISS, - - // General events - EVENT_GAME_START = 0, - EVENT_GAME_TICK, - EVENT_SELECTION_CHANGED, - EVENT_WORLD_CLICK, -}; - -// Only used for entity events... (adds them as a property) -static const wchar_t* const EventNames[EVENT_LAST] = -{ - /* EVENT_INITIALIZE */ L"onInitialize", - /* EVENT_DEATH */ L"onDeath", - /* EVENT_TICK */ L"onTick", - /* EVENT_CONTACT_ACTION */ L"onContactAction", /* For generic contact actions on a target unit, like attack or gather */ - /* EVENT_TARGET_EXHAUSTED*/ L"onTargetExhausted", /* Called when the target of a generic action dies */ - /* EVENT_START_CONSTRUCTION */ L"onStartConstruction", /* We were selected when the user placed a building */ - /* EVENT_START_PRODUCTION */ L"onStartProduction", /* We're about to start training/researching something (deduct resources, etc) */ - /* EVENT_CANCEL_PRODUCTION */ L"onCancelProduction", /* Something in production has been cancelled */ - /* EVENT_FINISH_PRODUCTION */ L"onFinishProduction", /* We've finished something in production */ - /* EVENT_TARGET_CHANGED */ L"onTargetChanged", /* If this unit is selected and the mouseover object changes */ - /* EVENT_PREPARE_ORDER */ L"onPrepareOrder", /* To check if a unit can execute a given order */ - /* EVENT_ORDER_TRANSITION */ L"onOrderTransition", /* When we change orders (sometimes...) */ - /* EVENT_NOTIFICATION */ L"onNotification", /*When we receive a notification */ - /* EVENT_FORMATION */ L"onFormation", /* When this unit does something with a formation */ - /* EVENT_IDLE */ L"onIdle", /* When this unit becomes idle, do something */ -}; - -#endif // #ifndef INCLUDED_EVENTTYPES - - diff --git a/source/scripting/JSConversions.cpp b/source/scripting/JSConversions.cpp index e2280af315..b9bfb602bf 100644 --- a/source/scripting/JSConversions.cpp +++ b/source/scripting/JSConversions.cpp @@ -24,7 +24,6 @@ #include "lib/sysdep/sysdep.h" // isfinite #include #include -#include "scripting/ScriptableComplex.inl" // CVector3D @@ -48,19 +47,6 @@ template<> jsval ToJSVal( const CVector3D& Native ) return( OBJECT_TO_JSVAL( Script ) ); } -// CScriptObject - -template<> jsval ToJSVal( CScriptObject& Native ) -{ - return( OBJECT_TO_JSVAL( Native.GetFunctionObject() ) ); -} - -template<> bool ToPrimitive( JSContext* UNUSED(cx), jsval v, CScriptObject& Storage ) -{ - Storage.SetJSVal( v ); - return( true ); -} - // int template<> jsval ToJSVal( const int& Native ) diff --git a/source/scripting/JSSerialization.h b/source/scripting/JSSerialization.h deleted file mode 100644 index b696a9e7aa..0000000000 --- a/source/scripting/JSSerialization.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// Functions for (de)serialization of jsvals - -// WIP, not yet functional - -#include "network/Serialization.h" -#include "JSConversions.h" -#include "ps/CStr.h" - -class jsval_ser : public ISerializable -{ - enum - { - TAG_BOOLEAN_FALSE, - TAG_BOOLEAN_TRUE, - TAG_INT, - TAG_DOUBLE, - TAG_STRING, - TAG_NOT_SERIALIZABLE = -1 - } m_tag; - jsval m_data; -public: - jsval_ser() : m_tag( TAG_NOT_SERIALIZABLE ) - { - } - jsval_ser( jsval data ) : m_data( data ) - { - if( m_data == JSVAL_FALSE ) - m_tag = TAG_BOOLEAN_FALSE; - if( m_data == JSVAL_TRUE ) - m_tag = TAG_BOOLEAN_TRUE; - if( JSVAL_IS_INT( m_data ) ) - m_tag = TAG_INT; - if( JSVAL_IS_DOUBLE( m_data ) ) - m_tag = TAG_DOUBLE; - if( JSVAL_IS_STRING( m_data ) ) - m_tag = TAG_STRING; - m_tag = TAG_NOT_SERIALIZABLE; - } - operator jsval() const - { - return( m_data ); - } - operator CStr() const - { - return( ToPrimitive( m_data ) ); - } - size_t GetSerializedLength() const - { - switch( m_tag ) - { - case TAG_BOOLEAN_FALSE: - case TAG_BOOLEAN_TRUE: - return( 1 ); - case TAG_INT: - return( 5 ); - case TAG_DOUBLE: - return( 9 ); - case TAG_STRING: - return( 1 + (ToPrimitive(m_data)).GetSerializedLength() ); - default: - debug_warn(L"An attempt was made to serialize a jsval other than a number, boolean or string." ); - return( 1 ); - } - } - u8* Serialize( u8* buffer ) const - { - Serialize_int_1( buffer, m_tag ); - switch( m_tag ) - { - case TAG_BOOLEAN_FALSE: - case TAG_BOOLEAN_TRUE: - break; - case TAG_INT: - { - u32 ival = JSVAL_TO_INT( m_data ); - Serialize_int_4( buffer, ival ); - } - break; - case TAG_DOUBLE: - { - union { - u64 ival; - double dval; - } val; - cassert(sizeof(u64) == sizeof(double)); - val.dval = *JSVAL_TO_DOUBLE( m_data ); - Serialize_int_8( buffer, val.ival ); - } - break; - case TAG_STRING: - buffer = ( ToPrimitive( m_data ) ).Serialize( buffer ); - break; - default: - debug_warn(L"An attempt was made to serialize a jsval other than a number, boolean or string." ); - break; - } - return( buffer ); - } - const u8* Deserialize( const u8* buffer, const u8* end ) - { - Deserialize_int_1( buffer, (u8&)m_tag ); - switch( m_tag ) - { - case TAG_BOOLEAN_FALSE: - m_data = JSVAL_FALSE; - break; - case TAG_BOOLEAN_TRUE: - m_data = JSVAL_TRUE; - break; - case TAG_INT: - { - u32 ival; - Deserialize_int_4( buffer, ival ); - m_data = INT_TO_JSVAL( ival ); - } - break; - case TAG_DOUBLE: - { - union { - u64 ival; - double dval; - } val; - cassert(sizeof(u64) == sizeof(double)); - Deserialize_int_8( buffer, val.ival ); - JS_NewDoubleValue( g_ScriptingHost.GetContext(), val.dval, &m_data ); - } - break; - case TAG_STRING: - { - CStrW ival; - buffer = ival.Deserialize( buffer, end ); - m_data = ToJSVal( ival ); - } - break; - default: - debug_warn(L"An attempt was made to deserialize a jsval other than a number, boolean or string." ); - break; - } - return( buffer ); - } -}; diff --git a/source/scripting/ScriptCustomTypes.cpp b/source/scripting/ScriptCustomTypes.cpp deleted file mode 100644 index 652218e352..0000000000 --- a/source/scripting/ScriptCustomTypes.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "ScriptingHost.h" -#include "ScriptCustomTypes.h" - -// POINT2D - -JSClass Point2dClass = -{ - "Point2d", 0, - JS_PropertyStub, JS_PropertyStub, - JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub, - JS_ConvertStub, JS_FinalizeStub -}; - -JSPropertySpec Point2dProperties[] = -{ - {"x", 0, JSPROP_ENUMERATE}, - {"y", 1, JSPROP_ENUMERATE}, - {0} -}; - -JSBool Point2d_Constructor(JSContext* UNUSED(cx), JSObject* obj, uintN argc, jsval* argv, jsval* UNUSED(rval)) -{ - if (argc == 2) - { - g_ScriptingHost.SetObjectProperty(obj, "x", argv[0]); - g_ScriptingHost.SetObjectProperty(obj, "y", argv[1]); - } - else - { - jsval zero = INT_TO_JSVAL(0); - g_ScriptingHost.SetObjectProperty(obj, "x", zero); - g_ScriptingHost.SetObjectProperty(obj, "y", zero); - } - - return JS_TRUE; -} - -// Colour - -void SColour::SColourInit( float _r, float _g, float _b, float _a ) -{ - r = _r; g = _g; b = _b; a = _a; -} - -void SColour::ScriptingInit() -{ - AddMethod( "toString", 0 ); - AddProperty( L"r", (float IJSObject::*)&SColour::r ); - AddProperty( L"g", (float IJSObject::*)&SColour::g ); - AddProperty( L"b", (float IJSObject::*)&SColour::b ); - AddProperty( L"a", (float IJSObject::*)&SColour::a ); - - CJSObject::ScriptingInit( "Colour", SColour::Construct, 3 ); -} - -CStr SColour::ToString( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) -{ - return "[object Colour: ( " + CStr(r) + ", " + CStr(g) + ", " + CStr(b) + ", " + CStr(a) + " )]"; -} - - -JSBool SColour::Construct( JSContext* UNUSED(cx), JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval ) -{ - debug_assert( argc >= 3 ); - float alpha = 1.0; - if( argc >= 4 ) alpha = ToPrimitive( argv[3] ); - - SColour* col = new SColour( ToPrimitive( argv[0] ), - ToPrimitive( argv[1] ), - ToPrimitive( argv[2] ), - alpha ); - - col->m_EngineOwned = false; - - *rval = OBJECT_TO_JSVAL( col->GetScript() ); - - return( JS_TRUE ); -} - -// (Simon) Added this to prevent a deep copy, which evidently makes direct -// copies of the heap allocated objects within CJSObject, which eventually -// goes boom -SColour &SColour::operator = (const SColour &o) -{ - r=o.r; - g=o.g; - b=o.b; - a=o.a; - - return *this; -} diff --git a/source/scripting/ScriptCustomTypes.h b/source/scripting/ScriptCustomTypes.h deleted file mode 100644 index c515c43f46..0000000000 --- a/source/scripting/ScriptCustomTypes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "scripting/ScriptableObject.h" - -#ifndef INCLUDED_SCRIPTCUSTOMTYPES -#define INCLUDED_SCRIPTCUSTOMTYPES - -// Custom object types - -// Whilst Point2d is fully coded, it is never registered so is not available in script -// This is mostly as a demonstration of what you need to code to add a new type - -// VECTOR2D -extern JSClass Point2dClass; -extern JSPropertySpec Point2dProperties[]; -JSBool Point2d_Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); - -// Colour -struct SColour : public CJSObject -{ -public: - float r, g, b, a; /* 0...1 */ - SColour() { SColourInit( 0.0f, 0.0f, 0.0f, 0.0f ); } - SColour( float r_, float g_, float b_ ) { SColourInit( r_, g_, b_, 1.0f ); } - SColour( float r_, float g_, float b_, float a_ ) { SColourInit( r_, g_, b_, a_ ); } - SColour( const SColour& other ) : CJSObject() { SColourInit( other.r, other.g, other.b, other.a ); } - void SColourInit( float r, float g, float b, float a ); - - SColour &operator = (const SColour &o); - - CStr ToString( JSContext* cx, uintN argc, jsval* argv ); - static void ScriptingInit(); - static JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); -}; - -#endif diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index 43f92795a5..a1d127ad48 100644 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -26,8 +26,6 @@ #include "ScriptGlue.h" #include "JSConversions.h" -#include "ScriptableComplex.inl" - #include "graphics/GameView.h" #include "graphics/LightEnv.h" #include "graphics/MapWriter.h" diff --git a/source/scripting/ScriptObject.cpp b/source/scripting/ScriptObject.cpp deleted file mode 100644 index 1c02854c36..0000000000 --- a/source/scripting/ScriptObject.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "ScriptObject.h" -#include "ScriptingHost.h" -#include "JSConversions.h" -#include "DOMEvent.h" - -CScriptObject::CScriptObject() -{ - Function = NULL; -} - -CScriptObject::~CScriptObject() -{ - Uproot(); -} - -void CScriptObject::Root() -{ - if( !Function ) - return; - - FunctionObject = JS_GetFunctionObject( Function ); - - JS_AddRoot( g_ScriptingHost.GetContext(), &FunctionObject ); -} - -void CScriptObject::Uproot() -{ - if( Function ) - JS_RemoveRoot( g_ScriptingHost.GetContext(), &FunctionObject ); -} - -CScriptObject::CScriptObject( JSFunction* _Function ) -{ - Function = NULL; - SetFunction( _Function ); -} - -CScriptObject::CScriptObject( jsval v ) -{ - Function = NULL; - SetJSVal( v ); -} - -CScriptObject::CScriptObject( const CScriptObject& copy ) -{ - Function = NULL; - SetFunction( copy.Function ); -} - -void CScriptObject::SetFunction( JSFunction* _Function ) -{ - Uproot(); - - Function = _Function; - - Root(); -} - -void CScriptObject::SetJSVal( jsval v ) -{ - CStrW Source; - switch( JS_TypeOfValue( g_ScriptingHost.GetContext(), v ) ) - { - case JSTYPE_STRING: - Source = g_ScriptingHost.ValueToUCString( v ); - Compile( L"unknown", Source ); - break; - case JSTYPE_FUNCTION: - SetFunction( JS_ValueToFunction( g_ScriptingHost.GetContext(), v ) ); - break; - default: - Function = NULL; - } -} - -JSObject* CScriptObject::GetFunctionObject() -{ - if( Function ) - return( FunctionObject ); - return( NULL ); -} - -// Executes a script attached to a JS object. -// Returns false if the script isn't defined, if the script can't be executed, -// otherwise true. Script return value is in rval. -bool CScriptObject::Run( JSObject* Context, jsval* rval, uintN argc, jsval* argv ) -{ - if( !Function ) - return( false ); - return( JS_TRUE == JS_CallFunction( g_ScriptingHost.GetContext(), Context, Function, argc, argv, rval ) ); -} - -// This variant casts script return value to a boolean, and passes it back. -bool CScriptObject::Run( JSObject* Context, uintN argc, jsval* argv ) -{ - jsval Temp; - if( !Run( Context, &Temp, argc, argv ) ) - return( false ); - return( ToPrimitive( Temp ) ); -} - -// Treat this as an event handler and dispatch an event to it. Return !evt->m_cancelled, as a convenience. -bool CScriptObject::DispatchEvent( JSObject* Context, CScriptEvent* evt ) -{ - if( Function ) - { - jsval Temp; - jsval EventObject = OBJECT_TO_JSVAL( evt->GetScript() ); - JS_CallFunction( g_ScriptingHost.GetContext(), Context, Function, 1, &EventObject, &Temp ); - } - return( evt->m_Blocked ); -} - -void CScriptObject::Compile( const CStrW& FileNameTag, const CStrW& FunctionBody ) -{ - if( Function ) - JS_RemoveRoot( g_ScriptingHost.GetContext(), &Function ); - - const char* argnames[] = { "evt" }; - utf16string str16=FunctionBody.utf16(); - Function = JS_CompileUCFunction( g_ScriptingHost.GetContext(), NULL, NULL, 1, argnames, str16.c_str(), str16.size(), CStr(FileNameTag), 0 ); - - Root(); -} diff --git a/source/scripting/ScriptObject.h b/source/scripting/ScriptObject.h deleted file mode 100644 index 272efc5259..0000000000 --- a/source/scripting/ScriptObject.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -// A generic type and some helper functions -// for scripts - -#ifndef INCLUDED_SCRIPTOBJECT -#define INCLUDED_SCRIPTOBJECT - -#include "scripting/SpiderMonkey.h" - -class CStrW; -class CScriptEvent; - -class CScriptObject -{ - JSFunction* Function; - JSObject* FunctionObject; - void Root(); - void Uproot(); - -public: - - CScriptObject(); - CScriptObject( JSFunction* _Function ); - CScriptObject( jsval v ); - CScriptObject( const CScriptObject& copy ); - - ~CScriptObject(); - - // Initialize in various ways: from a JS function, a string to be compiled, or a jsval containing either. - void SetFunction( JSFunction* _Function ); - void SetJSVal( jsval v ); - void Compile( const CStrW& FileNameTag, const CStrW& FunctionBody ); - - inline bool Defined() - { - return( Function != NULL ); - } - - inline operator bool() { return( Function != NULL ); } - inline bool operator!() { return( !Function ); } - inline bool operator==( const CScriptObject& compare ) { return( Function == compare.Function ); } - - // JSObject wrapping the function if it's defined, NULL if it isn't. - JSObject* GetFunctionObject(); - - // Executes a script attached to a JS object. - // Returns false if the script isn't defined, if the script can't be executed, - // otherwise true. Script return value is in rval. - bool Run( JSObject* Context, jsval* rval, uintN argc = 0, jsval* argv = NULL ); - // This variant casts script return value to a boolean, and passes it back. - bool Run( JSObject* Context, uintN argc = 0, jsval* argv = NULL ); - - // Treat this as an event handler and dispatch an event to it. - bool DispatchEvent( JSObject* Context, CScriptEvent* evt ); -}; - -#endif diff --git a/source/scripting/ScriptableComplex.cpp b/source/scripting/ScriptableComplex.cpp deleted file mode 100644 index 3614946331..0000000000 --- a/source/scripting/ScriptableComplex.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" -#include "ScriptableComplex.h" -#include "ScriptableComplex.inl" - -#include "lib/allocators/bucket.h" - -//----------------------------------------------------------------------------- -// suballocator for CJSComplex.m_Properties elements -// (must come after property defs, which are currently in the header) -//----------------------------------------------------------------------------- - -static Bucket bucket; -// HACK: it needs to be created/destroyed; since there is no -// global init/shutdown call here, we keep a refcnt. this assumes that -// going to 0 <==> shutdown! if that proves wrong, bucket_alloc will warn. -static size_t suballoc_refs; // initialized in suballoc_attach - -void jscomplexproperty_suballoc_attach() -{ - ONCE(\ - size_t el_size = std::max(sizeof(CJSValComplexProperty), sizeof(CJSComplexProperty));\ - (void)bucket_create(&bucket, el_size);\ - suballoc_refs = 0;\ - ); - suballoc_refs++; -} - -void jscomplexproperty_suballoc_detach() -{ - suballoc_refs--; - if(suballoc_refs == 0) - bucket_destroy(&bucket); -} - -void* jscomplexproperty_suballoc() -{ - return bucket_alloc(&bucket, 0); -} - -void jscomplexproperty_suballoc_free(IJSComplexProperty* p) -{ - // explicit dtor since caller uses placement new - p->~IJSComplexProperty(); - bucket_free(&bucket, p); -} diff --git a/source/scripting/ScriptableComplex.h b/source/scripting/ScriptableComplex.h deleted file mode 100644 index 4d1b5b5452..0000000000 --- a/source/scripting/ScriptableComplex.h +++ /dev/null @@ -1,312 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -/* -ScriptableComplex.h - -The version of CJSObject<> that retains the ability to use inheritance -in its objects. Shouldn't be used any more for anything but entity code. - -This file contains only declarations of class CJSComplex and its methods. -Their implementations are in ScriptableComplex.inl. Because CJSComplex is -a templated class, any source file that uses these methods directly must -#include ScritpableComplex.inl to link to them. However, files that -only need to know that something is a CJSComplex need not do this. This -was done to speed up compile times after modifying CJSComplex's internals: -before, 30+ files had to be recompiled because they #included Entity.h -which #includes ScriptableComplex.h. -*/ - -#ifndef INCLUDED_SCRIPTABLECOMPLEX -#define INCLUDED_SCRIPTABLECOMPLEX - -#include "scripting/ScriptingHost.h" -#include "scripting/ScriptObject.h" -#include "JSConversions.h" - -#include "lib/sysdep/stl.h" - -#include - -class IJSComplex; - -class IJSComplexProperty -{ -public: - - bool m_AllowsInheritance; - bool m_Inherited; - bool m_Intrinsic; - - // This is to make sure that all the fields are initialized at construction - inline IJSComplexProperty(): - m_AllowsInheritance(true), - m_Inherited(true), - m_Intrinsic(true) - {} - - virtual jsval Get( JSContext* cx, IJSComplex* owner ) = 0; - virtual void Set( JSContext* cx, IJSComplex* owner, jsval Value ) = 0; - - // Copies the data directly out of a parent property - // Warning: Don't use if you're not certain the properties are not of the same type. - virtual void ImmediateCopy( IJSComplex* CopyTo, IJSComplex* CopyFrom, IJSComplexProperty* CopyProperty ) = 0; - - jsval Get( IJSComplex* owner ) { return( Get( g_ScriptingHost.GetContext(), owner ) ); } - void Set( IJSComplex* owner, jsval Value ) { return( Set( g_ScriptingHost.GetContext(), owner, Value ) ); } - - virtual ~IJSComplexProperty() {} -}; - -class IJSComplex -{ - // Make copy constructor and assignment operator private - since copying of - // these objects is unsafe unless done specially. - // These will never be implemented (they are, after all, here to *prevent* - // copying) - IJSComplex(const IJSComplex &other); - IJSComplex& operator=(const IJSComplex &other); - -public: - typedef STL_HASH_MAP PropertyTable; - typedef std::vector InheritorsList; - typedef std::set StringTable; - typedef std::pair IteratorState; - - // Used for freshen/update - typedef void (IJSComplex::*NotifyFn)(); - - // Property getters and setters - typedef jsval (IJSComplex::*GetFn)(); - typedef void (IJSComplex::*SetFn)( jsval ); - - // Properties of this object - PropertyTable m_Properties; - - // Parent object - IJSComplex* m_Parent; - - // Objects that inherit from this - InheritorsList m_Inheritors; - - // Destructor - virtual ~IJSComplex() { } - - // Set the base, and rebuild - void SetBase( IJSComplex* m_Parent ); - - // Rebuild any intrinsic (mapped-to-C++-variable) properties - virtual void Rebuild() = 0; - - // HACK: Doesn't belong here. - virtual void RebuildClassSet() = 0; - - // Check for a property - virtual IJSComplexProperty* HasProperty( const CStrW& PropertyName ) = 0; - - // Get all properties of an object - virtual void FillEnumerateSet( IteratorState* it, CStrW* PropertyRoot = NULL ) = 0; - - // Retrieve the value of a property (returning false if that property is not defined) - virtual bool GetProperty( JSContext* cx, const CStrW& PropertyName, jsval* vp ) = 0; - - // Add a property (with immediate value) - virtual void AddProperty( const CStrW& PropertyName, jsval Value ) = 0; - virtual void AddProperty( const CStrW& PropertyName, const CStrW& Value ) = 0; - - inline IJSComplex() {} -}; - - -class CJSReflector; - -template -void AddMethodImpl( const char* Name, uintN MinArgs ); - -template -void AddClassPropertyImpl( const CStrW& PropertyName, PropType T::*Native, bool PropAllowInheritance = true, IJSComplex::NotifyFn Update = NULL, IJSComplex::NotifyFn Refresh = NULL ); - -template -void AddReadOnlyClassPropertyImpl( const CStrW& PropertyName, PropType T::*Native, bool PropAllowInheritance = true, IJSComplex::NotifyFn Update = NULL, IJSComplex::NotifyFn Refresh = NULL ); - -template -void MemberAddPropertyImpl( IJSComplex* obj, const CStrW& PropertyName, PropType* Native, bool PropAllowInheritance = true, IJSComplex::NotifyFn Update = NULL, IJSComplex::NotifyFn Refresh = NULL ); - -template -void MemberAddReadOnlyPropertyImpl( IJSComplex* obj, const CStrW& PropertyName, PropType* Native, bool PropAllowInheritance = true, IJSComplex::NotifyFn Update = NULL, IJSComplex::NotifyFn Refresh = NULL ); - -template class CJSComplex : public IJSComplex -{ -public: - typedef STL_HASH_MAP ReflectorTable; - template friend class CJSComplexPropertyAccessor; - JSObject* m_JS; - - - std::vector m_Watches; - - ReflectorTable m_Reflectors; - - static JSPropertySpec JSI_props[]; - static std::vector m_Methods; - static PropertyTable m_IntrinsicProperties; - - -public: - static JSClass JSI_class; - - // Whether native code is responsible for managing this object. - // Script constructors should clear this *BEFORE* creating a JS - // mirror (otherwise it'll be rooted). - - bool m_EngineOwned; - - // JS Property access - bool GetProperty( JSContext* cx, const CStrW& PropertyName, jsval* vp ); - void SetProperty( JSContext* cx, const CStrW& PropertyName, jsval* vp ); - void WatchNotify( JSContext* cx, const CStrW& PropertyName, jsval* newval ); - - // - // Functions that must be provided to JavaScript - // - static JSBool JSGetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ); - static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ); - static JSBool JSEnumerate( JSContext* cx, JSObject* obj, JSIterateOp enum_op, jsval* statep, jsid *idp ); - static JSBool SetWatchAll( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); - static JSBool UnWatchAll( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); - static void ScriptingInit( const char* ClassName, JSNative Constructor = NULL, uintN ConstructorMinArgs = 0 ); - static void ScriptingShutdown(); - static void DefaultFinalize( JSContext *cx, JSObject *obj ); - -public: - - // Creating and releasing script objects is done automatically most of the time, but you - // can do it explicitly. - void CreateScriptObject(); - void ReleaseScriptObject(); - - JSObject* GetScript() - { - if( !m_JS ) - CreateScriptObject(); - return( m_JS ); - } - - CJSComplex(); - virtual ~CJSComplex(); - void Shutdown(); - void SetBase( IJSComplex* Parent ); - void Rebuild(); - - - IJSComplexProperty* HasProperty( const CStrW& PropertyName ); - - void FillEnumerateSet( IteratorState* it, CStrW* PropertyRoot = NULL ); - - - void AddProperty( const CStrW& PropertyName, jsval Value ); - void AddProperty( const CStrW& PropertyName, const CStrW& Value ); - - static void AddClassProperty( const CStrW& PropertyName, GetFn Getter, SetFn Setter = NULL ); - - // these functions are themselves templatized. we don't want to implement - // them in the header because that would drag in many dependencies. - // - // therefore, the publicly visible functions actually only call out to - // external friend functions implemented in the .inl file. - // these receive the template parameters from the class as well as the - // ones added for the member function. - // - // for non-static members, the friends additionally take a "this" pointer. - template - static void AddMethod( const char* Name, uintN MinArgs ) - { - AddMethodImpl(Name, MinArgs); - } - - template - static void AddClassProperty( const CStrW& PropertyName, PropType T::*Native, bool PropAllowInheritance = true, NotifyFn Update = NULL, NotifyFn Refresh = NULL ) - { - AddClassPropertyImpl(PropertyName, Native, PropAllowInheritance, Update, Refresh); - } - - template - static void AddReadOnlyClassProperty( const CStrW& PropertyName, PropType T::*Native, bool PropAllowInheritance = true, NotifyFn Update = NULL, NotifyFn Refresh = NULL ) - { - AddReadOnlyClassPropertyImpl(PropertyName, Native, PropAllowInheritance, Update, Refresh); - } - - // PropertyName must not already exist! (verified in debug build) - template - void AddProperty( const CStrW& PropertyName, PropType* Native, bool PropAllowInheritance = true, NotifyFn Update = NULL, NotifyFn Refresh = NULL ) - { - MemberAddPropertyImpl(this, PropertyName, Native, PropAllowInheritance, Update, Refresh); - } - - // PropertyName must not already exist! (verified in debug build) - template - void AddReadOnlyProperty( const CStrW& PropertyName, PropType* Native, bool PropAllowInheritance = true, NotifyFn Update = NULL, NotifyFn Refresh = NULL ) - { - MemberAddReadOnlyPropertyImpl(this, PropertyName, Native, PropAllowInheritance, Update, Refresh); - } - - // helper routine for Add*Property. Their interface requires the - // property not already exist; we check for this (in debug builds) - // and if so, warn and free the previously new-ed memory in - // m_Properties[PropertyName] (avoids mem leak). - void DeletePreviouslyAssignedProperty( const CStrW& PropertyName ); -}; - - -// -// static members -// - -template JSClass CJSComplex::JSI_class = { - NULL, JSCLASS_HAS_PRIVATE | JSCLASS_NEW_ENUMERATE, - JS_PropertyStub, JS_PropertyStub, - JSGetProperty, JSSetProperty, - (JSEnumerateOp)JSEnumerate, JS_ResolveStub, - JS_ConvertStub, DefaultFinalize, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL -}; - -template JSPropertySpec CJSComplex::JSI_props[] = { - { NULL, 0, 0, NULL, NULL }, -}; - -template std::vector CJSComplex::m_Methods; -template typename CJSComplex::PropertyTable CJSComplex::m_IntrinsicProperties; - - - -template -void ScriptableComplex_InitComplexPropertyAccessor(); - - - -// -// suballocator for CJSComplex.m_Properties elements -// (referenced from implementation in .inl) -// -extern void jscomplexproperty_suballoc_attach(); -extern void jscomplexproperty_suballoc_detach(); -extern void* jscomplexproperty_suballoc(); -extern void jscomplexproperty_suballoc_free(IJSComplexProperty* p); - -#endif diff --git a/source/scripting/ScriptableComplex.inl b/source/scripting/ScriptableComplex.inl deleted file mode 100644 index 264731046e..0000000000 --- a/source/scripting/ScriptableComplex.inl +++ /dev/null @@ -1,1105 +0,0 @@ -/* -Implementation of CJSComplex's functions and related helper functions and classes. -This file must be #included in any CPP file that accesses these functions directly, -but may be omitted in those that don't. - -rationale: -we are changing CJSComplex often for purposes of optimization. this triggers -close to a full rebuild, which is unacceptable. -ideally, we would move the method implementations into a cpp file, and -then only that need be recompiled. -unfortunately that is exactly what the export keyword enables, -which is not likely to be implemented in VC. - -several workarounds have been investigated. -1) reduce symptoms of the problem by reducing #includes of entity.h, which is - what pulls CJSComplex in. done; it's been removed entirely from headers and - is currently only left in ~30 cpp files (could probably be - further reduced) - -2) de-templatize CJSComplex. result would be enabling the normal split of - interface vs. implementation in cpp file. - - this would be mostly feasible because it's really only used by - CEntity and CEntityTemplate. however, since there are 2 users, the - static class data (notably m_Methods) would have to be duplicated for each. - one possibility would be an 'array' of each, indexed via class id. - - also, static data could be reduced by having property lookup be done - via per-property hash tables, instead of the root object holding one - large table of the entire property names (e.g. traits.health.max). - in retrospect, this would probably have been better, but is probably - too much work to change now. - -3) instead of CEntity IS-A CJSComplex, use composition and pImpl. this would - decouple entity.h from changes in scriptablecomplex.h. - however, we'd have to dynamically allocate the CJSComplex in each entity - (required by pImpl and less efficient/more annoying). also, there would - potentially be trouble with ToJSVal, since we no longer derive from - CJSComplex. - this is not deemed worth the effort due to steps taken in #1. - -We decided to split off the implementation of CJSComplex as well as many of its -helper classes into a separate header, ScriptableComplex.inl. This way, -ScriptableComplex.h does not need to be modified unless we change the API, -but the implementations of CJSComplex's methods can be changed. However, this -also means that this header (ScriptableComplex.inl) must be #included in any -CPP file that directly accesses ScriptableComplex's methods - otherwise, the -linker won't find the definitions of these functions. Right now this is only -5 files, which results in much faster rebuilds after modifying this code. -*/ - -#ifndef SCRIPTABLE_COMPLEX_INL_INCLUDED -#define SCRIPTABLE_COMPLEX_INL_INCLUDED - -#include "ScriptableComplex.h" - -//----------------------------------------------------------------------------- -// CJSComplexPropertyAccessor -//----------------------------------------------------------------------------- - - -template class CJSComplex; - -template class CJSComplexPropertyAccessor -{ - T* m_Owner; - CStrW m_PropertyRoot; - template friend class CJSComplex; - -public: - CJSComplexPropertyAccessor( T* Owner, const CStrW& PropertyRoot ) - { - m_Owner = Owner; - m_PropertyRoot = PropertyRoot; - } - - static JSObject* CreateAccessor( JSContext* cx, T* Owner, const CStrW& PropertyRoot ) - { - JSObject* Accessor = JS_NewObject( cx, &JSI_Class, NULL, NULL ); - JS_SetPrivate( cx, Accessor, new CJSComplexPropertyAccessor( Owner, PropertyRoot ) ); - - return( Accessor ); - } - - // JW: ugly, but more efficient than previous approach - // (string = root + "." + id;). saves 50ms during init. - // made macro to ensure there is no extra overhead. -#define BUILD_PROPNAME(root, id)\ - PropName.reserve(50);\ - PropName += root;\ - PropName += '.';\ - PropName += id; - - static JSBool JSGetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) - { - CJSComplexPropertyAccessor* Instance = (CJSComplexPropertyAccessor*)JS_GetPrivate( cx, obj ); - if( !Instance ) return( JS_TRUE ); - - CStrW PropName; - BUILD_PROPNAME(Instance->m_PropertyRoot, g_ScriptingHost.ValueToUCString(id)); - - Instance->m_Owner->GetProperty( cx, PropName, vp ); - - return( JS_TRUE ); - } - - static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) - { - CJSComplexPropertyAccessor* Instance = (CJSComplexPropertyAccessor*)JS_GetPrivate( cx, obj ); - if( !Instance ) return( JS_TRUE ); - - CStrW PropName; - BUILD_PROPNAME(Instance->m_PropertyRoot, g_ScriptingHost.ValueToUCString(id)); - - Instance->m_Owner->SetProperty( cx, PropName, vp ); - - return( JS_TRUE ); - } - - static JSBool JSEnumerate( JSContext* cx, JSObject* obj, JSIterateOp enum_op, jsval* statep, jsid *idp ) - { - IJSComplex::IteratorState* it; - - switch( enum_op ) - { - case JSENUMERATE_INIT: - { - CJSComplexPropertyAccessor* Instance = (CJSComplexPropertyAccessor*)JS_GetPrivate( cx, obj ); - - it = new IJSComplex::IteratorState; - - if( Instance ) - { - size_t rlen = Instance->m_PropertyRoot.length(); - - IJSComplex::PropertyTable::iterator iit; - for( iit = T::m_IntrinsicProperties.begin(); iit != T::m_IntrinsicProperties.end(); iit++ ) - if( ( iit->first.length() > rlen ) && ( iit->first.Left( rlen ) == Instance->m_PropertyRoot ) && ( iit->first[rlen] == '.' ) ) - it->first.insert( CStrW( iit->first.substr( rlen + 1 ) ).BeforeFirst( L"." ) ); - - - Instance->m_Owner->FillEnumerateSet( it, &( Instance->m_PropertyRoot ) ); - } - it->second = it->first.begin(); - - *statep = PRIVATE_TO_JSVAL( it ); - - if( idp ) - *idp = INT_TO_JSVAL( it->first.size() ); - - return( JS_TRUE ); - } - case JSENUMERATE_NEXT: - it = (IJSComplex::IteratorState*)JSVAL_TO_PRIVATE( *statep ); - if( it->second == it->first.end() ) - { - delete( it ); - *statep = JSVAL_NULL; - return( JS_TRUE ); - } - - // I think this is what I'm supposed to do... (cheers, Philip) - if( !JS_ValueToId( cx, ToJSVal( *( it->second ) ), idp ) ) - return( JS_FALSE ); - - // EVIL HACK: since https://bugzilla.mozilla.org/show_bug.cgi?id=261887 (which is in - // the SpiderMonkey 1.6 release, and not in 1.5), you can't enumerate properties that - // don't actually exist on the object. This should probably be fixed by defining a custom - // Resolve function to make them look like they exist, but for now we just define the - // property on the object here so that it will exist by the time the JS iteration code - // does its checks. - JS_DefineProperty(cx, obj, CStr(*it->second).c_str(), JSVAL_VOID, NULL, NULL, 0); - - (it->second)++; - - *statep = PRIVATE_TO_JSVAL( it ); - return( JS_TRUE ); - case JSENUMERATE_DESTROY: - it = (IJSComplex::IteratorState*)JSVAL_TO_PRIVATE( *statep ); - delete( it ); - *statep = JSVAL_NULL; - return( JS_TRUE ); - } - return( JS_FALSE ); - } - - static JSBool JSPrimitive( JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval ) - { - CJSComplexPropertyAccessor* Instance = (CJSComplexPropertyAccessor*)JS_GetPrivate( cx, obj ); - if( !Instance ) return( JS_TRUE ); - - // Check all along the inheritance tree - // Possible optimization: Store the hashed value over the lookups - IJSComplex* Target = Instance->m_Owner; - IJSComplexProperty* Property; - - while( Target ) - { - Property = Target->HasProperty( Instance->m_PropertyRoot ); - if( Property ) - { - *rval = Property->Get( cx, Target ); - break; - } - Target = Target->m_Parent; - } - - return( JS_TRUE ); - } - - static JSBool JSToString( JSContext* cx, JSObject* obj, uintN UNUSED(argc), jsval* UNUSED(argv), jsval* rval ) - { - CJSComplexPropertyAccessor* Instance = (CJSComplexPropertyAccessor*)JS_GetPrivate( cx, obj ); - if( !Instance ) return( JS_TRUE ); - - // Check all along the inheritance tree - // TODO: Optimization: Store the hashed value over the lookups - IJSComplex* Target = Instance->m_Owner; - IJSComplexProperty* Property; - JSString* str = NULL; - - while( Target ) - { - Property = Target->HasProperty( Instance->m_PropertyRoot ); - if( Property ) - { - str = JS_ValueToString( cx, Property->Get( cx, Target ) ); - break; - } - Target = Target->m_Parent; - } - - *rval = STRING_TO_JSVAL( str ); - - return( JS_TRUE ); - } - - static JSClass JSI_Class; - - static void ScriptingInit() - { - JSFunctionSpec JSI_methods[] = { { "valueOf", JSPrimitive, 0, 0, 0 }, { "toString", JSToString, 0, 0, 0 }, { 0 } }; - JSPropertySpec JSI_props[] = { { 0 } }; - - g_ScriptingHost.DefineCustomObjectType( &JSI_Class, NULL, 0, JSI_props, JSI_methods, NULL, NULL ); - } -}; - -template JSClass CJSComplexPropertyAccessor::JSI_Class = { - "Property", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_ENUMERATE, - JS_PropertyStub, JS_PropertyStub, - JSGetProperty, JSSetProperty, - (JSEnumerateOp)JSEnumerate, JS_ResolveStub, - JS_ConvertStub, JS_FinalizeStub, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL -}; - - -template -void ScriptableComplex_InitComplexPropertyAccessor() -{ - CJSComplexPropertyAccessor::ScriptingInit(); -} - - -//----------------------------------------------------------------------------- -// various property types -//----------------------------------------------------------------------------- - -template class CJSSharedProperty : public IJSComplexProperty -{ - T IJSComplex::*m_Data; - - // Function on Owner to call after value is changed - IJSComplex::NotifyFn m_Update; - - // Function on Owner to call before reading or writing the value - IJSComplex::NotifyFn m_Freshen; - -public: - CJSSharedProperty( T IJSComplex::*Data, bool AllowsInheritance = false, IJSComplex::NotifyFn Update = NULL, IJSComplex::NotifyFn Freshen = NULL ) - { - m_Data = Data; - m_AllowsInheritance = AllowsInheritance; - m_Update = Update; - m_Freshen = Freshen; - m_Intrinsic = true; - m_Inherited = true; - } - jsval Get( JSContext* UNUSED(cx), IJSComplex* owner ) - { - if( m_Freshen ) (owner->*m_Freshen)(); - return( ToJSVal( owner->*m_Data ) ); - } - void ImmediateCopy( IJSComplex* CopyTo, IJSComplex* CopyFrom, IJSComplexProperty* CopyProperty ) - { - CJSSharedProperty* otherProp = (CJSSharedProperty*) CopyProperty; - T IJSComplex::*otherData = otherProp->m_Data; - CopyTo->*m_Data = CopyFrom->*otherData; - } - void Set( JSContext* cx, IJSComplex* owner, jsval Value ) - { - if( !ReadOnly ) - { - if( m_Freshen ) (owner->*m_Freshen)(); - if( ToPrimitive( cx, Value, owner->*m_Data ) ) - if( m_Update ) (owner->*m_Update)(); - } - } - -}; - -template class CJSComplexProperty : public IJSComplexProperty -{ - T* m_Data; - - // Function on Owner to call after value is changed - IJSComplex::NotifyFn m_Update; - - // Function on Owner to call before reading or writing the value - IJSComplex::NotifyFn m_Freshen; - -public: - CJSComplexProperty( T* Data, bool AllowsInheritance = false, IJSComplex::NotifyFn Update = NULL, IJSComplex::NotifyFn Freshen = NULL ) - { - m_Data = Data; - m_AllowsInheritance = AllowsInheritance; - m_Update = Update; - m_Freshen = Freshen; - m_Intrinsic = true; - } - jsval Get( JSContext* UNUSED(cx), IJSComplex* owner ) - { - if( m_Freshen ) (owner->*m_Freshen)(); - return( ToJSVal( *m_Data ) ); - } - void ImmediateCopy( IJSComplex* UNUSED(CopyTo), IJSComplex* UNUSED(CopyFrom), IJSComplexProperty* CopyProperty ) - { - *m_Data = *( ( (CJSComplexProperty*)CopyProperty )->m_Data ); - } - void Set( JSContext* cx, IJSComplex* owner, jsval Value ) - { - if( !ReadOnly ) - { - if( m_Freshen ) (owner->*m_Freshen)(); - if( ToPrimitive( cx, Value, *m_Data ) ) - if( m_Update ) (owner->*m_Update)(); - } - } - -}; - - -class CJSReflector -{ - template friend class CJSComplex; - JSObject* m_JSAccessor; -}; - -class CJSDynamicComplexProperty : public IJSComplexProperty -{ - template friend class CJSComplex; - - JSObject* m_JSAccessor; -public: - CJSDynamicComplexProperty() - { - m_JSAccessor = NULL; - m_Intrinsic = false; - m_Inherited = false; - } -}; - -class CJSValComplexProperty : public CJSDynamicComplexProperty -{ - template friend class CJSComplex; - - jsval m_Data; - -public: - CJSValComplexProperty( jsval Data, bool Inherited ) - { - m_Inherited = Inherited; - m_Data = Data; - Root(); - } - ~CJSValComplexProperty() - { - Uproot(); - } - void Root() - { - if( JSVAL_IS_GCTHING( m_Data ) ) -#ifndef NDEBUG - JS_AddNamedRoot( g_ScriptingHost.GetContext(), (void*)&m_Data, "jsval property" ); -#else - JS_AddRoot( g_ScriptingHost.GetContext(), (void*)&m_Data ); -#endif - } - void Uproot() - { - if( JSVAL_IS_GCTHING( m_Data ) ) - JS_RemoveRoot( g_ScriptingHost.GetContext(), (void*)&m_Data ); - } - jsval Get( JSContext* UNUSED(cx), IJSComplex* UNUSED(owner) ) - { - return( m_Data ); - } - void Set( JSContext* UNUSED(cx), IJSComplex* UNUSED(owner), jsval Value ) - { - Uproot(); - m_Data = Value; - Root(); - } - void ImmediateCopy( IJSComplex* UNUSED(CopyTo), IJSComplex* UNUSED(CopyFrom), - IJSComplexProperty* UNUSED(CopyProperty) ) - { - debug_warn(L"ImmediateCopy called on a CJSValComplexProperty (something's gone wrong with the inheritance on this object)" ); - } -}; - -class CJSFunctionComplexProperty : public IJSComplexProperty -{ - // Function on Owner to get the value - IJSComplex::GetFn m_Getter; - - // Function on Owner to set the value - IJSComplex::SetFn m_Setter; - -public: - CJSFunctionComplexProperty( IJSComplex::GetFn Getter, IJSComplex::SetFn Setter ) - { - m_Inherited = false; - m_Intrinsic = true; - m_Getter = Getter; - m_Setter = Setter; - // Must at least be able to read - debug_assert( m_Getter ); - } - jsval Get( JSContext* UNUSED(cx), IJSComplex* owner ) - { - return( (owner->*m_Getter)() ); - } - void Set( JSContext* UNUSED(cx), IJSComplex* owner, jsval Value ) - { - if( m_Setter ) - (owner->*m_Setter)( Value ); - } - void ImmediateCopy( IJSComplex* UNUSED(CopyTo), IJSComplex* UNUSED(CopyFrom), IJSComplexProperty* UNUSED(CopyProperty) ) - { - debug_warn(L"ImmediateCopy called on a property wrapping getter/setter functions (something's gone wrong with the inheritance for this object)" ); - } -}; - - -// Wrapper around native functions that are attached to CJSComplexs - -template class CNativeComplexFunction -{ -public: - static JSBool JSFunction( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ) - { - T* Native = ToNative( cx, obj ); - if( !Native ) - return( JS_TRUE ); - - *rval = ToJSVal( (Native->*NativeFunction)( cx, argc, argv ) ); - - return( JS_TRUE ); - } -}; - -//----------------------------------------------------------------------------- -// CJSComplex implementation -//----------------------------------------------------------------------------- - -template -void CJSComplex::SetProperty( JSContext* cx, const CStrW& PropertyName, jsval* vp ) -{ - if( !ReadOnly ) - { - IJSComplexProperty* prop = HasProperty( PropertyName ); - - if( prop ) - { - // Already exists - WatchNotify( cx, PropertyName, vp ); - prop->Set( cx, this, *vp ); - - if(!prop->m_Intrinsic) - prop->m_Inherited = false; - - // If it's a C++ property, reflect this change in objects that inherit this. - if( prop->m_AllowsInheritance && prop->m_Intrinsic ) - { - InheritorsList UpdateSet( m_Inheritors ); - - while( !UpdateSet.empty() ) - { - IJSComplex* UpdateObj = UpdateSet.back(); - UpdateSet.pop_back(); - IJSComplexProperty* UpdateProp = UpdateObj->HasProperty( PropertyName ); - // Property must exist, also be a C++ property, and not have its value specified. - if( UpdateProp && UpdateProp->m_Intrinsic && UpdateProp->m_Inherited ) - { - UpdateProp->Set( cx, this, *vp ); - InheritorsList::iterator it2; - for( it2 = UpdateObj->m_Inheritors.begin(); it2 != UpdateObj->m_Inheritors.end(); it2++ ) - UpdateSet.push_back( *it2 ); - } - } - } - } - else - { - // Need to add it - WatchNotify( cx, PropertyName, vp ); - AddProperty( PropertyName, *vp ); - } - } -} - - -template -void CJSComplex::WatchNotify( JSContext* cx, const CStrW& PropertyName, jsval* newval ) -{ - if( m_Watches.empty() ) return; - - jsval oldval = JSVAL_VOID; - GetProperty( cx, PropertyName, &oldval ); - - jsval args[3] = { ToJSVal( PropertyName ), oldval, *newval }; - - std::vector::iterator it; - for( it = m_Watches.begin(); it != m_Watches.end(); it++ ) - if( it->Run( GetScript(), newval, 3, args ) ) - args[2] = *newval; -} - - -// -// Functions that must be provided to JavaScript -// - -template -JSBool CJSComplex::JSGetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) -{ - T* Instance = ToNative( cx, obj ); - if( !Instance ) - return( JS_TRUE ); - - CStrW PropName = g_ScriptingHost.ValueToUCString( id ); - - if( !Instance->GetProperty( cx, PropName, vp ) ) - return( JS_TRUE ); - - return( JS_TRUE ); -} - - -template -JSBool CJSComplex::JSSetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) -{ - T* Instance = ToNative( cx, obj ); - if( !Instance ) - return( JS_TRUE ); - - CStrW PropName = g_ScriptingHost.ValueToUCString( id ); - - Instance->SetProperty( cx, PropName, vp ); - - return( JS_TRUE ); -} - - -template -JSBool CJSComplex::JSEnumerate( JSContext* cx, JSObject* obj, JSIterateOp enum_op, jsval* statep, jsid *idp ) -{ - IteratorState* it; - - switch( enum_op ) - { - case JSENUMERATE_INIT: - { - T* Instance = ToNative( cx, obj ); - - it = new IteratorState; - if( Instance ) - { - PropertyTable::iterator iit; - for( iit = T::m_IntrinsicProperties.begin(); iit != T::m_IntrinsicProperties.end(); iit++ ) - it->first.insert( iit->first ); - - Instance->FillEnumerateSet( it ); - } - - it->second = it->first.begin(); - *statep = PRIVATE_TO_JSVAL( it ); - - if( idp ) - *idp = INT_TO_JSVAL( it->first.size() ); - - return( JS_TRUE ); - } - case JSENUMERATE_NEXT: - it = (IteratorState*)JSVAL_TO_PRIVATE( *statep ); - if( it->second == it->first.end() ) - { - delete( it ); - *statep = JSVAL_NULL; - return( JS_TRUE ); - } - - // I think this is what I'm supposed to do... (cheers, Philip) - if( !JS_ValueToId( cx, ToJSVal( *( it->second ) ), idp ) ) - return( JS_FALSE ); - - // EVIL HACK: see the comment in the other JSEnumerate - JS_DefineProperty(cx, obj, CStr(*it->second).c_str(), JSVAL_VOID, NULL, NULL, 0); - - (it->second)++; - - *statep = PRIVATE_TO_JSVAL( it ); - return( JS_TRUE ); - case JSENUMERATE_DESTROY: - it = (IteratorState*)JSVAL_TO_PRIVATE( *statep ); - delete( it ); - *statep = JSVAL_NULL; - return( JS_TRUE ); - } - return( JS_FALSE ); -} - - -template -JSBool CJSComplex::SetWatchAll( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ) -{ - T* Native = ToNative( cx, obj ); - if( !Native ) - return( JS_TRUE ); - - debug_assert( argc >= 1 ); - - CScriptObject watch( argv[0] ); - std::vector::iterator it; - for( it = Native->m_Watches.begin(); it != Native->m_Watches.end(); it++ ) - if( *it == watch ) - { - *rval = JSVAL_FALSE; - return( JS_TRUE ); - } - - Native->m_Watches.push_back( watch ); - *rval = JSVAL_TRUE; - return( JS_TRUE ); -} - - -template -JSBool CJSComplex::UnWatchAll( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ) -{ - T* Native = ToNative( cx, obj ); - if( !Native ) - return( JS_TRUE ); - - if( argc >= 1 ) - { - CScriptObject watch( argv[0] ); - std::vector::iterator it; - for( it = Native->m_Watches.begin(); it != Native->m_Watches.end(); it++ ) - if( *it == watch ) - { - Native->m_Watches.erase( it ); - *rval = JSVAL_TRUE; - return( JS_TRUE ); - } - - *rval = JSVAL_FALSE; - } - else - { - Native->m_Watches.clear(); - *rval = JSVAL_TRUE; - } - return( JS_TRUE ); -} - - -template -void CJSComplex::ScriptingInit( const char* ClassName, JSNative Constructor, uintN ConstructorMinArgs ) -{ - JSFunctionSpec* JSI_methods = new JSFunctionSpec[ m_Methods.size() + 3 ]; - size_t MethodID; - for( MethodID = 0; MethodID < m_Methods.size(); MethodID++ ) - JSI_methods[MethodID] = m_Methods[MethodID]; - - JSFunctionSpec watchAll = { "watchAll", SetWatchAll, 1, 0, 0 }; - JSI_methods[MethodID + 0] = watchAll; - - JSFunctionSpec unwatchAll = { "unwatchAll", UnWatchAll, 1, 0, 0 }; - JSI_methods[MethodID + 1] = unwatchAll; - - JSI_methods[MethodID + 2].name = 0; - - JSI_class.name = ClassName; - - g_ScriptingHost.DefineCustomObjectType( &JSI_class, Constructor, ConstructorMinArgs, JSI_props, JSI_methods, NULL, NULL ); - - delete[]( JSI_methods ); - - atexit( ScriptingShutdown ); -} - -template -void CJSComplex::ScriptingShutdown() -{ - PropertyTable::iterator it; - for( it = m_IntrinsicProperties.begin(); it != m_IntrinsicProperties.end(); it++ ) - delete( it->second ); -} - - -template -void CJSComplex::DefaultFinalize( JSContext *cx, JSObject *obj ) -{ - T* Instance = ToNative( cx, obj ); - if( !Instance || Instance->m_EngineOwned ) - return; - - delete( Instance ); - JS_SetPrivate( cx, obj, NULL ); -} - -// Creating and releasing script objects is done automatically most of the time, but you -// can do it explicitly. -template -void CJSComplex::CreateScriptObject() -{ - if( !m_JS ) - { - m_JS = JS_NewObject( g_ScriptingHost.GetContext(), &JSI_class, NULL, NULL ); - if( m_EngineOwned ) - { -#ifndef NDEBUG // Name the GC roots something more useful than 'ScriptableObject.h' - JS_AddNamedRoot( g_ScriptingHost.GetContext(), (void*)&m_JS, JSI_class.name ); -#else - JS_AddRoot( g_ScriptingHost.GetContext(), (void*)&m_JS ); -#endif - } - JS_SetPrivate( g_ScriptingHost.GetContext(), m_JS, (T*)this ); - } -} - - -template -void CJSComplex::ReleaseScriptObject() -{ - if( m_JS ) - { - JS_SetPrivate( g_ScriptingHost.GetContext(), m_JS, NULL ); - if( m_EngineOwned ) - JS_RemoveRoot( g_ScriptingHost.GetContext(), &m_JS ); - m_JS = NULL; - } -} - - -template -CJSComplex::CJSComplex() -{ - jscomplexproperty_suballoc_attach(); - - m_Parent = NULL; - m_JS = NULL; - m_EngineOwned = true; -} - - -template -CJSComplex::~CJSComplex() -{ - Shutdown(); - - jscomplexproperty_suballoc_detach(); -} - - -template -void CJSComplex::Shutdown() -{ - PropertyTable::iterator it; - for( it = m_Properties.begin(); it != m_Properties.end(); it++ ) - { - if( !it->second->m_Intrinsic ) - { - CJSDynamicComplexProperty* extProp = (CJSValComplexProperty*)it->second; - if( extProp->m_JSAccessor ) - { - CJSComplexPropertyAccessor< CJSComplex >* accessor = (CJSComplexPropertyAccessor< CJSComplex >*)JS_GetPrivate( g_ScriptingHost.GetContext(), extProp->m_JSAccessor ); - debug_assert( accessor ); - delete( accessor ); - JS_SetPrivate( g_ScriptingHost.GetContext(), extProp->m_JSAccessor, NULL ); - JS_RemoveRoot( g_ScriptingHost.GetContext(), &( extProp->m_JSAccessor ) ); - } - } - - jscomplexproperty_suballoc_free(it->second); - } - - - ReflectorTable::iterator it_a; - for( it_a = m_Reflectors.begin(); it_a != m_Reflectors.end(); it_a++ ) - { - CJSComplexPropertyAccessor< CJSComplex >* accessor = (CJSComplexPropertyAccessor< CJSComplex >*)JS_GetPrivate( g_ScriptingHost.GetContext(), it_a->second->m_JSAccessor ); - debug_assert( accessor ); - delete( accessor ); - JS_SetPrivate( g_ScriptingHost.GetContext(), it_a->second->m_JSAccessor, NULL ); - JS_RemoveRoot( g_ScriptingHost.GetContext(), &( it_a->second->m_JSAccessor ) ); - delete( it_a->second ); - } - ReleaseScriptObject(); -} - - -template -void CJSComplex::SetBase( IJSComplex* Parent ) -{ - if( m_Parent ) - { - // Remove this from the list of our parent's inheritors - InheritorsList::iterator it; - for( it = m_Parent->m_Inheritors.begin(); it != m_Parent->m_Inheritors.end(); it++ ) - if( (*it) == this ) - { - m_Parent->m_Inheritors.erase( it ); - break; - } - } - m_Parent = Parent; - if( m_Parent ) - { - // Place this in the list of our parent's inheritors - m_Parent->m_Inheritors.push_back( this ); - Rebuild(); - } -} - -template -void CJSComplex::Rebuild() -{ - PropertyTable::iterator it; - // For each intrinsic property we have, - for( it = m_Properties.begin(); it != m_Properties.end(); it++ ) - { - const CStrW& prop_name = it->first; - IJSComplexProperty* prop = it->second; - - if( !prop->m_Intrinsic || !prop->m_Inherited ) - continue; - - // Attempt to locate it in the parent - IJSComplexProperty* parent_prop = m_Parent->HasProperty( prop_name ); - - // If it doesn't have it, we've inherited from an object of a different type - // This isn't allowed at the moment; but I don't have an totally convincing - // reason for forbidding it entirely. Mind, I can't think of any use for it, - // either. - // If it can be inherited, inherit it. - if( parent_prop && parent_prop->m_AllowsInheritance ) - { - debug_assert( parent_prop->m_Intrinsic ); - prop->ImmediateCopy( this, m_Parent, parent_prop ); - } - } - // Do the same for the shared properties table, too - for( it = m_IntrinsicProperties.begin(); it != m_IntrinsicProperties.end(); it++ ) - { - const CStrW& prop_name = it->first; - IJSComplexProperty* prop = it->second; - - if( !prop->m_Inherited ) - continue; - - IJSComplexProperty* parent_prop = m_Parent->HasProperty( prop_name ); - - if( parent_prop && parent_prop->m_AllowsInheritance ) - { - debug_assert( parent_prop->m_Intrinsic ); - prop->ImmediateCopy( this, m_Parent, parent_prop ); - } - } - - // Now recurse. - InheritorsList::iterator c; - for( c = m_Inheritors.begin(); c != m_Inheritors.end(); c++ ) - (*c)->Rebuild(); - -} - - -template -IJSComplexProperty* CJSComplex::HasProperty( const CStrW& PropertyName ) -{ - PropertyTable::iterator it; - it = T::m_IntrinsicProperties.find( PropertyName ); - if( it != T::m_IntrinsicProperties.end() ) - return( it->second ); - - it = m_Properties.find( PropertyName ); - if( it != m_Properties.end() ) - return( it->second ); - - return( NULL ); -} - - -template -void CJSComplex::FillEnumerateSet( IteratorState* it, CStrW* PropertyRoot) -{ - PropertyTable::iterator iit; - if( PropertyRoot ) - { - size_t rlen = PropertyRoot->length(); - for( iit = m_Properties.begin(); iit != m_Properties.end(); iit++ ) - if( ( iit->first.length() > rlen ) && ( iit->first.Left( rlen ) == *PropertyRoot ) && ( iit->first[rlen] == '.' ) ) - it->first.insert( CStrW( iit->first.substr( rlen + 1 ) ).BeforeFirst( L"." ) ); - } - else - { - for( iit = m_Properties.begin(); iit != m_Properties.end(); iit++ ) - it->first.insert( iit->first.BeforeFirst( L"." ) ); - } - if( m_Parent ) - m_Parent->FillEnumerateSet( it, PropertyRoot ); -} - - -template -void CJSComplex::AddProperty( const CStrW& PropertyName, jsval Value ) -{ - DeletePreviouslyAssignedProperty( PropertyName ); - void* mem = jscomplexproperty_suballoc(); - CJSDynamicComplexProperty* newProp = new(mem) CJSValComplexProperty( Value, false ); - m_Properties[PropertyName] = newProp; - - ReflectorTable::iterator it; - it = m_Reflectors.find( PropertyName ); - if( it != m_Reflectors.end() ) - { - // We had an accessor pointing to this property before it was defined. - newProp->m_JSAccessor = it->second->m_JSAccessor; - JS_RemoveRoot( g_ScriptingHost.GetContext(), &( it->second->m_JSAccessor ) ); - JS_AddRoot( g_ScriptingHost.GetContext(), &( newProp->m_JSAccessor ) ); - delete( it->second ); - m_Reflectors.erase( it ); - } -} - -template -void CJSComplex::AddProperty( const CStrW& PropertyName, const CStrW& Value ) -{ - AddProperty( PropertyName, JSParseString( Value ) ); -} - -template -void CJSComplex::AddClassProperty( const CStrW& PropertyName, GetFn Getter, SetFn Setter ) -{ - T::m_IntrinsicProperties[PropertyName] = new CJSFunctionComplexProperty( Getter, Setter ); -} - -// helper routine for Add*Property. Their interface requires the -// property not already exist; we check for this (in debug builds) -// and if so, warn and free the previously new-ed memory in -// m_Properties[PropertyName] (avoids mem leak). -template -void CJSComplex::DeletePreviouslyAssignedProperty( const CStrW& PropertyName ) -{ -#ifdef NDEBUG - UNUSED2(PropertyName); -#else - PropertyTable::iterator it; - it = m_Properties.find( PropertyName ); - if( it != m_Properties.end() ) - { - debug_warn(L"BUG: CJSComplexProperty added but already existed!"); - jscomplexproperty_suballoc_free(it->second); - } -#endif -} - - -template -bool CJSComplex::GetProperty( JSContext* cx, const CStrW& PropertyName, jsval* vp ) -{ - IJSComplexProperty* Property = HasProperty( PropertyName ); - if( Property && Property->m_Intrinsic ) - { - *vp = Property->Get( cx, this ); - } - else - { - CJSValComplexProperty* extProp; - - if( Property ) - { - extProp = (CJSValComplexProperty*)Property; - - // If it's already a JS object, there's no point in creating - // a PropertyAccessor for it; it can manage far better on its - // own (this was why valueOf() was necessary) - - if( !JSVAL_IS_OBJECT( extProp->m_Data ) ) - { - if( !extProp->m_JSAccessor ) - { - extProp->m_JSAccessor = CJSComplexPropertyAccessor< CJSComplex >::CreateAccessor( cx, this, PropertyName ); - JS_AddNamedRoot( cx, &extProp->m_JSAccessor, "property accessor" ); - } - - *vp = OBJECT_TO_JSVAL( extProp->m_JSAccessor ); - } - else - *vp = extProp->m_Data; - } - else - { - // Check to see if it exists on a parent - IJSComplex* check = m_Parent; - while( check ) - { - if( check->HasProperty( PropertyName ) ) break; - check = check->m_Parent; - } - - if( !check ) - return( false ); - - // FIXME: Fiddle a way so this /doesn't/ require multiple kilobytes - // of memory. Can't think of any better way to do it yet. Problem is - // that script may access a property that isn't defined locally, but - // is defined by an ancestor. We can't return an accessor to the - // ancestor's property, because then if it's altered it affects that - // object, not this. At the moment, creating a 'reflector' property - // accessor that references /this/ object to be returned to script. - - // (N.B. Can't just put JSComplexs* in the table -> table entries can - // move -> root no longer refers to the JSObject.) - - ReflectorTable::iterator it; - it = m_Reflectors.find( PropertyName ); - - if( it == m_Reflectors.end() ) - { - CJSReflector* reflector = new CJSReflector(); - reflector->m_JSAccessor = CJSComplexPropertyAccessor< CJSComplex >::CreateAccessor( cx, this, PropertyName ); - JS_AddRoot( cx, &reflector->m_JSAccessor ); - m_Reflectors.insert( std::pair( PropertyName, reflector ) ); - *vp = OBJECT_TO_JSVAL( reflector->m_JSAccessor ); - } - else - *vp = OBJECT_TO_JSVAL( it->second->m_JSAccessor ); - } - } - return( true ); -} - -template -void AddMethodImpl( const char* Name, uintN MinArgs ) -{ - JSFunctionSpec FnInfo = { Name, CNativeComplexFunction::JSFunction, MinArgs, 0, 0 }; - T::m_Methods.push_back( FnInfo ); -} - -template -void AddClassPropertyImpl( const CStrW& PropertyName, PropType T::*Native, bool PropAllowInheritance, IJSComplex::NotifyFn Update, IJSComplex::NotifyFn Refresh ) -{ - T::m_IntrinsicProperties[PropertyName] = new CJSSharedProperty( (PropType IJSComplex::*)Native, PropAllowInheritance, Update, Refresh ); -} - -template -void AddReadOnlyClassPropertyImpl( const CStrW& PropertyName, PropType T::*Native, bool PropAllowInheritance, IJSComplex::NotifyFn Update, IJSComplex::NotifyFn Refresh ) -{ - T::m_IntrinsicProperties[PropertyName] = new CJSSharedProperty( (PropType IJSComplex::*)Native, PropAllowInheritance, Update, Refresh ); -} - -// PropertyName must not already exist! (verified in debug build) -template -void MemberAddPropertyImpl( IJSComplex* obj, const CStrW& PropertyName, PropType* Native, bool PropAllowInheritance, IJSComplex::NotifyFn Update, IJSComplex::NotifyFn Refresh ) -{ - ((T*)obj)->DeletePreviouslyAssignedProperty( PropertyName ); - void* mem = jscomplexproperty_suballoc(); - obj->m_Properties[PropertyName] = new(mem) CJSComplexProperty( Native, PropAllowInheritance, Update, Refresh ); -} - -// PropertyName must not already exist! (verified in debug build) -template -void MemberAddReadOnlyPropertyImpl( IJSComplex* obj, const CStrW& PropertyName, PropType* Native, bool PropAllowInheritance, IJSComplex::NotifyFn Update, IJSComplex::NotifyFn Refresh ) -{ - ((T*)obj)->DeletePreviouslyAssignedProperty( PropertyName ); - void* mem = jscomplexproperty_suballoc(); - obj->m_Properties[PropertyName] = new(mem) CJSComplexProperty( Native, PropAllowInheritance, Update, Refresh ); -} - -#endif diff --git a/source/scripting/SynchedJSObject.cpp b/source/scripting/SynchedJSObject.cpp deleted file mode 100644 index ded1d8195c..0000000000 --- a/source/scripting/SynchedJSObject.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#include "precompiled.h" - -#include "SynchedJSObject.h" -#include "ps/Parser.h" -#include "ScriptCustomTypes.h" - -template <> -CStrW ToNetString(const size_t &val) -{ - return CStrW((unsigned long)val); -} - -template <> -void SetFromNetString(size_t &val, const CStrW& string) -{ - val=string.ToUInt(); -} - -template <> -CStrW ToNetString(const int &val) -{ - return CStrW(val); -} - -template <> -void SetFromNetString(int &val, const CStrW& string) -{ - val=string.ToInt(); -} - -template <> -CStrW ToNetString(const bool &val) -{ - return val ? L"true" : L"false"; -} - -template <> -void SetFromNetString(bool &val, const CStrW& string) -{ - val = (string == L"true"); -} - -template <> -CStrW ToNetString(const CStrW& data) -{ - return data; -} - -template <> void SetFromNetString(CStrW& data, const CStrW& string) -{ - data=string; -} - -template <> -CStrW ToNetString(const SColour &data) -{ - wchar_t buf[256]; - swprintf_s(buf, ARRAY_SIZE(buf), L"%f %f %f %f", data.r, data.g, data.b, data.a); - - return buf; -} - -template <> -void SetFromNetString(SColour &data, const CStrW& wstring) -{ - CParser &parser(CParserCache::Get("$value_$value_$value_$value")); - CParserLine line; - - line.ParseString(parser, CStr(wstring)); - - float values[4]; - if (line.GetArgCount() != 4) return; - for (size_t i=0; i<4; ++i) - { - if (!line.GetArgFloat(i, values[i])) - { - return; - } - } - - data.r = values[0]; - data.g = values[1]; - data.b = values[2]; - data.a = values[3]; -} - -void CSynchedJSObjectBase::IterateSynchedProperties(IterateCB *cb, void *userdata) -{ - SynchedPropertyIterator it=m_SynchedProperties.begin(); - while (it != m_SynchedProperties.end()) - { - cb(it->first, it->second, userdata); - ++it; - } -} - -ISynchedJSProperty *CSynchedJSObjectBase::GetSynchedProperty(const CStrW& name) -{ - SynchedPropertyIterator prop=m_SynchedProperties.find(name); - if (prop != m_SynchedProperties.end()) - return prop->second; - else - return NULL; -} - diff --git a/source/scripting/SynchedJSObject.h b/source/scripting/SynchedJSObject.h deleted file mode 100644 index 14d2f004a3..0000000000 --- a/source/scripting/SynchedJSObject.h +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright (C) 2009 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -/* - CSynchedJSObject - - DESCRIPTION: - A helper class for CJSObject that enables a callback to be called - whenever an attribute of the class changes and enables all (synched) - properties to be set and retrieved as strings for network sync. - - All string conversions are performed by specific functions that use a - strictly (hrm) defined format - or at least a format that is specific - for the type in question (which is why JSParseString can't be used - - the JS interface's ToString function is also not usable since it often - produces a human-readable format that doesn't parse well and might - change outside the control of the network protocol). - - This replaces CAttributeMap for both player and game attributes. - - USAGE: - First you must create your subclass, make it inherit from - CSynchedJSObject and implement the pure virtual method Update (see - prototype below) - - Then you may use it just like CJSObject (see ScriptableObject.h) - with - one exception: Any property you want to be synchronized (i.e. have the - new property functionality including the update callback) is added using - the AddSynchedProperty method instead: AddSynchedProperty(name, &m_Property) - - The extra arguments that exist in the AddProperty method haven't been - implemented (if you by any chance would need to, just do it ;-) - -*/ - -#ifndef INCLUDED_SYNCHEDJSOBJECT -#define INCLUDED_SYNCHEDJSOBJECT - -#include "ps/CStr.h" -#include "ScriptableObject.h" - -template -void SetFromNetString(T &data, const CStrW& string); - -template -CStrW ToNetString(const T &data); - -#define TYPE(type) \ - template <> CStrW ToNetString(const type &data); \ - template <> void SetFromNetString(type &data, const CStrW& string); - -TYPE(size_t) -TYPE(CStrW) - -#undef TYPE - -class ISynchedJSProperty: public IJSProperty -{ -public: - virtual void FromString(const CStrW& value)=0; - virtual CStrW ToString()=0; -}; - -// non-templated base class -struct CSynchedJSObjectBase -{ - typedef void (*UpdateFn)(CSynchedJSObjectBase *owner); - - template - class CSynchedJSProperty: public ISynchedJSProperty - { - PropType *m_Data; - CStrW m_Name; - CSynchedJSObjectBase *m_Owner; - UpdateFn m_Update; - - virtual void Set(JSContext* cx, IJSObject* UNUSED(owner), jsval value) - { - if (!ReadOnly) - { - if (ToPrimitive(cx, value, *m_Data)) - { - m_Owner->Update(m_Name, this); - if (m_Update) - m_Update(m_Owner); - } - } - } - virtual jsval Get(JSContext* UNUSED(cx), IJSObject* UNUSED(owner)) - { - return ToJSVal(*m_Data); - } - - virtual void ImmediateCopy(IJSObject* UNUSED(CopyFrom), IJSObject* UNUSED(CopyTo), IJSProperty* other) - { - *m_Data = *( ((CSynchedJSProperty*)other)->m_Data ); - } - - virtual void FromString(const CStrW& value) - { - SetFromNetString(*m_Data, value); - if (m_Update) - m_Update(m_Owner); - } - - virtual CStrW ToString() - { - return ToNetString(*m_Data); - } - - public: - inline CSynchedJSProperty(const CStrW& name, PropType* native, CSynchedJSObjectBase *owner, UpdateFn update=NULL): - m_Data(native), - m_Name(name), - m_Owner(owner), - m_Update(update) - { - } - }; - - typedef STL_HASH_MAP SynchedPropertyTable; - typedef SynchedPropertyTable::iterator SynchedPropertyIterator; - SynchedPropertyTable m_SynchedProperties; - -protected: - virtual ~CSynchedJSObjectBase() { } - - // Called every time a property changes. - // This is where the individual callbacks are dispatched from. - virtual void Update(const CStrW& name, ISynchedJSProperty *prop)=0; - -public: - ISynchedJSProperty *GetSynchedProperty(const CStrW& name); - - typedef void (IterateCB)(const CStrW& name, ISynchedJSProperty *prop, void *userdata); - void IterateSynchedProperties(IterateCB *cb, void *userdata); -}; - -template -class CSynchedJSObject: public CJSObject, public CSynchedJSObjectBase -{ -protected: - // Add a property to the object; if desired, a callback is called every time it changes. - // Replaces CJSObject's AddProperty. - template void AddSynchedProperty(const CStrW& name, T *native, UpdateFn update=NULL) - { - ISynchedJSProperty *prop=new CSynchedJSProperty(name, native, this, update); - this->m_NonsharedProperties[name]=prop; - this->m_SynchedProperties[name]=prop; - } -}; - -#endif diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index 7a4a2a16c0..8aa4ab93d6 100644 --- a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp @@ -94,7 +94,7 @@ MESSAGEHANDLER(SaveMap) CMapWriter writer; const VfsPath pathname = VfsPath(L"maps/scenarios/") / *msg->filename; writer.SaveMap(pathname, - g_Game->GetWorld()->GetTerrain(), &g_Game->GetWorld()->GetUnitManager(), + g_Game->GetWorld()->GetTerrain(), g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(), &g_LightEnv, g_Game->GetView()->GetCamera(), g_Game->GetView()->GetCinema(), g_Game->GetSimulation2());