New XML System, first pass.
This commit is contained in:
2
lib/SDL
2
lib/SDL
Submodule lib/SDL updated: c065a9b128...4a53dc5b8d
Submodule lib/freetype updated: e4586d960f...dec2743e6a
Submodule lib/openal-soft updated: 2da9d168b6...05f9ce8b97
@ -122,6 +122,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
|
|||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
lines.clear();
|
lines.clear();
|
||||||
|
textureMap.clear();
|
||||||
|
|
||||||
// Determine font dimensions.
|
// Determine font dimensions.
|
||||||
auto itText = newTexts.begin();
|
auto itText = newTexts.begin();
|
||||||
|
@ -29,33 +29,33 @@ void UIRichTextLabel::onStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::function<void(Xml*)> parseChildren = [&](Xml *node) {
|
std::function<void(Xml*)> parseChildren = [&](Xml *node) {
|
||||||
if(node->children.empty()) {
|
auto itChildren = node->childNodes.begin();
|
||||||
if(node->node == "root") return;
|
while(itChildren != node->childNodes.end()) {
|
||||||
struct UILabelText text;
|
auto child = *itChildren;
|
||||||
text.style = current;
|
if(child.nodeType == XML_NODE_TYPE_TEXT) {
|
||||||
text.text = node->value;
|
struct UILabelText text;
|
||||||
bufferTexts.push_back(text);
|
text.style = current;
|
||||||
} else {
|
text.text = child.value;
|
||||||
auto itNode = node->children.begin();
|
bufferTexts.push_back(text);
|
||||||
while(itNode != node->children.end()) {
|
} else if(child.nodeType == XML_NODE_TYPE_ELEMENT) {
|
||||||
auto child = *itNode;
|
auto node = child.child;
|
||||||
assertTrue(child->node == "font");
|
assertTrue(node->node == "font");
|
||||||
|
|
||||||
struct UILabelStyle style;
|
struct UILabelStyle style;
|
||||||
if(child->attributes.contains("font")) {
|
if(node->attributes.contains("font")) {
|
||||||
style.font = this->getGame()->assetManager.get<TrueTypeAsset>(child->attributes["font"]);
|
style.font = this->getGame()->assetManager.get<TrueTypeAsset>(node->attributes["font"]);
|
||||||
} else {
|
} else {
|
||||||
style.font = current.font;
|
style.font = current.font;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(child->attributes.contains("size")) {
|
if(node->attributes.contains("size")) {
|
||||||
style.size = std::stoi(child->attributes["size"]);
|
style.size = std::stoi(node->attributes["size"]);
|
||||||
} else {
|
} else {
|
||||||
style.size = current.size;
|
style.size = current.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(child->attributes.contains("style")) {
|
if(node->attributes.contains("style")) {
|
||||||
std::string s = child->attributes["style"];
|
std::string s = node->attributes["style"];
|
||||||
style.style = 0;
|
style.style = 0;
|
||||||
if(s.find("bold") != std::string::npos) style.style |= TRUE_TYPE_VARIANT_BOLD;
|
if(s.find("bold") != std::string::npos) style.style |= TRUE_TYPE_VARIANT_BOLD;
|
||||||
if(s.find("italic") != std::string::npos) style.style |= TRUE_TYPE_VARIANT_ITALICS;
|
if(s.find("italic") != std::string::npos) style.style |= TRUE_TYPE_VARIANT_ITALICS;
|
||||||
@ -63,25 +63,23 @@ void UIRichTextLabel::onStart() {
|
|||||||
style.style = current.style;
|
style.style = current.style;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(child->attributes.contains("color")) {
|
if(node->attributes.contains("color")) {
|
||||||
style.color = Color::fromString(child->attributes["color"]);
|
style.color = Color::fromString(node->attributes["color"]);
|
||||||
} else {
|
} else {
|
||||||
style.color = current.color;
|
style.color = current.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
styleStack.push_back(style);
|
styleStack.push_back(style);
|
||||||
current = style;
|
current = style;
|
||||||
|
parseChildren(node);
|
||||||
parseChildren(child);
|
|
||||||
|
|
||||||
styleStack.pop_back();
|
styleStack.pop_back();
|
||||||
current = styleStack.back();
|
current = styleStack.back();
|
||||||
++itNode;
|
|
||||||
}
|
}
|
||||||
|
++itChildren;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto root = Xml::load("<root>" + ((std::string)this->richText) + "</root>");
|
auto root = Xml::load("<root><font font=\"font_main\">" + ((std::string)this->richText) + "</font></root>");
|
||||||
parseChildren(&root);
|
parseChildren(&root);
|
||||||
this->rebufferQuads(bufferTexts);
|
this->rebufferQuads(bufferTexts);
|
||||||
}, this->richText)();
|
}, this->richText)();
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "prefabs/SimpleSpinningCubePrefab.hpp"
|
#include "prefabs/SimpleSpinningCubePrefab.hpp"
|
||||||
#include "scene/components/display/Camera.hpp"
|
#include "scene/components/display/Camera.hpp"
|
||||||
#include "scene/components/ui/text/UIRichTextLabel.hpp"
|
#include "scene/components/ui/text/UIRichTextLabel.hpp"
|
||||||
#include "prefabs/VNTextbox.hpp"
|
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class HelloWorldScene : public Scene {
|
class HelloWorldScene : public Scene {
|
||||||
@ -25,28 +24,12 @@ namespace Dawn {
|
|||||||
auto canvasItem = this->createSceneItem();
|
auto canvasItem = this->createSceneItem();
|
||||||
auto canvas = canvasItem->addComponent<UICanvas>();
|
auto canvas = canvasItem->addComponent<UICanvas>();
|
||||||
canvas->camera = camera;
|
canvas->camera = camera;
|
||||||
|
|
||||||
auto textboxItem = this->createSceneItem();
|
|
||||||
auto textbox = textboxItem->addComponent<UIRichTextLabel>();
|
|
||||||
textbox->alignX = UI_COMPONENT_ALIGN_STRETCH;
|
|
||||||
textbox->alignY = UI_COMPONENT_ALIGN_STRETCH;
|
|
||||||
textbox->alignment = glm::vec4(0, 0, 0, 0);
|
|
||||||
textbox->richText = std::string(
|
|
||||||
"<font font=\"font_main\" size=\"64\" style=\"italics\" color=\"MAGENTA\">"
|
|
||||||
"Hello World"
|
|
||||||
"</font>"
|
|
||||||
"<font font=\"font_main\" size=\"64\" style=\"bold\" color=\"WHITE\">"
|
|
||||||
"BBBBBB"
|
|
||||||
"</font>"
|
|
||||||
);
|
|
||||||
textbox->transform->setParent(canvas->transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Asset*> getRequiredAssets() override {
|
std::vector<Asset*> getRequiredAssets() override {
|
||||||
auto assMan = &this->game->assetManager;
|
auto assMan = &this->game->assetManager;
|
||||||
std::vector<Asset*> assets;
|
std::vector<Asset*> assets;
|
||||||
vectorAppend(&assets, SimpleSpinningCubePrefab::getRequiredAssets(assMan));
|
vectorAppend(&assets, SimpleSpinningCubePrefab::getRequiredAssets(assMan));
|
||||||
assets.push_back(assMan->get<TrueTypeAsset>("font_main"));
|
|
||||||
return assets;
|
return assets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,12 @@
|
|||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
|
XmlNode::XmlNode() {
|
||||||
|
this->child = nullptr;
|
||||||
|
this->value.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool_t Xml::isWhitespace(char_t c) {
|
bool_t Xml::isWhitespace(char_t c) {
|
||||||
return c == ' ' || c == '\r' || c == '\n' || c == '\t';
|
return c == ' ' || c == '\r' || c == '\n' || c == '\t';
|
||||||
}
|
}
|
||||||
@ -26,9 +32,8 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
bool_t insideTag = false;
|
bool_t insideTag = false;
|
||||||
std::string buffer = "";
|
std::string buffer = "";
|
||||||
std::string attrKey = "";
|
std::string attrKey = "";
|
||||||
std::string bufferWhitespaces;
|
|
||||||
bool_t valueIsInWhitespace = false;
|
|
||||||
size_t i = *j;
|
size_t i = *j;
|
||||||
|
struct XmlNode childNode;
|
||||||
|
|
||||||
while(c = data[i++]) {
|
while(c = data[i++]) {
|
||||||
if(insideTag) {
|
if(insideTag) {
|
||||||
@ -39,26 +44,21 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
case XML_PARSE_STATE_DOING_NOTHING:
|
case XML_PARSE_STATE_DOING_NOTHING:
|
||||||
if(c == '>') continue;
|
if(c == '>') continue;
|
||||||
if(c == '<') {
|
if(c == '<') {
|
||||||
|
// Parsing comment?
|
||||||
if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') {
|
if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') {
|
||||||
doingBeforeComment = doing;
|
doingBeforeComment = doing;
|
||||||
doing = XML_PARSE_STATE_PARSING_COMMENT;
|
doing = XML_PARSE_STATE_PARSING_COMMENT;
|
||||||
i += 3;
|
i += 3;
|
||||||
|
} else if(data[i] == '!' && !insideTag) {
|
||||||
|
// Likely <!DOCTYPE ...>
|
||||||
|
while((c = data[i++]) != '>') {
|
||||||
|
// Nothing needs doing here right now, in future may support doctype
|
||||||
|
}
|
||||||
|
continue;
|
||||||
} else if(insideTag) {
|
} else if(insideTag) {
|
||||||
if(data[i] == '/') {
|
if(data[i] == '/') {
|
||||||
i -= 1;
|
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
||||||
doing = XML_PARSE_STATE_PARSING_CHILD;
|
continue;
|
||||||
} else {
|
|
||||||
i -= 1;
|
|
||||||
auto child = new Xml();
|
|
||||||
Xml::load(child, data, &i);
|
|
||||||
xml->children.push_back(child);
|
|
||||||
doing = XML_PARSE_STATE_PARSING_CHILD;
|
|
||||||
|
|
||||||
|
|
||||||
// Remove last char since we kinda already parsed it.
|
|
||||||
xml->innerXml += child->outerXml;
|
|
||||||
xml->outerXml = xml->outerXml.substr(0, xml->outerXml.size()-1);
|
|
||||||
xml->outerXml += child->outerXml;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doing = XML_PARSE_STATE_PARSING_TAG_NAME;
|
doing = XML_PARSE_STATE_PARSING_TAG_NAME;
|
||||||
@ -69,8 +69,8 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml->innerXml += c;
|
if(insideTag) xml->innerXml += c;
|
||||||
if(Xml::isWhitespace(c)) continue;
|
if(Xml::isWhitespace(c)) continue;// NEEDS TO GO?
|
||||||
doing = XML_PARSE_STATE_PARSING_VALUE;
|
doing = XML_PARSE_STATE_PARSING_VALUE;
|
||||||
buffer += c;
|
buffer += c;
|
||||||
break;
|
break;
|
||||||
@ -86,7 +86,7 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
insideTag = false;
|
insideTag = false;
|
||||||
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
||||||
} else {
|
} else {
|
||||||
doing = c == '>' ? XML_PARSE_STATE_DOING_NOTHING : XML_PARSE_STATE_LOOKING_FOR_ATTRIBUTE;
|
doing = c == '>' ? XML_PARSE_STATE_PARSING_VALUE : XML_PARSE_STATE_LOOKING_FOR_ATTRIBUTE;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
// Look until we hit either the end of a tag, or the attribute itself
|
// Look until we hit either the end of a tag, or the attribute itself
|
||||||
if(Xml::isWhitespace(c) || c == '>' || c == '/' || c == '=') {
|
if(Xml::isWhitespace(c) || c == '>' || c == '/' || c == '=') {
|
||||||
if(c == '>' || c == '/') {
|
if(c == '>' || c == '/') {
|
||||||
doing = XML_PARSE_STATE_DOING_NOTHING;
|
doing = XML_PARSE_STATE_PARSING_VALUE;
|
||||||
if(c == '/') {
|
if(c == '/') {
|
||||||
level--;
|
level--;
|
||||||
insideTag = false;
|
insideTag = false;
|
||||||
@ -149,116 +149,86 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
case XML_PARSE_STATE_PARSING_VALUE:
|
case XML_PARSE_STATE_PARSING_VALUE:
|
||||||
// Keep parsing child until we find a < for an opening/closing tag.
|
// Keep parsing child until we find a < for an opening/closing tag.
|
||||||
if(c == '<' && !(data[i] == '<' || data[i-2] == '<')) {
|
if(c == '<' && !(data[i] == '<' || data[i-2] == '<')) {
|
||||||
|
if(buffer.size() > 0) {
|
||||||
|
childNode.nodeType = XML_NODE_TYPE_TEXT;
|
||||||
|
childNode.value = buffer;
|
||||||
|
xml->childNodes.push_back(childNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are we parsing the close tag, or parsing a child?
|
||||||
if(data[i] == '/') {
|
if(data[i] == '/') {
|
||||||
// In HTML Spec there could be a child here but not in XML spec.
|
|
||||||
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
||||||
xml->value = buffer;
|
xml->textContent = buffer;
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
valueIsInWhitespace = false;
|
|
||||||
bufferWhitespaces.clear();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') {
|
||||||
|
|
||||||
std::cout << "Detected unsupported use of a child within a node value, e.g. <div>Hello <b>world</b> how are you?</div>" << std::endl;
|
|
||||||
throw "Test";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
xml->innerXml += c;
|
|
||||||
|
|
||||||
if(Xml::isWhitespace(c)) {
|
|
||||||
if(!valueIsInWhitespace) {
|
|
||||||
bufferWhitespaces.clear();
|
|
||||||
bufferWhitespaces += c;
|
|
||||||
valueIsInWhitespace = true;
|
|
||||||
} else {
|
|
||||||
if(c != ' ') bufferWhitespaces += c;
|
|
||||||
}
|
|
||||||
// TODO: I can maybe consider indentation here
|
|
||||||
} else {
|
|
||||||
if(valueIsInWhitespace) {
|
|
||||||
buffer += bufferWhitespaces;
|
|
||||||
valueIsInWhitespace = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == '&') {
|
|
||||||
// Handle special characters. First read ahead to nearest semicolon OR
|
|
||||||
// nearest closing tag.
|
|
||||||
std::string sc;
|
|
||||||
while(c = data[i++]) {
|
|
||||||
xml->innerXml += c;
|
|
||||||
if(c == ';') break;
|
|
||||||
if(c == '<') assertUnreachable();//Invalid XML
|
|
||||||
sc += c;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valueIsInWhitespace) {
|
|
||||||
buffer += bufferWhitespaces;
|
|
||||||
valueIsInWhitespace = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sc == "lt") {
|
|
||||||
buffer += '<';
|
|
||||||
} else if(sc == "gt") {
|
|
||||||
buffer += '>';
|
|
||||||
} else if(sc == "amp") {
|
|
||||||
buffer += '&';
|
|
||||||
} else if(sc == "apos") {
|
|
||||||
buffer += '\'';
|
|
||||||
} else if(sc == "quot") {
|
|
||||||
buffer += '"';
|
|
||||||
} else if(sc == "nbsp") {
|
|
||||||
buffer += ' ';
|
|
||||||
} else {
|
|
||||||
// Try parse as integer
|
|
||||||
if(sc.size() > 1 && sc[0] == '#') {
|
|
||||||
int code = std::stoi(sc.substr(1));
|
|
||||||
buffer += (char)code;
|
|
||||||
} else {
|
|
||||||
std::cout << "Unknown Special character: " << sc << std::endl;
|
|
||||||
assertUnreachable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buffer += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XML_PARSE_STATE_PARSING_CHILD:
|
|
||||||
if(c == '<') {
|
|
||||||
// Read ahead and confirm this is a close or not
|
|
||||||
if(data[i] == '/') {
|
|
||||||
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') {
|
|
||||||
doingBeforeComment = doing;
|
doingBeforeComment = doing;
|
||||||
doing = XML_PARSE_STATE_PARSING_COMMENT;
|
doing = XML_PARSE_STATE_PARSING_COMMENT;
|
||||||
i += 3;
|
i += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Likely another child.
|
// Parsing child
|
||||||
auto child = new Xml();
|
|
||||||
i -= 1;
|
i -= 1;
|
||||||
|
|
||||||
|
// @deprecated
|
||||||
|
auto child = new Xml();
|
||||||
Xml::load(child, data, &i);
|
Xml::load(child, data, &i);
|
||||||
xml->children.push_back(child);
|
xml->children.push_back(child);
|
||||||
|
|
||||||
|
childNode = XmlNode();
|
||||||
|
childNode.nodeType = XML_NODE_TYPE_ELEMENT;
|
||||||
|
childNode.child = child;
|
||||||
|
xml->childNodes.push_back(childNode);
|
||||||
|
|
||||||
|
// Remove last char since we kinda already parsed it.
|
||||||
xml->innerXml += child->outerXml;
|
xml->innerXml += child->outerXml;
|
||||||
xml->outerXml = xml->outerXml.substr(0, xml->outerXml.size()-1);
|
xml->outerXml = xml->outerXml.substr(0, xml->outerXml.size()-1);
|
||||||
xml->outerXml += child->outerXml;
|
xml->outerXml += child->outerXml;
|
||||||
}
|
|
||||||
|
|
||||||
if(Xml::isWhitespace(c)) {
|
buffer.clear();
|
||||||
xml->innerXml += c;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In HTML Spec there's a chance for there to be a value here, but not
|
xml->innerXml += c;
|
||||||
// in the XML spec.
|
|
||||||
|
if(c == '&') {
|
||||||
|
// Handle special characters. First read ahead to nearest semicolon OR
|
||||||
|
// nearest closing tag.
|
||||||
|
std::string sc;
|
||||||
|
while(c = data[i++]) {
|
||||||
|
xml->innerXml += c;
|
||||||
|
if(c == ';') break;
|
||||||
|
if(c == '<') assertUnreachable();//Invalid XML
|
||||||
|
sc += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sc == "lt") {
|
||||||
|
buffer += '<';
|
||||||
|
} else if(sc == "gt") {
|
||||||
|
buffer += '>';
|
||||||
|
} else if(sc == "amp") {
|
||||||
|
buffer += '&';
|
||||||
|
} else if(sc == "apos") {
|
||||||
|
buffer += '\'';
|
||||||
|
} else if(sc == "quot") {
|
||||||
|
buffer += '"';
|
||||||
|
} else if(sc == "nbsp") {
|
||||||
|
buffer += ' ';
|
||||||
|
} else {
|
||||||
|
// Try parse as integer
|
||||||
|
if(sc.size() > 1 && sc[0] == '#') {
|
||||||
|
int code = std::stoi(sc.substr(1));
|
||||||
|
buffer += (char)code;
|
||||||
|
} else {
|
||||||
|
std::cout << "Unknown Special character: " << sc << std::endl;
|
||||||
|
assertUnreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer += c;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XML_PARSE_STATE_PARSING_CLOSE:
|
case XML_PARSE_STATE_PARSING_CLOSE:
|
||||||
|
@ -17,11 +17,18 @@ namespace Dawn {
|
|||||||
XML_PARSE_STATE_LOOKING_FOR_ATTRIBUTE_VALUE,
|
XML_PARSE_STATE_LOOKING_FOR_ATTRIBUTE_VALUE,
|
||||||
XML_PARSE_STATE_PARSING_ATTRIBUTE_VALUE,
|
XML_PARSE_STATE_PARSING_ATTRIBUTE_VALUE,
|
||||||
XML_PARSE_STATE_PARSING_VALUE,
|
XML_PARSE_STATE_PARSING_VALUE,
|
||||||
XML_PARSE_STATE_PARSING_CHILD,
|
|
||||||
XML_PARSE_STATE_PARSING_CLOSE,
|
XML_PARSE_STATE_PARSING_CLOSE,
|
||||||
XML_PARSE_STATE_PARSING_COMMENT
|
XML_PARSE_STATE_PARSING_COMMENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Xml;
|
||||||
|
struct XmlNode;
|
||||||
|
|
||||||
|
enum XmlNodeType {
|
||||||
|
XML_NODE_TYPE_TEXT,
|
||||||
|
XML_NODE_TYPE_ELEMENT
|
||||||
|
};
|
||||||
|
|
||||||
class Xml {
|
class Xml {
|
||||||
protected:
|
protected:
|
||||||
static bool_t isWhitespace(char_t c);
|
static bool_t isWhitespace(char_t c);
|
||||||
@ -31,10 +38,13 @@ namespace Dawn {
|
|||||||
static void load(Xml *xml, std::string data, size_t *j);
|
static void load(Xml *xml, std::string data, size_t *j);
|
||||||
|
|
||||||
std::string node;
|
std::string node;
|
||||||
std::string value;
|
|
||||||
std::string innerXml;
|
std::string innerXml;
|
||||||
std::string outerXml;
|
std::string outerXml;
|
||||||
|
std::string textContent;
|
||||||
std::map<std::string, std::string> attributes;
|
std::map<std::string, std::string> attributes;
|
||||||
|
std::vector<struct XmlNode> childNodes;
|
||||||
|
|
||||||
|
// @deprecated
|
||||||
std::vector<Xml*> children;
|
std::vector<Xml*> children;
|
||||||
|
|
||||||
std::vector<Xml*> getChildrenOfType(std::string type);
|
std::vector<Xml*> getChildrenOfType(std::string type);
|
||||||
@ -42,4 +52,12 @@ namespace Dawn {
|
|||||||
|
|
||||||
~Xml();
|
~Xml();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct XmlNode {
|
||||||
|
enum XmlNodeType nodeType;
|
||||||
|
std::string value;
|
||||||
|
Xml *child;
|
||||||
|
|
||||||
|
XmlNode();
|
||||||
|
};
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ int32_t SceneCodeParser::onParse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the code
|
// Get the code
|
||||||
out->code = node->value;
|
out->code = node->textContent;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Reference in New Issue
Block a user