Exemplo n.º 1
0
bool ThingTypeManager::loadOtml(std::string file)
{
    try {
        file = g_resources.guessFilePath(file, "otml");

        OTMLDocumentPtr doc = OTMLDocument::parse(file);
        for(const OTMLNodePtr& node : doc->children()) {
            ThingCategory category;
            if(node->tag() == "creatures")
                category = ThingCategoryCreature;
            else if(node->tag() == "items")
                category = ThingCategoryItem;
            else if(node->tag() == "effects")
                category = ThingCategoryEffect;
            else if(node->tag() == "missiles")
                category = ThingCategoryMissile;
            else {
                throw OTMLException(node, "not a valid thing category");
            }

            for(const OTMLNodePtr& node2 : node->children()) {
                uint16 id = stdext::safe_cast<uint16>(node2->tag());
                ThingTypePtr type = getThingType(id, category);
                if(!type)
                    throw OTMLException(node2, "thing not found");
                type->unserializeOtml(node2);
            }
        }
        return true;
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to read dat otml '%s': %s'", file, e.what()));
        return false;
    }
}
Exemplo n.º 2
0
void OTMLParser::parse()
{
    if(!in.good())
        throw OTMLException(doc, "cannot read from input stream");

    while(!in.eof())
        parseLine(getNextLine());
}
Exemplo n.º 3
0
OTMLNodePtr OTMLNode::at(const std::string& childTag)
{
    OTMLNodePtr res;
    for(const OTMLNodePtr& child : m_children) {
        if(child->tag() == childTag && !child->isNull()) {
            res = child;
            break;
        }
    }
    if(!res)
        throw OTMLException(asOTMLNode(), stdext::format("child node with tag '%s' not found", childTag));
    return res;
}
Exemplo n.º 4
0
int OTMLParser::getLineDepth(const std::string& line, bool multilining)
{
    // count number of spaces at the line beginning
    std::size_t spaces = 0;
    while(line[spaces] == ' ')
        spaces++;

    // pre calculate depth
    int depth = spaces / 2;

    if(!multilining || depth <= currentDepth) {
        // check the next character is a tab
        if(line[spaces] == '\t')
            throw OTMLException(doc, "indentation with tabs are not allowed", currentLine);

        // must indent every 2 spaces
        if(spaces % 2 != 0)
            throw OTMLException(doc, "must indent every 2 spaces", currentLine);
    }

    return depth;
}
Exemplo n.º 5
0
void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode)
{
    std::string tag = styleNode->tag();
    std::vector<std::string> split = stdext::split(tag, "<");
    if(split.size() != 2)
        throw OTMLException(styleNode, "not a valid style declaration");

    std::string name = split[0];
    std::string base = split[1];
    bool unique = false;

    stdext::trim(name);
    stdext::trim(base);

    if(name[0] == '#') {
        name = name.substr(1);
        unique = true;

        styleNode->setTag(name);
        styleNode->writeAt("__unique", true);
    }

    OTMLNodePtr oldStyle = m_styles[name];

    // Warn about redefined styles
    /*
    if(!g_app.isRunning() && (oldStyle && !oldStyle->valueAt("__unique", false))) {
        auto it = m_styles.find(name);
        if(it != m_styles.end())
            g_logger.warning(stdext::format("style '%s' is being redefined", name));
    }
    */

    if(!oldStyle || !oldStyle->valueAt("__unique", false) || unique) {
        OTMLNodePtr originalStyle = getStyle(base);
        if(!originalStyle)
            stdext::throw_exception(stdext::format("base style '%s', is not defined", base));
        OTMLNodePtr style = originalStyle->clone();
        style->merge(styleNode);
        style->setTag(name);
        m_styles[name] = style;
    }
}
Exemplo n.º 6
0
void OTMLParser::parseLine(std::string line)
{
    int depth = getLineDepth(line);

    if(depth == -1)
        return;

    // remove line sides spaces
    boost::trim(line);

    // skip empty lines
    if(line.empty())
        return;

    // skip comments
    if(boost::starts_with(line, "//"))
        return;

    // a depth above, change current parent to the previous added node
    if(depth == currentDepth+1) {
        currentParent = previousNode;
    // a depth below, change parent to previous parent
    } else if(depth < currentDepth) {
        for(int i=0;i<currentDepth-depth;++i)
            currentParent = currentParent->parent();
    // if it isn't the current depth, it's a syntax error
    } else if(depth != currentDepth)
        throw OTMLException(doc, "invalid indentation depth, are you indenting correctly?", currentLine);

    // sets current depth
    currentDepth = depth;

    // alright, new depth is set, the line is not empty and it isn't a comment
    // then it must be a node, so we parse it
    parseNode(line);
}
Exemplo n.º 7
0
OTMLNodePtr OTMLNode::atIndex(int childIndex)
{
    if(childIndex >= size() || childIndex < 0)
        throw OTMLException(asOTMLNode(), stdext::format("child node with index '%d' not found", childIndex));
    return m_children[childIndex];
}
Exemplo n.º 8
0
void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
{
    // load styles used by all widgets
    for(const OTMLNodePtr& node : styleNode->children()) {
        if(node->tag() == "color")
            setColor(node->value<Color>());
        else if(node->tag() == "x")
            setX(node->value<int>());
        else if(node->tag() == "y")
            setY(node->value<int>());
        else if(node->tag() == "pos")
            setPosition(node->value<Point>());
        else if(node->tag() == "width")
            setWidth(node->value<int>());
        else if(node->tag() == "height")
            setHeight(node->value<int>());
        else if(node->tag() == "rect")
            setRect(node->value<Rect>());
        else if(node->tag() == "background")
            setBackgroundColor(node->value<Color>());
        else if(node->tag() == "background-color")
            setBackgroundColor(node->value<Color>());
        else if(node->tag() == "background-offset-x")
            setBackgroundOffsetX(node->value<int>());
        else if(node->tag() == "background-offset-y")
            setBackgroundOffsetY(node->value<int>());
        else if(node->tag() == "background-offset")
            setBackgroundOffset(node->value<Point>());
        else if(node->tag() == "background-width")
            setBackgroundWidth(node->value<int>());
        else if(node->tag() == "background-height")
            setBackgroundHeight(node->value<int>());
        else if(node->tag() == "background-size")
            setBackgroundSize(node->value<Size>());
        else if(node->tag() == "background-rect")
            setBackgroundRect(node->value<Rect>());
        else if(node->tag() == "icon")
            setIcon(stdext::resolve_path(node->value(), node->source()));
        else if(node->tag() == "icon-source")
            setIcon(stdext::resolve_path(node->value(), node->source()));
        else if(node->tag() == "icon-color")
            setIconColor(node->value<Color>());
        else if(node->tag() == "icon-offset-x")
            setIconOffsetX(node->value<int>());
        else if(node->tag() == "icon-offset-y")
            setIconOffsetY(node->value<int>());
        else if(node->tag() == "icon-offset")
            setIconOffset(node->value<Point>());
        else if(node->tag() == "icon-width")
            setIconWidth(node->value<int>());
        else if(node->tag() == "icon-height")
            setIconHeight(node->value<int>());
        else if(node->tag() == "icon-size")
            setIconSize(node->value<Size>());
        else if(node->tag() == "icon-rect")
            setIconRect(node->value<Rect>());
        else if(node->tag() == "opacity")
            setOpacity(node->value<float>());
        else if(node->tag() == "enabled")
            setEnabled(node->value<bool>());
        else if(node->tag() == "visible")
            setVisible(node->value<bool>());
        else if(node->tag() == "checked")
            setChecked(node->value<bool>());
        else if(node->tag() == "dragable")
            setChecked(node->value<bool>());
        else if(node->tag() == "on")
            setOn(node->value<bool>());
        else if(node->tag() == "focusable")
            setFocusable(node->value<bool>());
        else if(node->tag() == "phantom")
            setPhantom(node->value<bool>());
        else if(node->tag() == "size")
            setSize(node->value<Size>());
        else if(node->tag() == "fixed-size")
            setFixedSize(node->value<bool>());
        else if(node->tag() == "clipping")
            setClipping(node->value<bool>());
        else if(node->tag() == "border") {
            auto split = stdext::split(node->value(), " ");
            if(split.size() == 2) {
                setBorderWidth(stdext::safe_cast<int>(split[0]));
                setBorderColor(stdext::safe_cast<Color>(split[1]));
            } else
                throw OTMLException(node, "border param must have its width followed by its color");
        }
        else if(node->tag() == "border-width")
            setBorderWidth(node->value<int>());
        else if(node->tag() == "border-width-top")
            setBorderWidthTop(node->value<int>());
        else if(node->tag() == "border-width-right")
            setBorderWidthRight(node->value<int>());
        else if(node->tag() == "border-width-bottom")
            setBorderWidthBottom(node->value<int>());
        else if(node->tag() == "border-width-left")
            setBorderWidthLeft(node->value<int>());
        else if(node->tag() == "border-color")
            setBorderColor(node->value<Color>());
        else if(node->tag() == "border-color-top")
            setBorderColorTop(node->value<Color>());
        else if(node->tag() == "border-color-right")
            setBorderColorRight(node->value<Color>());
        else if(node->tag() == "border-color-bottom")
            setBorderColorBottom(node->value<Color>());
        else if(node->tag() == "border-color-left")
            setBorderColorLeft(node->value<Color>());
        else if(node->tag() == "margin-top")
            setMarginTop(node->value<int>());
        else if(node->tag() == "margin-right")
            setMarginRight(node->value<int>());
        else if(node->tag() == "margin-bottom")
            setMarginBottom(node->value<int>());
        else if(node->tag() == "margin-left")
            setMarginLeft(node->value<int>());
        else if(node->tag() == "margin") {
            std::string marginDesc = node->value();
            std::vector<std::string> split;
            boost::split(split, marginDesc, boost::is_any_of(std::string(" ")));
            if(split.size() == 4) {
                setMarginTop(stdext::safe_cast<int>(split[0]));
                setMarginRight(stdext::safe_cast<int>(split[1]));
                setMarginBottom(stdext::safe_cast<int>(split[2]));
                setMarginLeft(stdext::safe_cast<int>(split[3]));
            } else if(split.size() == 3) {
                int marginTop = stdext::safe_cast<int>(split[0]);
                int marginHorizontal = stdext::safe_cast<int>(split[1]);
                int marginBottom = stdext::safe_cast<int>(split[2]);
                setMarginTop(marginTop);
                setMarginRight(marginHorizontal);
                setMarginBottom(marginBottom);
                setMarginLeft(marginHorizontal);
            } else if(split.size() == 2) {
                int marginVertical = stdext::safe_cast<int>(split[0]);
                int marginHorizontal = stdext::safe_cast<int>(split[1]);
                setMarginTop(marginVertical);
                setMarginRight(marginHorizontal);
                setMarginBottom(marginVertical);
                setMarginLeft(marginHorizontal);
            } else if(split.size() == 1) {
                int margin = stdext::safe_cast<int>(split[0]);
                setMarginTop(margin);
                setMarginRight(margin);
                setMarginBottom(margin);
                setMarginLeft(margin);
            }
        }
        else if(node->tag() == "padding-top")
            setPaddingTop(node->value<int>());
        else if(node->tag() == "padding-right")
            setPaddingRight(node->value<int>());
        else if(node->tag() == "padding-bottom")
            setPaddingBottom(node->value<int>());
        else if(node->tag() == "padding-left")
            setPaddingLeft(node->value<int>());
        else if(node->tag() == "padding") {
            std::string paddingDesc = node->value();
            std::vector<std::string> split;
            boost::split(split, paddingDesc, boost::is_any_of(std::string(" ")));
            if(split.size() == 4) {
                setPaddingTop(stdext::safe_cast<int>(split[0]));
                setPaddingRight(stdext::safe_cast<int>(split[1]));
                setPaddingBottom(stdext::safe_cast<int>(split[2]));
                setPaddingLeft(stdext::safe_cast<int>(split[3]));
            } else if(split.size() == 3) {
                int paddingTop = stdext::safe_cast<int>(split[0]);
                int paddingHorizontal = stdext::safe_cast<int>(split[1]);
                int paddingBottom = stdext::safe_cast<int>(split[2]);
                setPaddingTop(paddingTop);
                setPaddingRight(paddingHorizontal);
                setPaddingBottom(paddingBottom);
                setPaddingLeft(paddingHorizontal);
            } else if(split.size() == 2) {
                int paddingVertical = stdext::safe_cast<int>(split[0]);
                int paddingHorizontal = stdext::safe_cast<int>(split[1]);
                setPaddingTop(paddingVertical);
                setPaddingRight(paddingHorizontal);
                setPaddingBottom(paddingVertical);
                setPaddingLeft(paddingHorizontal);
            } else if(split.size() == 1) {
                int padding = stdext::safe_cast<int>(split[0]);
                setPaddingTop(padding);
                setPaddingRight(padding);
                setPaddingBottom(padding);
                setPaddingLeft(padding);
            }
        }
        // layouts
        else if(node->tag() == "layout") {
            std::string layoutType;
            if(node->hasValue())
                layoutType = node->value();
            else
                layoutType = node->valueAt<std::string>("type", "");

            if(!layoutType.empty()) {
                UILayoutPtr layout;
                if(layoutType == "horizontalBox")
                    layout = UIHorizontalLayoutPtr(new UIHorizontalLayout(asUIWidget()));
                else if(layoutType == "verticalBox")
                    layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget()));
                else if(layoutType == "grid")
                    layout = UIGridLayoutPtr(new UIGridLayout(asUIWidget()));
                else if(layoutType == "anchor")
                    layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget()));
                else
                    throw OTMLException(node, "cannot determine layout type");
                setLayout(layout);
            }

            if(node->hasChildren())
                m_layout->applyStyle(node);
        }
        // anchors
        else if(boost::starts_with(node->tag(), "anchors.")) {
            UIWidgetPtr parent = getParent();
            if(!parent) {
                if(m_firstOnStyle)
                    throw OTMLException(node, "cannot create anchor, there is no parent widget!");
                else
                    continue;
            }

            UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout();
            if(!anchorLayout)
                throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!");

            std::string what = node->tag().substr(8);
            if(what == "fill") {
                fill(node->value());
            } else if(what == "centerIn") {
                centerIn(node->value());
            } else {
                Fw::AnchorEdge anchoredEdge = Fw::translateAnchorEdge(what);

                if(node->value() == "none") {
                    removeAnchor(anchoredEdge);
                } else {
                    std::vector<std::string> split = stdext::split(node->value(), ".");
                    if(split.size() != 2)
                        throw OTMLException(node, "invalid anchor description");

                    std::string hookedWidgetId = split[0];
                    Fw::AnchorEdge hookedEdge = Fw::translateAnchorEdge(split[1]);

                    if(anchoredEdge == Fw::AnchorNone)
                        throw OTMLException(node, "invalid anchor edge");

                    if(hookedEdge == Fw::AnchorNone)
                        throw OTMLException(node, "invalid anchor target edge");

                    addAnchor(anchoredEdge, hookedWidgetId, hookedEdge);
                }
            }
            // lua functions
        } else if(boost::starts_with(node->tag(), "@")) {
            // load once
            if(m_firstOnStyle) {
                std::string funcName = node->tag().substr(1);
                std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]";
                g_lua.loadFunction(node->value(), funcOrigin);
                luaSetField(funcName);
            }
            // lua fields value
        } else if(boost::starts_with(node->tag(), "&")) {
            std::string fieldName = node->tag().substr(1);
            std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]";
            g_lua.evaluateExpression(node->value(), fieldOrigin);
            luaSetField(fieldName);
        }
    }
}