Half done with Scene Component Parsing

This commit is contained in:
2023-03-23 21:43:02 -07:00
parent 3782e731b2
commit 8c50c10be0
19 changed files with 308 additions and 411 deletions

View File

@@ -43,10 +43,15 @@ function(tool_prefab in)
set(DEPS prefabtool)
endif()
add_custom_target(prefab_${in}
COMMAND prefabtool --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_TEMP_DIR}"
STRING(REGEX REPLACE "[\.|\\|\/]" "-" prefab_name ${in})
add_custom_target(prefab_${prefab_name}
COMMAND prefabtool --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_GENERATED_DIR}/generatedprefabs" --sources="${DAWN_SOURCES_DIR}"
COMMENT "Generating prefab from ${in}"
DEPENDS ${DEPS}
)
add_dependencies(${DAWN_TARGET_NAME} prefab_${in})
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${DAWN_GENERATED_DIR}/generatedprefabs
)
add_dependencies(${DAWN_TARGET_NAME} prefab_${prefab_name})
endfunction()

View File

@@ -7,8 +7,67 @@
using namespace Dawn;
struct PrefabComponentParserRuleset PrefabRegistry::getRuleset(std::string 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);
} else {
if(itChildren->first == type+".hpp") {
// Load ruleset
std::string data;
File file(str + "/" + itChildren->first);
if(!file.readString(&data)) {
std::cout << "Failed to read ruleset file!" << file.filename << std::endl;
} else {
std::cout << "EPIC!" << file.filename << std::endl;
// Begin scanning contentsr
// std::string include = this->sources;
auto toRemove = File::normalizeSlashes(this->sources + "/");
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("/");
if(firstSlash != std::string::npos) {
includePath = includePath.substr(firstSlash + 1, includePath.size() - firstSlash - 1);
}
struct PrefabComponentParserRuleset ruleset;
ruleset.include = includePath;
ruleset.name = type;
// return;
assertUnreachable();
}
}
}
++itChildren;
}
it = pathsToScan.begin();
};
return { .name = "" };
}
//
std::vector<std::string> PrefabTool::getRequiredFlags() {
return { "input", "output" };
return { "input", "output", "sources" };
}
std::map<std::string, std::string> PrefabTool::getOptionalFlags() {
@@ -23,13 +82,23 @@ int32_t PrefabTool::start() {
}
std::string data;
if(!input.readString(&data)) return 1;
if(!input.readString(&data)) {
std::cout << "Failed to read input file!" << std::endl;
return 1;
}
struct PrefabRegistry registry;
registry.sources = flags["sources"];
auto xml = Xml::load(data);
std::string error;
struct Prefab prefab;
prefab.registry = &registry;
auto result = ((PrefabParser()).parse(&xml, &prefab, &error));
if(result != 0) return result;
if(result != 0) {
std::cout << "Failed to parse prefab: " << error << std::endl;
return result;
}
// Generate output
std::vector<std::string> outputData;
@@ -81,6 +150,8 @@ int32_t PrefabParser::onParse(
while(itChildren != node->children.end()) {
// Parse children as components
struct PrefabComponent component;
component.registry = out->registry;
auto ret = (PrefabComponentParser()).parse(*itChildren, &component, error);
if(ret != 0) return ret;
out->components.push_back(component);
@@ -111,44 +182,27 @@ int32_t PrefabComponentParser::onParse(
out->ref = values["ref"];
}
std::function<std::string(std::string)> stringParser = [&](std::string str) {
return "\"" + str + "\"";
};
// Handle different node types!
std::map<std::string, struct PrefabComponentParserRuleset> attributesForTypes = {
{ "UILabel", {
.include = "scene/components/ui/UILabel.hpp",
.optional = {
{ "text", stringParser }
}
} }
};
// Check if the node type is in the map
if(attributesForTypes.find(node->node) != attributesForTypes.end()) {
// Get the ruleset for this node type
auto ruleset = attributesForTypes[node->node];
out->include = ruleset.include;
out->type = node->node;
// Iterate all the optional attributes and store within the out if present
auto itOptional = ruleset.optional.begin();
while(itOptional != ruleset.optional.end()) {
if(node->attributes.find(itOptional->first) != node->attributes.end()) {
auto raw = node->attributes[itOptional->first];
auto parsed = itOptional->second(raw);
out->values[itOptional->first] = parsed;
}
++itOptional;
}
// TODO: Handle required attributes
} else {
*error = "Unknown node type: " + node->node;
// 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;
// Iterate all the optional attributes and store within the out if present
auto itOptional = ruleset.optional.begin();
while(itOptional != ruleset.optional.end()) {
if(node->attributes.find(itOptional->first) != node->attributes.end()) {
auto raw = node->attributes[itOptional->first];
auto parsed = itOptional->second(raw);
out->values[itOptional->first] = parsed;
}
++itOptional;
}
return 0;
}
@@ -162,7 +216,7 @@ void PrefabGen::generate(
struct ClassGenInfo classInfo;
classInfo.clazz = info->name;
classInfo.extend = "SceneItemPrefab<" + info->name + ">";
classInfo.constructorArgs = "Scene *scene, sceneid_t id";
classInfo.constructorArgs = "Scene *scene, sceneitemid_t id";
classInfo.extendArgs = "scene, id";
struct MethodGenInfo methodAssets;

View File

@@ -5,17 +5,27 @@
#pragma once
#include "util/DawnTool.hpp"
#include "util/File.hpp"
#include "util/Directory.hpp"
#include "util/XmlParser.hpp"
#include "util/CodeGen.hpp"
#include <regex>
namespace Dawn {
struct PrefabComponentParserRuleset {
std::string name;
std::string include;
std::map<std::string, std::function<std::string(std::string)>> optional;
};
struct PrefabRegistry {
std::string sources;
struct PrefabComponentParserRuleset getRuleset(std::string type);
};
struct PrefabComponent {
struct PrefabRegistry *registry;
std::string include;
std::string type;
std::map<std::string, std::string> values;
@@ -23,6 +33,8 @@ namespace Dawn {
};
struct Prefab {
struct PrefabRegistry *registry;
std::string name;
std::string type;
std::vector<struct PrefabComponent> components;