diff --git a/src/dawntools/prefabtool/PrefabTool.cpp b/src/dawntools/prefabtool/PrefabTool.cpp index 8aa70830..980fafc1 100644 --- a/src/dawntools/prefabtool/PrefabTool.cpp +++ b/src/dawntools/prefabtool/PrefabTool.cpp @@ -32,8 +32,6 @@ struct PrefabComponentParserRuleset PrefabRegistry::getRuleset(std::string type) 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 + "/"); @@ -48,11 +46,43 @@ struct PrefabComponentParserRuleset PrefabRegistry::getRuleset(std::string type) struct PrefabComponentParserRuleset ruleset; ruleset.include = includePath; ruleset.name = type; - + // Find each instance of "@optional" when it's used within a comment + // e.g. // @optional or /* @optional */ in the string data. + std::regex regex("^(\\s)*(\\/\\/|\\/\\*\\s*)(\\@optional)(\\s*\\*\\/)?(\\s)$", std::regex_constants::ECMAScript); + std::sregex_iterator it(data.begin(), data.end(), regex); + std::sregex_iterator end; - // return; - assertUnreachable(); + while(it != end) { + std::smatch match = *it; + + auto nextLineStart = data.rfind('\n', match.position() + match.length()) + 1; + auto nextLineEnd = data.find('\n', nextLineStart); + auto nextLine = data.substr(nextLineStart, nextLineEnd - nextLineStart); + + std::regex regex2("^\\s*([^\\s]+)\\s+([^\\s;]+)\\s*;", std::regex_constants::ECMAScript); + std::sregex_iterator it2(nextLine.begin(), nextLine.end(), regex2); + std::sregex_iterator end2; + while(it2 != end2) { + // Log out all matches + std::smatch match2 = *it2; + std::string type = match2[1].str(); + std::string name = match2[2].str(); + + // Type may be StateProperty, so we need to extract the type + auto regex3 = std::regex("^StateProperty<([^>]+)>$", std::regex_constants::ECMAScript); + std::smatch match3; + if(std::regex_match(type, match3, regex3)) { + type = match3[1].str(); + } + + // Set a parser for this type + ruleset.optional[name] = type; + ++it2; + } + ++it; + } + return ruleset; } } } @@ -192,13 +222,54 @@ int32_t PrefabComponentParser::onParse( out->include = ruleset.include; out->type = node->node; + // Define parser types here. + auto rawParser = [&](std::string v){ + return v; + }; + + auto stringParser = [&](std::string v){ + return "\"" + v + "\""; + }; + + auto floatParser = [&](std::string v){ + // Make sure number contains decimal + if(v.find(".") == std::string::npos) { + v += ".0"; + } + // Make sure number contains a number before the decimal + if(v.find(".") == 0) { + v = "0" + v; + } + // Make sure ends with f + if(v.find("f") == std::string::npos) { + v += "f"; + } + return v; + }; + + // 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 type = itOptional->second; + + std::function parser = rawParser; + if(type.find("string") != std::string::npos) { + parser = stringParser; + } else if(type.find("float") != std::string::npos) { + parser = floatParser; + } else if(type.find("*") == (type.size() - 1)) { + type = type.substr(0, type.size() - 1); + parser = rawParser; + } else { + *error = "Unkown parser for type: " + type; + return 1; + } + 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; + out->values[itOptional->first] = parser(raw); } ++itOptional; } diff --git a/src/dawntools/prefabtool/PrefabTool.hpp b/src/dawntools/prefabtool/PrefabTool.hpp index f65880e3..7b44b1e2 100644 --- a/src/dawntools/prefabtool/PrefabTool.hpp +++ b/src/dawntools/prefabtool/PrefabTool.hpp @@ -11,10 +11,14 @@ #include namespace Dawn { + enum PrefabcComponentParserRulesetType { + STRIN + }; + struct PrefabComponentParserRuleset { std::string name; std::string include; - std::map> optional; + std::map optional; }; struct PrefabRegistry { diff --git a/src/dawntools/util/Directory.cpp b/src/dawntools/util/Directory.cpp index 8bbc2bdd..225248c5 100644 --- a/src/dawntools/util/Directory.cpp +++ b/src/dawntools/util/Directory.cpp @@ -12,24 +12,24 @@ Directory::Directory(std::string dirname) { } bool_t Directory::open() { - if(this->handle) return true; - this->handle = opendir(this->filename.c_str()); - return this->handle != nullptr; + if(!this->exists()) return false; + if (handle != std::filesystem::end(handle)) return true; + handle = std::filesystem::directory_iterator(filename); + return handle != std::filesystem::end(handle); } bool_t Directory::isOpen() { - return this->handle != nullptr; + return handle != std::filesystem::end(handle); } void Directory::close() { - if(this->handle) { - closedir(this->handle); - this->handle = nullptr; + if(this->isOpen()) { + handle = std::filesystem::directory_iterator(); } } bool_t Directory::exists() { - return this->open(); + return std::filesystem::exists(filename); } void Directory::mkdirp() { @@ -37,20 +37,18 @@ void Directory::mkdirp() { } std::map Directory::readDirectory() { + this->close(); if(!this->open()) return {}; + std::map children; - - struct dirent *dp; - while((dp = readdir(this->handle)) != NULL) { - if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) { - continue; + for(const auto& entry : handle) { + if (entry.is_directory()) { + children[entry.path().filename().string()] = DIRECTORY_CHILD_TYPE_DIRECTORY; + } else if (entry.is_regular_file()) { + children[entry.path().filename().string()] = DIRECTORY_CHILD_TYPE_FILE; } - - //Skip anything that isn't a file or directory (symlinks, etc.) - if(dp->d_type != DT_DIR && dp->d_type != DT_REG) continue; - std::string fn = std::string(dp->d_name); - children[fn] = dp->d_type == DT_DIR ? DIRECTORY_CHILD_TYPE_DIRECTORY : DIRECTORY_CHILD_TYPE_FILE; } + this->close(); return children; } diff --git a/src/dawntools/util/Directory.hpp b/src/dawntools/util/Directory.hpp index fcf686d3..991a2d09 100644 --- a/src/dawntools/util/Directory.hpp +++ b/src/dawntools/util/Directory.hpp @@ -5,6 +5,7 @@ #pragma once #include "util/File.hpp" +#include namespace Dawn { enum DirectoryChildType { @@ -15,7 +16,7 @@ namespace Dawn { class Directory { public: std::string filename; - DIR *handle = nullptr; + std::filesystem::directory_iterator handle; Directory(std::string dir);