gint node_remove_wire (Node *node, Wire *wire) { gboolean dot; g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); if (node->wire_count == 0) return FALSE; if (!g_slist_find (node->wires, wire)) { NG_DEBUG ("node_remove_wire: not there.\n"); return FALSE; } dot = node_needs_dot (node); node->wires = g_slist_remove (node->wires, wire); node->wire_count--; if (dot && (!node_needs_dot (node))) g_signal_emit_by_name (G_OBJECT (node), "node_dot_removed", &node->key); return TRUE; }
static void netlist_helper_nl_wire_traverse (Wire *wire, GSList **lst) { GSList *nodes; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); if (wire_is_visited (wire)) return; wire_set_visited (wire, TRUE); for (nodes = wire_get_nodes (wire); nodes; nodes = nodes->next) { GSList *pins; Part *part; Node *node = nodes->data; for (pins=node->pins; pins; pins=pins->next) { char *template, *tmp; char **template_split; part = PART (((Pin *)pins->data)->part); tmp = part_get_property (part, "template"); if (!tmp) continue;
static void write_xml_wire (Wire *wire, parseXmlContext *ctxt) { xmlNodePtr node_wire; gchar *str; Coords start_pos, end_pos; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); // Create a node for the wire. node_wire = xmlNewChild (ctxt->node_wires, ctxt->ns, BAD_CAST "wire", NULL); if (!node_wire) { g_warning ("Failed during save of wire.\n"); return; } wire_get_start_pos (wire, &start_pos); wire_get_end_pos (wire, &end_pos); Node *node; Coords last, current, tmp; GSList *iter, *copy; copy = g_slist_sort (g_slist_copy (wire_get_nodes (wire)), cmp_nodes); current = last = start_pos; for (iter = copy; iter; iter = iter->next) { node = iter->data; if (node==NULL) { g_warning ("Node of wire did not exist [%p].", node); continue; } tmp = node->key; if (coords_equal(&tmp, &start_pos)) continue; if (coords_equal(&tmp, &end_pos)) continue; last = current; current = tmp; str = g_strdup_printf ("(%g %g)(%g %g)", last.x, last.y, current.x, current.y); xmlNewChild (node_wire, ctxt->ns, BAD_CAST "points", BAD_CAST str); g_free (str); } last = current; current = end_pos; str = g_strdup_printf ("(%g %g)(%g %g)", last.x, last.y, current.x, current.y); xmlNewChild (node_wire, ctxt->ns, BAD_CAST "points", BAD_CAST str); g_free (str); g_slist_free (copy); }
static void write_xml_wire (Wire *wire, parseXmlContext *ctxt) { xmlNodePtr node_wire; gchar *str; SheetPos start_pos, end_pos; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); // Create a node for the wire. node_wire = xmlNewChild (ctxt->node_wires, ctxt->ns, BAD_CAST "wire", NULL); if (!node_wire) { g_warning ("Failed during save of wire.\n"); return; } wire_get_start_pos (wire, &start_pos); wire_get_end_pos (wire, &end_pos); str = g_strdup_printf ("(%g %g)(%g %g)", start_pos.x, start_pos.y, end_pos.x, end_pos.y); xmlNewChild (node_wire, ctxt->ns, BAD_CAST "points", BAD_CAST str); g_free (str); }
// Create a SheetItem from an ItemData object. This is a bit ugly. // It could be beautified by having a method that creates the item. // E.g. sheet_item->new_from_data (data); SheetItem * sheet_item_factory_create_sheet_item (Sheet *sheet, ItemData *data) { SheetItem *item; g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (IS_ITEM_DATA (data), NULL); g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (IS_SHEET (sheet), NULL); item = NULL; // Pick the right model. if (IS_PART (data)) { NG_DEBUG ("sheet_item_factory_create_sheet_item part\n\n"); item = SHEET_ITEM (part_item_new (sheet, PART (data))); } else if (IS_WIRE (data)) { NG_DEBUG ("sheet_item_factory_create_sheet_item wire\n\n"); item = SHEET_ITEM (wire_item_new (sheet, WIRE (data))); } else if (IS_TEXTBOX (data)) { NG_DEBUG ("sheet_item_factory_create_sheet_item text\n\n"); item = SHEET_ITEM (textbox_item_new (sheet, TEXTBOX (data))); } else g_warning ("Unknown Item type."); return item; }
gint node_add_wire (Node *node, Wire *wire) { gboolean dot; g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); if (g_slist_find (node->wires, wire)) { NG_DEBUG ("node_add_wire: wire already there.\n"); return FALSE; } dot = node_needs_dot (node); node->wires = g_slist_prepend (node->wires, wire); node->wire_count++; if (!dot && node_needs_dot (node)) g_signal_emit_by_name (G_OBJECT (node), "node_dot_added", &node->key); return TRUE; }
void wire_get_start_pos (Wire *wire, Coords *pos) { g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); g_return_if_fail (pos != NULL); item_data_get_pos (ITEM_DATA (wire), pos); }
static GSList * wire_intersect_parts (NodeStore *store, Wire *wire) { GList *list; GSList *ip_list; Node *node; SheetPos lookup_pos; SheetPos part_pos, wire_pos, wire_length; Part *part; double x, y, wire_x1, wire_y1, wire_x2, wire_y2; int i, num_pins; g_return_val_if_fail (store != NULL, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); ip_list = NULL; wire_get_pos_and_length (wire, &wire_pos, &wire_length); wire_x1 = wire_pos.x; wire_x2 = wire_pos.x + wire_length.x; wire_y1 = wire_pos.y; wire_y2 = wire_pos.y + wire_length.y; // Go through all the parts and see which of their // pins that intersect the wire. for (list = store->parts; list; list = list->next) { part = list->data; num_pins = part_get_num_pins (part); item_data_get_pos (ITEM_DATA (part), &part_pos); for (i = 0; i < num_pins; i++) { Pin *pins; pins = part_get_pins (part); x = part_pos.x + pins[i].offset.x; y = part_pos.y + pins[i].offset.y; lookup_pos.x = x; lookup_pos.y = y; // If there is a wire at this pin's position, // add it to the return list. if (is_wire_at_pos (wire_x1, wire_y1, wire_x2, wire_y2, lookup_pos)) { node = node_store_get_node (store, lookup_pos); if (node != NULL) ip_list = g_slist_prepend (ip_list, node); } } } g_list_free_full (list, g_object_unref); return ip_list; }
static void wire_changed (ItemData *data) { Coords loc; g_return_if_fail (IS_WIRE (data)); item_data_get_pos (data, &loc); g_signal_emit_by_name ((GObject *)data, "moved", &loc); g_signal_emit_by_name ((GObject *)data, "changed"); }
static gboolean wire_register (ItemData *data) { NodeStore *store; g_return_val_if_fail (IS_WIRE (data), FALSE); store = item_data_get_store (data); return node_store_add_wire (store, WIRE (data)); }
static void wire_item_paste (Sheet *sheet, ItemData *data) { g_return_if_fail (sheet != NULL); g_return_if_fail (IS_SHEET (sheet)); g_return_if_fail (data != NULL); g_return_if_fail (IS_WIRE (data)); sheet_add_ghost_item (sheet, data); }
static void wire_copy (ItemData *dest, ItemData *src) { Wire *dest_wire, *src_wire; g_return_if_fail (dest != NULL); g_return_if_fail (IS_WIRE (dest)); g_return_if_fail (src != NULL); g_return_if_fail (IS_WIRE (src)); if (parent_class->copy != NULL) parent_class->copy (dest, src); dest_wire = WIRE (dest); src_wire = WIRE (src); dest_wire->priv->nodes = NULL; dest_wire->priv->length = src_wire->priv->length; }
static void wire_unregister (ItemData *data) { NodeStore *store; g_return_if_fail (IS_WIRE (data)); store = item_data_get_store (data); node_store_remove_wire (store, WIRE (data)); }
static void wire_item_paste (SchematicView *sv, ItemData *data) { g_return_if_fail (sv != NULL); g_return_if_fail (IS_SCHEMATIC_VIEW (sv)); g_return_if_fail (data != NULL); g_return_if_fail (IS_WIRE (data)); schematic_view_add_ghost_item (sv, data); }
void wire_set_visited (Wire *wire, gboolean is_visited) { WirePriv *priv; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); priv = wire->priv; priv->visited = is_visited; }
gboolean wire_is_visited (Wire *wire) { WirePriv *priv; g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); priv = wire->priv; return priv->visited; }
GSList *wire_get_nodes (Wire *wire) { WirePriv *priv; g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); priv = wire->priv; return priv->nodes; }
void wire_get_pos_and_length (Wire *wire, Coords *pos, Coords *length) { WirePriv *priv; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); g_return_if_fail (pos != NULL); priv = wire->priv; item_data_get_pos (ITEM_DATA (wire), pos); *length = priv->length; }
void wire_get_start_and_end_pos (Wire *wire, Coords *start, Coords *end) { WirePriv *priv; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); g_return_if_fail (start != NULL); g_return_if_fail (end != NULL); priv = wire->priv; item_data_get_pos (ITEM_DATA (wire), start); *end = coords_sum (start, &(priv->length)); }
void wire_get_end_pos (Wire *wire, Coords *pos) { WirePriv *priv; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); g_return_if_fail (pos != NULL); priv = wire->priv; item_data_get_pos (ITEM_DATA (wire), pos); pos->x += priv->length.x; pos->y += priv->length.y; }
static ItemData *wire_clone (ItemData *src) { Wire *new_wire; ItemDataClass *id_class; g_return_val_if_fail (src != NULL, NULL); g_return_val_if_fail (IS_WIRE (src), NULL); id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (src)); if (id_class->copy == NULL) return NULL; new_wire = g_object_new (TYPE_WIRE, NULL); id_class->copy (ITEM_DATA (new_wire), src); return ITEM_DATA (new_wire); }
int node_store_remove_wire (NodeStore *store, Wire *wire) { GSList *list; SheetPos lookup_key, pos, length; g_return_val_if_fail (store != NULL, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); if (item_data_get_store (ITEM_DATA (wire)) == NULL) { g_warning ("Trying to remove non-stored wire."); return FALSE; } wire_get_pos_and_length (wire, &pos, &length); store->wires = g_list_remove (store->wires, wire); store->items = g_list_remove (store->items, wire); // If the nodes that this wire passes through will be // empty when the wire is removed, remove the node as well. // We must work on a copy of the nodes list, since it // changes as we remove nodes. list = g_slist_copy (wire_get_nodes (wire)); for (; list; list = list->next) { Node *node = list->data; lookup_key = node->key; node_remove_wire (node, wire); wire_remove_node (wire, node); if (node_is_empty (node)) g_hash_table_remove (store->nodes, &lookup_key); } g_slist_free (list); return TRUE; }
gint wire_add_node (Wire *wire, Node *node) { WirePriv *priv; g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); priv = wire->priv; if (g_slist_find (priv->nodes, node)) { return FALSE; } priv->nodes = g_slist_prepend (priv->nodes, node); return TRUE; }
// Pretty-prints the tile at the given position. static void display_tile(Coords pos) { Tile *tile = &TILE(pos); int light = shadowed(pos) ? 0 : L2(pos - player.pos) <= player.radius ? 7777 : min(tile->light, 7777); printf("\033[38;5;%dm", 232 + light / 338); print_at(pos, tile_glyphs[tile->type]); if (IS_DIGGABLE(pos) && !IS_DOOR(pos)) display_wall(pos); if (IS_WIRE(pos) && !IS_DOOR(pos)) display_wire(pos); if (tile->item) print_at(pos, item_glyphs[tile->item]); if (!tile->revealed) print_at(pos, " "); }
static void wire_traverse (Wire *wire) { GSList *iter; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); if (wire_is_visited (wire)) return; wire_set_visited (wire, TRUE); g_signal_emit_by_name (wire, "highlight"); for (iter = wire_get_nodes (wire); iter; iter = iter->next) { Node *node = iter->data; node_traverse (node); } }
static void wire_print (ItemData *data, cairo_t *cr, SchematicPrintContext *ctx) { Coords start_pos, end_pos; Wire *wire; g_return_if_fail (data != NULL); g_return_if_fail (IS_WIRE (data)); wire = WIRE (data); wire_get_start_pos (wire, &start_pos); wire_get_end_pos (wire, &end_pos); cairo_save (cr); gdk_cairo_set_source_rgba (cr, &ctx->colors.wires); cairo_move_to (cr, start_pos.x, start_pos.y); cairo_line_to (cr, end_pos.x, end_pos.y); cairo_stroke (cr); cairo_restore (cr); }
void wire_set_length (Wire *wire, Coords *length) { WirePriv *priv; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); priv = wire->priv; priv->length = *length; if (length->x == 0) { wire->priv->direction = WIRE_DIR_VERT; } else if (length->y == 0) { wire->priv->direction = WIRE_DIR_HORIZ; } else { wire->priv->direction = WIRE_DIR_DIAG; } g_signal_emit_by_name (G_OBJECT (wire), "changed"); }
/** * removes/unregisters a wire from the nodestore * this does _not_ free the wire itself! */ gboolean node_store_remove_wire (NodeStore *store, Wire *wire) { GSList *copy, *iter; Coords lookup_key; g_return_val_if_fail (store, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); if (item_data_get_store (ITEM_DATA (wire)) == NULL) { g_warning ("Trying to remove not-stored wire %p.", wire); return FALSE; } store->wires = g_list_remove (store->wires, wire); store->items = g_list_remove (store->items, wire); // If the nodes that this wire passes through will be // empty when the wire is removed, remove the node as well. // FIXME if done properly, a list copy is _not_ necessary copy = g_slist_copy (wire_get_nodes (wire)); for (iter = copy; iter; iter = iter->next) { Node *node = iter->data; lookup_key = node->key; node_remove_wire (node, wire); wire_remove_node (wire, node); if (node_is_empty (node)) g_hash_table_remove (store->nodes, &lookup_key); } g_slist_free (copy); return TRUE; }
static void wire_traverse (Wire *wire) { GSList *nodes; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); if (wire_is_visited (wire)) return; wire_set_visited (wire, TRUE); g_signal_emit_by_name (wire, "highlight"); for (nodes = wire_get_nodes (wire); nodes; nodes = nodes->next) { Node *node = nodes->data; node_traverse (node); } g_slist_free_full (nodes, g_object_unref); }
/** * add/register the wire to the nodestore * * @param store * @param wire * @returns TRUE if the wire was added or merged, else FALSE */ gboolean node_store_add_wire (NodeStore *store, Wire *wire) { GList *list; Node *node; int i = 0; g_return_val_if_fail (store, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); // Check for intersection with other wires. for (list = store->wires; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_WIRE (list->data)); Coords where = {-77.77, -77.77}; Wire *other = list->data; if (do_wires_intersect (wire, other, &where)) { if (is_t_crossing (wire, other, &where) || is_t_crossing (other, wire, &where)) { node = node_store_get_or_create_node (store, where); node_add_wire (node, wire); node_add_wire (node, other); wire_add_node (wire, node); wire_add_node (other, node); NG_DEBUG ("Add wire %p to wire %p @ %lf,%lf.\n", wire, other, where.x, where.y); } else { // magic node removal if a x crossing is overlapped with another wire node = node_store_get_node (store, where); NG_DEBUG ("Nuke that node [ %p ] at coords inbetween", node); if (node) { Coords c[4]; wire_get_start_and_end_pos (other, c + 0, c + 1); wire_get_start_and_end_pos (wire, c + 2, c + 3); if (!coords_equal (&where, c + 0) && !coords_equal (&where, c + 1) && !coords_equal (&where, c + 2) && !coords_equal (&where, c + 3)) { wire_remove_node (wire, node); wire_remove_node (other, node); node_remove_wire (node, wire); node_remove_wire (node, other); } } } } } // Check for overlapping with other wires. do { for (list = store->wires; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_WIRE (list->data)); Wire *other = list->data; Coords so, eo; const gboolean overlap = do_wires_overlap (wire, other, &so, &eo); NG_DEBUG ("overlap [ %p] and [ %p ] -- %s", wire, other, overlap == TRUE ? "YES" : "NO"); if (overlap) { Node *sn = node_store_get_node (store, eo); Node *en = node_store_get_node (store, so); #if 1 wire = vulcanize_wire (store, wire, other, &so, &eo); node_store_remove_wire (store, g_object_ref (other)); // equiv // wire_unregister // XXX FIXME this // modifies the list // we iterate over! // delay this until idle, so all handlers like adding view // representation are completed so existing wire-items can be deleted // properly // this is not fancy nor nice but seems to work fairly nicly g_idle_add (delayed_wire_delete, other); break; NG_DEBUG ("overlapping of %p with %p ", wire, other); #else if (!sn && !en) { wire = vulcanize_wire (store, wire, other, &so, &eo); } else if (!sn) { NG_DEBUG ("do_something(TM) : %p sn==NULL ", other); } else if (!en) { NG_DEBUG ("do_something(TM) : %p en==NULL ", other); } else { NG_DEBUG ("do_something(TM) : %p else ", other); } #endif } else { NG_DEBUG ("not of %p with %p ", wire, other); } } } while (list); // Check for intersection with parts (pins). for (list = store->parts; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_PART (list->data)); Coords part_pos; gint num_pins = -1; Part *part = list->data; num_pins = part_get_num_pins (part); item_data_get_pos (ITEM_DATA (part), &part_pos); // Go through all the parts and see which of their // pins that intersect the wire. for (i = 0; i < num_pins; i++) { Pin *pins; Coords lookup_pos; pins = part_get_pins (part); lookup_pos.x = part_pos.x + pins[i].offset.x; lookup_pos.y = part_pos.y + pins[i].offset.y; // If there is a wire at this pin's position, // add it to the return list. if (is_point_on_wire (wire, &lookup_pos)) { Node *node; node = node_store_get_node (store, lookup_pos); if (node != NULL) { // Add the wire to the node (pin) that it intersected. node_add_wire (node, wire); wire_add_node (wire, node); NG_DEBUG ("Add wire %p to pin (node) %p.\n", wire, node); } else { g_warning ("Bug: Found no node at pin at (%g %g).\n", lookup_pos.x, lookup_pos.y); } } } } g_object_set (G_OBJECT (wire), "store", store, NULL); store->wires = g_list_prepend (store->wires, wire); store->items = g_list_prepend (store->items, wire); return TRUE; }