Switch from pointers to IDs
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Sat, 21 Dec 2024 11:11:47 +0000 (12:11 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Sat, 21 Dec 2024 11:18:45 +0000 (12:18 +0100)
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
src/build_helper.c
src/c_bind.c
src/c_connect.c
src/c_draw.c
src/colors.c
src/main.c
src/schema_mode.c
src/sim_main.c
src/sim_node.c

index f3d33510423c462769c7da00da7f131dca43f439..a8c0a84164b17da2b81bd96772fe4092861408a3 100644 (file)
@@ -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);
index 0c2377fd8ed03c4868d456cc6a231d78210a8ad3..ff0f6d90e2ce9430eb091ec896092f4d472c78d1 100644 (file)
@@ -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);
index 3ff755258abbdaabf8b5e0f73f03d893cfacfcb3..2716f997f4e2ad4f4b41acec325d2c84872fba6f 100644 (file)
@@ -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);
 }
index d9361edbd65c9e89c315328930f81260ac334245..46d648828380351d6c8c5658318121a31e09dae6 100644 (file)
@@ -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);
 }
index 2852ee15cfde54dbb6ea585103dbca5d21a146f8..f06b5424a42e244ca68214794210830bafcc278b 100644 (file)
@@ -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
        {
index 6f6d9453030ebf62f61b0a23208eb0c2d20d3a98..0f6cadac1b3367789aca057aaab4a489ec058fc3 100644 (file)
@@ -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;
index e6cf3fe339cd5f19d3650e5e707074170989487a..9ba80e2a7509dee1a8ddc697c0ed956e73e7f779 100644 (file)
@@ -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);
index fd0626c6cd9f10b07bac479171d2e9251f3a266e..61534144cfef70ed2694351f22c7c7cf905c63b5 100644 (file)
@@ -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 ;
index a161a5ec631258eef644eac209b80808be16cd7a..cb52bf1d2bdcec7d3ae5eb996a31fc73a53c879c 100644 (file)
@@ -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);
 }
index 1b35650e1ce87bf80dbaedded9d5c8e8761c2399..745d21ea12cf9c76a073c3a7dce62aa4797a76f8 100644 (file)
@@ -2,14 +2,14 @@
 #include "libft.h"
 #include <stdlib.h>
 
-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);