Exemple #1
0
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;
}
Exemple #2
0
/**
 * 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;
}
Exemple #3
0
/**
 * 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;
}