diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | src/particle.cpp | 30 | ||||
-rw-r--r-- | src/resources/itemdb.cpp | 22 | ||||
-rw-r--r-- | src/resources/mapreader.cpp | 14 | ||||
-rw-r--r-- | src/resources/monsterdb.cpp | 29 | ||||
-rw-r--r-- | src/resources/npcdb.cpp | 285 | ||||
-rw-r--r-- | src/resources/npcdb.h | 112 | ||||
-rw-r--r-- | src/resources/spritedef.cpp | 32 | ||||
-rw-r--r-- | src/resources/spritedef.h | 6 | ||||
-rw-r--r-- | src/utils/xml.cpp | 36 | ||||
-rw-r--r-- | src/utils/xml.h | 37 |
11 files changed, 303 insertions, 309 deletions
@@ -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 |