diff --git a/app/gui/grid/modeling.cpp b/app/gui/grid/modeling.cpp index 22481408..e64927fb 100644 --- a/app/gui/grid/modeling.cpp +++ b/app/gui/grid/modeling.cpp @@ -76,11 +76,28 @@ static void show_grid_component_options(grid_component& grid) noexcept grid.opts = static_cast(selected_options); } - int selected_type = ordinal(grid.connection_type); - if (ImGui::Combo("Type", &selected_type, grid_type, grid_type_count)) { - if (selected_type != ordinal(grid.connection_type)) - grid.connection_type = - enum_cast(selected_type); + { + int selected_type = ordinal(grid.out_connection_type); + if (ImGui::Combo("Output connection type", + &selected_type, + grid_type, + grid_type_count)) { + if (selected_type != ordinal(grid.out_connection_type)) + grid.out_connection_type = + enum_cast(selected_type); + } + } + + { + int selected_type = ordinal(grid.in_connection_type); + if (ImGui::Combo("Input connection type", + &selected_type, + grid_type, + grid_type_count)) { + if (selected_type != ordinal(grid.in_connection_type)) + grid.in_connection_type = + enum_cast(selected_type); + } } int selected_neighbors = ordinal(grid.neighbors); @@ -120,73 +137,133 @@ static bool get_or_add_y(component& compo, std::string_view name) noexcept return false; } -static bool new_in_out(component& compo) noexcept +static bool new_in_out_x(component& compo) noexcept +{ + return get_or_add_x(compo, "in"); +} + +static bool new_in_out_y(component& compo) noexcept { - return get_or_add_x(compo, "in") and get_or_add_y(compo, "out"); + return get_or_add_y(compo, "out"); } -static bool new_number_4(component& compo) noexcept +static bool new_number_4_x(component& compo) noexcept { return get_or_add_x(compo, "45") and get_or_add_x(compo, "54") and - get_or_add_x(compo, "56") and get_or_add_x(compo, "65") and - get_or_add_y(compo, "45") and get_or_add_y(compo, "54") and + get_or_add_x(compo, "56") and get_or_add_x(compo, "65"); +} + +static bool new_number_4_y(component& compo) noexcept +{ + return get_or_add_y(compo, "45") and get_or_add_y(compo, "54") and get_or_add_y(compo, "56") and get_or_add_y(compo, "65"); } -static bool new_name_4(component& compo) noexcept +static bool new_name_4_x(component& compo) noexcept { return get_or_add_x(compo, "N") and get_or_add_x(compo, "S") and - get_or_add_x(compo, "W") and get_or_add_x(compo, "E") and - get_or_add_y(compo, "N") and get_or_add_y(compo, "S") and + get_or_add_x(compo, "W") and get_or_add_x(compo, "E"); +} + +static bool new_name_4_y(component& compo) noexcept +{ + return get_or_add_y(compo, "N") and get_or_add_y(compo, "S") and get_or_add_y(compo, "W") and get_or_add_y(compo, "E"); } -static bool new_number_8(component& compo) noexcept +static bool new_number_8_x(component& compo) noexcept { - return new_number_4(compo) and get_or_add_x(compo, "44") and + return new_number_4_x(compo) and get_or_add_x(compo, "44") and get_or_add_x(compo, "46") and get_or_add_x(compo, "64") and - get_or_add_x(compo, "66") and get_or_add_y(compo, "44") and + get_or_add_x(compo, "66"); +} + +static bool new_number_8_y(component& compo) noexcept +{ + return new_number_4_y(compo) and get_or_add_y(compo, "44") and get_or_add_y(compo, "46") and get_or_add_y(compo, "64") and get_or_add_y(compo, "66"); } -static bool new_name_8(component& compo) noexcept +static bool new_name_8_x(component& compo) noexcept { - return new_name_4(compo) and get_or_add_x(compo, "NW") and + return new_name_4_x(compo) and get_or_add_x(compo, "NW") and get_or_add_x(compo, "NE") and get_or_add_x(compo, "SW") and - get_or_add_x(compo, "SE") and get_or_add_y(compo, "NW") and + get_or_add_x(compo, "SE"); +} + +static bool new_name_8_y(component& compo) noexcept +{ + return new_name_4_y(compo) and get_or_add_y(compo, "NW") and get_or_add_y(compo, "NE") and get_or_add_y(compo, "SW") and get_or_add_y(compo, "SE"); } -static bool assign_name(grid_component& grid, component& compo) noexcept +static bool assign_name_x(grid_component& grid, component& compo) noexcept +{ + switch (grid.neighbors) { + case grid_component::neighborhood::four: + switch (grid.in_connection_type) { + case grid_component::type::in_out: + return new_in_out_x(compo); + + case grid_component::type::name: + return new_name_4_x(compo); + + case grid_component::type::number: + return new_number_4_x(compo); + } + + unreachable(); + break; + + case grid_component::neighborhood::eight: + switch (grid.in_connection_type) { + case grid_component::type::in_out: + return new_in_out_x(compo); + + case grid_component::type::name: + return new_name_8_x(compo); + + case grid_component::type::number: + return new_number_8_x(compo); + } + + unreachable(); + break; + } + + unreachable(); +} + +static bool assign_name_y(grid_component& grid, component& compo) noexcept { switch (grid.neighbors) { case grid_component::neighborhood::four: - switch (grid.connection_type) { + switch (grid.out_connection_type) { case grid_component::type::in_out: - return new_in_out(compo); + return new_in_out_y(compo); case grid_component::type::name: - return new_name_4(compo); + return new_name_4_y(compo); case grid_component::type::number: - return new_number_4(compo); + return new_number_4_y(compo); } unreachable(); break; case grid_component::neighborhood::eight: - switch (grid.connection_type) { + switch (grid.out_connection_type) { case grid_component::type::in_out: - return new_in_out(compo); + return new_in_out_y(compo); case grid_component::type::name: - return new_name_8(compo); + return new_name_8_y(compo); case grid_component::type::number: - return new_number_8(compo); + return new_number_8_y(compo); } unreachable(); @@ -196,6 +273,11 @@ static bool assign_name(grid_component& grid, component& compo) noexcept unreachable(); } +static bool assign_name(grid_component& grid, component& compo) noexcept +{ + return assign_name_x(grid, compo) and assign_name_y(grid, compo); +} + static void show_grid_editor_options(application& app, grid_component_editor_data& ed, grid_component& grid) noexcept diff --git a/lib/include/irritator/modeling.hpp b/lib/include/irritator/modeling.hpp index b8a48877..9927df7c 100644 --- a/lib/include/irritator/modeling.hpp +++ b/lib/include/irritator/modeling.hpp @@ -542,9 +542,10 @@ struct grid_component { //! @return success() or @c project::error::not_enough_memory. status build_cache(modeling& mod) noexcept; - options opts = options::none; - type connection_type = type::name; - neighborhood neighbors = neighborhood::four; + options opts = options::none; + type in_connection_type = type::name; + type out_connection_type = type::name; + neighborhood neighbors = neighborhood::four; }; /// random-graph type: diff --git a/lib/src/json.cpp b/lib/src/json.cpp index 107e0c7f..6354576f 100644 --- a/lib/src/json.cpp +++ b/lib/src/json.cpp @@ -475,8 +475,8 @@ struct reader { template bool for_members(const rapidjson::Value& val, - const std::string_view (&names)[N], - Function&& fn) noexcept + const std::string_view (&names)[N], + Function&& fn) noexcept { if (!val.IsObject()) report_json_error(error_id::value_not_object); @@ -1936,8 +1936,8 @@ struct reader { return nullptr; } - auto search_dir_in_reg(registred_path& reg, - std::string_view name) noexcept -> dir_path* + auto search_dir_in_reg(registred_path& reg, std::string_view name) noexcept + -> dir_path* { for (auto dir_id : reg.children) { if (auto* dir = mod().dir_paths.try_to_get(dir_id); dir) { @@ -2006,8 +2006,8 @@ struct reader { return nullptr; } - auto search_file(dir_path& dir, - std::string_view name) noexcept -> file_path* + auto search_file(dir_path& dir, std::string_view name) noexcept + -> file_path* { for (auto file_id : dir.children) if (auto* file = mod().file_paths.try_to_get(file_id); file) @@ -3180,9 +3180,13 @@ struct reader { is_int_less_than(grid_component::row_max) && copy_to(grid.column); - if ("connection-type"sv == name) + if ("in-connection-type"sv == name) return read_temp_integer(value) && - copy_to(grid.connection_type); + copy_to(grid.in_connection_type); + + if ("out-connection-type"sv == name) + return read_temp_integer(value) && + copy_to(grid.out_connection_type); if ("children"sv == name) return read_grid_children(value, grid); @@ -5590,8 +5594,10 @@ static void write_grid_component(cache_rw& /*cache*/, w.Int(grid.row); w.Key("columns"); w.Int(grid.column); - w.Key("connection-type"); - w.Int(ordinal(grid.connection_type)); + w.Key("in-connection-type"); + w.Int(ordinal(grid.in_connection_type)); + w.Key("out-connection-type"); + w.Int(ordinal(grid.out_connection_type)); w.Key("children"); w.StartArray(); diff --git a/lib/src/modeling-grid.cpp b/lib/src/modeling-grid.cpp index 8e36b061..2492ef25 100644 --- a/lib/src/modeling-grid.cpp +++ b/lib/src/modeling-grid.cpp @@ -177,9 +177,36 @@ void build_grid_connections(modeling& mod, std::array dests; std::array valids; - switch (grid.connection_type) { + switch (grid.out_connection_type) { case grid_component::type::in_out: srcs.fill(p_id::out); + break; + + case grid_component::type::name: + srcs[0] = { p_id::NE }; + srcs[1] = { p_id::NW }; + srcs[2] = { p_id::SE }; + srcs[3] = { p_id::SW }; + srcs[4] = { p_id::N }; + srcs[5] = { p_id::S }; + srcs[6] = { p_id::E }; + srcs[7] = { p_id::W }; + break; + + case grid_component::type::number: + srcs[0] = { p_id::n44 }; + srcs[1] = { p_id::n46 }; + srcs[2] = { p_id::n64 }; + srcs[3] = { p_id::n66 }; + srcs[4] = { p_id::n45 }; + srcs[5] = { p_id::n54 }; + srcs[6] = { p_id::n56 }; + srcs[7] = { p_id::n65 }; + break; + } + + switch (grid.in_connection_type) { + case grid_component::type::in_out: dests[0] = { row - 1, col - 1, p_id::in }; dests[1] = { row - 1, col + 1, p_id::in }; dests[2] = { row + 1, col - 1, p_id::in }; @@ -191,14 +218,6 @@ void build_grid_connections(modeling& mod, break; case grid_component::type::name: - srcs[0] = { p_id::NE }; - srcs[1] = { p_id::NW }; - srcs[2] = { p_id::SE }; - srcs[3] = { p_id::SW }; - srcs[4] = { p_id::N }; - srcs[5] = { p_id::S }; - srcs[6] = { p_id::E }; - srcs[7] = { p_id::W }; dests[0] = { row - 1, col - 1, p_id::SW }; dests[1] = { row - 1, col + 1, p_id::SE }; dests[2] = { row + 1, col - 1, p_id::NW }; @@ -210,14 +229,6 @@ void build_grid_connections(modeling& mod, break; case grid_component::type::number: - srcs[0] = { p_id::n44 }; - srcs[1] = { p_id::n46 }; - srcs[2] = { p_id::n64 }; - srcs[3] = { p_id::n66 }; - srcs[4] = { p_id::n45 }; - srcs[5] = { p_id::n54 }; - srcs[6] = { p_id::n56 }; - srcs[7] = { p_id::n65 }; dests[0] = { row - 1, col - 1, p_id::n66 }; dests[1] = { row + 1, col - 1, p_id::n64 }; dests[2] = { row + 1, col, p_id::n46 }; diff --git a/lib/test/mod-to-sim.cpp b/lib/test/mod-to-sim.cpp index 62ae805a..83bb83b2 100644 --- a/lib/test/mod-to-sim.cpp +++ b/lib/test/mod-to-sim.cpp @@ -560,9 +560,10 @@ int main() auto& cg = mod.alloc_grid_component(); auto& g = mod.grid_components.get(cg.id.grid_id); g.resize(5, 5, mod.components.get_id(c3)); - g.opts = irt::grid_component::options::none; - g.connection_type = irt::grid_component::type::in_out; - g.neighbors = irt::grid_component::neighborhood::four; + g.opts = irt::grid_component::options::none; + g.in_connection_type = irt::grid_component::type::in_out; + g.out_connection_type = irt::grid_component::type::in_out; + g.neighbors = irt::grid_component::neighborhood::four; expect(!!pj.set(mod, sim, cg)); expect(gt(g.cache_connections.ssize(), 0)); @@ -661,7 +662,8 @@ int main() auto& cg = mod.alloc_grid_component(); auto& g = mod.grid_components.get(cg.id.grid_id); g.resize(5, 5, mod.components.get_id(c3)); - g.connection_type = irt::grid_component::type::in_out; + g.in_connection_type = irt::grid_component::type::in_out; + g.out_connection_type = irt::grid_component::type::in_out; expect(!!pj.set(mod, sim, cg)); expect(eq(pj.tree_nodes_size().first, g.row * g.column * 3 + 1));