From d03a1205f99244550c784b4c8c2694ae643f0278 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Ji=C5=99i=C5=A1t=C4=9B?= Date: Sun, 4 Feb 2024 14:01:48 +0100 Subject: [PATCH] Change t_mosfet to remember node id instead of ptr This prevents looking for node id when drawing. Some changes were present when I started this change. I can't really tell, what they were, but from the diffs it looks like just 2 or 3 minor cosmetic changes. Sorry. --- TODO | 3 ++- inc/FET_sim.h | 25 +++++++++++++++---------- src/build_helper.c | 33 +++++++++++++++++---------------- src/c_addfet.c | 5 +++-- src/c_bind.c | 6 +++--- src/colors.c | 17 ++++++++--------- src/main.c | 20 +++++++++++++------- src/sim_main.c | 15 ++++++++++----- src/sim_node.c | 10 +++++----- src/text.c | 5 ++--- 10 files changed, 78 insertions(+), 61 deletions(-) diff --git a/TODO b/TODO index 25d0489..823f579 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ TODO -rewrite t_fet and t_node to store indexes insted of pointers to connected parts rewrite command parsing (what I've created is just ugly) come up with better file structure create language to write circuits in (circuit language?) (something like MHRD language?) @@ -13,3 +12,5 @@ pass 42 norminette DONE foundations of logic expand simulator commands +rewrite t_fet and t_node to store indexes insted of pointers to connected parts + - t_node would not benefit from this, so only t_mosfet stores ids of nodes diff --git a/inc/FET_sim.h b/inc/FET_sim.h index 612fc5d..328b45b 100644 --- a/inc/FET_sim.h +++ b/inc/FET_sim.h @@ -5,6 +5,8 @@ # define MAX_ARGS 3 +#include + // zkrat means short circuit in my language. I opted for this because // C does not permit short (it is type) and short_circuit was too long typedef enum e_state @@ -25,12 +27,15 @@ typedef enum e_terminal gate, } t_terminal; +typedef ssize_t t_nodeid; + typedef struct s_node { - int checked; - t_state state; - t_state set_state; - t_vec connected; + t_nodeid id; + int checked; + t_state state; + t_state set_state; + t_vec connected; } t_node; typedef enum e_type @@ -41,11 +46,11 @@ typedef enum e_type typedef struct s_mosfet { - int is_opened; - t_type type; - t_node *gate; - t_node *source; - t_node *drain; + int is_opened; + t_type type; + t_nodeid gate; + t_nodeid source; + t_nodeid drain; } t_mosfet; typedef enum e_command @@ -95,7 +100,7 @@ typedef struct s_input void add_node(t_vec *nodes, t_state set_state); void add_mosfet(t_vec *mosfets, t_type type); -void bind_fet_node(t_mosfet *mosfet, t_node *node, t_terminal terminal); +void bind_fet_node(t_vec *nodes, t_mosfet *mosfet, t_nodeid newid, t_terminal terminal); void free_node(void *node); int process_input(t_vec *nodes, t_vec *mosfets); diff --git a/src/build_helper.c b/src/build_helper.c index 20a9f7d..cc5a7ad 100644 --- a/src/build_helper.c +++ b/src/build_helper.c @@ -1,36 +1,36 @@ #include "FET_sim.h" #include "libft.h" -void bind_fet_node(t_mosfet *mosfet, t_node *node, t_terminal terminal) +void bind_fet_node(t_vec *nodes, t_mosfet *mosfet, t_nodeid newid, t_terminal terminal) { - t_node *old; - size_t index; + t_nodeid oldid; - old = NULL; + oldid = -1; if (terminal == source) { - old = mosfet->source; - mosfet->source = node; - ft_vec_append(&node->connected, &mosfet); + oldid = mosfet->source; + mosfet->source = newid; + ft_vec_append(&((t_node *)ft_vec_access(nodes, newid))->connected, &mosfet); } else if (terminal == drain) { - old = mosfet->drain; - mosfet->drain = node; - ft_vec_append(&node->connected, &mosfet); + oldid = mosfet->drain; + mosfet->drain = newid; + ft_vec_append(&((t_node *)ft_vec_access(nodes, newid))->connected, &mosfet); } else { - mosfet->gate = node; + mosfet->gate = newid; } - if (old && ft_vec_find_index(&old->connected, &mosfet, &index) == success) + if (oldid != -1) { - ft_vec_forget(&old->connected, index); + ft_vec_forget(&((t_node *)ft_vec_access(nodes, oldid))->connected, oldid); } return ; } // memset is used to initialize struct padding +// could be removed void add_node(t_vec *nodes, t_state set_state) { t_node node; @@ -39,6 +39,7 @@ void add_node(t_vec *nodes, t_state set_state) node.checked = 0; node.state = set_state; node.set_state = set_state; + node.id = nodes->size; ft_vec_init(&node.connected, sizeof(t_mosfet *)); ft_vec_append(nodes, &node); return ; @@ -50,9 +51,9 @@ void add_mosfet(t_vec *mosfets, t_type type) mosfet.is_opened = 0; mosfet.type = type; - mosfet.gate = NULL; - mosfet.drain = NULL; - mosfet.source = NULL; + mosfet.gate = -1; + mosfet.drain = -1; + mosfet.source = -1; ft_vec_append(mosfets, &mosfet); return ; } diff --git a/src/c_addfet.c b/src/c_addfet.c index 6ce663b..0e7d89c 100644 --- a/src/c_addfet.c +++ b/src/c_addfet.c @@ -5,15 +5,15 @@ int c_addfet(t_input input, t_vec *mosfets) { size_t i; + ft_printf("Indexes of added FETs:\n\t"); if (input.argc == 1 && input.argv[0].type == type) { add_mosfet(mosfets, input.argv[0].val.type); - ft_printf("Index of added FET: %u\n", mosfets->size - 1); + ft_printf("%u", mosfets->size - 1); } else if (input.argc == 2 && input.argv[0].type == type && input.argv[1].type == num) { i = 0; - ft_printf("Index of added FETs:\n\t"); while (i < input.argv[1].val.num) { ft_printf("%u ", mosfets->size); @@ -21,6 +21,7 @@ int c_addfet(t_input input, t_vec *mosfets) ++i; } } + ft_printf("\n"); /*else print_wrong_usage(input);*/ return (1); diff --git a/src/c_bind.c b/src/c_bind.c index 87e412d..28b359f 100644 --- a/src/c_bind.c +++ b/src/c_bind.c @@ -3,7 +3,7 @@ int c_bind(t_input input, t_vec *nodes, t_vec *mosfets) { - t_node *node; + t_nodeid nodeid; t_mosfet *mosfet; t_terminal term; @@ -13,9 +13,9 @@ int c_bind(t_input input, t_vec *nodes, t_vec *mosfets) print_wrong_usage(input); return (1); }*/ - node = ft_vec_access(nodes, input.argv[0].val.num); + nodeid = input.argv[0].val.num; mosfet = ft_vec_access(mosfets, input.argv[1].val.num); term = input.argv[2].val.terminal; - bind_fet_node(mosfet, node, term); + bind_fet_node(nodes, mosfet, nodeid, term); return (1); } diff --git a/src/colors.c b/src/colors.c index deb0795..855c63b 100644 --- a/src/colors.c +++ b/src/colors.c @@ -23,27 +23,26 @@ const char *state_color_escape(t_state state) void draw_single(t_vec *nodes, t_vec *mosfets, size_t i) { t_mosfet *mosfet; - size_t index; mosfet = ft_vec_access(mosfets, i); - if (ft_vec_find_index(nodes, mosfet->source, &index) == success) + if (mosfet->source != -1 && (size_t)mosfet->source < nodes->size) { - ft_printf(" %u\n", index); - ft_printf(" %s|%s\n", state_color_escape(mosfet->source->state), g_default_ac); + ft_printf(" %u\n", mosfet->source); + ft_printf(" %s|%s\n", state_color_escape(((t_node *)ft_vec_access(nodes, mosfet->source))->state), g_default_ac); } else { ft_printf(" %sNULL%s\n", g_red_ac, g_default_ac); ft_printf(" %s|%s\n", g_red_ac, g_default_ac); } - if (ft_vec_find_index(nodes, mosfet->gate, &index) == success) - ft_printf("%4u%s--%s%c\n", index, state_color_escape(mosfet->gate->state), g_default_ac, mosfet->type); + if (mosfet->gate != -1 && (size_t)mosfet->gate < nodes->size) + ft_printf("%4u%s--%s%c\n", mosfet->gate, state_color_escape(((t_node *)ft_vec_access(nodes, mosfet->gate))->state), g_default_ac, mosfet->type); else ft_printf("%sNULL--%s%c\n", g_red_ac, g_default_ac, mosfet->type); - if (ft_vec_find_index(nodes, mosfet->drain, &index) == success) + if (mosfet->drain != -1 && (size_t)mosfet->drain < nodes->size) { - ft_printf(" %s|%s\n", state_color_escape(mosfet->drain->state), g_default_ac); - ft_printf(" %u\n\n", index); + ft_printf(" %s|%s\n", state_color_escape(((t_node *)ft_vec_access(nodes, mosfet->drain))->state), g_default_ac); + ft_printf(" %u\n\n", mosfet->drain); } else { diff --git a/src/main.c b/src/main.c index 55a773f..38a577f 100644 --- a/src/main.c +++ b/src/main.c @@ -2,15 +2,17 @@ #include "libft.h" #include +// Does not use input +// Just builds a single FET void build_graph(__attribute__((unused)) const char *filename, t_vec *nodes, t_vec *mosfets) { add_node(nodes, off); add_node(nodes, off); add_node(nodes, pull_up); add_mosfet(mosfets, p); - bind_fet_node(ft_vec_access(mosfets, 0), ft_vec_access(nodes, 0), gate); - bind_fet_node(ft_vec_access(mosfets, 0), ft_vec_access(nodes, 1), drain); - bind_fet_node(ft_vec_access(mosfets, 0), ft_vec_access(nodes, 2), source); + bind_fet_node(nodes, ft_vec_access(mosfets, 0), 0, gate); + bind_fet_node(nodes, ft_vec_access(mosfets, 0), 1, drain); + bind_fet_node(nodes, ft_vec_access(mosfets, 0), 2, source); return ; } @@ -119,13 +121,15 @@ int has_correct_argc(t_input input) c = input.command; argc = input.argc; - if ((c == next || c == draw || c == addfet || c == help) && argc > 1) + if ((c == next || c == draw || c == help) && argc > 1) return (0); if (c == setnode && argc != 2) return (0); if (c == bind && argc != 3) return (0); - if (c == addnode && argc > 2) + if ((c == addnode || c == addfet) && argc > 2) + return (0); + if (c == addfet && argc == 0) return (0); return (1); } @@ -149,7 +153,7 @@ int parse_arg(t_input *input, const char *str, size_t i) int res; res = 0; - if (is_num != 0 && (c == next || c == draw || (c == setnode && i == 0) + if (is_num && (c == next || c == draw || (c == setnode && i == 0) || (c == addfet && i == 1) || (c == addnode && (input->argc == 1 || i == 1)) || (c == bind && i < 2))) { @@ -237,7 +241,7 @@ int process_input(t_vec *nodes, t_vec *mosfets) int res; static t_input input = {.command = help, .argc = 0}; - ft_printf("FET_sim>"); + ft_printf("FET_sim> "); if (!get_input(&input)) return (1); res = 1; @@ -269,10 +273,12 @@ int main(__attribute__((unused)) int argc, char **argv) ft_vec_init(&nodes, sizeof(t_node)); ft_vec_init(&mosfets, sizeof(t_mosfet)); build_graph(argv[1], &nodes, &mosfets); + update_nodes(&nodes); while (process_input(&nodes, &mosfets)) { continue ; } + ft_printf("\n"); update_nodes(NULL); ft_vec_free(&nodes, free_node); ft_vec_free(&mosfets, NULL); diff --git a/src/sim_main.c b/src/sim_main.c index 14cc9b5..12f04c0 100644 --- a/src/sim_main.c +++ b/src/sim_main.c @@ -1,11 +1,16 @@ #include "FET_sim.h" #include "libft.h" -static void update_mosfet(t_mosfet *mosfet) +static void update_mosfet(t_vec *nodes, t_mosfet *mosfet) { t_state state; - state = mosfet->gate->state; + if (mosfet->gate == -1) + { + mosfet->is_opened = 0; + return ; + } + state = ((t_node *)ft_vec_access(nodes, mosfet->gate))->state; if (mosfet->type == p && state == on) mosfet->is_opened = 1; else if (mosfet->type == n && state == off) @@ -15,7 +20,7 @@ static void update_mosfet(t_mosfet *mosfet) return ; } -static void update_mosfets(t_vec *mosfets) +static void update_mosfets(t_vec *nodes, t_vec *mosfets) { size_t i; t_mosfet *mosfet; @@ -24,7 +29,7 @@ static void update_mosfets(t_vec *mosfets) while (i < mosfets->size) { mosfet = ft_vec_access(mosfets, i); - update_mosfet(mosfet); + update_mosfet(nodes, mosfet); ++i; } return ; @@ -33,6 +38,6 @@ static void update_mosfets(t_vec *mosfets) int sim_step(t_vec *nodes, t_vec *mosfets) { update_nodes(nodes); - update_mosfets(mosfets); + update_mosfets(nodes, mosfets); return (1); } diff --git a/src/sim_node.c b/src/sim_node.c index eee368e..432a996 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_nodeid get_neighbour_nodeid(const t_mosfet *mosfet, const t_nodeid start) { if (mosfet->source == start) return (mosfet->drain); return (mosfet->source); } -static void find_connected(t_node *node, t_vec *connected_nodes) +static void find_connected(t_vec *nodes, t_node *node, t_vec *connected_nodes) { size_t i; t_node *neigh_node; @@ -25,8 +25,8 @@ static void find_connected(t_node *node, t_vec *connected_nodes) mosfet = *(t_mosfet **)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 = ft_vec_access(nodes, get_neighbour_nodeid(mosfet, node->id)); + find_connected(nodes, neigh_node, connected_nodes); } ++i; } @@ -74,7 +74,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, 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); diff --git a/src/text.c b/src/text.c index 086351d..b46ca15 100644 --- a/src/text.c +++ b/src/text.c @@ -59,14 +59,13 @@ static const char g_help_exit_str[] = "" static const char g_general_help_str[] = "" "This is a FET_sim - simulator of FET (Field Effect Transistor) logic.\n" "Version number: %s" - "You can use the following commands:\n" + "You can use the following commands:\n\n" "next [STEPS] \t\t- advances the simulation\n" "draw [IND] \t\t- draws the state of the simulation\n" "setnode IND STATE \t- sets the \"set_state\" of the node indexed by IND to STATE\n" "addnode [STATE] [NUM] \t- adds new nodes\n" "addfet TYPE [NUM] \t- adds new FETs\n" - "bind NODE FET TERMINAL \t- binds node indexed by NODE to TERMINAL\n \ - \t\t\t of transistor indexed by FET\n" + "bind NODE FET TERMINAL \t- binds node indexed by NODE to TERMINAL of transistor indexed by FET\n" "help [COMMAND] \t\t- shows this help or help for COMMAND\n" "exit [...] \t\t- exits this program\n\n"; -- 2.30.2