Half done with Scene Component Parsing
This commit is contained in:
@@ -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()
|
@@ -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 = ®istry;
|
||||
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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user