diff --git a/xml_converter/generators/code_generator.py b/xml_converter/generators/code_generator.py index c35fc1d1..dbd5c683 100644 --- a/xml_converter/generators/code_generator.py +++ b/xml_converter/generators/code_generator.py @@ -506,6 +506,7 @@ def generate_cpp_variable_data( cpp_includes.hpp_relative_includes.add("icon_gen.hpp") cpp_includes.hpp_relative_includes.add("trail_gen.hpp") + cpp_includes.cpp_absolute_includes.add("utility") cpp_includes.cpp_absolute_includes.add("type_traits") for filepath, document in sorted(self.data.items()): diff --git a/xml_converter/generators/cpp_templates/class_template.cpp b/xml_converter/generators/cpp_templates/class_template.cpp index 51932b58..2cf0f2d2 100644 --- a/xml_converter/generators/cpp_templates/class_template.cpp +++ b/xml_converter/generators/cpp_templates/class_template.cpp @@ -93,7 +93,12 @@ vector {{cpp_class}}::as_xml() const { return xml_node_contents; } -waypoint::{{cpp_class}} {{cpp_class}}::as_protobuf() const { +{% if cpp_class == "Category": %} + waypoint::{{cpp_class}} {{cpp_class}}::as_protobuf(string full_category_name, map>* parsed_pois) const { + full_category_name += this->name; +{% else %} + waypoint::{{cpp_class}} {{cpp_class}}::as_protobuf() const { +{% endif %} waypoint::{{cpp_class}} proto_{{cpp_class_header}}; {% if cpp_class == "Icon": %} waypoint::Trigger* trigger = nullptr; @@ -146,8 +151,24 @@ waypoint::{{cpp_class}} {{cpp_class}}::as_protobuf() const { } {% endif %} {% if cpp_class == "Category": %} + + auto pois = parsed_pois->find(full_category_name); + + if (pois != parsed_pois->end()) { + for (unsigned int i = 0; i < pois->second.size(); i++) { + if (pois->second[i]->classname() == "POI") { + Icon* icon = dynamic_cast(pois->second[i]); + proto_{{cpp_class_header}}.add_icon()->MergeFrom(icon->as_protobuf()); + } + else if (pois->second[i]->classname() == "Trail") { + Trail* trail = dynamic_cast(pois->second[i]); + proto_{{cpp_class_header}}.add_trail()->MergeFrom(trail->as_protobuf()); + } + } + } + for (const auto& [key, val] : this->children) { - waypoint::{{cpp_class}} proto_{{cpp_class_header}}_child = val.as_protobuf(); + waypoint::{{cpp_class}} proto_{{cpp_class_header}}_child = val.as_protobuf(full_category_name + ".", parsed_pois); proto_{{cpp_class_header}}.add_children()->CopyFrom(proto_{{cpp_class_header}}_child); } {% endif %} diff --git a/xml_converter/generators/cpp_templates/class_template.hpp b/xml_converter/generators/cpp_templates/class_template.hpp index 19d7aa26..72102bf5 100644 --- a/xml_converter/generators/cpp_templates/class_template.hpp +++ b/xml_converter/generators/cpp_templates/class_template.hpp @@ -34,7 +34,11 @@ class {{cpp_class}} : public Parseable { virtual std::vector as_xml() const; virtual std::string classname(); bool init_xml_attribute(rapidxml::xml_attribute<>* attribute, std::vector* errors, std::string base_dir = ""); - waypoint::{{cpp_class}} as_protobuf() const; + {% if cpp_class == "Category": %} + waypoint::{{cpp_class}} as_protobuf(std::string full_category_name, std::map>* parsed_pois) const; + {% else: %} + waypoint::{{cpp_class}} as_protobuf() const; + {% endif %} void parse_protobuf(waypoint::{{cpp_class}} proto_{{cpp_class_header}}); {% if attributes_of_type_marker_category %} bool validate_attributes_of_type_marker_category(); diff --git a/xml_converter/proto/waypoint.proto b/xml_converter/proto/waypoint.proto index 33545ca2..ab239d57 100644 --- a/xml_converter/proto/waypoint.proto +++ b/xml_converter/proto/waypoint.proto @@ -4,8 +4,6 @@ package waypoint; message Waypoint { repeated Category category = 1; - repeated Icon icon = 2; - repeated Trail trail = 3; } message Category { @@ -15,10 +13,11 @@ message Category { string name = 4; string tip_description = 5; repeated Category children = 6; + repeated Icon icon = 7; + repeated Trail trail = 8; } message Icon { - Category category = 1; TexturePath texture_path = 2; GUID guid = 3; int32 map_id = 4; @@ -53,10 +52,10 @@ message Icon { bool tentative__render_on_minimap = 2051; string bhdraft__schedule = 2052; float bhdraft__schedule_duration = 2053; + Category category = 2054; } message Trail { - Category category = 1; TexturePath texture_path = 2; GUID guid = 3; int32 map_id = 4; @@ -85,6 +84,7 @@ message Trail { bool tentative__render_on_minimap = 2051; string bhdraft__schedule = 2052; float bhdraft__schedule_duration = 2053; + Category category = 2054; } message TexturePath { diff --git a/xml_converter/src/category_gen.cpp b/xml_converter/src/category_gen.cpp index 392eff0b..f480a007 100644 --- a/xml_converter/src/category_gen.cpp +++ b/xml_converter/src/category_gen.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "attribute/bool.hpp" #include "attribute/string.hpp" @@ -94,7 +95,8 @@ vector Category::as_xml() const { return xml_node_contents; } -waypoint::Category Category::as_protobuf() const { +waypoint::Category Category::as_protobuf(string full_category_name, map>* parsed_pois) const { + full_category_name += this->name; waypoint::Category proto_category; if (this->default_visibility_is_set) { proto_category.set_default_visibility(this->default_visibility); @@ -111,8 +113,24 @@ waypoint::Category Category::as_protobuf() const { if (this->tooltip_description_is_set) { proto_category.set_tip_description(this->tooltip_description); } + + auto pois = parsed_pois->find(full_category_name); + + if (pois != parsed_pois->end()) { + for (unsigned int i = 0; i < pois->second.size(); i++) { + if (pois->second[i]->classname() == "POI") { + Icon* icon = dynamic_cast(pois->second[i]); + proto_category.add_icon()->MergeFrom(icon->as_protobuf()); + } + else if (pois->second[i]->classname() == "Trail") { + Trail* trail = dynamic_cast(pois->second[i]); + proto_category.add_trail()->MergeFrom(trail->as_protobuf()); + } + } + } + for (const auto& [key, val] : this->children) { - waypoint::Category proto_category_child = val.as_protobuf(); + waypoint::Category proto_category_child = val.as_protobuf(full_category_name + ".", parsed_pois); proto_category.add_children()->CopyFrom(proto_category_child); } return proto_category; diff --git a/xml_converter/src/category_gen.hpp b/xml_converter/src/category_gen.hpp index 3ef42874..89e7a96c 100644 --- a/xml_converter/src/category_gen.hpp +++ b/xml_converter/src/category_gen.hpp @@ -32,6 +32,6 @@ class Category : public Parseable { virtual std::vector as_xml() const; virtual std::string classname(); bool init_xml_attribute(rapidxml::xml_attribute<>* attribute, std::vector* errors, std::string base_dir = ""); - waypoint::Category as_protobuf() const; + waypoint::Category as_protobuf(std::string full_category_name, std::map>* parsed_pois) const; void parse_protobuf(waypoint::Category proto_category); }; diff --git a/xml_converter/src/xml_converter.cpp b/xml_converter/src/xml_converter.cpp index 1617b099..225819ba 100644 --- a/xml_converter/src/xml_converter.cpp +++ b/xml_converter/src/xml_converter.cpp @@ -104,27 +104,31 @@ void remove_proto_child(waypoint::Category* proto_category, set categori } void write_protobuf_file(string proto_directory, map* marker_categories, vector* parsed_pois) { - // Creates a Waypoint message that contains all categories - waypoint::Waypoint all_categories; - for (const auto& category : *marker_categories) { - waypoint::Category proto_category = category.second.as_protobuf(); - all_categories.add_category()->CopyFrom(proto_category); - } - waypoint::Waypoint proto_pois; // Collects a set of map ids from Icon and Trail data std::set map_ids; ofstream trail_data_file; + map> map_of_pois; for (const auto& parsed_poi : *parsed_pois) { if (parsed_poi->classname() == "POI") { Icon* icon = dynamic_cast(parsed_poi); map_ids.insert(icon->map_id); + map_of_pois[icon->category.category].push_back(icon); } else if (parsed_poi->classname() == "Trail") { Trail* trail = dynamic_cast(parsed_poi); map_ids.insert(trail->map_id); + map_of_pois[trail->category.category].push_back(trail); } } + + // Creates a Waypoint message that contains all categories + waypoint::Waypoint all_categories; + for (const auto& category : *marker_categories) { + waypoint::Category proto_category = category.second.as_protobuf("", &map_of_pois); + all_categories.add_category()->CopyFrom(proto_category); + } + waypoint::Waypoint output_message; std::set categories_to_retain; for (int map_id : map_ids) { @@ -138,15 +142,12 @@ void write_protobuf_file(string proto_directory, map* marker_c Icon* icon = dynamic_cast(parsed_poi); if (icon->map_id == map_id) { populate_categories_to_retain(icon->category.category, &categories_to_retain); - output_message.add_icon()->MergeFrom(icon->as_protobuf()); } } else if (parsed_poi->classname() == "Trail") { Trail* trail = dynamic_cast(parsed_poi); if (trail->map_id == map_id) { populate_categories_to_retain(trail->category.category, &categories_to_retain); - waypoint::Trail proto_trail = trail->as_protobuf(); - output_message.add_trail()->MergeFrom(proto_trail); } } } @@ -248,22 +249,6 @@ vector parse_pois(rapidxml::xml_node<>* root_node, map parse_proto_pois(waypoint::Waypoint proto_message) { - vector markers; - - for (int i = 0; i < proto_message.icon_size(); i++) { - Icon* icon = new Icon(); - icon->parse_protobuf(proto_message.icon(i)); - markers.push_back(icon); - } - for (int i = 0; i < proto_message.trail_size(); i++) { - Trail* trail = new Trail(); - trail->parse_protobuf(proto_message.trail(i)); - markers.push_back(trail); - } - return markers; -} - void parse_marker_categories(rapidxml::xml_node<>* node, map* marker_categories, vector* errors, int depth = 0) { if (get_node_name(node) == "MarkerCategory") { string name = lowercase(find_attribute_value(node, "name")); @@ -278,12 +263,31 @@ void parse_marker_categories(rapidxml::xml_node<>* node, map* errors->push_back(new XMLNodeNameError("Unknown MarkerCategory Tag", node)); } } -void parse_proto_marker_categories(::waypoint::Category proto_category, map* marker_categories) { - string name = proto_category.name(); - Category* this_category = &(*marker_categories)[name]; + +void parse_waypoint_categories(string full_category_name, ::waypoint::Category proto_category, map* marker_categories, vector* parsed_pois) { + full_category_name += proto_category.name(); + Category* this_category = &(*marker_categories)[full_category_name]; this_category->parse_protobuf(proto_category); + + for (int i = 0; i < proto_category.icon_size(); i++) { + Icon* icon = new Icon(); + icon->parse_protobuf(proto_category.icon(i)); + // TODO: The field category in Icon is being deprciated + // This overwrites any icon.category with its position in the heirarchy + icon->category.category = full_category_name; + parsed_pois->push_back(icon); + } + for (int i = 0; i < proto_category.trail_size(); i++) { + Trail* trail = new Trail(); + trail->parse_protobuf(proto_category.trail(i)); + // TODO: The field category in Trail is being deprciated + // This overwrites any trail.category with its position in the heirarchy + trail->category.category = full_category_name; + parsed_pois->push_back(trail); + } + for (int i = 0; i < proto_category.children_size(); i++) { - parse_proto_marker_categories(proto_category.children(i), &(this_category->children)); + parse_waypoint_categories(full_category_name + ".", proto_category.children(i), &(this_category->children), parsed_pois); } } @@ -335,10 +339,8 @@ void read_protobuf_file(string proto_filepath, map* marker_cat infile.open(proto_filepath, ios::in | ios::binary); proto_message.ParseFromIstream(&infile); for (int i = 0; i < proto_message.category_size(); i++) { - parse_proto_marker_categories(proto_message.category(i), marker_categories); + parse_waypoint_categories("", proto_message.category(i), marker_categories, parsed_pois); } - vector temp_vector = parse_proto_pois(proto_message); - move(temp_vector.begin(), temp_vector.end(), back_inserter(*parsed_pois)); } bool filename_comp(string a, string b) { @@ -506,24 +508,23 @@ int main() { cout << "The protobuf write function took " << ms << " milliseconds to run" << endl; //////////////////////////////////////////////////////////////////////////// - // This section tests that the protobuf file can be parsed back to xml + // This section can test that a protobuf file can be parsed back to xml //////////////////////////////////////////////////////////////////////////// - parsed_pois.clear(); - marker_categories.clear(); - - begin = chrono::high_resolution_clock::now(); - read_protobuf_file("./protobins/50.data", &marker_categories, &parsed_pois); - end = chrono::high_resolution_clock::now(); - dur = end - begin; - ms = std::chrono::duration_cast(dur).count(); - cout << "The protobuf read function took " << ms << " milliseconds to run" << endl; - - begin = chrono::high_resolution_clock::now(); - write_xml_file("./protobins/50.xml", &marker_categories, &parsed_pois); - end = chrono::high_resolution_clock::now(); - dur = end - begin; - ms = std::chrono::duration_cast(dur).count(); - cout << "The xml write function took " << ms << " milliseconds to run" << endl; + // parsed_pois.clear(); + // marker_categories.clear(); + // begin = chrono::high_resolution_clock::now(); + // read_protobuf_file("./protobins/1.data", &marker_categories, &parsed_pois); + // end = chrono::high_resolution_clock::now(); + // dur = end - begin; + // ms = std::chrono::duration_cast(dur).count(); + // cout << "The protobuf read function took " << ms << " milliseconds to run" << endl; + + // begin = chrono::high_resolution_clock::now(); + // write_xml_file("./protobins/1.xml", &marker_categories, &parsed_pois); + // end = chrono::high_resolution_clock::now(); + // dur = end - begin; + // ms = std::chrono::duration_cast(dur).count(); + // cout << "The xml write function took " << ms << " milliseconds to run" << endl; return 0; }