r5445 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Fri Aug 14 17:53:21 CEST 2009


Author: werner
Date: 2009-08-14 17:53:21 +0200 (Fri, 14 Aug 2009)
New Revision: 5445

Modified:
   trunk/eda/fped/inst.c
Log:
- when selecting an item in the canvas, we now check that the underlying object
  is still connected. This prevents surprises when making extensive changes
  during instantiation failure.



Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2009-08-14 14:39:17 UTC (rev 5444)
+++ trunk/eda/fped/inst.c	2009-08-14 15:53:21 UTC (rev 5445)
@@ -40,7 +40,10 @@
 
 static unsigned long active_set = 0;
 
+static struct inst_ops vec_ops;
+static struct inst_ops frame_ops;
 
+
 #define	IS_ACTIVE	((active_set & 1))
 
 
@@ -87,13 +90,44 @@
 }
 
 
-/* ----- selection --------------------------------------------------------- */
+/* ----- check connectedness ----------------------------------------------- */
 
 
-static struct inst_ops vec_ops;
-static struct inst_ops frame_ops;
+/*
+ * After an instantiation failure, the instances can get out of sync with the
+ * object tree, and attempts to select an item on the canvas can cause accesses
+ * to objects that aren't there anymore. So we need to check if we can still
+ * reach the corresponding object.
+ *
+ * Note: even this isn't bullet-proof. Theoretically, we may get a new object
+ * in the old place. However, this probably doesn't do any serious damage.
+ */
 
 
+static int inst_connected(const struct inst *inst)
+{
+	const struct frame *frame;
+	const struct vec *vec;
+	const struct obj *obj;
+
+	for (frame = frames; frame; frame = frame->next) {
+		if (inst->ops == &vec_ops) {
+			for (vec = frame->vecs; vec; vec = vec->next)
+				if (vec == inst->vec)
+					return 1;
+		} else {
+			for (obj = frame->objs; obj; obj = obj->next)
+				if (obj == inst->obj)
+					return 1;
+		}
+	}
+	return 0;
+}
+
+
+/* ----- selection --------------------------------------------------------- */
+
+
 static void set_path(int on)
 {
 	struct inst *inst;
@@ -140,6 +174,8 @@
 		for (inst = insts[prio]; inst; inst = inst->next) {
 			if (!inst->active || !inst->ops->distance)
 				continue;
+			if (!inst_connected(inst))
+				continue;
 			dist = inst->ops->distance(inst, pos, draw_ctx.scale);
 			if (dist >= 0 && (!selected_inst || best_dist > dist)) {
 				selected_inst = inst;
@@ -158,6 +194,8 @@
 	for (inst = insts[ip_vec]; inst; inst = inst->next) {
 		if (!inst->active)
 			continue;
+		if (!inst_connected(inst))
+			continue;
 		dist = gui_dist_vec_fallback(inst, pos, draw_ctx.scale);
 		if (dist >= 0 && (!selected_inst || best_dist > dist)) {
 			selected_inst = inst;




More information about the commitlog mailing list