Пример #1
0
int main()  
{      
	XmlDocument doc("config.xml");
	// 获取connect节点 
	XmlNode connect = doc.firstNode("connect");  

	// 获取全局属性配置
	XmlNode node = connect.firstNode("property");
	printf("global property:\n");
	for (; !node.isNull(); node = node.nextSibling("property"))
	{
		printf("name: %s value: %s\n", node["name"], node["value"]);
	}

	XmlNode pool = connect.firstNode("pool");
	printf("pools:\n");
	for (; !pool.isNull(); pool = pool.nextSibling("pool"))
	{
		printf("pool:\n");
		printf("name: %s\n", pool["name"]);
		node = pool.firstNode("property");
		for (; !node.isNull(); node = node.nextSibling("property"))
		{
			printf("name: %s value: %s\n", node["name"], node["value"]);
		}
	}

	doc.save("config.xml2");

	return EXIT_SUCCESS;  
}  
Пример #2
0
//===========================================
// Sprite::assignData
//
// All tags and attributes are optional.
//===========================================
void Sprite::assignData(const XmlNode data) {
   if (data.isNull() || data.name() != "Sprite") return;

   try {
      XmlNode node = data.firstChild();

      if (!node.isNull() && node.name() == "Entity") {
         Entity::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "EntityAnimations") {
         EntityAnimations::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "EntityTransformations") {
         EntityTransformations::assignData(node);
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Sprite; ");
      throw;
   }
}
Пример #3
0
//===========================================
// Polygon::Polygon
//===========================================
Polygon::Polygon(const XmlNode data)
   : Asset(internString("Polygon")),
     m_outlineModel(Renderer::LINES),
     m_interiorModel(Renderer::TRIANGLES),
     m_renderer(Renderer::getInstance()) {

   try {
      XML_NODE_CHECK(data, Polygon);

      clear();

      XmlNode node = data.firstChild();
      while (!node.isNull() && node.name() == "Vec2f") {
         boost::shared_ptr<Vec2f> vert(new Vec2f(node));
         m_verts.push_back(vert);

         ++m_nVerts;
         node = node.nextSibling();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Polygon; ");
      throw;
   }

   restructure();
   updateModels();
}
Пример #4
0
//===========================================
// CreditsMenu::CreditsMenu
//===========================================
CreditsMenu::CreditsMenu(const XmlNode data)
   : Asset(internString("CreditsMenu")),
     Entity(data.firstChild().firstChild().firstChild()),
     Menu(data.firstChild()) {

   try {
      AssetManager assetManager;

      XML_NODE_CHECK(data, CreditsMenu);

      XmlNode node = data.nthChild(1);
      XML_NODE_CHECK(node, font);

      XmlAttribute attr = node.firstAttribute();
      XML_ATTR_CHECK(attr, ptr);

      long id = attr.getLong();
      m_font = boost::dynamic_pointer_cast<Dodge::Font>(assetManager.getAssetPointer(id));

      if (!m_font)
         throw XmlException("Bad font asset id", __FILE__, __LINE__);

      node = node.nextSibling();
      XML_NODE_CHECK(node, fadeInTime);
      m_fadeInTime = node.getFloat();
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class CreditsMenu; ");
      throw;
   }

   init();
}
Пример #5
0
//===========================================
// Animation::Animation
//===========================================
Animation::Animation(const XmlNode data)
   : Asset(internString("Animation")),
     m_state(STOPPED),
     m_frameReady(false) {

   try {
      XML_NODE_CHECK(data, Animation);

      XmlAttribute attr = data.firstAttribute();
      XML_ATTR_CHECK(attr, name);
      m_name = internString(attr.getString());

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, duration);
      m_duration = attr.getFloat();

      uint_t f = 0;
      XmlNode node = data.firstChild();
      while (!node.isNull() && node.name() == "AnimFrame") {
         AnimFrame frame(node);
         frame.number = f;

         m_frames.push_back(frame);

         ++f;
         node = node.nextSibling();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Animation; ");
      throw;
   }
}
Пример #6
0
//===========================================
// GameSettings::parseGameModes
//===========================================
void GameSettings::parseGameModes(XmlNode data) {
   XmlNode node = data.firstChild();

   while (!node.isNull() && node.name() == "GameOptions") {
      difficultyModes.push_back(pGameOptions_t(new GameOptions(node)));
      node = node.nextSibling();
   }
}
Пример #7
0
//===========================================
// XmlNode::nthChild
//===========================================
XmlNode XmlNode::nthChild(uint_t n) const {
    if (isNull()) throw XmlException("Node is NULL", __FILE__, __LINE__);

    XmlNode c = firstChild();
    for (uint_t i = 0; i < n; ++i) c = c.nextSibling();

    return c;
}
Пример #8
0
      //===========================================
      // PhysicalSprite::assignData
      //===========================================
      virtual void assignData(const XmlNode data) {
         if (data.isNull() || data.name() != "PhysicalSprite") return;

         XmlNode node = data.firstChild();

         if (!node.isNull() && node.name() == "Sprite") {
            Sprite::assignData(node);
            node = node.nextSibling();
         }

         if (!node.isNull() && node.name() == "EntityPhysics") {
            T_PHYSICS::assignData(data.nthChild(1));
         }
      }
Пример #9
0
//===========================================
// TextEntity::TextEntity
//===========================================
TextEntity::TextEntity(const XmlNode data)
   : Asset(internString("TextEntity")),
     Entity(data.firstChild()),
     m_renderer(Renderer::getInstance()),
     m_model(Renderer::TRIANGLES) {

   try {
      XML_NODE_CHECK(data, TextEntity);

      XmlNode node = data.nthChild(1);
      XML_NODE_CHECK(node, font);

      XmlAttribute attr = node.firstAttribute();
      XML_ATTR_CHECK(attr, ptr);
      long fontId = attr.getLong();

      AssetManager assetManager;
      pFont_t font = boost::dynamic_pointer_cast<Dodge::Font>(assetManager.getAssetPointer(fontId));

      if (!font)
         throw XmlException("Bad asset id", __FILE__, __LINE__);

      m_font = font;

      node = node.nextSibling();
      XML_NODE_CHECK(node, textSize);
      m_size = Vec2f(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, text);
      setText(node.getString());
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class TextEntity; ");
      throw;
   }
}
Пример #10
0
//===========================================
// TextEntity::assignData
//===========================================
void TextEntity::assignData(const XmlNode data) {
   try {
      if (data.isNull() || data.name() != "TextEntity") return;

      XmlNode node = data.nthChild(1);
      if (!node.isNull() && node.name() == "font") {

         XmlAttribute attr = node.firstAttribute();
         if (!attr.isNull() && attr.name() == "ptr") {
            long fontId = attr.getLong();

            AssetManager assetManager;
            pFont_t font = boost::dynamic_pointer_cast<Dodge::Font>(assetManager.getAssetPointer(fontId));

            if (!font)
               throw XmlException("Bad asset id", __FILE__, __LINE__);

            m_font = font;
         }

         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "textSize") {
         m_size = Vec2f(node.firstChild());
         node = node.nextSibling();
      }

      XML_NODE_CHECK(node, text);
      setText(node.getString());
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class TextEntity; ");
      throw;
   }
}
Пример #11
0
//===========================================
// Counter::assignData
//===========================================
void Counter::assignData(const Dodge::XmlNode data) {
   try {
      XML_NODE_CHECK(data, Counter)

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "CTextEntity") {
         CTextEntity::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "value") {
         m_value = node.getInt();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Counter; ");
      throw;
   }
}
Пример #12
0
//===========================================
// Throwable::assignData
//===========================================
void Throwable::assignData(const Dodge::XmlNode data) {
   try {
      XML_NODE_CHECK(data, Throwable)

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "Item") {
         Item::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "Sprite") {
         Sprite::assignData(node);
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Throwable; ");
      throw;
   }
}
Пример #13
0
//===========================================
// GameSettings::GameSettings
//===========================================
GameSettings::GameSettings(const XmlNode data)
   : Asset(internString("GameSettings")) {

   try {
      XML_NODE_CHECK(data, GameSettings);

      XmlNode node = data.firstChild();
      XML_NODE_CHECK(node, soundTrack);
      musicTrack = gGetWorkingDir() + "/" + node.getString();

      node = node.nextSibling();
      XML_NODE_CHECK(node, bgColour);
      bgColour = Colour(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, minefieldBoundary);
      minefieldBoundary = Range(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, tileSize);
      tileSize = Vec2f(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, startMenuId);
      startMenuId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, pauseMenuId);
      pauseMenuId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, gameOptionsMenuId);
      gameOptionsMenuId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, playerId);
      playerId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, exitId);
      exitId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, numericTileProtoId);
      numericTileProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, mineProtoId);
      mineProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, soilProtoId);
      soilProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, coinProtoId);
      coinProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, nuggetProtoId);
      nuggetProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, throwableProtoId);
      throwableProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, zombieProtoId);
      zombieProtoId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, timeCounterId);
      timeCounterId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, scoreCounterId);
      scoreCounterId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, txtRestartId);
      txtRestartId = node.getLong();

      node = node.nextSibling();
      XML_NODE_CHECK(node, gameModes);
      parseGameModes(node);
   }
   catch (XmlException& e) {
      e.prepend("Error loading game settings; ");
      throw;
   }
}
Пример #14
0
//===========================================
// Entity::assignData
//===========================================
void Entity::assignData(const XmlNode data) {
   if (data.isNull() || data.name() != "Entity") return;

   AssetManager assetManager;
   ShapeFactory shapeFactory;

   try {
      bool silent = isSilent();
      setSilent(true);

      XmlAttribute attr = data.firstAttribute();
      if (!attr.isNull() && attr.name() == "type") {
         m_type = internString(attr.getString());
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "name") {
         m_name = internString(attr.getString());
         attr = attr.nextAttribute();
      }

      Vec2f transl = m_transl;

      if (!attr.isNull() && attr.name() == "x") {
         transl.x = attr.getFloat();
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "y") {
         transl.y = attr.getFloat();
         attr = attr.nextAttribute();
      }

      setTranslation(transl);

      if (!attr.isNull() && attr.name() == "z") {
         m_z = attr.getFloat();

         // So that no Z values are 'exactly' equal
         m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX);

         attr = attr.nextAttribute();
      }

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "shape") {
         m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild()));
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "scale") {
         setScale(Vec2f(node.firstChild()));
         node = node.nextSibling();
      }

      if (!attr.isNull() && attr.name() == "rot") {
         setRotation(attr.getFloat());
      }

      if (!node.isNull() && node.name() == "fillColour") {
         m_fillColour = Colour(node.firstChild());
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "lineColour") {
         m_lineColour = Colour(node.firstChild());
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "lineWidth") {
         m_lineWidth = node.getInt();
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "children") {
         XmlNode node_ = node.firstChild();

         while (!node_.isNull() && node_.name() == "child") {
            XmlAttribute attr = node_.firstAttribute();

            if (!attr.isNull() && attr.name() == "ptr") {
               long id = attr.getLong();

               pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id));

               if (!child)
                  throw XmlException("Bad entity asset id", __FILE__, __LINE__);

               addChild(child);
            }

            node_ = node_.nextSibling();
         }
      }

      setSilent(silent);
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Entity; ");
      throw;
   }

   recomputeBoundary();
}
Пример #15
0
bool Test::testCase1() const {
    bool pass = true;
    bool b = false;

    if (m_verbose) cout << "\tCASE 1: Parsing good document and checking tree\n";
    try {
        XmlDocument doc;
        doc.parse("./test1.xml");

        /*
        <?xml version="1.0" encoding="utf-8"?>
        <element1 a="1" b="2">
           <element2 c="3" d="true"/>
           <element3>Hello World!</element3>
           <element4 a="123">
              <element5 yes="no">
                 <element6 str="This is a string" num="4.5"/>
                 <element7>99.8</element7>
              </element5>
           </element4>
        </element1>
        */

        XmlNode node = doc.firstNode();
        node = node.nextSibling();

        SUBCASE_CHECK_CRITICAL(!node.isNull());
        SUBCASE_CHECK(node.name().compare("element1") == 0, pass, b);

        XmlAttribute attr = node.firstAttribute();
        SUBCASE_CHECK_CRITICAL(!attr.isNull());
        SUBCASE_CHECK(attr.name().compare("a") == 0, pass, b);
        SUBCASE_CHECK(attr.getInt() == 1, pass, b);

        attr = attr.nextAttribute();
        SUBCASE_CHECK_CRITICAL(!attr.isNull());
        SUBCASE_CHECK(attr.name().compare("b") == 0, pass, b);
        SUBCASE_CHECK(attr.getInt() == 2, pass, b);

        {
            XmlNode node_ = node.firstChild();
            SUBCASE_CHECK_CRITICAL(!node_.isNull());
            SUBCASE_CHECK(node_.name().compare("element2") == 0, pass, b);

            XmlAttribute attr = node_.firstAttribute();
            SUBCASE_CHECK_CRITICAL(!attr.isNull());
            SUBCASE_CHECK(attr.name().compare("c") == 0, pass, b);
            SUBCASE_CHECK(attr.getInt() == 3, pass, b);

            attr = attr.nextAttribute();
            SUBCASE_CHECK_CRITICAL(!attr.isNull());
            SUBCASE_CHECK(attr.name().compare("d") == 0, pass, b);
            SUBCASE_CHECK(attr.getString().compare("true") == 0, pass, b);

            node_ = node_.nextSibling();
            SUBCASE_CHECK_CRITICAL(!node_.isNull());
            SUBCASE_CHECK(node_.name().compare("element3") == 0, pass, b);
            SUBCASE_CHECK(node_.getString().compare("Hello World!") == 0, pass, b);

            node_ = node_.nextSibling();
            SUBCASE_CHECK_CRITICAL(!node_.isNull());
            SUBCASE_CHECK(node_.name().compare("element4") == 0, pass, b);

            attr = node_.firstAttribute();
            SUBCASE_CHECK_CRITICAL(!attr.isNull());
            SUBCASE_CHECK(attr.name().compare("a") == 0, pass, b);
            SUBCASE_CHECK(attr.getInt() == 123, pass, b);

            {
                XmlNode node__ = node_.firstChild();
                SUBCASE_CHECK_CRITICAL(!node__.isNull());
                SUBCASE_CHECK(node__.name().compare("element5") == 0, pass, b);

                XmlAttribute attr = node__.firstAttribute();
                SUBCASE_CHECK_CRITICAL(!attr.isNull());
                SUBCASE_CHECK(attr.name().compare("yes") == 0, pass, b);
                SUBCASE_CHECK(attr.getString().compare("no") == 0, pass, b);

                {
                    XmlNode node___ = node__.firstChild();
                    SUBCASE_CHECK_CRITICAL(!node___.isNull());
                    SUBCASE_CHECK(node___.name().compare("element6") == 0, pass, b);

                    XmlAttribute attr = node___.firstAttribute();
                    SUBCASE_CHECK_CRITICAL(!attr.isNull());
                    SUBCASE_CHECK(attr.name().compare("str") == 0, pass, b);
                    SUBCASE_CHECK(attr.getString().compare("This is a string") == 0, pass, b);

                    attr = attr.nextAttribute();
                    SUBCASE_CHECK_CRITICAL(!attr.isNull());
                    SUBCASE_CHECK(attr.name().compare("num") == 0, pass, b);
                    SUBCASE_CHECK(attr.getFloat() == 4.5, pass, b);
                }
            }
        }
    }
    catch (XmlException& e) {
        pass = false;
        if (m_verbose) {
            cout << e.what() << "\n";
        }
    }

    if (m_verbose) cout << (pass ? "\tPASS\n" : "\tFAIL\n");
    return pass;
}
Пример #16
0
bool Test::testCase4() const {
    if (m_verbose) cout << "\tCase 4: Move node between documents (2)\n";

    /*
    <nodeA>
       <nodeB a="1" b="two" c="3.4"/>
       <nodeC d="true">
          <nodeD>
             Hello World!
          </nodeD>
          <nodeE>
             Goodbye World!
          </nodeE>
       </nodeC>
    </nodeA>
    */

    XmlDocument doc2;

    try {
        XmlDocument doc1;
        doc1.parse("./test4.xml");

        XmlNode node = doc1.firstNode();
        XML_NODE_CHECK(node, nodeA);

        node = node.firstChild();
        XML_NODE_CHECK(node, nodeB);

        node = node.nextSibling();
        XML_NODE_CHECK(node, nodeC);

        XmlNode node_ = doc2.addNode("MyNode");
        node_.addNode(node);
    } // doc1 destroyed here
    catch (XmlException& e) {
        if (m_verbose) {
            cout << e.what() << "\n";
        }
        return false;
    }

    bool pass = true;
    bool b = false;

    XmlNode node = doc2.firstNode();
    SUBCASE_CHECK_CRITICAL(!node.isNull());
    SUBCASE_CHECK(node.name().compare("MyNode") == 0, pass, b);

    XmlNode node_ = node.firstChild();
    SUBCASE_CHECK_CRITICAL(!node_.isNull());
    SUBCASE_CHECK(node_.name().compare("nodeC") == 0, pass, b);

    XmlAttribute attr = node_.firstAttribute();
    SUBCASE_CHECK_CRITICAL(!attr.isNull());
    SUBCASE_CHECK(attr.name().compare("d") == 0, pass, b);
    SUBCASE_CHECK(attr.getString().compare("true") == 0, pass, b);

    XmlNode node__ = node_.firstChild();
    SUBCASE_CHECK_CRITICAL(!node__.isNull());
    SUBCASE_CHECK(node__.name().compare("nodeD") == 0, pass, b);

    node__ = node__.nextSibling();
    SUBCASE_CHECK_CRITICAL(!node__.isNull());
    SUBCASE_CHECK(node__.name().compare("nodeE") == 0, pass, b);

    if (m_verbose) cout << (pass ? "\tPASS\n" : "\tFAIL\n");
    return pass;
}
Пример #17
0
//===========================================
// Application::constructAsset
//===========================================
pAsset_t Application::constructAsset(const XmlNode data) {
   long proto = -1;
   bool addToWorld = false;

   XmlAttribute attr = data.firstAttribute();
   attr = attr.nextAttribute();

   if (!attr.isNull() && attr.name() == "proto") {
      proto = attr.getLong();
      attr = attr.nextAttribute();
   }

   if (!attr.isNull() && attr.name() == "addToWorld") {
      addToWorld = attr.getBool();
   }

   XmlNode node = data.firstChild();


   // Construct non-Entity assets

   if (node.name() == "Texture") return pAsset_t(new Texture(node));
   // ...


   // Construct Entities

   pEntity_t entity;

   // Does the XML description reference a prototype?
   if (proto != -1) {
      entity = pEntity_t(dynamic_cast<Entity*>(m_assetManager.cloneAsset(proto)));

      if (!entity)
         throw Exception("Prototype not found", __FILE__, __LINE__);

      // If the prototype has an Item object (aux data), set it to point at the entity.
      IAuxData* p = entity->getAuxDataPtr();
      if (p) {
         Item* item = dynamic_cast<Item*>(p);
         assert(item);

         item->setEntity(entity.get());
      }

      // If this XML node contains the entity along with an Item
      bool hasAuxData = false;
      if (node.name() == "ExtEntity") {
         node = node.firstChild();
         hasAuxData = true;
      }

      // The Entity node comes before the Item node
      entity->assignData(node);

      // Now we construct the Item
      if (hasAuxData) {
         node = node.nextSibling();

         if (node.name() != "Item")
            throw Exception("Expected Item node", __FILE__, __LINE__);

         Item* item = new Item(node);
         item->setEntity(entity.get());

         entity->attachAuxData(unique_ptr<Item>(item));
      }
   }
   // If XML description does not reference a prototype
   else {
      bool hasAuxData = false;
      if (node.name() == "ExtEntity") {
         node = node.firstChild();
         hasAuxData = true;
      }

      if (node.name() == "Player") entity = pEntity_t(new Player(node));
      if (node.name() == "Soil") entity = pEntity_t(new Soil(node));
      if (node.name() == "ParallaxSprite") entity = pEntity_t(new ParallaxSprite(node));
      if (node.name() == "Entity") entity = pEntity_t(new Entity(node));
      if (node.name() == "Sprite") entity = pEntity_t(new Sprite(node));
      if (node.name() == "PhysicalEntity") entity = pEntity_t(new PhysicalEntity<Box2dPhysics>(node));
      if (node.name() == "PhysicalSprite") entity = pEntity_t(new PhysicalSprite<Box2dPhysics>(node));

      if (!entity) {
         Exception ex("Unrecognised entity type '", __FILE__, __LINE__);
         ex.append(node.name());
         ex.append("'");
         throw ex;
      }

      if (hasAuxData) {
         node = node.nextSibling();

         if (node.name() != "Item")
            throw Exception("Expected Item node", __FILE__, __LINE__);

         Item* item = new Item(node);
         item->setEntity(entity.get());

         entity->attachAuxData(unique_ptr<Item>(item));
      }
   }

   if (addToWorld) {
      entity->addToWorld();
      m_worldSpace.insertAndTrackEntity(entity);
      m_entities[entity->getName()] = entity;
   }

   return entity;
}
Пример #18
0
//===========================================
// Entity::Entity
//===========================================
Entity::Entity(const XmlNode data)
   : Asset(internString("Entity")),
     m_silent(false),
     m_parent(NULL) {

   AssetManager assetManager;
   ShapeFactory shapeFactory;

   try {
      setSilent(true);

      XML_NODE_CHECK(data, Entity);

      XmlAttribute attr = data.firstAttribute();
      XML_ATTR_CHECK(attr, type);
      m_type = internString(attr.getString());

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, name);
      m_name = internString(attr.getString());

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, x);
      m_transl.x = attr.getFloat();

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, y);
      m_transl.y = attr.getFloat();

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, z);
      m_z = attr.getFloat();

      // So that no Z values are 'exactly' equal
      m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX);

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, rot);
      float32_t rot = attr.getFloat();

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "shape") {
         m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild()));
         node = node.nextSibling();
      }

      m_rot = 0;
      setRotation(rot);

      XML_NODE_CHECK(node, scale);
      m_scale = Vec2f(1.f, 1.f);
      setScale(Vec2f(node.firstChild()));

      node = node.nextSibling();
      XML_NODE_CHECK(node, fillColour);
      m_fillColour = Colour(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, lineColour);
      m_lineColour = Colour(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, lineWidth);
      m_lineWidth = node.getInt();

      node = node.nextSibling();
      XML_NODE_CHECK(node, children);
      XmlNode node_ = node.firstChild();
      while (!node_.isNull() && node_.name() == "child") {
         XmlAttribute attr = node_.firstAttribute();

         if (!attr.isNull() && attr.name() == "ptr") {
            long id = attr.getLong();

            pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id));

            if (!child)
               throw XmlException("Bad entity asset id", __FILE__, __LINE__);

            addChild(child);
         }

         node_ = node_.nextSibling();
      }

      setSilent(false);

      ++m_count;
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Entity; ");
      throw;
   }

   recomputeBoundary();
}