// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "SceneItemParser.hpp" using namespace Dawn; std::vector SceneItemParser::getRequiredAttributes() { return std::vector(); } std::map SceneItemParser::getOptionalAttributes() { return { { "ref", "" }, { "position", "" }, { "lookAt", "" }, { "scale", "" }, { "prefab", "" }, { "alignment", "" }, { "alignX", "" }, { "aignY", "" }, { "menuX", "" }, { "menuY", "" }, { "label", "" } }; } int32_t SceneItemParser::onParse( Xml *node, std::map values, struct SceneItem *out, std::string *error ) { out->ref = values["ref"]; if(values["position"].size() > 0) { out->position = vec3Parser(values["position"], error); if(error->size() > 0) return 1; } if(values["alignment"].size() > 0) { out->alignment = vec4Parser(values["alignment"], error); if(error->size() > 0) return 1; } if(values["alignX"].size() > 0) { out->alignX = uiComponentAlignParser(values["alignX"], error); if(error->size() > 0) return 1; } if(values["alignY"].size() > 0) { out->alignY = uiComponentAlignParser(values["alignY"], error); if(error->size() > 0) return 1; } if(values["menuX"].size() > 0) { out->menuX = intParser(values["menuX"], error); if(error->size() > 0) return 1; } if(values["menuY"].size() > 0) { out->menuY = intParser(values["menuY"], error); if(error->size() > 0) return 1; } if(values["scale"].size() > 0) { out->scale = vec3Parser(values["scale"], error); if(error->size() > 0) return 1; } if(values["label"].size() > 0) { out->label = stringParser(values["label"], error); if(error->size() > 0) return 1; } if(values["lookAt"].size() > 0) { auto lookAtSplit = stringSplit(values["lookAt"], ","); if(lookAtSplit.size() != 6) { *error = "Invalid lookAt value: " + values["lookAt"]; return 1; } out->lookAtPosition = vec3Parser(lookAtSplit[0] + "," + lookAtSplit[1] + "," + lookAtSplit[2], error); if(error->size() > 0) return 1; out->lookAtTarget = vec3Parser(lookAtSplit[3] + "," + lookAtSplit[4] + "," + lookAtSplit[5], error); if(error->size() > 0) return 1; } out->prefab = values["prefab"]; struct SceneItemDependency dep; auto itChildren = node->childNodes.begin(); while(itChildren != node->childNodes.end()) { if(itChildren->nodeType != XML_NODE_TYPE_ELEMENT) { ++itChildren; continue; } // Parse child nodes, they may be components or not auto c = itChildren->child; if(c->node == "child" || c->node == "item") { struct SceneItem child; child.registry = out->registry; auto ret = (SceneItemParser()).parse(c, &child, error); if(ret != 0) return ret; out->children.push_back(child); // Add a dependency. This solves the reference order problem. struct SceneItemDependency dep; dep.type = SCENE_ITEM_DEPENDENCY_TYPE_ITEM; dep.position = out->children.size() - 1; out->dependencies.push_back(dep); } else if(c->node == "asset") { struct SceneAsset asset; auto ret = (SceneAssetParser()).parse(c, &asset, error); if(ret != 0) return ret; out->assets.push_back(asset); } else if(c->node == "code") { struct SceneCode code; auto ret = (SceneCodeParser()).parse(c, &code, error); if(ret != 0) return ret; out->code.push_back(code); // Add Dep dep.type = SCENE_ITEM_DEPENDENCY_TYPE_CODE; dep.position = out->code.size() - 1; out->dependencies.push_back(dep); } else { struct SceneItemComponent component; component.registry = out->registry; auto ret = (SceneItemComponentParser()).parse(c, &component, error); if(ret != 0) return ret; out->components.push_back(component); // Add dep struct SceneItemDependency dep; dep.type = SCENE_ITEM_DEPENDENCY_TYPE_COMPONENT; dep.position = out->components.size() - 1; out->dependencies.push_back(dep); } ++itChildren; } return 0; }