Skip to content

Commit

Permalink
mod: improve generic/grid/graph error handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
quesnel committed May 28, 2024
1 parent d74c6d2 commit 45c451e
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 38 deletions.
100 changes: 93 additions & 7 deletions lib/include/irritator/modeling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ class generic_component
using child_limiter = static_limiter<i32, 64, 64 * 16>;
using connection_limiter = static_limiter<i32, 64 * 4, 64 * 16 * 4>;

struct children_error {};
struct connection_error {};
struct input_connection_error {};
struct output_connection_error {};

generic_component() noexcept;

generic_component(const child_limiter child_limit,
Expand Down Expand Up @@ -399,6 +404,15 @@ class generic_component
const std::span<parameter> 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 {
Expand Down Expand Up @@ -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:
Expand All @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand All @@ -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
70 changes: 61 additions & 9 deletions lib/src/modeling-generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ result<child_id> 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);
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -187,10 +195,10 @@ status generic_component::import(
{
table<child_id, child_id> 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;
Expand Down Expand Up @@ -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
48 changes: 43 additions & 5 deletions lib/src/modeling-graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<unsigned>(children.capacity()) });

const auto vec = build_graph_children(mod, *this);
build_graph_connections(mod, *this, vec);
Expand Down Expand Up @@ -488,10 +491,10 @@ result<input_connection_id> 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));
}
Expand All @@ -502,12 +505,47 @@ result<output_connection_id> 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
27 changes: 10 additions & 17 deletions lib/src/modeling-grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 45c451e

Please sign in to comment.