diff --git a/lib/include/irritator/modeling.hpp b/lib/include/irritator/modeling.hpp index 44030b30..fcb90aa4 100644 --- a/lib/include/irritator/modeling.hpp +++ b/lib/include/irritator/modeling.hpp @@ -289,6 +289,11 @@ class generic_component using child_limiter = static_limiter; using connection_limiter = static_limiter; + struct children_error {}; + struct connection_error {}; + struct input_connection_error {}; + struct output_connection_error {}; + generic_component() noexcept; generic_component(const child_limiter child_limit, @@ -399,6 +404,15 @@ class generic_component const std::span parameters = {}) noexcept; u64 make_next_unique_id() const noexcept { return next_unique_id++; } + + static auto build_error_handlers(log_manager& l) noexcept; + static void format_connection_error(log_entry& e) noexcept; + static void format_connection_full_error(log_entry& e) noexcept; + static void format_input_connection_error(log_entry& e) noexcept; + static void format_input_connection_full_error(log_entry& e) noexcept; + static void format_output_connection_error(log_entry& e) noexcept; + static void format_output_connection_full_error(log_entry& e) noexcept; + static void format_children_error(log_entry& e) noexcept; }; struct grid_component { @@ -560,11 +574,11 @@ struct grid_component { type out_connection_type = type::name; neighborhood neighbors = neighborhood::four; - auto build_error_handlers(log_manager& l) const noexcept; - void format_input_connection_error(log_entry& e) const noexcept; - void format_output_connection_error(log_entry& e) const noexcept; - void format_children_connection_error(log_entry& e, - e_memory* mem) const noexcept; + static auto build_error_handlers(log_manager& l) noexcept; + static void format_input_connection_error(log_entry& e) noexcept; + static void format_output_connection_error(log_entry& e) noexcept; + static void format_children_connection_error(log_entry& e, + e_memory mem) noexcept; }; /// random-graph type: @@ -581,6 +595,10 @@ class graph_component public: static inline constexpr i32 children_max = 4096; + struct input_connection_error {}; + struct output_connection_error {}; + struct children_error {}; + enum class vertex_id : u32; enum class edge_id : u32; @@ -722,6 +740,13 @@ class graph_component status build_cache(modeling& mod) noexcept; connection_type type = connection_type::name; + + static auto build_error_handlers(log_manager& l) noexcept; + static void format_input_connection_error(log_entry& e) noexcept; + static void format_input_connection_full_error(log_entry& e) noexcept; + static void format_output_connection_error(log_entry& e) noexcept; + static void format_output_connection_full_error(log_entry& e) noexcept; + static void format_children_error(log_entry& e, e_memory mem) noexcept; }; struct component { @@ -1712,7 +1737,7 @@ inline void project::for_each_children(tree_node& tn, } } -inline auto grid_component::build_error_handlers(log_manager& l) const noexcept +inline auto grid_component::build_error_handlers(log_manager& l) noexcept { return std::make_tuple( [&](input_connection_error, already_exist_error) { @@ -1723,12 +1748,73 @@ inline auto grid_component::build_error_handlers(log_manager& l) const noexcept l.push(log_level::error, [&](auto& e) { format_output_connection_error(e); }); }, - [&](children_connection_error, e_memory* mem) { + [&](children_connection_error, e_memory mem) { l.push(log_level::error, [&](auto& e) { format_children_connection_error(e, mem); }); }); } +inline auto graph_component::build_error_handlers(log_manager& l) noexcept +{ + return std::make_tuple( + [&](input_connection_error, already_exist_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_error(e); }); + }, + [&](input_connection_error, container_full_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_full_error(e); }); + }, + [&](output_connection_error, already_exist_error) { + l.push(log_level::error, + [&](auto& e) { format_output_connection_error(e); }); + }, + [&](output_connection_error, container_full_error) { + l.push(log_level::error, + [&](auto& e) { format_output_connection_full_error(e); }); + }, + [&](children_error, e_memory mem) { + l.push(log_level::error, + [&](auto& e) { format_children_error(e, mem); }); + }); +} + +inline auto generic_component::build_error_handlers(log_manager& l) noexcept +{ + return std::make_tuple( + [&](connection_error, container_full_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_error(e); }); + }, + [&](connection_error, already_exist_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_error(e); }); + }, + [&](connection_error, container_full_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_error(e); }); + }, + [&](input_connection_error, already_exist_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_error(e); }); + }, + [&](input_connection_error, container_full_error) { + l.push(log_level::error, + [&](auto& e) { format_input_connection_full_error(e); }); + }, + [&](output_connection_error, already_exist_error) { + l.push(log_level::error, + [&](auto& e) { format_output_connection_error(e); }); + }, + [&](output_connection_error, container_full_error) { + l.push(log_level::error, + [&](auto& e) { format_output_connection_full_error(e); }); + }, + [&](children_error, container_full_error) { + l.push(log_level::error, [&](auto& e) { format_children_error(e); }); + }); +} + } // namespace irt #endif diff --git a/lib/src/modeling-generic.cpp b/lib/src/modeling-generic.cpp index 377843b9..3c3eb899 100644 --- a/lib/src/modeling-generic.cpp +++ b/lib/src/modeling-generic.cpp @@ -40,7 +40,7 @@ result generic_component::copy_to( const auto src_idx = get_index(src_id); if (not dst.children.can_alloc()) - return new_error(modeling::part::children); + return new_error(children_error{}, container_full_error{}); auto& new_c = dst.children.alloc(); const auto new_c_id = dst.children.get_id(new_c); @@ -136,18 +136,18 @@ status generic_component::connect([[maybe_unused]] const modeling& mod, const connection::port p_dst) noexcept { if (exists(src, p_src, dst, p_dst)) - return new_error(modeling::part::connections); + return new_error(connection_error{}, already_exist_error{}); if (src.type == child_type::model) { if (dst.type == child_type::model) { if (not is_ports_compatible( src.id.mdl_type, p_src.model, dst.id.mdl_type, p_dst.model)) - return new_error(modeling::part::connections); + return new_error(connection_error{}, incompatibility_error{}); } } if (not connections.can_alloc(1)) - return new_error(modeling::part::connections); + return new_error(connection_error{}, container_full_error{}); connections.alloc(children.get_id(src), p_src, children.get_id(dst), p_dst); @@ -159,7 +159,11 @@ status generic_component::connect_input(const port_id x, const connection::port port) noexcept { if (not input_connections.can_alloc(1)) - return new_error(modeling::part::connections); + return new_error(input_connection_error{}, container_full_error{}); + + for (const auto& con : input_connections) + if (con.x == x and con.dst == children.get_id(dst) and con.port == port) + return new_error(input_connection_error{}, already_exist_error{}); input_connections.alloc(x, children.get_id(dst), port); @@ -171,7 +175,11 @@ status generic_component::connect_output(const port_id y, const connection::port port) noexcept { if (not output_connections.can_alloc(1)) - return new_error(modeling::part::connections); + return new_error(output_connection_error{}, container_full_error{}); + + for (const auto& con : output_connections) + if (con.y == y and con.src == children.get_id(src) and con.port == port) + return new_error(output_connection_error{}, already_exist_error{}); output_connections.alloc(y, children.get_id(src), port); @@ -187,10 +195,10 @@ status generic_component::import( { table src_to_this; - for (const auto& c : children) { - if (not this->children.can_alloc()) - return new_error(modeling::part::children); + if (not this->children.can_alloc(children.size())) + return new_error(children_error{}, container_full_error{}); + for (const auto& c : children) { auto& new_c = this->children.alloc(); new_c.type = c.type; new_c.id = c.id; @@ -256,4 +264,48 @@ status generic_component::import( return success(); } +void generic_component::format_connection_error(log_entry& e) noexcept +{ + e.buffer = "Internal connection already exists in this generic component"; + e.level = log_level::notice; +} + +void generic_component::format_connection_full_error(log_entry& e) noexcept +{ + e.buffer = "Internal connection list is full in this generic component"; + e.level = log_level::error; +} + +void generic_component::format_input_connection_error(log_entry& e) noexcept +{ + e.buffer = "Input connection already exists in this generic component"; + e.level = log_level::notice; +} + +void generic_component::format_input_connection_full_error( + log_entry& e) noexcept +{ + e.buffer = "Input connection list is full in this generic component"; + e.level = log_level::error; +} + +void generic_component::format_output_connection_error(log_entry& e) noexcept +{ + e.buffer = "Input connection already exists in this generic component"; + e.level = log_level::notice; +} + +void generic_component::format_output_connection_full_error( + log_entry& e) noexcept +{ + e.buffer = "Output connection list is full in this generic component"; + e.level = log_level::error; +} + +void generic_component::format_children_error(log_entry& e) noexcept +{ + e.buffer = "Not enough available space for model in this generic component"; + e.level = log_level::error; +} + } // namespace irt diff --git a/lib/src/modeling-graph.cpp b/lib/src/modeling-graph.cpp index c8eb1372..41c58e0d 100644 --- a/lib/src/modeling-graph.cpp +++ b/lib/src/modeling-graph.cpp @@ -401,7 +401,10 @@ status graph_component::build_cache(modeling& mod) noexcept cache.reserve(children.size()); if (not cache.can_alloc(children.size())) - return new_error(project::error::not_enough_memory); + return new_error( + graph_component::children_error{}, + e_memory{ children.size(), + static_cast(children.capacity()) }); const auto vec = build_graph_children(mod, *this); build_graph_connections(mod, *this, vec); @@ -488,10 +491,10 @@ result graph_component::connect_input( const port_id id) noexcept { if (exists_input_connection(x, v, id)) - return new_error(modeling::part::connections); + return new_error(input_connection_error{}, already_exist_error{}); if (not input_connections.can_alloc(1)) - return new_error(modeling::part::connections); + return new_error(input_connection_error{}, container_full_error{}); return input_connections.get_id(input_connections.alloc(x, v, id)); } @@ -502,12 +505,47 @@ result graph_component::connect_output( const port_id id) noexcept { if (exists_output_connection(y, v, id)) - return new_error(modeling::part::connections); + return new_error(input_connection_error{}, already_exist_error{}); if (not output_connections.can_alloc(1)) - return new_error(modeling::part::connections); + return new_error(input_connection_error{}, container_full_error{}); return output_connections.get_id(output_connections.alloc(y, v, id)); } +void graph_component::format_input_connection_error(log_entry& e) noexcept +{ + e.buffer = "Input connection already exists in this graph component"; + e.level = log_level::notice; +} + +void graph_component::format_input_connection_full_error(log_entry& e) noexcept +{ + e.buffer = "Input connection list is full in this graph component"; + e.level = log_level::error; +} + +void graph_component::format_output_connection_error(log_entry& e) noexcept +{ + e.buffer = "Input connection already exists in this graph component"; + e.level = log_level::notice; +} + +void graph_component::format_output_connection_full_error(log_entry& e) noexcept +{ + e.buffer = "Output connection list is full in this graph component"; + e.level = log_level::error; +} + +void graph_component::format_children_error(log_entry& e, e_memory mem) noexcept +{ + format(e.buffer, + "Not enough available space for model " + "in this grid component({}, {}) ", + mem.request, + mem.capacity); + + e.level = log_level::error; +} + } // namespace irt diff --git a/lib/src/modeling-grid.cpp b/lib/src/modeling-grid.cpp index 10cf5271..302d6261 100644 --- a/lib/src/modeling-grid.cpp +++ b/lib/src/modeling-grid.cpp @@ -384,34 +384,27 @@ status grid_component::build_cache(modeling& mod) noexcept return success(); } -void grid_component::format_input_connection_error(log_entry& e) const noexcept +void grid_component::format_input_connection_error(log_entry& e) noexcept { e.buffer = "Input connection already exists in this grid component"; e.level = log_level::notice; } -void grid_component::format_output_connection_error(log_entry& e) const noexcept +void grid_component::format_output_connection_error(log_entry& e) noexcept { e.buffer = "Input connection already exists in this grid component"; e.level = log_level::notice; } -void grid_component::format_children_connection_error( - log_entry& e, - e_memory* mem) const noexcept +void grid_component::format_children_connection_error(log_entry& e, + e_memory mem) noexcept { - if (mem) { - format(e.buffer, - "Not enough available space for model or connection " - "in this grid component({}, {}) ", - mem->request, - mem->capacity); - e.level = log_level::error; - } else { - e.buffer = "Not enough available space for model or " - "connection in this grid component"; - e.level = log_level::error; - } + format(e.buffer, + "Not enough available space for model or connection " + "in this grid component({}, {}) ", + mem.request, + mem.capacity); + e.level = log_level::error; } } // namespace irt