Moved C++ tools out
This commit is contained in:
20
archive/dawntools/util/parser/CMakeLists.txt
Normal file
20
archive/dawntools/util/parser/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2023 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
set(D ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
set(
|
||||
DAWN_TOOL_SOURCES
|
||||
${DAWN_TOOL_SOURCES}
|
||||
${D}/SceneParser.cpp
|
||||
${D}/SceneItemParser.cpp
|
||||
${D}/SceneAssetParser.cpp
|
||||
${D}/SceneCodeParser.cpp
|
||||
${D}/SceneItemComponentParser.cpp
|
||||
${D}/SceneItemComponentRegistry.cpp
|
||||
|
||||
CACHE INTERNAL
|
||||
${DAWN_CACHE_TARGET}
|
||||
)
|
40
archive/dawntools/util/parser/SceneAssetParser.cpp
Normal file
40
archive/dawntools/util/parser/SceneAssetParser.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneAssetParser.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<std::string> SceneAssetParser::getRequiredAttributes() {
|
||||
return { "type", "name" };
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> SceneAssetParser::getOptionalAttributes() {
|
||||
return {
|
||||
{ "ref", "" }
|
||||
};
|
||||
}
|
||||
|
||||
int32_t SceneAssetParser::onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneAsset *out,
|
||||
std::string *error
|
||||
) {
|
||||
out->fileName = values["name"];
|
||||
|
||||
if(values["type"] == "texture") {
|
||||
out->type = SCENE_ASSET_TYPE_TEXTURE;
|
||||
} else if(values["type"] == "truetype") {
|
||||
out->type = SCENE_ASSET_TYPE_TRUETYPE_FONT;
|
||||
} else {
|
||||
*error = "Unknown asset type '" + values["type"] + "'";
|
||||
return 1;
|
||||
}
|
||||
|
||||
out->ref = values["ref"];
|
||||
|
||||
return 0;
|
||||
}
|
34
archive/dawntools/util/parser/SceneAssetParser.hpp
Normal file
34
archive/dawntools/util/parser/SceneAssetParser.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/XmlParser.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum SceneAssetType {
|
||||
SCENE_ASSET_TYPE_TEXTURE,
|
||||
SCENE_ASSET_TYPE_TRUETYPE_FONT
|
||||
};
|
||||
|
||||
struct SceneAsset {
|
||||
SceneAssetType type;
|
||||
std::string fileName;
|
||||
std::string usageName;
|
||||
std::string ref;
|
||||
};
|
||||
|
||||
class SceneAssetParser : public XmlParser<SceneAsset> {
|
||||
public:
|
||||
virtual std::vector<std::string> getRequiredAttributes();
|
||||
virtual std::map<std::string, std::string> getOptionalAttributes();
|
||||
|
||||
virtual int32_t onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneAsset *out,
|
||||
std::string *error
|
||||
);
|
||||
};
|
||||
}
|
41
archive/dawntools/util/parser/SceneCodeParser.cpp
Normal file
41
archive/dawntools/util/parser/SceneCodeParser.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneCodeParser.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<std::string> SceneCodeParser::getRequiredAttributes() {
|
||||
return { "type" };
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> SceneCodeParser::getOptionalAttributes() {
|
||||
return {};
|
||||
}
|
||||
|
||||
int32_t SceneCodeParser::onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneCode *out,
|
||||
std::string *error
|
||||
) {
|
||||
// Get the type
|
||||
std::string type = values["type"];
|
||||
if(type == "properties") {
|
||||
out->codeType = SCENE_CODE_TYPE_PROPERTIES;
|
||||
} else if(type == "init") {
|
||||
out->codeType = SCENE_CODE_TYPE_INIT;
|
||||
} else if(type == "include") {
|
||||
out->codeType = SCENE_CODE_TYPE_INCLUDE;
|
||||
} else {
|
||||
*error = "Invalid type '" + type + "' for SceneCode.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the code
|
||||
out->code = node->textContent;
|
||||
|
||||
return 0;
|
||||
}
|
33
archive/dawntools/util/parser/SceneCodeParser.hpp
Normal file
33
archive/dawntools/util/parser/SceneCodeParser.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/XmlParser.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum SceneCodeType {
|
||||
SCENE_CODE_TYPE_PROPERTIES,
|
||||
SCENE_CODE_TYPE_INIT,
|
||||
SCENE_CODE_TYPE_INCLUDE
|
||||
};
|
||||
|
||||
struct SceneCode {
|
||||
enum SceneCodeType codeType;
|
||||
std::string code;
|
||||
};
|
||||
|
||||
class SceneCodeParser : public XmlParser<struct SceneCode> {
|
||||
public:
|
||||
virtual std::vector<std::string> getRequiredAttributes();
|
||||
virtual std::map<std::string, std::string> getOptionalAttributes();
|
||||
|
||||
virtual int32_t onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneCode *out,
|
||||
std::string *error
|
||||
);
|
||||
};
|
||||
}
|
80
archive/dawntools/util/parser/SceneItemComponentParser.cpp
Normal file
80
archive/dawntools/util/parser/SceneItemComponentParser.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItemComponentParser.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<std::string> SceneItemComponentParser::getRequiredAttributes() {
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> SceneItemComponentParser::getOptionalAttributes() {
|
||||
return { { "ref", "" } };
|
||||
}
|
||||
|
||||
int32_t SceneItemComponentParser::onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneItemComponent *out,
|
||||
std::string *error
|
||||
) {
|
||||
// Check if values contains key "ref" and has a string of size more than 0
|
||||
if(values.find("ref") != values.end() && values["ref"].size() > 0) {
|
||||
out->ref = values["ref"];
|
||||
}
|
||||
|
||||
// Get the ruleset.
|
||||
auto ruleset = out->registry->getRuleset(node->node);
|
||||
if(ruleset.name.size() == 0) {
|
||||
*error = "Unknown prefab node type: " + node->node;
|
||||
return 1;
|
||||
}
|
||||
|
||||
out->include = ruleset.include;
|
||||
out->type = node->node;
|
||||
|
||||
// Define parser types here.
|
||||
|
||||
// Iterate all the optional attributes and store within the out if present
|
||||
auto itOptional = ruleset.optional.begin();
|
||||
while(itOptional != ruleset.optional.end()) {
|
||||
// Determine the parser to use
|
||||
auto name = itOptional->first;
|
||||
auto type = itOptional->second;
|
||||
|
||||
std::function<std::string(std::string, std::string*)> parser = rawParser;
|
||||
try {
|
||||
parser = parserFromTypeName(type);
|
||||
} catch(std::string err) {
|
||||
if(name[0] == '*') {
|
||||
name = name.substr(1, name.size());
|
||||
parser = rawParser;
|
||||
} else {
|
||||
*error = "Unknown parser for type: " + type + "::" + name;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(node->attributes.find(name) != node->attributes.end()) {
|
||||
auto raw = node->attributes[name];
|
||||
out->values[name] = parser(raw, error);
|
||||
if(error->size() != 0) return 1;
|
||||
}
|
||||
++itOptional;
|
||||
}
|
||||
|
||||
auto itInnerXml = ruleset.innerXml.begin();
|
||||
while(itInnerXml != ruleset.innerXml.end()) {
|
||||
auto name = itInnerXml->first;
|
||||
auto type = itInnerXml->second;
|
||||
|
||||
out->values[name] = stringParser(node->innerXml, error);
|
||||
if(error->size() != 0) return 1;
|
||||
++itInnerXml;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
30
archive/dawntools/util/parser/SceneItemComponentParser.hpp
Normal file
30
archive/dawntools/util/parser/SceneItemComponentParser.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/parser/SceneItemComponentRegistry.hpp"
|
||||
#include "util/parser/TypeParsers.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct SceneItemComponent {
|
||||
struct SceneItemComponentRegistry *registry;
|
||||
std::string include;
|
||||
std::string type;
|
||||
std::map<std::string, std::string> values;
|
||||
std::string ref;
|
||||
};
|
||||
|
||||
class SceneItemComponentParser : public XmlParser<struct SceneItemComponent> {
|
||||
protected:
|
||||
std::vector<std::string> getRequiredAttributes() override;
|
||||
std::map<std::string, std::string> getOptionalAttributes() override;
|
||||
int32_t onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneItemComponent *out,
|
||||
std::string *error
|
||||
) override;
|
||||
};
|
||||
}
|
203
archive/dawntools/util/parser/SceneItemComponentRegistry.cpp
Normal file
203
archive/dawntools/util/parser/SceneItemComponentRegistry.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItemComponentRegistry.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
struct SceneItemComponentRuleset SceneItemComponentRegistry::parseFile(
|
||||
File *file,
|
||||
std::string clazz
|
||||
) {
|
||||
assertNotNull(file, "SceneItemCOmponentRegistry::parseFile: File is null");
|
||||
|
||||
std::string data;
|
||||
if(!file->readString(&data)) {
|
||||
std::cout << "Failed to read ruleset file!" << std::endl;
|
||||
return { .name = "" };
|
||||
}
|
||||
|
||||
// Begin scanning contentsr
|
||||
// std::string include = this->sources;
|
||||
auto toRemove = File::normalizeSlashes(this->sources + FILE_PATH_SEP);
|
||||
auto includePath = file->filename.substr(toRemove.size(), file->filename.size() - toRemove.size());
|
||||
|
||||
// Now locate the first subdir since we don't want to include the root path (e.g. dawn, dawnrose, etc)
|
||||
auto firstSlash = includePath.find(FILE_PATH_SEP);
|
||||
if(firstSlash != std::string::npos) {
|
||||
includePath = includePath.substr(firstSlash + 1, includePath.size() - firstSlash - 1);
|
||||
}
|
||||
|
||||
struct SceneItemComponentRuleset ruleset;
|
||||
// Replace all file seps with slashes
|
||||
size_t pos = 0;
|
||||
while ((pos = includePath.find(FILE_PATH_SEP, pos)) != std::string::npos) {
|
||||
includePath.replace(pos, 1, "/");
|
||||
pos += 1;
|
||||
}
|
||||
ruleset.include = includePath;
|
||||
ruleset.name = clazz;
|
||||
|
||||
std::regex_constants::syntax_option_type regexFlags;
|
||||
#if defined(__GNUC__)
|
||||
regexFlags = std::regex_constants::ECMAScript | std::regex_constants::multiline;
|
||||
#else
|
||||
regexFlags = std::regex_constants::ECMAScript;
|
||||
#endif
|
||||
|
||||
// First, let's look for what class(es) this class extends
|
||||
std::regex regexClassName("class\\s+\\w+\\s+:\\s+", regexFlags);
|
||||
std::smatch match;
|
||||
if(std::regex_search(data, match, regexClassName)) {
|
||||
// Now find the next "{"
|
||||
auto matchStart = match.position() + match.length();
|
||||
auto openBracePos = data.find("{", matchStart);
|
||||
if(openBracePos == std::string::npos) {
|
||||
std::cout << "Failed to find open brace for class!" << std::endl;
|
||||
return { .name = "" };
|
||||
}
|
||||
|
||||
// Match each of the class names
|
||||
std::regex regexClass("(public\\s+(\\w+))[,\\s{]+", regexFlags);
|
||||
std::sregex_iterator itClass(data.begin() + matchStart, data.begin() + openBracePos, regexClass);
|
||||
std::sregex_iterator endClass;
|
||||
while(itClass != endClass) {
|
||||
// Get the class name
|
||||
auto className = itClass->str(2);
|
||||
itClass++;
|
||||
|
||||
// We don't parse interface classes
|
||||
if(className[0] == 'I') continue;
|
||||
ruleset.extends.push_back(className);
|
||||
}
|
||||
}
|
||||
|
||||
// Find each instance of "@optional" when it's used within a comment
|
||||
// e.g. // @optional or /* @optional */ in the string data.1
|
||||
std::regex regex("^\\s*(?:\\/\\/|\\/\\*){1}\\s*\\@(optional|innerXml)\\s*(?:\\*\\/)?\\s*$", regexFlags);
|
||||
std::sregex_iterator it(data.begin(), data.end(), regex);
|
||||
std::sregex_iterator end;
|
||||
while(it != end) {
|
||||
// Extract the kind of parameter this is
|
||||
std::smatch match;
|
||||
if(!std::regex_search(data, match, regex)) {
|
||||
std::cout << "Failed to determine parameter type!" << std::endl;
|
||||
return { .name = "" };
|
||||
}
|
||||
|
||||
std::string paramType = match[1].str();
|
||||
|
||||
// Find the next ";"
|
||||
auto endPos = data.find(";", it->position() + it->length());
|
||||
if(endPos == std::string::npos) {
|
||||
std::cout << "Failed to find end of line for attribute!" << std::endl;
|
||||
return { .name = "" };
|
||||
}
|
||||
|
||||
// Go backwards see if there's an equals sign after the match but before endPos
|
||||
auto equalsPos = data.rfind("=", endPos);
|
||||
|
||||
// If there's an equals sign, we search backwards from there,
|
||||
// otherwise we search backwards from the ;
|
||||
auto varStart = it->position() + it->length() + 1;
|
||||
size_t lastSearchPos = (
|
||||
(equalsPos == std::string::npos || equalsPos <= varStart) ?
|
||||
endPos :
|
||||
equalsPos
|
||||
);
|
||||
|
||||
// Now we have our string
|
||||
auto varLength = lastSearchPos - varStart;
|
||||
auto variableString = data.substr(varStart, varLength);
|
||||
|
||||
// Now (should) be able to extract the type;
|
||||
std::regex regex2("^\\s*(?:[\\S]+<)?([\\w*:_\\s]+)(?:[\\S]+)? (\\**[\\w]+)\\s*$", regexFlags);
|
||||
std::smatch match2;
|
||||
if(!std::regex_search(variableString, match2, regex2)) {
|
||||
std::cout << "Failed to extract type and name from variable string! " << variableString << std::endl;
|
||||
return { .name = "" };
|
||||
}
|
||||
|
||||
// Now we have our type and name
|
||||
auto type = match2[1].str();
|
||||
auto name = match2[2].str();
|
||||
|
||||
// Now store depending on the type
|
||||
if(paramType == "optional") {
|
||||
ruleset.selfOptional[name] = type;
|
||||
} else if(paramType == "innerXml") {
|
||||
ruleset.innerXml[name] = type;
|
||||
} else {
|
||||
assertUnreachable("SceneItemComponentRegistry::parseFile: Unknown parameter type");
|
||||
}
|
||||
++it;
|
||||
}
|
||||
return ruleset;
|
||||
}
|
||||
|
||||
struct SceneItemComponentRuleset SceneItemComponentRegistry::getRuleset(std::string type) {
|
||||
if(this->rulesets.find(type) != this->rulesets.end()) {
|
||||
return this->rulesets[type];
|
||||
}
|
||||
|
||||
std::vector<std::string> pathsToScan;
|
||||
pathsToScan.push_back(this->sources);
|
||||
|
||||
auto it = pathsToScan.begin();
|
||||
while(it != pathsToScan.end()) {
|
||||
auto str = *it;
|
||||
pathsToScan.erase(it);
|
||||
|
||||
Directory dir = Directory(str);
|
||||
auto children = dir.readDirectory();
|
||||
|
||||
auto itChildren = children.begin();
|
||||
while(itChildren != children.end()) {
|
||||
if(itChildren->second == DIRECTORY_CHILD_TYPE_DIRECTORY) {
|
||||
pathsToScan.push_back(str + "/" + itChildren->first);
|
||||
++itChildren;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(itChildren->first != type+".hpp") {
|
||||
++itChildren;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Load ruleset
|
||||
File file(str + "/" + itChildren->first);
|
||||
auto parsed = SceneItemComponentRegistry::parseFile(&file, type);
|
||||
if(parsed.name == "") {
|
||||
std::cout << "Parsing error occured on " << type << std::endl;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
// Update optionals
|
||||
parsed.optional.insert(parsed.selfOptional.begin(), parsed.selfOptional.end());
|
||||
|
||||
// Recursively parse children
|
||||
auto itExtends = parsed.extends.begin();
|
||||
while(itExtends != parsed.extends.end()) {
|
||||
auto ruleset = this->getRuleset(*itExtends);
|
||||
if(ruleset.name == "") {
|
||||
++itExtends;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Merge ruleset
|
||||
parsed.optional.insert(ruleset.optional.begin(), ruleset.optional.end());
|
||||
++itExtends;
|
||||
}
|
||||
|
||||
this->rulesets[type] = parsed;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
it = pathsToScan.begin();
|
||||
};
|
||||
|
||||
return { .name = "" };
|
||||
}
|
41
archive/dawntools/util/parser/SceneItemComponentRegistry.hpp
Normal file
41
archive/dawntools/util/parser/SceneItemComponentRegistry.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/DawnTool.hpp"
|
||||
#include "util/Directory.hpp"
|
||||
#include "util/XmlParser.hpp"
|
||||
#include "util/CodeGen.hpp"
|
||||
#include "util/string.hpp"
|
||||
#include <regex>
|
||||
|
||||
namespace Dawn {
|
||||
struct SceneItemComponentRuleset {
|
||||
std::string name;
|
||||
std::string include;
|
||||
std::map<std::string, std::string> selfOptional;
|
||||
std::map<std::string, std::string> innerXml;
|
||||
std::map<std::string, std::string> optional;
|
||||
std::vector<std::string> extends;
|
||||
};
|
||||
|
||||
struct SceneItemComponentRegistry {
|
||||
std::string sources;
|
||||
std::map<std::string, struct SceneItemComponentRuleset> rulesets;
|
||||
|
||||
struct SceneItemComponentRuleset parseFile(
|
||||
File *file,
|
||||
std::string clazz
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets a prefab component ruleset for a specific scene item component type.
|
||||
*
|
||||
* @param type Scene Item Component Type to get ruleset for.
|
||||
* @return The found ruleset, or an empty ruleset if not found.
|
||||
*/
|
||||
struct SceneItemComponentRuleset getRuleset(std::string type);
|
||||
};
|
||||
}
|
152
archive/dawntools/util/parser/SceneItemParser.cpp
Normal file
152
archive/dawntools/util/parser/SceneItemParser.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
// 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<std::string> SceneItemParser::getRequiredAttributes() {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> SceneItemParser::getOptionalAttributes() {
|
||||
return {
|
||||
{ "ref", "" },
|
||||
{ "position", "" },
|
||||
{ "lookAt", "" },
|
||||
{ "scale", "" },
|
||||
{ "prefab", "" },
|
||||
{ "alignment", "" },
|
||||
{ "alignX", "" },
|
||||
{ "aignY", "" },
|
||||
{ "menuX", "" },
|
||||
{ "menuY", "" },
|
||||
{ "label", "" }
|
||||
};
|
||||
}
|
||||
|
||||
int32_t SceneItemParser::onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> 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;
|
||||
}
|
55
archive/dawntools/util/parser/SceneItemParser.hpp
Normal file
55
archive/dawntools/util/parser/SceneItemParser.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/parser/SceneItemComponentParser.hpp"
|
||||
#include "util/parser/SceneAssetParser.hpp"
|
||||
#include "util/parser/SceneCodeParser.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum SceneItemDependencyType {
|
||||
SCENE_ITEM_DEPENDENCY_TYPE_ITEM,
|
||||
SCENE_ITEM_DEPENDENCY_TYPE_COMPONENT,
|
||||
SCENE_ITEM_DEPENDENCY_TYPE_CODE,
|
||||
};
|
||||
|
||||
struct SceneItemDependency {
|
||||
enum SceneItemDependencyType type;
|
||||
size_t position;
|
||||
};
|
||||
|
||||
struct SceneItem {
|
||||
struct SceneItemComponentRegistry *registry;
|
||||
std::string ref;
|
||||
std::string position;
|
||||
std::string alignment;
|
||||
std::string alignX;
|
||||
std::string alignY;
|
||||
std::string lookAtPosition;
|
||||
std::string lookAtTarget;
|
||||
std::string scale;
|
||||
std::string prefab;
|
||||
std::string menuX;
|
||||
std::string menuY;
|
||||
std::string label;
|
||||
std::vector<struct SceneItemComponent> components;
|
||||
std::vector<struct SceneItem> children;
|
||||
std::vector<struct SceneAsset> assets;
|
||||
std::vector<struct SceneCode> code;
|
||||
std::vector<struct SceneItemDependency> dependencies;
|
||||
};
|
||||
|
||||
class SceneItemParser : public XmlParser<struct SceneItem> {
|
||||
protected:
|
||||
std::vector<std::string> getRequiredAttributes() override;
|
||||
std::map<std::string, std::string> getOptionalAttributes() override;
|
||||
int32_t onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct SceneItem *out,
|
||||
std::string *error
|
||||
) override;
|
||||
};
|
||||
}
|
78
archive/dawntools/util/parser/SceneParser.cpp
Normal file
78
archive/dawntools/util/parser/SceneParser.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneParser.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<std::string> SceneParser::getRequiredAttributes() {
|
||||
return { "name" };
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> SceneParser::getOptionalAttributes() {
|
||||
return {
|
||||
{ "extend", "" }
|
||||
};
|
||||
}
|
||||
|
||||
int32_t SceneParser::onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct Scene *out,
|
||||
std::string *error
|
||||
) {
|
||||
int32_t ret;
|
||||
|
||||
//Create the scene item
|
||||
out->name = values["name"];
|
||||
out->extend = values["extend"];
|
||||
|
||||
struct SceneItemDependency dep;
|
||||
|
||||
//Parse the children
|
||||
auto itChildren = node->childNodes.begin();
|
||||
while(itChildren != node->childNodes.end()) {
|
||||
if(itChildren->nodeType != XML_NODE_TYPE_ELEMENT) {
|
||||
++itChildren;
|
||||
continue;
|
||||
}
|
||||
|
||||
Xml *child = itChildren->child;
|
||||
|
||||
if(child->node == "asset") {
|
||||
struct SceneAsset asset;
|
||||
auto ret = (SceneAssetParser()).parse(child, &asset, error);
|
||||
if(ret != 0) return ret;
|
||||
out->assets.push_back(asset);
|
||||
|
||||
} else if(child->node == "item") {
|
||||
struct SceneItem item;
|
||||
item.registry = out->registry;
|
||||
ret = (SceneItemParser()).parse(child, &item, error);
|
||||
if(ret != 0) return 1;
|
||||
out->items.push_back(item);
|
||||
|
||||
//Add the dependency
|
||||
dep.type = SCENE_ITEM_DEPENDENCY_TYPE_ITEM;
|
||||
dep.position = out->items.size() - 1;
|
||||
out->dependencies.push_back(dep);
|
||||
|
||||
} else if(child->node == "code") {
|
||||
struct SceneCode code;
|
||||
ret = (SceneCodeParser()).parse(child, &code, error);
|
||||
if(ret != 0) return ret;
|
||||
out->code.push_back(code);
|
||||
|
||||
//Add the dependency
|
||||
dep.type = SCENE_ITEM_DEPENDENCY_TYPE_CODE;
|
||||
dep.position = out->code.size() - 1;
|
||||
out->dependencies.push_back(dep);
|
||||
}
|
||||
|
||||
++itChildren;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
32
archive/dawntools/util/parser/SceneParser.hpp
Normal file
32
archive/dawntools/util/parser/SceneParser.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/parser/SceneItemParser.hpp"
|
||||
#include "util/parser/SceneCodeParser.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct Scene {
|
||||
std::string name;
|
||||
std::string extend;
|
||||
std::vector<struct SceneItem> items;
|
||||
std::vector<struct SceneCode> code;
|
||||
std::vector<struct SceneAsset> assets;
|
||||
struct SceneItemComponentRegistry *registry;
|
||||
std::vector<struct SceneItemDependency> dependencies;
|
||||
};
|
||||
|
||||
class SceneParser : public XmlParser<struct Scene> {
|
||||
protected:
|
||||
std::vector<std::string> getRequiredAttributes() override;
|
||||
std::map<std::string, std::string> getOptionalAttributes() override;
|
||||
int32_t onParse(
|
||||
Xml *node,
|
||||
std::map<std::string, std::string> values,
|
||||
struct Scene *out,
|
||||
std::string *error
|
||||
) override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user