From c5712d126e31837d3bac0ea0023e54cfd39ff088 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Ji=C5=99i=C5=A1t=C4=9B?= Date: Sat, 21 Dec 2024 12:11:47 +0100 Subject: [PATCH] Switch from pointers to IDs Mosfets holding pointers to nodes (and nodes to mosfets) causes problems when the nodes (or mosfets) vector reallocates. The reallocation invalidates any pointers. Holding the ID prevents the invalidation, but may cause performance issues as the vector needs to be searched for the ID (binary search would help and is applicable). The IDs also make the code more networked, because the nodes and mosfets vectors need to be passed to many more functions. --- inc/FET_sim.h | 28 ++++++------ src/build_helper.c | 109 +++++++++++++++++++++++++++------------------ src/c_bind.c | 2 +- src/c_connect.c | 14 +++--- src/c_draw.c | 6 +-- src/colors.c | 54 +++++++++++----------- src/main.c | 5 ++- src/schema_mode.c | 22 ++++----- src/sim_main.c | 16 +++---- src/sim_node.c | 20 ++++----- 10 files changed, 147 insertions(+), 129 deletions(-) diff --git a/inc/FET_sim.h b/inc/FET_sim.h index f3d3351..a8c0a84 100644 --- a/inc/FET_sim.h +++ b/inc/FET_sim.h @@ -34,6 +34,8 @@ typedef enum e_type typedef unsigned long t_id; +extern const t_id INVALID_ID; + typedef enum e_orientation { UP = 0, @@ -72,9 +74,9 @@ typedef struct s_mosfet t_id id; int is_opened; t_type type; - t_node *gate; - t_node *source; - t_node *drain; + t_id gate; + t_id source; + t_id drain; t_position position; t_orientation orientation; } t_mosfet; @@ -137,22 +139,22 @@ t_node *add_node(t_vec *nodes, t_state set_state); t_mosfet *add_mosfet(t_vec *mosfets, t_type type, t_position pos, t_orientation orient); t_node *get_node_by_id(t_vec *nodes, t_id id); t_mosfet *get_mosfet_by_id(t_vec *mosfets, t_id id); -void bind_fet_node(t_mosfet *mosfet, t_node *node, t_terminal terminal); -t_node *get_node_of_terminal(t_mosfet *mosfet, t_terminal terminal); -int transfer_mosfet(t_mosfet *mosfet, t_node *from, t_node *to); -int merge_nodes(t_node *node1, t_node *node2); +void bind_fet_node(t_vec *nodes, t_mosfet *mosfet, t_node *node, t_terminal terminal); +t_node *get_node_of_terminal(t_vec *nodes, const t_mosfet *mosfet, t_terminal terminal); +int transfer_mosfet(t_vec *nodes, t_mosfet *mosfet, t_node *from, t_node *to); +int merge_nodes(t_vec *nodes, t_vec *mosfets, t_node *node1, t_node *node2); void free_node(void *node); int process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets); int get_input(WINDOW *command_win, t_input *input); const char *state_color_escape(t_state state); -void draw_single(WINDOW *command_win, const t_mosfet *mosfet); -void schema_draw_mosfet(WINDOW *schematics_win, const t_mosfet *mosfet); +void draw_single(WINDOW *command_win, t_vec *nodes, const t_mosfet *mosfet); +void schema_draw_mosfet(WINDOW *schematics_win, t_vec *nodes, const t_mosfet *mosfet); void schema_draw_node(WINDOW *schematics_win, const t_node *node); -void update_nodes(t_vec *nodes); -int should_open(const t_mosfet *mosfet); +void update_nodes(t_vec *nodes, t_vec *mosfets); +int should_open(t_vec *nodes, const t_mosfet *mosfet); int sim_step(t_vec *nodes, t_vec *mosfets); void setup_terminal(t_windows *windows); @@ -172,11 +174,11 @@ t_state resolve_state(t_vec *connected_nodes); void apply_state(t_state state, t_vec *connected_nodes); t_state reduce_state(t_state state); -int c_addfet(WINDOW *command_win, t_input input, t_vec *mosfets); +int c_addfet(WINDOW *command_win, t_input inputs, t_vec *mosfets); int c_addnode(WINDOW *command_win, t_input input, t_vec *nodes); int c_bind(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets); int c_connect(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets); -int c_draw(WINDOW *command_win, t_input input, t_vec *mosfets); +int c_draw(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets); int c_help(WINDOW *command_win, t_input input); int c_next(t_input input, t_vec *nodes, t_vec *mosfets); int c_setnode(WINDOW *command_win, t_input input, t_vec *nodes); diff --git a/src/build_helper.c b/src/build_helper.c index 0c2377f..ff0f6d9 100644 --- a/src/build_helper.c +++ b/src/build_helper.c @@ -1,36 +1,56 @@ #include "FET_sim.h" #include "libft.h" -int transfer_mosfet(t_mosfet *mosfet, t_node *from, t_node *to) +const t_id INVALID_ID = 0; + +int transfer_mosfet(t_vec *nodes, t_mosfet *mosfet, t_node *from, t_node *to) { - if (mosfet->source == from) - bind_fet_node(mosfet, to, source); - if (mosfet->gate == from) - bind_fet_node(mosfet, to, gate); - if (mosfet->drain == from) - bind_fet_node(mosfet, to, drain); + if (mosfet->source == from->id) + bind_fet_node(nodes, mosfet, to, source); + if (mosfet->gate == from->id) + bind_fet_node(nodes, mosfet, to, gate); + if (mosfet->drain == from->id) + bind_fet_node(nodes, mosfet, to, drain); return (0); } -// node 2 should be erased perhaps? -int merge_nodes(t_node *node1, t_node *node2) +t_mosfet *get_connected(t_vec *mosfets, t_vec *connected, size_t ind) +{ + t_id mosfet_id; + + mosfet_id = *(t_id *)ft_vec_access(connected, ind); + return (get_mosfet_by_id(mosfets, mosfet_id)); +} + +int node_identity(const void *, const void *); +static void remove_node(t_vec *nodes, t_node *to_remove) +{ + size_t index; + + if (ft_vec_find_index(nodes, to_remove, &index, node_identity) != success) + return ; + ft_vec_erase(nodes, index, free_node); + return ; +} + +int merge_nodes(t_vec *nodes, t_vec *mosfets, t_node *node1, t_node *node2) { size_t i; - t_mosfet **mosfet; + t_mosfet *mosfet; t_node_segment *seg; i = 0; while (i < node2->connected.size) { - mosfet = ft_vec_access(&node2->connected, i); - transfer_mosfet(*mosfet, node2, node1); + mosfet = get_connected(mosfets, &node2->connected, i); + transfer_mosfet(nodes, mosfet, node2, node1); ++i; } i = 0; while (i < node2->connected_gates.size) { - mosfet = ft_vec_access(&node2->connected_gates, i); - transfer_mosfet(*mosfet, node2, node1); + mosfet = get_connected(mosfets, &node2->connected_gates, i); + transfer_mosfet(nodes, mosfet, node2, node1); ++i; } i = 0; @@ -40,18 +60,18 @@ int merge_nodes(t_node *node1, t_node *node2) ft_vec_append(&node1->segments, seg); ++i; } - ft_vec_forget_range(&node2->segments, node2->segments.size, 0); + remove_node(nodes, node2); return (0); } -t_node *get_node_of_terminal(t_mosfet *mosfet, t_terminal terminal) +t_node *get_node_of_terminal(t_vec *nodes, const t_mosfet *mosfet, t_terminal terminal) { if (terminal == source) - return (mosfet->source); + return (get_node_by_id(nodes, mosfet->source)); if (terminal == gate) - return (mosfet->gate); + return (get_node_by_id(nodes, mosfet->gate)); if (terminal == drain) - return (mosfet->drain); + return (get_node_by_id(nodes, mosfet->drain)); return (NULL); } @@ -95,47 +115,48 @@ int mosfet_identity_indirect(const void *v_mosfet1_ptr, const void *v_mosfet2_pt return (mosfet_identity(*mosfet1, *mosfet2)); } -void bind_fet_node(t_mosfet *mosfet, t_node *node, t_terminal terminal) +static int id_equality(const void *v_id1, const void *v_id2) +{ + return (*(t_id *)v_id1 - *(t_id *)v_id2); +} + +void bind_fet_node(t_vec *nodes, t_mosfet *mosfet, t_node *node, t_terminal terminal) { - t_node *old; + t_node *old_node; size_t index; - old = NULL; + old_node = get_node_of_terminal(nodes, mosfet, terminal); if (terminal == source) { - old = mosfet->source; - mosfet->source = node; - ft_vec_append(&node->connected, &mosfet); - if (old && ft_vec_find_index(&node->connected, &mosfet, &index, mosfet_identity_indirect) == success) - ft_vec_forget(&old->connected, index); + mosfet->source = node->id; + ft_vec_append(&node->connected, &(mosfet->id)); + if (old_node && ft_vec_find_index(&node->connected, &(mosfet->id), &index, id_equality) == success) + ft_vec_forget(&old_node->connected, index); } else if (terminal == drain) { - old = mosfet->drain; - mosfet->drain = node; - ft_vec_append(&node->connected, &mosfet); - if (old && ft_vec_find_index(&node->connected, &mosfet, &index, mosfet_identity_indirect) == success) - ft_vec_forget(&old->connected, index); + mosfet->drain = node->id; + ft_vec_append(&node->connected, &(mosfet->id)); + if (old_node && ft_vec_find_index(&node->connected, &(mosfet->id), &index, id_equality) == success) + ft_vec_forget(&old_node->connected, index); } else { - old = mosfet->gate; - mosfet->gate = node; - ft_vec_append(&node->connected_gates, &mosfet); - if (old && ft_vec_find_index(&node->connected_gates, &mosfet, &index, mosfet_identity_indirect) == success) - ft_vec_forget(&old->connected_gates, index); + mosfet->gate = node->id; + ft_vec_append(&node->connected_gates, &(mosfet->id)); + if (old_node && ft_vec_find_index(&node->connected_gates, &(mosfet->id), &index, id_equality) == success) + ft_vec_forget(&old_node->connected_gates, index); } return ; } static t_id get_new_id(void) { - static t_id id = 0; + static t_id id = INVALID_ID + 1; return (id++); } -// memset is used to initialize struct padding t_node *add_node(t_vec *nodes, t_state set_state) { t_node node; @@ -144,8 +165,8 @@ t_node *add_node(t_vec *nodes, t_state set_state) node.checked = 0; node.state = set_state; node.set_state = set_state; - ft_vec_init(&node.connected, sizeof(t_mosfet *)); - ft_vec_init(&node.connected_gates, sizeof(t_mosfet *)); + ft_vec_init(&node.connected, sizeof(t_id)); + ft_vec_init(&node.connected_gates, sizeof(t_id)); ft_vec_init(&node.segments, sizeof(t_node_segment)); ft_vec_append(nodes, &node); return (ft_vec_access(nodes, nodes->size - 1)); @@ -158,9 +179,9 @@ t_mosfet *add_mosfet(t_vec *mosfets, t_type type, t_position pos, t_orientation mosfet.id = get_new_id(); mosfet.is_opened = 0; mosfet.type = type; - mosfet.gate = NULL; - mosfet.drain = NULL; - mosfet.source = NULL; + mosfet.gate = INVALID_ID; + mosfet.drain = INVALID_ID; + mosfet.source = INVALID_ID; mosfet.position = pos; mosfet.orientation = orient; ft_vec_append(mosfets, &mosfet); diff --git a/src/c_bind.c b/src/c_bind.c index 3ff7552..2716f99 100644 --- a/src/c_bind.c +++ b/src/c_bind.c @@ -27,6 +27,6 @@ int c_bind(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets) return (1); } term = input.argv[2].val.terminal; - bind_fet_node(mosfet, node, term); + bind_fet_node(nodes, mosfet, node, term); return (1); } diff --git a/src/c_connect.c b/src/c_connect.c index d9361ed..46d6488 100644 --- a/src/c_connect.c +++ b/src/c_connect.c @@ -15,25 +15,25 @@ int c_connect(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets) print_mosfet_id_error(command_win, input.argv[0].val.num); return (1); } - term_node1 = get_node_of_terminal(mosfet1, input.argv[1].val.terminal); + term_node1 = get_node_of_terminal(nodes, mosfet1, input.argv[1].val.terminal); mosfet2 = get_mosfet_by_id(mosfets, input.argv[2].val.num); if (!mosfet2) { print_mosfet_id_error(command_win, input.argv[2].val.num); return (1); } - term_node2 = get_node_of_terminal(mosfet2, input.argv[3].val.terminal); + term_node2 = get_node_of_terminal(nodes, mosfet2, input.argv[3].val.terminal); if (term_node1 && term_node2) - return (!merge_nodes(term_node1, term_node2)); + return (!merge_nodes(nodes, mosfets, term_node1, term_node2)); else if (term_node1) - bind_fet_node(mosfet2, term_node1, input.argv[3].val.terminal); + bind_fet_node(nodes, mosfet2, term_node1, input.argv[3].val.terminal); else if (term_node2) - bind_fet_node(mosfet1, term_node2, input.argv[1].val.terminal); + bind_fet_node(nodes, mosfet1, term_node2, input.argv[1].val.terminal); else { new_node = add_node(nodes, unknown); - bind_fet_node(mosfet1, new_node, input.argv[1].val.terminal); - bind_fet_node(mosfet2, new_node, input.argv[3].val.terminal); + bind_fet_node(nodes, mosfet1, new_node, input.argv[1].val.terminal); + bind_fet_node(nodes, mosfet2, new_node, input.argv[3].val.terminal); } return (1); } diff --git a/src/c_draw.c b/src/c_draw.c index 2852ee1..f06b542 100644 --- a/src/c_draw.c +++ b/src/c_draw.c @@ -1,7 +1,7 @@ #include "FET_sim.h" #include "libft.h" -int c_draw(WINDOW *command_win, t_input input, t_vec *mosfets) +int c_draw(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets) { size_t i; const t_mosfet *mosfet; @@ -12,7 +12,7 @@ int c_draw(WINDOW *command_win, t_input input, t_vec *mosfets) while (i < mosfets->size) { mosfet = ft_vec_caccess(mosfets, i); - draw_single(command_win, ft_vec_caccess(mosfets, i)); + draw_single(command_win, nodes, ft_vec_caccess(mosfets, i)); ++i; } } @@ -22,7 +22,7 @@ int c_draw(WINDOW *command_win, t_input input, t_vec *mosfets) if (!mosfet) print_mosfet_id_error(command_win, input.argv[0].val.num); else - draw_single(command_win, mosfet); + draw_single(command_win, nodes, mosfet); } /*else { diff --git a/src/colors.c b/src/colors.c index 6f6d945..0f6cada 100644 --- a/src/colors.c +++ b/src/colors.c @@ -41,16 +41,16 @@ static t_nc_color get_state_color(t_state state) return (NC_RED); } -static t_nc_color get_switch_color(const t_mosfet *mosfet) +static t_nc_color get_switch_color(t_vec *nodes, const t_mosfet *mosfet) { t_nc_color color; if (mosfet->is_opened) { - if (mosfet->source) - color = get_state_color(mosfet->source->state); - else if (mosfet->drain) - color = get_state_color(mosfet->drain->state); + if (mosfet->source != INVALID_ID) + color = get_state_color(get_node_of_terminal(nodes, mosfet, source)->state); + else if (mosfet->drain != INVALID_ID) + color = get_state_color(get_node_of_terminal(nodes, mosfet, drain)->state); else color = NC_RED; } @@ -87,18 +87,18 @@ static void print_in_color(WINDOW *command_win, const char *str, t_nc_color colo return ; } -static void draw_switch(WINDOW *win, const t_mosfet *mosfet, t_orientation orientation) +static void draw_switch(WINDOW *win, t_vec *nodes, const t_mosfet *mosfet, t_orientation orientation) { t_nc_color color; t_switch_symbol_set set; t_symbol switch_sym; - color = get_switch_color(mosfet); + color = get_switch_color(nodes, mosfet); set = get_switch_set(orientation); - if (mosfet->is_opened && should_open(mosfet)) + if (mosfet->is_opened && should_open(nodes, mosfet)) switch_sym = set.open; - else if ((mosfet->is_opened && !should_open(mosfet)) - || (!mosfet->is_opened && should_open(mosfet))) + else if ((mosfet->is_opened && !should_open(nodes, mosfet)) + || (!mosfet->is_opened && should_open(nodes, mosfet))) switch_sym = set.transition; else switch_sym = set.closed; @@ -108,7 +108,7 @@ static void draw_switch(WINDOW *win, const t_mosfet *mosfet, t_orientation orien return ; } -void schema_draw_mosfet(WINDOW *schematics_win, const t_mosfet *mosfet) +void schema_draw_mosfet(WINDOW *schematics_win, t_vec *nodes, const t_mosfet *mosfet) { t_position old_pos; t_position work_pos; @@ -125,7 +125,7 @@ void schema_draw_mosfet(WINDOW *schematics_win, const t_mosfet *mosfet) else if (mosfet->orientation == RIGHT) --work_pos.x; wmove(schematics_win, work_pos.y, work_pos.x); - draw_switch(schematics_win, mosfet, mosfet->orientation); + draw_switch(schematics_win, nodes, mosfet, mosfet->orientation); wmove(schematics_win, old_pos.y, old_pos.x); return ; } @@ -162,12 +162,12 @@ void schema_draw_node(WINDOW *schematics_win, const t_node *node) return ; } -static void draw_top(WINDOW *command_win, const t_mosfet *mosfet) +static void draw_top(WINDOW *command_win, t_vec *nodes, const t_mosfet *mosfet) { if (mosfet->source) { - wprintw(command_win, " %lu\n", mosfet->source->id); - print_in_color(command_win, " |\n", get_state_color(mosfet->source->state)); + wprintw(command_win, " %lu\n", mosfet->source); + print_in_color(command_win, " |\n", get_state_color(get_node_of_terminal(nodes, mosfet, source)->state)); } else { @@ -177,41 +177,41 @@ static void draw_top(WINDOW *command_win, const t_mosfet *mosfet) return ; } -static void draw_middle(WINDOW *command_win, const t_mosfet *mosfet) +static void draw_middle(WINDOW *command_win, t_vec *nodes, const t_mosfet *mosfet) { if (mosfet->gate) { - wprintw(command_win, "%4lu", mosfet->gate->id); - print_in_color(command_win, "-", get_state_color(mosfet->gate->state)); + wprintw(command_win, "%4lu", mosfet->gate); + print_in_color(command_win, "-", get_state_color(get_node_of_terminal(nodes, mosfet, gate)->state)); } else print_in_color(command_win, "NULL-", NC_RED); waddch(command_win, mosfet->type); - draw_switch(command_win, mosfet, LEFT); + draw_switch(command_win, nodes, mosfet, LEFT); waddch(command_win, '\n'); return ; } -static void draw_bottom(WINDOW *command_win, const t_mosfet *mosfet) +static void draw_bottom(WINDOW *command_win, t_vec *nodes, const t_mosfet *mosfet) { wprintw(command_win, " "); if (mosfet->drain) - print_in_color(command_win, "|\n", get_state_color(mosfet->drain->state)); + print_in_color(command_win, "|\n", get_state_color(get_node_of_terminal(nodes, mosfet, drain)->state)); else print_in_color(command_win, "|\n", NC_RED); if (mosfet->drain) - wprintw(command_win, " %lu", mosfet->drain->id); + wprintw(command_win, " %lu", mosfet->drain); else print_in_color(command_win, " NULL", NC_RED); wprintw(command_win, "\n\n"); return ; } -void draw_single(WINDOW *command_win, const t_mosfet *mosfet) +void draw_single(WINDOW *command_win, t_vec *nodes, const t_mosfet *mosfet) { - draw_top(command_win, mosfet); - draw_middle(command_win, mosfet); - draw_bottom(command_win, mosfet); + draw_top(command_win, nodes, mosfet); + draw_middle(command_win, nodes, mosfet); + draw_bottom(command_win, nodes, mosfet); return ; } @@ -226,7 +226,7 @@ int refresh_schema_win(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets) while (i < mosfets->size) { mosfet = ft_vec_caccess(mosfets, i); - schema_draw_mosfet(schematics_win, mosfet); + schema_draw_mosfet(schematics_win, nodes, mosfet); ++i; } i = 0; diff --git a/src/main.c b/src/main.c index e6cf3fe..9ba80e2 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,7 @@ void build_graph(const char *filename, t_vec *nodes, t_vec *mosfets) void free_node(void *node) { ft_vec_free(&((t_node *)node)->connected, NULL); + ft_vec_free(&((t_node *)node)->connected_gates, NULL); return ; } @@ -230,7 +231,7 @@ int process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets) if (input.command == next) res = c_next(input, nodes, mosfets); else if (input.command == draw) - res = c_draw(windows->command_win, input, mosfets); + res = c_draw(windows->command_win, input, nodes, mosfets); else if (input.command == setnode) res = c_setnode(windows->command_win, input, nodes); else if (input.command == addnode) @@ -254,7 +255,7 @@ int process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets) void cleanup(t_vec *nodes, t_vec *mosfets, t_windows *windows) { - update_nodes(NULL); + update_nodes(NULL, NULL); ft_vec_free(nodes, free_node); ft_vec_free(mosfets, NULL); clean_terminal(windows); diff --git a/src/schema_mode.c b/src/schema_mode.c index fd0626c..6153414 100644 --- a/src/schema_mode.c +++ b/src/schema_mode.c @@ -101,22 +101,14 @@ void add_terminal_segment(t_node *node, t_mosfet *mosfet, t_terminal term) } -void add_terminal_nodes(WINDOW *schematics_win, t_vec *nodes, t_mosfet *mosfet) +void add_terminal_node(WINDOW *schematics_win, t_vec *nodes, t_mosfet *mosfet, t_terminal terminal) { t_node *node; node = add_node(nodes, floating); - bind_fet_node(mosfet, node, source); - node = add_node(nodes, floating); - bind_fet_node(mosfet, node, gate); - node = add_node(nodes, floating); - bind_fet_node(mosfet, node, drain); - add_terminal_segment(mosfet->source, mosfet, source); - add_terminal_segment(mosfet->gate, mosfet, gate); - add_terminal_segment(mosfet->drain, mosfet, drain); - schema_draw_node(schematics_win, mosfet->source); - schema_draw_node(schematics_win, mosfet->gate); - schema_draw_node(schematics_win, mosfet->drain); + bind_fet_node(nodes, mosfet, node, terminal); + add_terminal_segment(node, mosfet, terminal); + schema_draw_node(schematics_win, node); return ; } @@ -146,7 +138,7 @@ void schema_add_mosfet(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets, t_p return ; while (1) { - schema_draw_mosfet(schematics_win, mosfet); + schema_draw_mosfet(schematics_win, nodes, mosfet); ch = wgetch(schematics_win); if (ch == 'r' || ch == 'R') { @@ -164,7 +156,9 @@ void schema_add_mosfet(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets, t_p mosfet->orientation = (mosfet->orientation - 1 + 4) % 4; else { - add_terminal_nodes(schematics_win, nodes, mosfet); + add_terminal_node(schematics_win, nodes, mosfet, source); + add_terminal_node(schematics_win, nodes, mosfet, gate); + add_terminal_node(schematics_win, nodes, mosfet, drain); wmove(schematics_win, mosfet->position.y, mosfet->position.x); ungetch(ch); return ; diff --git a/src/sim_main.c b/src/sim_main.c index a161a5e..cb52bf1 100644 --- a/src/sim_main.c +++ b/src/sim_main.c @@ -2,15 +2,15 @@ #include "libft.h" // Maybe an error should be return when gate is NULL -int should_open(const t_mosfet *mosfet) +int should_open(t_vec *nodes, const t_mosfet *mosfet) { - if (!mosfet->gate) + if (mosfet->gate == INVALID_ID) return (0); - return ((mosfet->type == p && mosfet->gate->state == off) - || (mosfet->type == n && mosfet->gate->state == on)); + return ((mosfet->type == p && get_node_of_terminal(nodes, mosfet, gate)->state == off) + || (mosfet->type == n && get_node_of_terminal(nodes, mosfet, gate)->state == on)); } -static void update_mosfets(t_vec *mosfets) +static void update_mosfets(t_vec *nodes, t_vec *mosfets) { size_t i; t_mosfet *mosfet; @@ -19,7 +19,7 @@ static void update_mosfets(t_vec *mosfets) while (i < mosfets->size) { mosfet = ft_vec_access(mosfets, i); - mosfet->is_opened = should_open(mosfet); + mosfet->is_opened = should_open(nodes, mosfet); ++i; } return ; @@ -27,7 +27,7 @@ static void update_mosfets(t_vec *mosfets) int sim_step(t_vec *nodes, t_vec *mosfets) { - update_mosfets(mosfets); - update_nodes(nodes); + update_mosfets(nodes, mosfets); + update_nodes(nodes, mosfets); return (1); } diff --git a/src/sim_node.c b/src/sim_node.c index 1b35650..745d21e 100644 --- a/src/sim_node.c +++ b/src/sim_node.c @@ -2,14 +2,14 @@ #include "libft.h" #include -static t_node *get_neighbour_node(const t_mosfet *mosfet, const t_node *start) +static t_node *get_neighbour_node(t_vec *nodes, const t_mosfet *mosfet, const t_node *start) { - if (mosfet->source == start) - return (mosfet->drain); - return (mosfet->source); + if (mosfet->source == start->id) + return (get_node_of_terminal(nodes, mosfet, drain)); + return (get_node_of_terminal(nodes, mosfet, source)); } -static void find_connected(t_node *node, t_vec *connected_nodes) +static void find_connected(t_vec *nodes, t_vec *mosfets, t_node *node, t_vec *connected_nodes) { size_t i; t_node *neigh_node; @@ -22,11 +22,11 @@ static void find_connected(t_node *node, t_vec *connected_nodes) i = 0; while (i < node->connected.size) { - mosfet = *(t_mosfet **)ft_vec_access(&node->connected, i); + mosfet = get_mosfet_by_id(mosfets, *(t_id *)ft_vec_access(&node->connected, i)); if (mosfet->is_opened) { - neigh_node = get_neighbour_node(mosfet, node); - find_connected(neigh_node, connected_nodes); + neigh_node = get_neighbour_node(nodes, mosfet, node); + find_connected(nodes, mosfets, neigh_node, connected_nodes); } ++i; } @@ -55,7 +55,7 @@ static void reset_nodes(t_vec *nodes) // so I provide this mechanism. It may be removed in the future if // it seems to be a reasonable decision. -void update_nodes(t_vec *nodes) +void update_nodes(t_vec *nodes, t_vec *mosfets) { size_t i; t_state state; @@ -75,7 +75,7 @@ void update_nodes(t_vec *nodes) cur_node = ft_vec_access(nodes, i); if (!cur_node->checked) { - find_connected(cur_node, &connected_nodes); + find_connected(nodes, mosfets, cur_node, &connected_nodes); state = resolve_state(&connected_nodes); apply_state(reduce_state(state), &connected_nodes); ft_vec_forget_range(&connected_nodes, connected_nodes.size, 0); -- 2.30.2