1) Added support for nested tags to XMLNode.

2) Made all xml files well formed.
3) Minor code cleanups.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3324 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-03-31 02:52:01 +00:00
parent 3f4e171872
commit f860816241
13 changed files with 157 additions and 209 deletions

View File

@ -93,8 +93,6 @@ supertuxkart_SOURCES = \
io/file_manager.hpp \
io/xml_node.cpp \
io/xml_node.hpp \
io/xml_reader.cpp \
io/xml_reader.hpp\
items/attachment.cpp \
items/attachment.hpp \
items/attachment_manager.cpp \

View File

@ -17,8 +17,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef MOVING_TEXTURE_H
#define MOVING_TEXTURE_H
#ifndef MOVING_TEXTURE_HPP
#define MOVING_TEXTURE_HPP
#include <string>
#define _WINSOCKAPI_

View File

@ -668,10 +668,6 @@
RelativePath="..\..\io\xml_node.cpp"
>
</File>
<File
RelativePath="..\..\io\xml_reader.cpp"
>
</File>
</Filter>
<Filter
Name="input"
@ -1278,10 +1274,6 @@
RelativePath="..\..\io\xml_node.hpp"
>
</File>
<File
RelativePath="..\..\io\xml_reader.hpp"
>
</File>
</Filter>
<Filter
Name="input"

View File

@ -6,7 +6,6 @@
#include "input/input.hpp"
#include <iostream>
#include <fstream>
#include "io/xml_reader.hpp"
#include "io/xml_node.hpp"
enum DeviceType

View File

@ -209,12 +209,20 @@ FileManager::~FileManager()
} // ~FileManager
//-----------------------------------------------------------------------------
XMLReader *FileManager::getXMLReader(const std::string &f)
io::IXMLReader *FileManager::getXMLReader(const std::string &filename)
{
io::IXMLReader *r = m_file_system->createXMLReader(f.c_str());
if(!r) return NULL;
return new XMLReader(r);
return m_file_system->createXMLReader(filename.c_str());
} // getXMLReader
//-----------------------------------------------------------------------------
/** Reads in a XML file and converts it into a XMLNode tree.
* \param filename Name of the XML file to read.
*/
XMLNode *FileManager::getXMLTree(const std::string &filename)
{
io::IXMLReader *xml_reader = getXMLReader(filename);
if(!xml_reader) return NULL;
return new XMLNode(xml_reader);
} // getXMLTree
//-----------------------------------------------------------------------------
void FileManager::pushModelSearchPath(const std::string& path)

View File

@ -19,13 +19,15 @@
#ifndef HEADER_FILE_MANAGER_HPP
#define HEADER_FILE_MANAGER_HPP
#include <string>
#include <vector>
#include <set>
#include "irrlicht.h"
using namespace irr;
#include "io/xml_reader.hpp"
#include "io/xml_node.hpp"
class FileManager
{
@ -54,7 +56,8 @@ public:
~FileManager();
void setDevice(IrrlichtDevice *device);
void dropFileSystem();
XMLReader *getXMLReader(const std::string &f);
io::IXMLReader *getXMLReader(const std::string &filename);
XMLNode *getXMLTree(const std::string &filename);
std::string getHomeDir () const;
std::string getTrackDir () const;

View File

@ -1,4 +1,4 @@
// $Id: xml_reader.hpp 694 2006-08-29 07:42:36Z hiker $
// $Id: xml_node.hpp 694 2006-08-29 07:42:36Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Joerg Henrichs
@ -16,46 +16,110 @@
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_IRRLICHT
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "utils/string_utils.hpp"
#include "utils/vec3.hpp"
XMLNode::XMLNode(const std::string &name, io::IXMLReader *xml)
XMLNode::XMLNode(io::IXMLReader *xml)
{
m_name = name;
while(xml->getNodeType()!=io::EXN_ELEMENT && xml->read());
readXML(xml);
} // XMLNode
// ----------------------------------------------------------------------------
/** Reads a XML file and convert it intoa XMLNode tree.
* \param filename Name of the XML file to read.
*/
XMLNode::XMLNode(const std::string &filename)
{
io::IXMLReader *xml = file_manager->getXMLReader(filename);
bool is_first_element = true;
while(xml->read())
{
switch (xml->getNodeType())
{
case io::EXN_ELEMENT:
{
if(!is_first_element)
{
fprintf(stderr,
"More than one root element in '%s' - ignored.\n",
filename.c_str());
}
readXML(xml);
is_first_element = false;
break;
}
case io::EXN_ELEMENT_END: break; // Ignore all other types
case io::EXN_UNKNOWN: break;
case io::EXN_COMMENT: break;
case io::EXN_TEXT: break;
default: break;
} // switch
} // while
} // XMLNode
// ----------------------------------------------------------------------------
/** Stores all attributes, and reads in all children.
* \param xml The XML reader.
*/
void XMLNode::readXML(io::IXMLReader *xml)
{
m_name = std::string(core::stringc(xml->getNodeName()).c_str());
for(unsigned int i=0; i<xml->getAttributeCount(); i++)
{
std::string name = core::stringc(xml->getAttributeName(i)).c_str();
core::stringw value = xml->getAttributeValue(i);
m_attributes[name] = value;
} // for i
#ifdef TEST_ONLY
// If no children, we are done
if(xml->isEmptyElement())
return;
/** Read all children elements. */
while(xml->read())
{
switch (xml->getNodeType())
{
case io::EXN_ELEMENT: break;
case io::EXN_ELEMENT_END:
printf("found end\n");
break;// Ignore all other types
case io::EXN_UNKNOWN:
printf("found end\n");
case io::EXN_ELEMENT:
m_nodes.push_back(new XMLNode(xml));
break;
case io::EXN_COMMENT:
printf("found end\n");
break;
case io::EXN_TEXT:
printf("found end\n");
break;
default:
printf("found end\n");
case io::EXN_ELEMENT_END:
// End of this element found.
return;
break;
case io::EXN_UNKNOWN: break;
case io::EXN_COMMENT: break;
case io::EXN_TEXT: break;
default: break;
} // switch
} // while
#endif
} // XMLNode
} // readXML
// ----------------------------------------------------------------------------
/** Returns the i.th node.
* \param i Number of node to return.
*/
XMLNode *XMLNode::getNode(unsigned int i)
{
return m_nodes[i];
} // getNode
// ----------------------------------------------------------------------------
/** Returns the node with the given name.
* \param s Name of the node to return.
*/
XMLNode *XMLNode::getNode(const std::string &s)
{
for(unsigned int i=0; i<m_nodes.size(); i++)
{
if(m_nodes[i]->getName()==s) return m_nodes[i];
}
return NULL;
} // getNode
// ----------------------------------------------------------------------------
/** If 'attribute' was defined, set 'value' to the value of the
@ -302,4 +366,3 @@ int XMLNode::getHPR(Vec3 *value) const
} // getHPR Vec3
// ----------------------------------------------------------------------------
#endif

View File

@ -1,4 +1,4 @@
// $Id: xml_reader.hpp 694 2006-08-29 07:42:36Z hiker $
// $Id: xml_node.hpp 694 2006-08-29 07:42:36Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Joerg Henrichs
@ -17,7 +17,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_IRRLICHT
#ifndef HEADER_XML_NODE_HPP
#define HEADER_XML_NODE_HPP
@ -38,10 +37,14 @@ private:
std::map<std::string, core::stringw> m_attributes;
/** List of all sub nodes. */
std::vector<XMLNode *> m_nodes;
void readXML(io::IXMLReader *xml);
public:
XMLNode(const std::string &name, io::IXMLReader *xml);
XMLNode(io::IXMLReader *xml);
XMLNode(const std::string &filename);
const std::string &getName() const {return m_name; }
XMLNode *getNode(const std::string &name);
XMLNode *getNode(const std::string &name);
XMLNode *getNode(unsigned int i);
unsigned int getNumNodes() {return m_nodes.size(); }
int get(const std::string &attribute, std::string *value) const;
int get(const std::string &attribute, int *value) const;
int get(const std::string &attribute, float *value) const;
@ -54,7 +57,7 @@ public:
int get(const std::string &attribute, std::vector<int> *value) const;
int get(core::vector3df *value) const;
int getXYZ(core::vector3df *value) const;
int getXYZ(Vec3 *value) const;
int getXYZ(Vec3 *vaslue) const;
int getHPR(core::vector3df *value) const;
int getHPR(Vec3 *value) const;
/** Handy functions to test the bit pattern returned by get(vector3df*).*/
@ -67,4 +70,3 @@ public:
}; // XMLNode
#endif
#endif

View File

@ -1,70 +0,0 @@
// $Id: xml_reader.hpp 694 2006-08-29 07:42:36Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Joerg Henrichs
//
// This program 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 3
// of the License, or (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_IRRLICHT
#include "io/xml_reader.hpp"
#include "io/xml_node.hpp"
XMLReader::XMLReader(io::IXMLReader *xml)
{
while(xml->read())
{
switch (xml->getNodeType())
{
case io::EXN_ELEMENT:
{
// FIXME: is there an easier way to convert
// stringw to std::string?
std::string s = core::stringc(xml->getNodeName()).c_str();
const XMLNode *node = new XMLNode(s, xml);
m_all_nodes.push_back(node);
break;
}
case io::EXN_ELEMENT_END: // Ignore all other types
case io::EXN_UNKNOWN:
case io::EXN_COMMENT:
case io::EXN_TEXT:
default: break;
} // switch
} // while
} // XMLReader
// ----------------------------------------------------------------------------
unsigned int XMLReader::getNumNodes() const
{
return m_all_nodes.size();
} // getNumNodes
// ----------------------------------------------------------------------------
const XMLNode *XMLReader::getNode(unsigned int n) const
{
return m_all_nodes[n];
} // getNode
// ----------------------------------------------------------------------------
const XMLNode *XMLReader::getNode(const std::string &node_name) const
{
for(unsigned int i=0; i<m_all_nodes.size(); i++)
{
if(m_all_nodes[i]->getName()==node_name) return m_all_nodes[i];
}
return NULL;
} // getNode
#endif

View File

@ -1,45 +0,0 @@
// $Id: xml_reader.hpp 694 2006-08-29 07:42:36Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Joerg Henrichs
//
// This program 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 3
// of the License, or (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_IRRLICHT
#ifndef HEADER_XML_READER_HPP
#define HEADER_XML_READER_HPP
#include <string>
#include <vector>
#include "irrlicht.h"
using namespace irr;
class XMLNode;
class XMLReader
{
private:
io::IXMLReader *m_reader;
std::vector<const XMLNode *> m_all_nodes;
public:
XMLReader(io::IXMLReader *r);
unsigned int getNumNodes() const;
const XMLNode *getNode(const std::string &node_name) const;
const XMLNode *getNode(unsigned int n) const;
}; // XMLReader
#endif
#endif

View File

@ -17,9 +17,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "io/xml_node.hpp"
#include "io/xml_reader.hpp"
#include "material.hpp"
#include <stdexcept>
@ -27,6 +24,7 @@
#include "stk_config.hpp"
#include "graphics/irr_driver.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "utils/string_utils.hpp"

View File

@ -113,11 +113,11 @@ void MaterialManager::addSharedMaterial(const std::string& filename)
//-----------------------------------------------------------------------------
bool MaterialManager::pushTempMaterial(const std::string& filename)
{
XMLReader *xml = file_manager->getXMLReader(filename);
if(!xml) return true;
for(unsigned int i=0; i<xml->getNumNodes(); i++)
XMLNode *root = file_manager->getXMLTree(filename);
if(!root || root->getName()!="materials") return true;
for(unsigned int i=0; i<root->getNumNodes(); i++)
{
const XMLNode *node = xml->getNode(i);
const XMLNode *node = root->getNode(i);
if(!node)
{
// We don't have access to the filename at this stage anymore :(

View File

@ -863,54 +863,54 @@ void Track::loadTrack(const std::string &filename)
m_ambient_color = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f);
m_specular_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
m_diffuse_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
XMLReader *xml = file_manager->getXMLReader(m_filename);
const XMLNode *node = xml->getNode("track");
if(!node)
XMLNode *root = file_manager->getXMLTree(m_filename);
if(!root || root->getName()!="track")
{
std::ostringstream o;
o<<"Can't load track '"<<filename<<"', no track element.";
throw std::runtime_error(o.str());
}
node->get("name", &m_name);
node->get("description", &m_description);
node->get("designer", &m_designer);
node->get("version", &m_version);
root->get("name", &m_name);
root->get("description", &m_description);
root->get("designer", &m_designer);
root->get("version", &m_version);
std::vector<std::string> filenames;
node->get("music", &filenames);
root->get("music", &filenames);
getMusicInformation(filenames, m_music);
node->get("item", &m_item_style);
node->get("screenshot", &m_screenshot);
node->get("item", &m_item_style);
node->get("screenshot", &m_screenshot);
node->get("sky-color", &m_sky_color);
node->get("start-x", &m_start_x);
node->get("start-y", &m_start_y);
node->get("start-z", &m_start_z);
node->get("start-heading", &m_start_heading);
node->get("use-fog", &m_use_fog);
node->get("fog-color", &m_fog_color);
node->get("fog-density", &m_fog_density);
node->get("fog-start", &m_fog_start);
node->get("fog-end", &m_fog_end);
node->get("sun-position", &m_sun_position);
node->get("sun-ambient", &m_ambient_color);
node->get("sun-specular", &m_specular_color);
node->get("sun-diffuse", &m_diffuse_color);
node->get("gravity", &m_gravity);
node->get("arena", &m_is_arena);
node->get("groups", &m_groups);
root->get("item", &m_item_style);
root->get("screenshot", &m_screenshot);
root->get("item", &m_item_style);
root->get("screenshot", &m_screenshot);
root->get("sky-color", &m_sky_color);
root->get("start-x", &m_start_x);
root->get("start-y", &m_start_y);
root->get("start-z", &m_start_z);
root->get("start-heading", &m_start_heading);
root->get("use-fog", &m_use_fog);
root->get("fog-color", &m_fog_color);
root->get("fog-density", &m_fog_density);
root->get("fog-start", &m_fog_start);
root->get("fog-end", &m_fog_end);
root->get("sun-position", &m_sun_position);
root->get("sun-ambient", &m_ambient_color);
root->get("sun-specular", &m_specular_color);
root->get("sun-diffuse", &m_diffuse_color);
root->get("gravity", &m_gravity);
root->get("arena", &m_is_arena);
root->get("groups", &m_groups);
if(m_groups.size()==0)
m_groups.push_back("standard");
// if both camera position and rotation are defined,
// set the flag that the track has final camera position
m_has_final_camera = node->get("camera-final-position",
m_has_final_camera = root->get("camera-final-position",
&m_camera_final_position)!=1;
m_has_final_camera &= node->get("camera-final-hpr",
m_has_final_camera &= root->get("camera-final-hpr",
&m_camera_final_hpr) !=1;
m_camera_final_hpr.degreeToRad();
m_sky_type = SKY_NONE;
node = xml->getNode("sky-dome");
XMLNode *node = root->getNode("sky-dome");
if(node)
{
m_sky_type = SKY_DOME;
@ -919,7 +919,7 @@ void Track::loadTrack(const std::string &filename)
m_sky_sphere_percent = 1.0f;
m_sky_texture_percent = 1.0f;
std::string s;
node->get("texture", &s );
node->get("texture", &s );
m_sky_textures.push_back(s);
node->get("vertical", &m_sky_vert_segments );
node->get("horizontal", &m_sky_hori_segments );
@ -927,7 +927,7 @@ void Track::loadTrack(const std::string &filename)
node->get("texture-percent", &m_sky_texture_percent);
} // if sky-dome
node = xml->getNode("sky-box");
node = root->getNode("sky-box");
if(node)
{
std::string s;
@ -1300,22 +1300,22 @@ void Track::loadTrackModel()
// Start building the scene graph
#ifdef HAVE_IRRLICHT
std::string path = file_manager->getTrackFile(getIdent()+".scene");
XMLReader *xml = file_manager->getXMLReader(path);
XMLNode *root = file_manager->getXMLTree(path);
// Make sure that we have a track (which is used for raycasts to
// place other objects).
const XMLNode *node = xml->getNode("track");
if(!node)
if(!root || root->getName()!="scene")
{
std::ostringstream msg;
msg<< "No track model defined in '"<<path
<<"', aborting.";
throw std::runtime_error(msg.str());
}
XMLNode *node = root->getNode("track");
loadMainTrack(*node);
for(unsigned int i=0; i<xml->getNumNodes(); i++)
for(unsigned int i=0; i<root->getNumNodes(); i++)
{
const XMLNode *node = xml->getNode(i);
const XMLNode *node = root->getNode(i);
const std::string name = node->getName();
// The track object was already converted before the loop
if(name=="track") continue;