Prefab tool improveed
This commit is contained in:
		@@ -58,33 +58,42 @@ struct PrefabComponentParserRuleset PrefabRegistry::getRuleset(std::string type)
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
              auto nextLineStart = data.rfind('\n', match.position() + match.length()) + 1;
 | 
			
		||||
              auto nextLineEnd = data.find('\n', nextLineStart);
 | 
			
		||||
              auto nextLine = data.substr(nextLineStart, nextLineEnd - nextLineStart);
 | 
			
		||||
              // ^\s*((?:struct[\s]+|enum[\s]+)?[^\s]+)\s+([^\s;=]+)(?:.*?);$
 | 
			
		||||
              std::regex regex2("(?:struct\\s+|enum\\s+)?(\\w+(?:::\\w+)*(?:\\s*\\*\\s*)?)\\s*(\\*?)\\s*(\\w+)\\s*(?:=\\s*(?:[^;{]+|\\{[^{}]*\\})|(?=;))?", std::regex_constants::ECMAScript);
 | 
			
		||||
              std::sregex_iterator it2(nextLine.begin(), nextLine.end(), regex2);
 | 
			
		||||
              std::sregex_iterator end2;
 | 
			
		||||
              while(it2 != end2) {
 | 
			
		||||
                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();
 | 
			
		||||
              // 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 optional attribute!" << std::endl;
 | 
			
		||||
                return { .name = "" };
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
                // Set a parser for this type
 | 
			
		||||
              // 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*$", std::regex_constants::ECMAScript);
 | 
			
		||||
              std::smatch match;
 | 
			
		||||
              if(!std::regex_search(variableString, match, 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 = match[1].str();
 | 
			
		||||
              auto name = match[2].str();
 | 
			
		||||
              ruleset.optional[name] = type;
 | 
			
		||||
                ++it2;
 | 
			
		||||
              }
 | 
			
		||||
              ++it;
 | 
			
		||||
            }
 | 
			
		||||
            return ruleset;
 | 
			
		||||
@@ -258,6 +267,7 @@ int32_t PrefabComponentParser::onParse(
 | 
			
		||||
  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)> parser = rawParser;
 | 
			
		||||
@@ -270,14 +280,17 @@ int32_t PrefabComponentParser::onParse(
 | 
			
		||||
    } else if(type.find("*") == (type.size() - 1)) {
 | 
			
		||||
      type = type.substr(0, type.size() - 1);
 | 
			
		||||
      parser = rawParser;
 | 
			
		||||
    } else if(name[0] == '*') {
 | 
			
		||||
      name = name.substr(1, name.size());
 | 
			
		||||
      parser = rawParser;
 | 
			
		||||
    } else {
 | 
			
		||||
      *error = "Unkown parser for type: " + type;
 | 
			
		||||
      *error = "Unkown parser for type: " + type + "::" + name;
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(node->attributes.find(itOptional->first) != node->attributes.end()) {
 | 
			
		||||
      auto raw = node->attributes[itOptional->first];
 | 
			
		||||
      out->values[itOptional->first] = parser(raw);
 | 
			
		||||
    if(node->attributes.find(name) != node->attributes.end()) {
 | 
			
		||||
      auto raw = node->attributes[name];
 | 
			
		||||
      out->values[name] = parser(raw);
 | 
			
		||||
    }
 | 
			
		||||
    ++itOptional;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user