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