From 5daac34ef95eb64ff66ebd50f4073621e99dec88 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Thu, 29 Apr 2010 23:22:18 +0000 Subject: [PATCH] Support startup scripts in map files, for testing. Support CDATA sections when writing XML. This was SVN commit r7483. --- source/graphics/MapReader.cpp | 4 +++ source/graphics/MapReader.h | 2 ++ source/graphics/MapWriter.cpp | 16 +++++++--- source/graphics/MapWriter.h | 4 +-- source/ps/XML/XMLWriter.cpp | 30 ++++++++++++++----- source/ps/XML/XMLWriter.h | 9 ++++-- source/ps/XML/tests/test_XMLWriter.h | 16 ++++++++++ source/simulation2/Simulation2.cpp | 20 +++++++++++++ source/simulation2/Simulation2.h | 3 ++ .../GameInterface/Handlers/MapHandlers.cpp | 3 +- 10 files changed, 90 insertions(+), 17 deletions(-) diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 159ef01098..f0ef6754a9 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -1174,6 +1174,10 @@ int CXMLReader::ProgressiveRead() { ReadTriggers(node); } + else if (name == "Script") + { + m_MapReader.pSimulation2->SetStartupScript(CStrW(node.GetText())); + } else { debug_printf(L"Invalid XML element in map file: %ls\n", CStrW(name).c_str()); diff --git a/source/graphics/MapReader.h b/source/graphics/MapReader.h index b1df478b8b..0519c563e3 100644 --- a/source/graphics/MapReader.h +++ b/source/graphics/MapReader.h @@ -78,6 +78,8 @@ private: std::vector m_Tiles; // lightenv stored in file CLightEnv m_LightEnv; + // startup script + CStrW m_Script; // state latched by LoadMap and held until DelayedLoadFinished CFileUnpacker unpacker; diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index 28e8d5672b..2a902d4ad2 100644 --- a/source/graphics/MapWriter.cpp +++ b/source/graphics/MapWriter.cpp @@ -62,7 +62,8 @@ 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, - CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema) + CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, + CSimulation2* pSimulation2) { CFilePacker packer(CURRENT_FILE_VERSION, "PSMP"); @@ -73,7 +74,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); + WriteXML(pathnameXML, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -180,7 +181,8 @@ void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain* pTerrain) } void CMapWriter::WriteXML(const VfsPath& filename, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, - CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema) + CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, + CSimulation2* pSimulation2) { XML_Start(); @@ -188,6 +190,12 @@ void CMapWriter::WriteXML(const VfsPath& filename, XML_Element("Scenario"); XML_Attribute("version", (int)CURRENT_FILE_VERSION); + if (pSimulation2 && !pSimulation2->GetStartupScript().empty()) + { + XML_Element("Script"); + XML_CDATA(pSimulation2->GetStartupScript().c_str()); + } + { XML_Element("Environment"); @@ -603,6 +611,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); + writer.SaveMap(newPathname, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); } } diff --git a/source/graphics/MapWriter.h b/source/graphics/MapWriter.h index 6606adac18..9493868a67 100644 --- a/source/graphics/MapWriter.h +++ b/source/graphics/MapWriter.h @@ -48,7 +48,7 @@ public: void SaveMap(const VfsPath& pathname, CTerrain* pTerr, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, - CCinemaManager* pCinema); + CCinemaManager* pCinema, CSimulation2* pSimulation2); // RewriteAllMaps: for use during development: load/save all maps, to // update them to the newest format. @@ -71,7 +71,7 @@ private: // WriteXML: output some other data (entities, etc) in XML format void WriteXML(const VfsPath& pathname, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, - CCinemaManager* pCinema); + CCinemaManager* pCinema, CSimulation2* pSimulation2); void WriteTriggerGroup(XMLWriter_File& xml_file_, const MapTriggerGroup& group, const std::list& groupList); void WriteTrigger(XMLWriter_File& xml_file_, const MapTrigger& trigger); diff --git a/source/ps/XML/XMLWriter.cpp b/source/ps/XML/XMLWriter.cpp index 3e2a74f039..b9623a0a70 100644 --- a/source/ps/XML/XMLWriter.cpp +++ b/source/ps/XML/XMLWriter.cpp @@ -56,6 +56,13 @@ namespace return ret; } + CStr escapeCDATA(const char* input) + { + CStr ret = input; + ret.Replace("]]>", "]]>]]>' @@ -169,9 +176,18 @@ void XMLWriter_File::ElementEnd(const char* name, int type) } } -void XMLWriter_File::ElementText(const char* text) +void XMLWriter_File::ElementText(const char* text, bool cdata) { - m_Data += escapeCharacterData(text); + if (cdata) + { + m_Data += ""; + } + else + { + m_Data += escapeCharacterData(text); + } } @@ -200,15 +216,15 @@ void XMLWriter_Element::Close(int type) // Template specialisations for various string types: -template <> void XMLWriter_Element::Text(const char* text) +template <> void XMLWriter_Element::Text(const char* text, bool cdata) { Close(EL_TEXT); - m_File->ElementText(text); + m_File->ElementText(text, cdata); } -template <> void XMLWriter_Element::Text(const wchar_t* text) +template <> void XMLWriter_Element::Text(const wchar_t* text, bool cdata) { - Text( CStrW(text).ToUTF8().c_str() ); + Text( CStrW(text).ToUTF8().c_str(), cdata ); } // @@ -219,7 +235,7 @@ template <> void XMLWriter_File::ElementAttribute(const char* name, { ElementStart(NULL, name); m_Data += ">"; - ElementText(value); + ElementText(value, false); ElementEnd(name, EL_TEXT); } else diff --git a/source/ps/XML/XMLWriter.h b/source/ps/XML/XMLWriter.h index d63bfc10e6..4adaeba4e0 100644 --- a/source/ps/XML/XMLWriter.h +++ b/source/ps/XML/XMLWriter.h @@ -80,7 +80,10 @@ end of XMLWriter.cpp. #define XML_Element(name) XMLWriter_Element xml_element_ (xml_file_, name) // Add text to the interior of the current element: <...>text -#define XML_Text(text) xml_element_.Text(text) +#define XML_Text(text) xml_element_.Text(text, false) + +// Add CDATA-escaped text to the interior of the current element: <...> +#define XML_CDATA(text) xml_element_.Text(text, true) // Add an attribute to the current element: <... name="value" ...> #define XML_Attribute(name, value) xml_element_.Attribute(name, value) @@ -119,7 +122,7 @@ private: friend class XMLWriter_Element; void ElementStart(XMLWriter_Element* element, const char* name); - void ElementText(const char* text); + void ElementText(const char* text, bool cdata); template void ElementAttribute(const char* name, const T& value, bool newelement); void ElementClose(); void ElementEnd(const char* name, int type); @@ -139,7 +142,7 @@ public: XMLWriter_Element(XMLWriter_File& file, const char* name); ~XMLWriter_Element(); - template void Text(constCharPtr text); + template void Text(constCharPtr text, bool cdata); template void Attribute(const char* name, T value) { m_File->ElementAttribute(name, value, false); } template void Setting(const char* name, T value) { m_File->ElementAttribute(name, value, true); } void Close(int type); diff --git a/source/ps/XML/tests/test_XMLWriter.h b/source/ps/XML/tests/test_XMLWriter.h index ad0482ac28..461f9368ab 100644 --- a/source/ps/XML/tests/test_XMLWriter.h +++ b/source/ps/XML/tests/test_XMLWriter.h @@ -208,6 +208,22 @@ public: ); } + void test_cdata_escape() + { + XML_Start(); + + { + XML_Element("Test"); + XML_CDATA("abc > ]]> < & \"\" "); + } + + CStr output = XML_GetOutput(); + TS_ASSERT_STR_EQUALS(output, + "\n\n" + " ]]>]]>" + ); + } + void test_comment_escape() { XML_Start(); diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 435c6dea25..f39a348794 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -51,6 +51,7 @@ public: m_ComponentManager.ResetState(); m_DeltaTime = 0.0; + m_TurnNumber = 0; CParamNode noParam; CComponentManager::ComponentTypeId cid; @@ -92,8 +93,12 @@ public: CComponentManager m_ComponentManager; double m_DeltaTime; + std::wstring m_StartupScript; + std::set m_LoadedScripts; + uint32_t m_TurnNumber; + static const int TURN_LENGTH = 300; // TODO: Use CTurnManager }; @@ -149,6 +154,9 @@ void CSimulation2Impl::Update(float frameTime) CMessageTurnStart msgTurnStart; m_ComponentManager.BroadcastMessage(msgTurnStart); + if (m_TurnNumber == 0 && !m_StartupScript.empty()) + m_ComponentManager.GetScriptInterface().LoadScript(L"map startup script", m_StartupScript); + CmpPtr cmpCommandQueue(m_SimContext, SYSTEM_ENTITY); if (!cmpCommandQueue.null()) cmpCommandQueue->ProcessCommands(); @@ -158,6 +166,8 @@ void CSimulation2Impl::Update(float frameTime) // Clean up any entities destroyed during the simulation update m_ComponentManager.FlushDestroyedComponents(); + + ++m_TurnNumber; } } @@ -275,6 +285,16 @@ bool CSimulation2::LoadDefaultScripts() ); } +void CSimulation2::SetStartupScript(const std::wstring& code) +{ + m->m_StartupScript = code; +} + +const std::wstring& CSimulation2::GetStartupScript() +{ + return m->m_StartupScript; +} + LibError CSimulation2::ReloadChangedFile(const VfsPath& path) { return m->ReloadChangedFile(path); diff --git a/source/simulation2/Simulation2.h b/source/simulation2/Simulation2.h index 3bcd3014f2..29139d0617 100644 --- a/source/simulation2/Simulation2.h +++ b/source/simulation2/Simulation2.h @@ -64,6 +64,9 @@ public: */ bool LoadDefaultScripts(); + void SetStartupScript(const std::wstring& script); + const std::wstring& GetStartupScript(); + /** * Reload any scripts that were loaded from the given filename. * (This is used to implement hotloading.) diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index 52aa4200fd..bb534dbd55 100644 --- a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp @@ -164,7 +164,8 @@ MESSAGEHANDLER(SaveMap) writer.SaveMap(pathname, g_Game->GetWorld()->GetTerrain(), &g_Game->GetWorld()->GetUnitManager(), g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(), - &g_LightEnv, g_Game->GetView()->GetCamera(), g_Game->GetView()->GetCinema()); + &g_LightEnv, g_Game->GetView()->GetCamera(), g_Game->GetView()->GetCinema(), + g_Game->GetSimulation2()); } }