summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--src/particle.cpp30
-rw-r--r--src/resources/itemdb.cpp22
-rw-r--r--src/resources/mapreader.cpp14
-rw-r--r--src/resources/monsterdb.cpp29
-rw-r--r--src/resources/npcdb.cpp285
-rw-r--r--src/resources/npcdb.h112
-rw-r--r--src/resources/spritedef.cpp32
-rw-r--r--src/resources/spritedef.h6
-rw-r--r--src/utils/xml.cpp36
-rw-r--r--src/utils/xml.h37
11 files changed, 303 insertions, 309 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c989157..958c6a7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-04-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/particle.cpp, src/utils/xml.cpp, src/utils/xml.h,
+ src/resources/mapreader.cpp, src/resources/spritedef.cpp,
+ src/resources/npcdb.h, src/resources/monsterdb.cpp,
+ src/resources/itemdb.cpp, src/resources/npcdb.cpp,
+ src/resources/spritedef.h: Added XML::Document class which simplifies
+ parsing an XML document and automatically cleans it up again.
+
2008-04-03 Philipp Sehmisch <tmw@crushnet.org>
* src/localplayer.cpp: Spawning a particle effect whenever the client
diff --git a/src/particle.cpp b/src/particle.cpp
index dcb2eed3..ba5386f6 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -217,35 +217,17 @@ Particle::addEffect(const std::string &particleEffectFile,
{
Particle *newParticle = NULL;
- // XML parser initialisation stuff
- int size;
- ResourceManager *resman = ResourceManager::getInstance();
- char *data = (char*) resman->loadFile(particleEffectFile.c_str(), size);
-
- if (!data) {
- logger->log("Warning: Particle engine could not find %s !",
- particleEffectFile.c_str());
- return NULL;
- }
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
+ XML::Document doc(particleEffectFile);
+ xmlNodePtr rootNode = doc.rootNode();
- if (!doc) {
- logger->log("Warning: Particle engine found syntax error in %s!",
- particleEffectFile.c_str());
- return NULL;
- }
-
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "effect"))
{
- logger->log("Warning: %s is not a valid particle effect definition file!",
- particleEffectFile.c_str());
- xmlFreeDoc(doc);
+ logger->log("Error loading particle: %s", particleEffectFile.c_str());
return NULL;
}
+ ResourceManager *resman = ResourceManager::getInstance();
+
// Parse particles
for_each_xml_child_node(effectChildNode, rootNode)
{
@@ -302,8 +284,6 @@ Particle::addEffect(const std::string &particleEffectFile,
mChildParticles.push_back(newParticle);
}
- xmlFreeDoc(doc);
-
return newParticle;
}
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index d507987a..ada9482f 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -103,26 +103,12 @@ void ItemDB::load()
mUnknown->setSprite("error.xml", GENDER_MALE);
mUnknown->setSprite("error.xml", GENDER_FEMALE);
- ResourceManager *resman = ResourceManager::getInstance();
- int size;
- char *data = (char*) resman->loadFile("items.xml", size);
+ XML::Document doc("items.xml");
+ xmlNodePtr rootNode = doc.rootNode();
- if (!data) {
- logger->error("ItemDB: Could not find items.xml!");
- }
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
-
- if (!doc)
- {
- logger->error("ItemDB: Error while parsing item database (items.xml)!");
- }
-
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items"))
{
- logger->error("ItemDB: items.xml is not a valid database file!");
+ logger->error("ItemDB: Error while loading items.xml!");
}
for_each_xml_child_node(node, rootNode)
@@ -200,8 +186,6 @@ void ItemDB::load()
#undef CHECK_PARAM
}
- xmlFreeDoc(doc);
-
mLoaded = true;
}
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index a07fc18d..3864580b 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -183,21 +183,19 @@ MapReader::readMap(const std::string &filename)
inflatedSize = fileSize;
}
- xmlDocPtr doc = xmlParseMemory((char*) inflated, inflatedSize);
+ XML::Document doc((char*) inflated, inflatedSize);
free(inflated);
- // Parse the inflated map data
- if (doc) {
- xmlNodePtr node = xmlDocGetRootElement(doc);
+ xmlNodePtr node = doc.rootNode();
- if (!node || !xmlStrEqual(node->name, BAD_CAST "map")) {
+ // Parse the inflated map data
+ if (node) {
+ if (!xmlStrEqual(node->name, BAD_CAST "map")) {
logger->log("Error: Not a map file (%s)!", filename.c_str());
}
- else
- {
+ else {
map = readMap(node, filename);
}
- xmlFreeDoc(doc);
} else {
logger->log("Error while parsing map file (%s)!", filename.c_str());
}
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index e7e855fa..f531a41d 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -51,27 +51,12 @@ MonsterDB::load()
logger->log("Initializing monster database...");
- ResourceManager *resman = ResourceManager::getInstance();
- int size;
- char *data = (char*)resman->loadFile("monsters.xml", size);
+ XML::Document doc("monsters.xml");
+ xmlNodePtr rootNode = doc.rootNode();
- if (!data)
- {
- logger->error("Monster Database: Could not find monsters.xml!");
- }
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
-
- if (!doc)
- {
- logger->error("Monster Database: Error while parsing monster database (monsters.xml)!");
- }
-
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "monsters"))
{
- logger->error("Monster Database: monster.xml is not a valid database file!");
+ logger->error("Monster Database: Error while loading monster.xml!");
}
//iterate <monster>s
@@ -161,16 +146,14 @@ MonsterDB::load()
mMonsterInfos[XML::getProperty(monsterNode, "id", 0)] = currentInfo;
}
- xmlFreeDoc(doc);
-
mLoaded = true;
}
void
MonsterDB::unload()
{
- for_each ( mMonsterInfos.begin(), mMonsterInfos.end(),
- make_dtor(mMonsterInfos));
+ for_each(mMonsterInfos.begin(), mMonsterInfos.end(),
+ make_dtor(mMonsterInfos));
mMonsterInfos.clear();
mLoaded = false;
@@ -178,7 +161,7 @@ MonsterDB::unload()
const MonsterInfo&
-MonsterDB::get (int id)
+MonsterDB::get(int id)
{
MonsterInfoIterator i = mMonsterInfos.find(id);
diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp
index e60431c3..6c205bc9 100644
--- a/src/resources/npcdb.cpp
+++ b/src/resources/npcdb.cpp
@@ -1,151 +1,134 @@
-/*
- * The Mana World
- * Copyright 2008 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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
- * any later version.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: monsterdb.cpp 3999 2008-03-23 01:27:13Z b_lindeijer $
- */
-
-#include "npcdb.h"
-
-#include "resourcemanager.h"
-
-#include "../log.h"
-
-#include "../utils/dtor.h"
-#include "../utils/xml.h"
-
-namespace
-{
- NPCInfos mNPCInfos;
- NPCInfo mUnknown;
- bool mLoaded = false;
-}
-
-void NPCDB::load()
-{
- if (mLoaded)
- return;
-
- NPCsprite *unknownSprite = new NPCsprite;
- unknownSprite->sprite = "error.xml";
- unknownSprite->variant = 0;
- mUnknown.push_back(unknownSprite);
-
- logger->log("Initializing NPC database...");
-
- ResourceManager *resman = ResourceManager::getInstance();
- int size;
- char *data = (char*)resman->loadFile("npcs.xml", size);
-
- if (!data)
- {
- logger->error("NPC Database: Could not find npcs.xml!");
- }
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
-
- if (!doc)
- {
- logger->error("NPC Database: Error while parsing NPC database (npcs.xml)!");
- }
-
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "npcs"))
- {
- logger->error("NPC Database: npcs.xml is not a valid database file!");
- }
-
- //iterate <monster>s
- for_each_xml_child_node(npcNode, rootNode)
- {
- if (!xmlStrEqual(npcNode->name, BAD_CAST "npc"))
- continue;
-
- int id = XML::getProperty(npcNode, "id", 0);
- if (id == 0)
- {
- logger->log("NPC Database: NPC with missing ID in npcs.xml!");
- continue;
- }
-
- NPCInfo *currentInfo = new NPCInfo;
-
- for_each_xml_child_node(spriteNode, npcNode)
- {
- if (!xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
- continue;
-
- NPCsprite *currentSprite = new NPCsprite;
- currentSprite->sprite = (const char*)spriteNode->xmlChildrenNode->content;
- currentSprite->variant = XML::getProperty(spriteNode, "variant", 0);
- currentInfo->push_back(currentSprite);
- }
-
- mNPCInfos[id] = currentInfo;
-
- }
-
- xmlFreeDoc(doc);
-
- mLoaded = true;
-}
-
-void
-NPCDB::unload()
-{
- for ( NPCInfosIterator i = mNPCInfos.begin();
- i != mNPCInfos.end();
- i++)
- {
- while (!i->second->empty())
- {
- delete i->second->front();
- i->second->pop_front();
- }
- delete i->second;
- }
-
- mNPCInfos.clear();
-
- while (!mUnknown.empty())
- {
- delete mUnknown.front();
- mUnknown.pop_front();
- }
-
- mLoaded = false;
-}
-
-const NPCInfo&
-NPCDB::get (int id)
-{
- NPCInfosIterator i = mNPCInfos.find(id);
-
- if (i == mNPCInfos.end())
- {
- logger->log("NPCDB: Warning, unknown NPC ID %d requested", id);
- return mUnknown;
- }
- else
- {
- return *(i->second);
- }
-}
-
+/*
+ * The Mana World
+ * Copyright 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id: monsterdb.cpp 3999 2008-03-23 01:27:13Z b_lindeijer $
+ */
+
+#include "npcdb.h"
+
+#include "resourcemanager.h"
+
+#include "../log.h"
+
+#include "../utils/dtor.h"
+#include "../utils/xml.h"
+
+namespace
+{
+ NPCInfos mNPCInfos;
+ NPCInfo mUnknown;
+ bool mLoaded = false;
+}
+
+void NPCDB::load()
+{
+ if (mLoaded)
+ return;
+
+ NPCsprite *unknownSprite = new NPCsprite;
+ unknownSprite->sprite = "error.xml";
+ unknownSprite->variant = 0;
+ mUnknown.push_back(unknownSprite);
+
+ logger->log("Initializing NPC database...");
+
+ XML::Document doc("npcs.xml");
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "npcs"))
+ {
+ logger->error("NPC Database: Error while loading items.xml!");
+ }
+
+ //iterate <monster>s
+ for_each_xml_child_node(npcNode, rootNode)
+ {
+ if (!xmlStrEqual(npcNode->name, BAD_CAST "npc"))
+ continue;
+
+ int id = XML::getProperty(npcNode, "id", 0);
+ if (id == 0)
+ {
+ logger->log("NPC Database: NPC with missing ID in npcs.xml!");
+ continue;
+ }
+
+ NPCInfo *currentInfo = new NPCInfo;
+
+ for_each_xml_child_node(spriteNode, npcNode)
+ {
+ if (!xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
+ continue;
+
+ NPCsprite *currentSprite = new NPCsprite;
+ currentSprite->sprite = (const char*)spriteNode->xmlChildrenNode->content;
+ currentSprite->variant = XML::getProperty(spriteNode, "variant", 0);
+ currentInfo->push_back(currentSprite);
+ }
+
+ mNPCInfos[id] = currentInfo;
+
+ }
+
+ mLoaded = true;
+}
+
+void
+NPCDB::unload()
+{
+ for ( NPCInfosIterator i = mNPCInfos.begin();
+ i != mNPCInfos.end();
+ i++)
+ {
+ while (!i->second->empty())
+ {
+ delete i->second->front();
+ i->second->pop_front();
+ }
+ delete i->second;
+ }
+
+ mNPCInfos.clear();
+
+ while (!mUnknown.empty())
+ {
+ delete mUnknown.front();
+ mUnknown.pop_front();
+ }
+
+ mLoaded = false;
+}
+
+const NPCInfo&
+NPCDB::get(int id)
+{
+ NPCInfosIterator i = mNPCInfos.find(id);
+
+ if (i == mNPCInfos.end())
+ {
+ logger->log("NPCDB: Warning, unknown NPC ID %d requested", id);
+ return mUnknown;
+ }
+ else
+ {
+ return *(i->second);
+ }
+}
+
diff --git a/src/resources/npcdb.h b/src/resources/npcdb.h
index 30431e59..3b2acd89 100644
--- a/src/resources/npcdb.h
+++ b/src/resources/npcdb.h
@@ -1,56 +1,56 @@
-/*
- * The Mana World
- * Copyright 2008 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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
- * any later version.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: monsterdb.h 3456 2007-08-13 21:09:12Z gmelquio $
- */
-
-#ifndef _TMW_NPC_DB_H
-#define _TMW_NPC_DB_H
-
-#include <map>
-#include <list>
-#include <string>
-
-struct NPCsprite
-{
- std::string sprite;
- int variant;
-};
-
-typedef std::list<NPCsprite*> NPCInfo;
-typedef std::map<int, NPCInfo*> NPCInfos;
-
-/**
- * NPC information database.
- */
-namespace NPCDB
-{
- void
- load();
-
- void
- unload();
-
- const NPCInfo& get(int id);
-
- typedef NPCInfos::iterator NPCInfosIterator;
-}
-
-#endif
+/*
+ * The Mana World
+ * Copyright 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id: monsterdb.h 3456 2007-08-13 21:09:12Z gmelquio $
+ */
+
+#ifndef _TMW_NPC_DB_H
+#define _TMW_NPC_DB_H
+
+#include <map>
+#include <list>
+#include <string>
+
+struct NPCsprite
+{
+ std::string sprite;
+ int variant;
+};
+
+typedef std::list<NPCsprite*> NPCInfo;
+typedef std::map<int, NPCInfo*> NPCInfos;
+
+/**
+ * NPC information database.
+ */
+namespace NPCDB
+{
+ void
+ load();
+
+ void
+ unload();
+
+ const NPCInfo& get(int id);
+
+ typedef NPCInfos::iterator NPCInfosIterator;
+}
+
+#endif
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index d8dfb23d..1662e2ac 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -51,7 +51,6 @@ SpriteDef::getAction(SpriteAction action) const
SpriteDef *SpriteDef::load(std::string const &animationFile, int variant)
{
- int size;
ResourceManager *resman = ResourceManager::getInstance();
std::string::size_type pos = animationFile.find('|');
@@ -59,27 +58,18 @@ SpriteDef *SpriteDef::load(std::string const &animationFile, int variant)
if (pos != std::string::npos)
palettes = animationFile.substr(pos + 1);
- char *data = (char*) resman->loadFile
- (animationFile.substr(0, pos).c_str(), size);
+ XML::Document doc(animationFile.substr(0, pos));
+ xmlNodePtr rootNode = doc.rootNode();
- if (!data && animationFile != "graphics/sprites/error.xml")
- return load("graphics/sprites/error.xml", 0);
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
-
- if (!doc)
- {
- logger->log("Error, failed to parse %s.", animationFile.c_str());
- return NULL;
- }
-
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "sprite"))
{
- logger->log("Error, failed to parse %s.", animationFile.c_str());
- xmlFreeDoc(doc);
- return NULL;
+ logger->log("Error, failed to parse %s", animationFile.c_str());
+
+ if (animationFile != "graphics/sprites/error.xml") {
+ return load("graphics/sprites/error.xml", 0);
+ } else {
+ return NULL;
+ }
}
// Get the variant
@@ -109,8 +99,6 @@ SpriteDef *SpriteDef::load(std::string const &animationFile, int variant)
}
}
- xmlFreeDoc(doc);
-
def->substituteActions();
return def;
}
@@ -277,7 +265,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
void
SpriteDef::includeSprite(xmlNodePtr includeNode)
{
- std::string filename = XML::getProperty(includeNode, "file", "");
+ const std::string filename = XML::getProperty(includeNode, "file", "");
ResourceManager *resman = ResourceManager::getInstance();
SpriteDef *sprite = resman->getSprite("graphics/sprites/" + filename);
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 65105973..c94e38f6 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -97,11 +97,10 @@ class SpriteDef : public Resource
makeSpriteAction(const std::string &action);
private:
-
/**
* Constructor.
*/
- SpriteDef(): mAction(NULL), mDirection(DIRECTION_DOWN), mLastTime(0) {}
+ SpriteDef() {}
/**
* Destructor.
@@ -159,9 +158,6 @@ class SpriteDef : public Resource
ImageSets mImageSets;
Actions mActions;
- Action *mAction;
- SpriteDirection mDirection;
- int mLastTime;
};
#endif
diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp
index e30450f0..98b474cb 100644
--- a/src/utils/xml.cpp
+++ b/src/utils/xml.cpp
@@ -22,9 +22,45 @@
*/
#include "xml.h"
+#include "../log.h"
+#include "../resources/resourcemanager.h"
namespace XML
{
+ Document::Document(const std::string &filename):
+ mDoc(NULL)
+ {
+ int size;
+ ResourceManager *resman = ResourceManager::getInstance();
+ char *data = (char*) resman->loadFile(filename.c_str(), size);
+
+ if (data) {
+ mDoc = xmlParseMemory(data, size);
+ free(data);
+
+ if (!mDoc)
+ logger->log("Error parsing XML file %s", filename.c_str());
+ } else {
+ logger->log("Error loading %s", filename.c_str());
+ }
+ }
+
+ Document::Document(const char *data, int size)
+ {
+ mDoc = xmlParseMemory(data, size);
+ }
+
+ Document::~Document()
+ {
+ if (mDoc)
+ xmlFreeDoc(mDoc);
+ }
+
+ xmlNodePtr Document::rootNode()
+ {
+ return mDoc ? xmlDocGetRootElement(mDoc) : 0;
+ }
+
int
getProperty(xmlNodePtr node, const char* name, int def)
{
diff --git a/src/utils/xml.h b/src/utils/xml.h
index ef3bad3d..5473b2ca 100644
--- a/src/utils/xml.h
+++ b/src/utils/xml.h
@@ -34,6 +34,43 @@
namespace XML
{
/**
+ * A helper class for parsing an XML document, which also cleans it up
+ * again (RAII).
+ */
+ class Document
+ {
+ public:
+ /**
+ * Constructor that attempts to load the given file through the
+ * resource manager. Logs errors.
+ */
+ Document(const std::string &filename);
+
+ /**
+ * Constructor that attempts to load an XML document from memory.
+ * Does not log errors.
+ *
+ * @param data the string to parse as XML
+ * @param size the length of the string in bytes
+ */
+ Document(const char *data, int size);
+
+ /**
+ * Destructor. Frees the loaded XML file.
+ */
+ ~Document();
+
+ /**
+ * Returns the root node of the document (or NULL if there was a
+ * load error).
+ */
+ xmlNodePtr rootNode();
+
+ private:
+ xmlDocPtr mDoc;
+ };
+
+ /**
* Gets an integer property from an xmlNodePtr.
*/
int