1
0
forked from 0ad/0ad

Support startup scripts in map files, for testing.

Support CDATA sections when writing XML.

This was SVN commit r7483.
This commit is contained in:
Ykkrosh 2010-04-29 23:22:18 +00:00
parent 08720c9a58
commit 5daac34ef9
10 changed files with 90 additions and 17 deletions

View File

@ -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());

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -56,6 +56,13 @@ namespace
return ret;
}
CStr escapeCDATA(const char* input)
{
CStr ret = input;
ret.Replace("]]>", "]]>]]&gt;<![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

View File

@ -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);

View File

@ -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 > ]]>]]&gt;<![CDATA[ < & \"\" ]]></Test>"
);
}
void test_comment_escape()
{
XML_Start();

View File

@ -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);

View File

@ -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.)

View File

@ -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());
}
}