First pass at prefab tool (done)
This commit is contained in:
@ -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 + "/");
|
||||
@ -49,10 +47,42 @@ struct PrefabComponentParserRuleset PrefabRegistry::getRuleset(std::string type)
|
||||
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;
|
||||
|
||||
while(it != end) {
|
||||
std::smatch match = *it;
|
||||
|
||||
// return;
|
||||
assertUnreachable();
|
||||
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<type>, 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<std::string(std::string)> 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;
|
||||
}
|
||||
|
@ -11,10 +11,14 @@
|
||||
#include <regex>
|
||||
|
||||
namespace Dawn {
|
||||
enum PrefabcComponentParserRulesetType {
|
||||
STRIN
|
||||
};
|
||||
|
||||
struct PrefabComponentParserRuleset {
|
||||
std::string name;
|
||||
std::string include;
|
||||
std::map<std::string, std::function<std::string(std::string)>> optional;
|
||||
std::map<std::string, std::string> optional;
|
||||
};
|
||||
|
||||
struct PrefabRegistry {
|
||||
|
@ -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<std::string, enum DirectoryChildType> Directory::readDirectory() {
|
||||
this->close();
|
||||
if(!this->open()) return {};
|
||||
|
||||
std::map<std::string, enum DirectoryChildType> 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;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "util/File.hpp"
|
||||
#include <filesystem>
|
||||
|
||||
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);
|
||||
|
||||
|
Reference in New Issue
Block a user