Support startup scripts in map files, for testing.
Support CDATA sections when writing XML. This was SVN commit r7483.
This commit is contained in:
parent
08720c9a58
commit
5daac34ef9
@ -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());
|
||||
|
@ -78,6 +78,8 @@ private:
|
||||
std::vector<STileDesc> m_Tiles;
|
||||
// lightenv stored in file
|
||||
CLightEnv m_LightEnv;
|
||||
// startup script
|
||||
CStrW m_Script;
|
||||
|
||||
// state latched by LoadMap and held until DelayedLoadFinished
|
||||
CFileUnpacker unpacker;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<MapTriggerGroup>& groupList);
|
||||
void WriteTrigger(XMLWriter_File& xml_file_, const MapTrigger& trigger);
|
||||
|
@ -56,6 +56,13 @@ namespace
|
||||
return ret;
|
||||
}
|
||||
|
||||
CStr escapeCDATA(const char* input)
|
||||
{
|
||||
CStr ret = input;
|
||||
ret.Replace("]]>", "]]>]]><![CDATA[");
|
||||
return ret;
|
||||
}
|
||||
|
||||
CStr escapeComment(const char* input)
|
||||
{
|
||||
// Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
|
||||
@ -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 += "<![CDATA[";
|
||||
m_Data += escapeCDATA(text);
|
||||
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*>(const char* text)
|
||||
template <> void XMLWriter_Element::Text<const char*>(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*>(const wchar_t* text)
|
||||
template <> void XMLWriter_Element::Text<const wchar_t*>(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*>(const char* name,
|
||||
{
|
||||
ElementStart(NULL, name);
|
||||
m_Data += ">";
|
||||
ElementText(value);
|
||||
ElementText(value, false);
|
||||
ElementEnd(name, EL_TEXT);
|
||||
}
|
||||
else
|
||||
|
@ -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: <...><![CDATA[text]]></...>
|
||||
#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 <typename T> 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 <typename constCharPtr> void Text(constCharPtr text);
|
||||
template <typename constCharPtr> void Text(constCharPtr text, bool cdata);
|
||||
template <typename T> void Attribute(const char* name, T value) { m_File->ElementAttribute(name, value, false); }
|
||||
template <typename T> void Setting(const char* name, T value) { m_File->ElementAttribute(name, value, true); }
|
||||
void Close(int type);
|
||||
|
@ -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,
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"
|
||||
"<Test><![CDATA[abc > ]]>]]><![CDATA[ < & \"\" ]]></Test>"
|
||||
);
|
||||
}
|
||||
|
||||
void test_comment_escape()
|
||||
{
|
||||
XML_Start();
|
||||
|
@ -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<std::wstring> 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<ICmpCommandQueue> 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);
|
||||
|
@ -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.)
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user