From d7bc08301470eaf96f0fa6b6600d22f0d9dc8551 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Sat, 21 May 2011 19:24:10 -0300 Subject: [PATCH] use exceptions in FML --- data/modules/mainmenu/optionswindow.yml | 2 +- src/framework/core/configs.cpp | 8 +- src/framework/core/resources.cpp | 2 +- src/framework/graphics/font.cpp | 8 +- src/framework/ui/uiloader.cpp | 24 ++-- src/framework/ui/uiloader.h | 4 +- src/framework/ui/uiskins.cpp | 62 ++++----- src/framework/util/color.h | 16 ++- src/framework/util/fml.cpp | 164 ++++++++++++++++++------ src/framework/util/fml.h | 149 ++++++++++++++------- src/framework/util/point.h | 11 +- src/framework/util/rect.h | 15 ++- src/framework/util/size.h | 10 +- src/framework/util/util.h | 2 +- 14 files changed, 304 insertions(+), 173 deletions(-) diff --git a/data/modules/mainmenu/optionswindow.yml b/data/modules/mainmenu/optionswindow.yml index 11f380f5..45a7da56 100644 --- a/data/modules/mainmenu/optionswindow.yml +++ b/data/modules/mainmenu/optionswindow.yml @@ -86,7 +86,7 @@ window#optionsWindow margin.bottom: 60 label#motdLabel - text: |- + text: | Show the most recent Message of the Day anchors.left: parent.left diff --git a/src/framework/core/configs.cpp b/src/framework/core/configs.cpp index 142d1351..f5bff931 100644 --- a/src/framework/core/configs.cpp +++ b/src/framework/core/configs.cpp @@ -36,14 +36,14 @@ bool Configs::load(const std::string& fileName) if(!g_resources.loadFile(fileName, fin)) return false; - FML::Parser parser; - if(parser.load(fin)) { + try { + FML::Parser parser(fin, fileName); FML::Node* doc = parser.getDocument(); foreach(FML::Node* node, *doc) m_confsMap[node->tag()] = node->value(); - } else { - flogError("ERROR: Malformed config file: %s", parser.getErrorMessage()); + } catch(FML::Exception e) { + flogError("ERROR: Malformed config file: %s", e.what()); return false; } diff --git a/src/framework/core/resources.cpp b/src/framework/core/resources.cpp index 608be2a6..9962f180 100644 --- a/src/framework/core/resources.cpp +++ b/src/framework/core/resources.cpp @@ -118,7 +118,7 @@ bool Resources::loadFile(const std::string& fileName, std::iostream& out) char *buffer = new char[fileSize]; PHYSFS_read(file, (void*)buffer, 1, fileSize); out.write(buffer, fileSize); - delete buffer; + delete[] buffer; } else out.clear(std::ios::eofbit); PHYSFS_close(file); diff --git a/src/framework/graphics/font.cpp b/src/framework/graphics/font.cpp index cd65474e..49e03444 100644 --- a/src/framework/graphics/font.cpp +++ b/src/framework/graphics/font.cpp @@ -77,8 +77,8 @@ bool Font::load(const std::string& file) std::string textureName; Size glyphSize; - FML::Parser parser(fin); - if(!parser.hasError()) { + try { + FML::Parser parser(fin, file); FML::Node* doc = parser.getDocument(); // required values @@ -115,8 +115,8 @@ bool Font::load(const std::string& file) m_glyphsSize[glyph].width(), m_glyphHeight); } - } else { - flogError("ERROR: Malformed font file \"%s\":\n %s", file.c_str() % parser.getErrorMessage()); + } catch(FML::Exception e) { + flogError("ERROR: Malformed font file \"%s\":\n %s", file.c_str() % e.what()); return false; } diff --git a/src/framework/ui/uiloader.cpp b/src/framework/ui/uiloader.cpp index 133f6d16..8d55bfe9 100644 --- a/src/framework/ui/uiloader.cpp +++ b/src/framework/ui/uiloader.cpp @@ -75,10 +75,8 @@ UIElementPtr UILoader::loadFromFile(std::string filePath, const UIContainerPtr& return UIElementPtr(); } - m_currentFile = filePath; - - FML::Parser parser(fin); - if(!parser.hasError()) { + try { + FML::Parser parser(fin, filePath); FML::Node* doc = parser.getDocument(); // get element id @@ -105,8 +103,8 @@ UIElementPtr UILoader::loadFromFile(std::string filePath, const UIContainerPtr& // report onLoad events element->onLoad(); return element; - } else { - flogError("ERROR: Failed to load ui %s: %s", filePath.c_str() % parser.getErrorMessage()); + } catch(FML::Exception e) { + flogError("ERROR: Failed to load ui %s: %s", filePath.c_str() % e.what()); } return UIElementPtr(); @@ -192,14 +190,14 @@ void UILoader::loadElement(const UIElementPtr& element, FML::Node* node) // load events if(FML::Node* cnode = node->at("onLoad")) { - if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(element, "onLoad"))) + if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(element, cnode))) g_lua.setScriptableField(element, "onLoad"); else logError(cnode->generateErrorMessage("failed to parse inline lua script")); } if(FML::Node* cnode = node->at("onDestroy")) { - if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(element, "onDestroy"))) + if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(element, cnode))) g_lua.setScriptableField(element, "onDestroy"); else logError(cnode->generateErrorMessage("failed to parse inline lua script")); @@ -254,19 +252,19 @@ void UILoader::loadButton(const UIButtonPtr& button, FML::Node* node) // set on click event if(FML::Node* cnode = node->at("onClick")) { - if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(button, "onClick"))) + if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(button, cnode))) g_lua.setScriptableField(button, "onClick"); else logError(cnode->generateErrorMessage("failed to parse inline lua script")); } } -std::string UILoader::getElementSourceDesc(const UIElementPtr& element, const std::string& key) +std::string UILoader::getElementSourceDesc(const UIElementPtr& element, const FML::Node *node) { std::string desc; - desc += g_resources.resolvePath(m_currentFile) + ":" + element->getId(); - if(key.length() > 0) - desc += "[" + key + "]"; + desc += g_resources.resolvePath(node->what()) + ":" + element->getId(); + if(!node->tag().empty()) + desc += "[" + node->tag() + "]"; return desc; } diff --git a/src/framework/ui/uiloader.h b/src/framework/ui/uiloader.h index 370d8da0..87d32ee3 100644 --- a/src/framework/ui/uiloader.h +++ b/src/framework/ui/uiloader.h @@ -55,9 +55,7 @@ private: // specific elements loading void loadButton(const UIButtonPtr& button, FML::Node* node); - std::string getElementSourceDesc(const UIElementPtr& element, const std::string& key = ""); - - std::string m_currentFile; + std::string getElementSourceDesc(const UIElementPtr& element, const FML::Node *node); }; extern UILoader g_uiLoader; diff --git a/src/framework/ui/uiskins.cpp b/src/framework/ui/uiskins.cpp index 4315649e..99eb4d44 100644 --- a/src/framework/ui/uiskins.cpp +++ b/src/framework/ui/uiskins.cpp @@ -43,11 +43,11 @@ void UISkins::load(const std::string& skinName) if(!g_resources.loadFile(skinName + ".yml", fin)) flogFatal("FATAL ERROR: Could not load skin \"%s", skinName.c_str()); - FML::Parser parser(fin); - if(!parser.hasError()) { + try { + FML::Parser parser(fin, skinName); FML::Node* doc = parser.getDocument(); - m_defaultFont = g_fonts.get(doc->readAt("default font")); + m_defaultFont = g_fonts.get(doc->valueAt("default font")); if(!m_defaultFont) logFatal("FATAL ERROR: Could not load skin default font"); @@ -57,48 +57,30 @@ void UISkins::load(const std::string& skinName) if(!defaultTextureName.empty()) m_defaultTexture = g_textures.get(defaultTextureName); - if(FML::Node* node = doc->at("buttons")) { + foreach(FML::Node* node, *doc) { + UIElementSkinPtr skin; foreach(FML::Node* cnode, *node) { - UIElementSkinPtr skin = UIElementSkinPtr(new UIButtonSkin(cnode->tag())); + if(node->tag() == "buttons") + skin = UIElementSkinPtr(new UIButtonSkin(cnode->tag())); + else if(node->tag() == "panels") + skin = UIElementSkinPtr(new UIElementSkin(cnode->tag(), UI::Panel)); + else if(node->tag() == "windows") + skin = UIElementSkinPtr(new UIWindowSkin(cnode->tag())); + else if(node->tag() == "labels") + skin = UIElementSkinPtr(new UILabelSkin(cnode->tag())); + else if(node->tag() == "text edits") + skin = UIElementSkinPtr(new UITextEditSkin(cnode->tag())); + else if(node->tag() == "line decorations") + skin = UIElementSkinPtr(new UIElementSkin(cnode->tag(), UI::LineDecoration)); + else { + break; + } skin->load(cnode); m_elementSkins.push_back(skin); } } - - if(FML::Node* node = doc->at("panels")) { - foreach(FML::Node* cnode, *node) { - UIElementSkinPtr skin = UIElementSkinPtr(new UIElementSkin(cnode->tag(), UI::Panel)); - skin->load(cnode); - m_elementSkins.push_back(skin); - } - } - - if(FML::Node* node = doc->at("windows")) { - foreach(FML::Node* cnode, *node) { - UIElementSkinPtr skin = UIElementSkinPtr(new UIWindowSkin(cnode->tag())); - skin->load(cnode); - m_elementSkins.push_back(skin); - } - } - - if(FML::Node* node = doc->at("labels")) { - foreach(FML::Node* cnode, *node) { - UIElementSkinPtr skin = UIElementSkinPtr(new UILabelSkin(cnode->tag())); - skin->load(cnode); - m_elementSkins.push_back(skin); - } - } - - - if(FML::Node* node = doc->at("text edits")) { - foreach(FML::Node* cnode, *node) { - UIElementSkinPtr skin = UIElementSkinPtr(new UITextEditSkin(cnode->tag())); - skin->load(cnode); - m_elementSkins.push_back(skin); - } - } - } else { - flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinName.c_str() % parser.getErrorMessage()); + } catch(FML::Exception e) { + flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinName.c_str() % e.what()); } g_resources.popCurrentPath(); diff --git a/src/framework/util/color.h b/src/framework/util/color.h index d4bb5dcc..c222deed 100644 --- a/src/framework/util/color.h +++ b/src/framework/util/color.h @@ -76,14 +76,18 @@ inline std::ostream& operator<<(std::ostream& out, const Color& color) return out; } -inline void operator>>(const FML::Node& node, Color& color) +inline bool operator>>(const FML::Node& node, Color& color) { int r, g, b, a; - *node.at(0) >> r; - *node.at(1) >> g; - *node.at(2) >> b; - *node.at(3) >> a; - color.setRGBA(r,g,b,a); + if(node.readAt(0, &r) && + node.readAt(1, &g) && + node.readAt(2, &b)) { + a = 255; + node.readAt(3, &a); + color.setRGBA(r,g,b,a); + return true; + } + return false; } #endif // COLOR_H diff --git a/src/framework/util/fml.cpp b/src/framework/util/fml.cpp index a9cbd25b..bdc31076 100644 --- a/src/framework/util/fml.cpp +++ b/src/framework/util/fml.cpp @@ -38,6 +38,12 @@ bool fml_convert(const std::string& input, std::string& output) { return true; } +std::string fml_int2str(int v) +{ + std::stringstream ss; + ss << v; + return ss.str(); +} /////////////////////////////////////////////////////////////////////////////// // Node @@ -48,6 +54,13 @@ Node::~Node() delete (*it); } +std::string Node::what() const +{ + if(m_parser) + return m_parser->what(); + return std::string(); +} + Node* Node::at(const std::string& childTag) const { for(NodeList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { @@ -64,22 +77,6 @@ Node* Node::at(int pos) const return m_children[pos]; } -std::string Node::value(const std::string& def) const -{ - if(!m_value.empty()) - return m_value; - return def; -} - -std::string Node::valueAt(const std::string childTag, const std::string& def) const -{ - for(NodeList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { - if((*it)->tag() == childTag) - return (*it)->value(); - } - return def; -} - void Node::addNode(Node *node) { if(node->hasTag() && node->hasValue()) { @@ -99,15 +96,101 @@ void Node::addNode(Node *node) std::string Node::generateErrorMessage(const std::string& message) const { std::stringstream ss; - ss << "FML error "; - if(m_parser && !m_parser->getWhat().empty()) - ss << "in " << m_parser->getWhat(); - if(m_line > 0) - ss << "at line " << m_line; + ss << "FML error"; + if(!(what().empty())) + ss << " in '" << what() << "'"; + if(m_line > 0) { + ss << " at line " << m_line; + if(hasTag()) + ss << ", in node '" << tag() << "'"; + } ss << ": " << message; return ss.str(); } +std::string Node::emitValue() +{ + std::string tmpValue = value(); + + bool shouldQuote = false; + if(tmpValue.find_first_of("\\") != std::string::npos) { + boost::replace_all(tmpValue, "\\", "\\\\"); + shouldQuote = true; + } + if(tmpValue.find_first_of("\"") != std::string::npos) { + boost::replace_all(tmpValue, "\"", "\\\""); + shouldQuote = true; + } + if(tmpValue.find_first_of("\n") != std::string::npos) { + boost::replace_all(tmpValue, "\n", "\\n"); + shouldQuote = true; + } + + if(shouldQuote) { + tmpValue.append("\""); + tmpValue.insert(0, "\""); + } + + return tmpValue; +} + +std::string Node::emit(int depth) +{ + std::stringstream ss; + std::stringstream inlinestr; + bool shouldInline = false; + + for(int i=1;i 0) { + shouldInline = true; + + if(hasTag()) + ss << tag(); + + if(hasValue()) { + if(hasTag()) + ss << ": "; + else + ss << "- "; + ss << emitValue(); + ss << std::endl; + shouldInline = false; + } + + if(size() > 8 || size() == 0) + shouldInline = false; + } + + if(shouldInline) { + inlinestr << "["; + for(NodeList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { + Node* child = (*it); + if(child->hasTag() || ss.str().length() > 31) { + shouldInline = false; + break; + } else { + if(it != m_children.begin()) + inlinestr << ", "; + inlinestr << child->emitValue(); + } + } + inlinestr << "]"; + } + + if(shouldInline) { + ss << ": " << inlinestr.str() << std::endl; + } else { + if(!hasValue()) + ss << std::endl; + + for(NodeList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) + ss << (*it)->emit(depth+1); + } + + return ss.str(); +} /////////////////////////////////////////////////////////////////////////////// // Parser @@ -118,7 +201,7 @@ Parser::~Parser() delete m_rootNode; } -bool Parser::load(std::istream& in) +void Parser::load(std::istream& in) { // initialize root node if(m_rootNode) @@ -137,15 +220,11 @@ bool Parser::load(std::istream& in) std::string line; std::getline(in, line); parseLine(line); - if(hasError()) - return false; } // stop multilining if enabled if(isMultilining()) stopMultilining(); - - return !hasError(); } void Parser::parseLine(std::string& line) @@ -173,7 +252,7 @@ void Parser::parseLine(std::string& line) depth = numSpaces / 2; // check for syntax error if(numSpaces % 2 != 0) { - setErrorMessage("file must be idented every 2 whitespaces", m_currentLine); + throwError("file must be idented every 2 whitespaces", m_currentLine); return; } } @@ -189,7 +268,7 @@ void Parser::parseLine(std::string& line) m_currentParent = m_currentParent->parent(); // else if nots the same depth it's a syntax error } else if(depth != m_currentDepth) { - setErrorMessage("invalid indentation level", m_currentLine); + throwError("invalid indentation level", m_currentLine); return; } @@ -246,16 +325,17 @@ Node *Parser::parseNode(std::string& line) boost::trim(value); boost::tokenizer > tokens(value); for(boost::tokenizer >::iterator it = tokens.begin(); it != tokens.end(); ++it) { - value = *it; - boost::trim(value); - - Node *child = new Node(this); - child->setLine(m_currentLine); - child->setValue(value); - node->addNode(child); + std::string tmp = (*it); + boost::trim(tmp); + if(!tmp.empty()) { + Node *child = new Node(this); + child->setLine(m_currentLine); + child->setValue(tmp); + node->addNode(child); + } } } else - setErrorMessage("missing ']' in sequence", m_currentLine); + throwError("missing ']' in sequence", m_currentLine); } // text scalar else { @@ -291,7 +371,7 @@ void Parser::startMultilining(const std::string& param) m_multilineMode = MULTILINE_FOLD_FLOW; break; default: - setErrorMessage("invalid multiline identifier", m_currentLine); + throwError("invalid multiline identifier", m_currentLine); break; } } @@ -343,16 +423,16 @@ bool Parser::parseMultiline(std::string line) return false; } -void Parser::setErrorMessage(const std::string& message, int line) +void Parser::throwError(const std::string& message, int line) { std::stringstream ss; - ss << "FML syntax error in "; + ss << "FML syntax error"; if(!m_what.empty()) - ss << m_what << " "; + ss << " in '" << m_what << "'"; if(line > 0) - ss << "at line " << line; + ss << " at line " << line; ss << ": " << message; - m_error = ss.str(); + throw Exception(ss.str()); } } // namespace FML { diff --git a/src/framework/util/fml.h b/src/framework/util/fml.h index e6dc196f..86222783 100644 --- a/src/framework/util/fml.h +++ b/src/framework/util/fml.h @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include #include #include @@ -26,6 +29,16 @@ bool fml_convert(const V& in, T& out) { return !!ss; } +std::string fml_int2str(int v); + +/////////////////////////////////////////////////////////////////////////////// +// Exception + +class Exception : public std::runtime_error { +public: + explicit Exception(const std::string& what) : std::runtime_error(what) {} +}; + /////////////////////////////////////////////////////////////////////////////// // Node @@ -54,6 +67,7 @@ public: int line() const { return m_line; } int size() const { return m_children.size(); } Node* parent() { return m_parent; } + std::string what() const; // iterators typedef NodeList::iterator iterator; @@ -69,6 +83,7 @@ public: // util for generating error message std::string generateErrorMessage(const std::string& message) const; + void throwError(const std::string& message) const { throw Exception(generateErrorMessage(message)); } // extracting values operator template @@ -79,45 +94,95 @@ public: Node* at(int pos) const; // get values - std::string value(const std::string& def = std::string()) const; - std::string valueAt(const std::string childTag, const std::string& def = std::string()) const; + std::string value(const std::string& def = std::string()) const { + if(!m_value.empty()) + return m_value; + return def; + } - // read values - template - T read(T def = T()) const { - T v = def; - *this >> v; - return v; + std::string valueAt(const std::string childTag, const std::string& def = std::string()) const { + if(Node* node = at(childTag)) + return node->value(); + return def; } + std::string valueAt(int pos, const std::string& def = std::string()) const { + if(Node* node = at(pos)) + return node->value(); + return def; + } + + // read values into memory template - bool read(T* v) const { - return (*this >> *v); + void read(T* v) const { + if(!(*this >> *v)) + throw Exception(generateErrorMessage("failed to cast node value to type " + std::string(typeid(T).name()))); } template - T readAt(const std::string& childTag, T def = T()) const { - T v = def; - for(NodeList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { - if((*it)->tag() == childTag) { - *(*it) >> v; - break; - } + bool readAt(const std::string& childTag, T* v) const { + if(Node* node = at(childTag)) { + node->read(v); + return true; } - return v; + return false; } template - bool readAt(const std::string& childTag, T* v) const { - for(NodeList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { - if((*it)->tag() == childTag) - return (*(*it) >> *v); + bool readAt(int pos, T* v) const { + if(Node* node = at(pos)) { + node->read(v); + return true; } return false; } + // read values + template + T read() const { + T v; + read(&v); + return v; + } + + template + T readAt(const std::string& childTag) const { + if(Node* node = at(childTag)) + return node->read(); + throw Exception(generateErrorMessage("child node " + childTag + " not found")); + return T(); + } + + template + T readAt(int pos) const { + if(Node* node = at(pos)) + return node->read(); + throw Exception(generateErrorMessage("child node at pos " + fml_int2str(pos) + " not found")); + return T(); + } + + // read values with defaults + template + T readAt(const std::string& childTag, const T& def) const { + if(Node* node = at(childTag)) + return node->read(); + else + return def; + } + + template + T readAt(int pos, const T& def) const { + if(Node* node = at(pos)) + return node->read(); + else + return def; + } + void addNode(Node* node); + std::string emitValue(); + std::string emit(int depth = 0); + private: Parser* m_parser; Node* m_parent; @@ -140,32 +205,29 @@ bool operator >> (const Node& node, T& v) template bool operator >> (const Node& node, std::vector& v) { - bool ret = true; - v.clear(); - v.resize(node.size()); - for(unsigned i=0;i> v[i])) - ret = false; - } - return ret; + std::vector& tmp; + tmp.resize(node.size()); + for(unsigned i=0;i(i); + v = tmp; + return true; } template bool operator >> (const Node& node, std::map& m) { - bool ret = true; - m.clear(); + std::map tmp; for(Node::const_iterator it = node.begin(); it != node.end(); ++it) { - Node* child = (*it); K k; T v; - if(fml_convert(child->tag(), k)) { - *child >> v; - m[k] = v; - ret = false; - } + if(fml_convert((*it)->tag(), k)) { + (*it)->read(&v); + tmp[k] = v; + } else + return false; } - return ret; + m = tmp; + return true; } @@ -186,12 +248,10 @@ public: Parser(std::istream& in, std::string what = std::string()) : m_rootNode(0), m_what(what) { load(in); } ~Parser(); - bool load(std::istream& in); + void load(std::istream& in); Node* getDocument() const { return m_rootNode; } - bool hasError() const { return !m_error.empty(); } - std::string getErrorMessage() { return m_error; } - std::string getWhat() { return m_what; } + std::string what() { return m_what; } protected: void parseLine(std::string& line); @@ -203,7 +263,7 @@ protected: bool parseMultiline(std::string line); bool isMultilining() { return m_multilineMode != DONT_MULTILINE; } - void setErrorMessage(const std::string& message, int line = 0); + void throwError(const std::string& message, int line = 0); private: int m_currentDepth; @@ -213,7 +273,6 @@ private: Node* m_rootNode; MultilineMode m_multilineMode; std::string m_multilineData; - std::string m_error; std::string m_what; }; diff --git a/src/framework/util/point.h b/src/framework/util/point.h index aae4b88c..f5c16d24 100644 --- a/src/framework/util/point.h +++ b/src/framework/util/point.h @@ -86,10 +86,15 @@ inline std::ostream& operator<<(std::ostream& out, const TPoint& point) } template -inline void operator>>(const FML::Node& node, TPoint& point) +inline bool operator>>(const FML::Node& node, TPoint& point) { - *node.at(0) >> point.x; - *node.at(1) >> point.y; + T x, y; + if(node.readAt(0, &x) && node.readAt(1, &y)) { + point.x = x; + point.y = y; + return true; + } + return false; } #endif diff --git a/src/framework/util/rect.h b/src/framework/util/rect.h index dfa810d2..02412eeb 100644 --- a/src/framework/util/rect.h +++ b/src/framework/util/rect.h @@ -310,14 +310,17 @@ inline std::ostream& operator<<(std::ostream& out, const TRect& rect) } template -inline void operator>>(const FML::Node& node, TRect& rect) +inline bool operator>>(const FML::Node& node, TRect& rect) { T x, y, width, height; - *node.at(0) >> x; - *node.at(1) >> y; - *node.at(2) >> width; - *node.at(3) >> height; - rect.setRect(x, y, width, height); + if(node.readAt(0, &x) && + node.readAt(1, &y) && + node.readAt(2, &width) && + node.readAt(3, &height)) { + rect.setRect(x, y, width, height); + return true; + } + return false; } #endif // RECT_H diff --git a/src/framework/util/size.h b/src/framework/util/size.h index f22449b6..a6f5fc26 100644 --- a/src/framework/util/size.h +++ b/src/framework/util/size.h @@ -112,12 +112,14 @@ typedef TSize Size; typedef TSize SizeF; template -inline void operator>>(const FML::Node& node, TSize& size) +inline bool operator>>(const FML::Node& node, TSize& size) { T w, h; - *node.at(0) >> w; - *node.at(1) >> h; - size.setSize(w, h); + if(node.readAt(0, &w) && node.readAt(1, &h)) { + size.setSize(w, h); + return true; + } + return false; } #endif diff --git a/src/framework/util/util.h b/src/framework/util/util.h index ac467f86..6477a951 100644 --- a/src/framework/util/util.h +++ b/src/framework/util/util.h @@ -41,7 +41,7 @@ R convert_cast(T t) try { ret = boost::lexical_cast(t); } catch(boost::bad_lexical_cast bad) { - flogError("Error converting type: %s", bad.what()); + flogError("Error converting value: %s", bad.what()); } return ret; }