//=========================================== // PauseMenu::PauseMenu //=========================================== PauseMenu::PauseMenu(const XmlNode data) : Asset(internString("PauseMenu")), Entity(data.firstChild().firstChild().firstChild()), Menu(data.firstChild()) { try { AssetManager assetManager; XML_NODE_CHECK(data, PauseMenu); XmlNode node = data.nthChild(1); XML_NODE_CHECK(node, flare); XmlAttribute attr = node.firstAttribute(); XML_ATTR_CHECK(attr, ptr); long id = attr.getLong(); m_flare = boost::dynamic_pointer_cast<CSprite>(assetManager.getAssetPointer(id)); if (!m_flare) throw XmlException("Bad asset id for flare item", __FILE__, __LINE__); m_flare->addToWorld(); } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class PauseMenu; "); throw; } }
//=========================================== // 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(); }
//=========================================== // PhysicalSprite::PhysicalSprite //=========================================== explicit PhysicalSprite(const XmlNode data) : Asset(internString("PhysicalSprite")), Entity(data.firstChild().firstChild()), Sprite(data.firstChild()), T_PHYSICS(this, data.nthChild(1)) { XML_NODE_CHECK(data, PhysicalSprite); }
//=========================================== // Soil::Soil //=========================================== Soil::Soil(const XmlNode data) : Asset(internString("Soil")), Entity(data.firstChild().firstChild()), Item(data.firstChild()), Sprite(data.nthChild(1)) { try { XML_NODE_CHECK(data, Soil); } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class Soil; "); throw; } init(); }
//=========================================== // 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(); }
//=========================================== // 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; } }
//=========================================== // 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; } }
//=========================================== // EntityParallax::assignData //=========================================== void EntityParallax::assignData(const XmlNode data) { try { if (data.isNull() || data.name() != "EntityParallax") return; XmlNode node = data.firstChild(); if (!node.isNull() && node.name() == "range") { m_range = Vec2f(node.firstChild()); } } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class EntityParallax; "); throw; } init(); }
//=========================================== // 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(); } }
//=========================================== // EntityParallax::EntityParallax //=========================================== EntityParallax::EntityParallax(Entity* entity, const XmlNode data) : m_entity(entity) { try { XML_NODE_CHECK(data, EntityParallax); XmlNode node = data.firstChild(); XML_NODE_CHECK(node, range); m_range = Vec2f(node.firstChild()); } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class EntityParallax; "); throw; } init(); }
//=========================================== // Application::setMapSettings //=========================================== void Application::setMapSettings(const XmlNode data) { try { XML_NODE_CHECK(data, customSettings); XmlNode node = data.firstChild(); XML_NODE_CHECK(node, bgColour); m_bgColour = Colour(node.firstChild()); const Range& mb = m_mapLoader.getMapBoundary(); Range boundary(mb.getPosition() - Vec2f(0.1, 0.1), mb.getSize() + Vec2f(0.2, 0.2)); m_worldSpace.init(unique_ptr<Quadtree<pEntity_t> >(new Quadtree<pEntity_t>(1, boundary))); } catch (XmlException& e) { e.prepend("Error loading map settings; "); throw; } }
//=========================================== // 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)); } }
//=========================================== // PauseMenu::assignData //=========================================== void PauseMenu::assignData(const XmlNode data) { try { XML_NODE_CHECK(data, PauseMenu) XmlNode node = data.firstChild(); if (!node.isNull() && node.name() == "Menu") { Menu::assignData(node); } } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class PauseMenu; "); throw; } }
//=========================================== // 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; } }
//=========================================== // Soil::assignData //=========================================== void Soil::assignData(const XmlNode data) { try { XML_NODE_CHECK(data, Soil) 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 Soil; "); throw; } }
//=========================================== // 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; } }
//=========================================== // 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; } }
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; }
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; }
//=========================================== // 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; }
//=========================================== // 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(); }
//=========================================== // 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(); }