1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-11-17 20:14:03 +02:00

- undelete after recursive delete now brings back everything deleted in that

operation, not just one object at a time
- vector reference counting is not needed now that we have recursive delete.
  Removed it.
- completed recursive delete of vectors
- gridify: give new vectors a minimum length, so that we don't get a weird
  display when starting a new footprint.



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5391 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-06 04:33:49 +00:00
parent 08b788b929
commit 68b4fec921
9 changed files with 111 additions and 152 deletions

3
README
View File

@ -403,4 +403,5 @@ make the changes in the input area at the bottom.
To delete an object, select it and press Delete. Deleted objects can To delete an object, select it and press Delete. Deleted objects can
be undeleted by pressing "u". If any other changes have been made be undeleted by pressing "u". If any other changes have been made
since deletion, fped may misbehave. since deletion, fped may misbehave. If deleting a vector, all items
that reference it are deleted.

160
delete.c
View File

@ -41,9 +41,16 @@ static struct deletion {
struct obj *prev; struct obj *prev;
} obj; } obj;
} u; } u;
int group;
struct deletion *next; struct deletion *next;
} *deletions = NULL; } *deletions = NULL;
static int groups = 0;
static void do_delete_vec(struct vec *vec);
static void do_delete_obj(struct obj *obj);
static struct deletion *new_deletion(enum del_type type) static struct deletion *new_deletion(enum del_type type)
{ {
@ -51,6 +58,7 @@ static struct deletion *new_deletion(enum del_type type)
del = alloc_type(struct deletion); del = alloc_type(struct deletion);
del->type = type; del->type = type;
del->group = groups;
del->next = deletions; del->next = deletions;
deletions = del; deletions = del;
return del; return del;
@ -60,38 +68,64 @@ static struct deletion *new_deletion(enum del_type type)
/* ----- vectors ----------------------------------------------------------- */ /* ----- vectors ----------------------------------------------------------- */
static void dereference_vec(struct vec *vec)
{
assert(!vec->n_refs);
put_vec(vec->base);
}
static void destroy_vec(struct vec *vec) static void destroy_vec(struct vec *vec)
{ {
assert(!vec->n_refs);
free_expr(vec->x); free_expr(vec->x);
free_expr(vec->y); free_expr(vec->y);
free(vec); free(vec);
} }
static void rereference_vec(struct vec *vec) static void delete_vecs_by_ref(struct vec *vecs, const struct vec *ref)
{ {
get_vec(vec->base); while (vecs) {
if (vecs->base == ref)
do_delete_vec(vecs);
vecs = vecs->next;
}
} }
void delete_vec(struct vec *vec) static int obj_has_ref(const struct obj *obj, const struct vec *ref)
{
if (obj->base == ref)
return 1;
switch (obj->type) {
case ot_frame:
return 0;
case ot_line:
return obj->u.line.other == ref;
case ot_rect:
return obj->u.rect.other == ref;
case ot_pad:
return obj->u.pad.other == ref;
case ot_arc:
return obj->u.arc.start == ref || obj->u.arc.end == ref;
case ot_meas:
default:
abort();
}
}
static void delete_objs_by_ref(struct obj **objs, const struct vec *ref)
{
struct obj *obj;
for (obj = *objs; obj; obj = obj->next)
if (obj_has_ref(obj, ref))
do_delete_obj(obj);
}
static void do_delete_vec(struct vec *vec)
{ {
struct vec *walk, *prev; struct vec *walk, *prev;
struct deletion *del; struct deletion *del;
if (vec->n_refs) { delete_vecs_by_ref(vec->frame->vecs, vec);
fail("vector has %d reference%s", vec->n_refs, delete_objs_by_ref(&vec->frame->objs, vec);
vec->n_refs == 1 ? "" : "s");
return;
}
prev = NULL; prev = NULL;
for (walk = vec->frame->vecs; walk != vec; walk = walk->next) for (walk = vec->frame->vecs; walk != vec; walk = walk->next)
prev = walk; prev = walk;
@ -99,13 +133,19 @@ void delete_vec(struct vec *vec)
prev->next = vec->next; prev->next = vec->next;
else else
vec->frame->vecs = vec->next; vec->frame->vecs = vec->next;
dereference_vec(vec);
del = new_deletion(dt_vec); del = new_deletion(dt_vec);
del->u.vec.ref = vec; del->u.vec.ref = vec;
del->u.vec.prev = prev; del->u.vec.prev = prev;
} }
void delete_vec(struct vec *vec)
{
groups++;
do_delete_vec(vec);
}
static void undelete_vec(struct vec *vec, struct vec *prev) static void undelete_vec(struct vec *vec, struct vec *prev)
{ {
if (prev) { if (prev) {
@ -115,42 +155,12 @@ static void undelete_vec(struct vec *vec, struct vec *prev)
assert(vec->next == vec->frame->vecs); assert(vec->next == vec->frame->vecs);
vec->frame->vecs = vec; vec->frame->vecs = vec;
} }
rereference_vec(vec);
} }
/* ----- objects ----------------------------------------------------------- */ /* ----- objects ----------------------------------------------------------- */
static void dereference_obj(struct obj *obj)
{
switch (obj->type) {
case ot_frame:
/* nothing */
break;
case ot_pad:
put_vec(obj->u.pad.other);
break;
case ot_line:
put_vec(obj->u.line.other);
break;
case ot_rect:
put_vec(obj->u.rect.other);
break;
case ot_arc:
put_vec(obj->u.arc.start);
put_vec(obj->u.arc.end);
break;
case ot_meas:
put_vec(obj->u.meas.other);
break;
default:
abort();
}
put_vec(obj->base);
}
static void destroy_obj(struct obj *obj) static void destroy_obj(struct obj *obj)
{ {
switch (obj->type) { switch (obj->type) {
@ -179,36 +189,7 @@ static void destroy_obj(struct obj *obj)
} }
static void rereference_obj(struct obj *obj) static void do_delete_obj(struct obj *obj)
{
switch (obj->type) {
case ot_frame:
/* nothing */
break;
case ot_pad:
get_vec(obj->u.pad.other);
break;
case ot_line:
get_vec(obj->u.line.other);
break;
case ot_rect:
get_vec(obj->u.rect.other);
break;
case ot_arc:
get_vec(obj->u.arc.start);
get_vec(obj->u.arc.end);
break;
case ot_meas:
get_vec(obj->u.meas.other);
break;
default:
abort();
}
get_vec(obj->base);
}
void delete_obj(struct obj *obj)
{ {
struct obj *walk, *prev; struct obj *walk, *prev;
struct deletion *del; struct deletion *del;
@ -220,13 +201,19 @@ void delete_obj(struct obj *obj)
prev->next = obj->next; prev->next = obj->next;
else else
obj->frame->objs = obj->next; obj->frame->objs = obj->next;
dereference_obj(obj);
del = new_deletion(dt_obj); del = new_deletion(dt_obj);
del->u.obj.ref = obj; del->u.obj.ref = obj;
del->u.obj.prev = prev; del->u.obj.prev = prev;
} }
void delete_obj(struct obj *obj)
{
groups++;
do_delete_obj(obj);
}
static void undelete_obj(struct obj *obj, struct obj *prev) static void undelete_obj(struct obj *obj, struct obj *prev)
{ {
if (prev) { if (prev) {
@ -236,7 +223,6 @@ static void undelete_obj(struct obj *obj, struct obj *prev)
assert(obj->next == obj->frame->objs); assert(obj->next == obj->frame->objs);
obj->frame->objs = obj; obj->frame->objs = obj;
} }
rereference_obj(obj);
} }
@ -260,6 +246,7 @@ void delete_frame(struct frame *frame)
{ {
struct deletion *del; struct deletion *del;
groups++;
delete_references(frame); delete_references(frame);
del = new_deletion(dt_frame); del = new_deletion(dt_frame);
@ -318,7 +305,7 @@ int destroy(void)
} }
int undelete(void) static int undelete_one(void)
{ {
struct deletion *del; struct deletion *del;
@ -342,3 +329,16 @@ int undelete(void)
free(del); free(del);
return 1; return 1;
} }
int undelete(void)
{
int group;
if (!deletions)
return 0;
group = deletions->group;
while (deletions && deletions->group == group)
undelete_one();
return 1;
}

2
dump.c
View File

@ -114,8 +114,6 @@ static int n_vec_refs(const struct vec *vec)
const struct vec *walk; const struct vec *walk;
int n; int n;
if (!vec->n_refs)
return 0;
n = 0; n = 0;
for (walk = vec->frame->vecs; walk; walk = walk->next) for (walk = vec->frame->vecs; walk; walk = walk->next)
if (walk->base == vec) if (walk->base == vec)

5
fpd.y
View File

@ -345,7 +345,6 @@ vec:
$$->base = $2; $$->base = $2;
$$->x = $4; $$->x = $4;
$$->y = $6; $$->y = $6;
$$->n_refs = 0;
$$->frame = curr_frame; $$->frame = curr_frame;
$$->next = NULL; $$->next = NULL;
last_vec = $$; last_vec = $$;
@ -366,7 +365,6 @@ base:
yyerrorf(". without predecessor"); yyerrorf(". without predecessor");
YYABORT; YYABORT;
} }
$$->n_refs++;
} }
| ID | ID
{ {
@ -375,7 +373,6 @@ base:
yyerrorf("unknown vector \"%s\"", $1); yyerrorf("unknown vector \"%s\"", $1);
YYABORT; YYABORT;
} }
$$->n_refs++;
} }
; ;
@ -406,7 +403,7 @@ obj:
$$ = new_obj(ot_arc); $$ = new_obj(ot_arc);
$$->base = $2; $$->base = $2;
$$->u.arc.start = $3; $$->u.arc.start = $3;
$$->u.arc.end = get_vec($3); $$->u.arc.end = $3;
$$->u.arc.width = $4; $$->u.arc.width = $4;
} }
| TOK_ARC base base base opt_expr | TOK_ARC base base base opt_expr

2
fped.c
View File

@ -54,7 +54,7 @@ int main(int argc, char **argv)
if (error) if (error)
return error; return error;
// dump(stdout); dump(stdout);
return 0; return 0;
} }

View File

@ -80,8 +80,7 @@ static struct vec *new_vec(struct inst *base)
vec = alloc_type(struct vec); vec = alloc_type(struct vec);
vec->name = NULL; vec->name = NULL;
vec->base = inst_get_ref(base); vec->base = inst_get_vec(base);
vec->n_refs = 0;
vec->next = NULL; vec->next = NULL;
vec->frame = active_frame; vec->frame = active_frame;
for (walk = &active_frame->vecs; *walk; walk = &(*walk)->next); for (walk = &active_frame->vecs; *walk; walk = &(*walk)->next);
@ -97,7 +96,7 @@ static struct obj *new_obj(enum obj_type type, struct inst *base)
obj = alloc_type(struct obj); obj = alloc_type(struct obj);
obj->type = type; obj->type = type;
obj->frame = active_frame; obj->frame = active_frame;
obj->base = inst_get_ref(base); obj->base = inst_get_vec(base);
obj->next = NULL; obj->next = NULL;
obj->lineno = 0; obj->lineno = 0;
for (walk = &active_frame->objs; *walk; walk = &(*walk)->next); for (walk = &active_frame->objs; *walk; walk = &(*walk)->next);
@ -164,10 +163,20 @@ static struct pix_buf *draw_move_rect_common(struct inst *inst,
/* ----- vec --------------------------------------------------------------- */ /* ----- vec --------------------------------------------------------------- */
static void gridify(struct coord base, struct coord *pos) static struct coord gridify(struct coord base, struct coord pos)
{ {
pos->x -= fmod(pos->x-base.x, mm_to_units(0.1)); struct coord new;
pos->y -= fmod(pos->y-base.y, mm_to_units(0.1)); unit_type unit = mm_to_units(0.1);
new.x = pos.x-(pos.x-base.x % unit);
new.y = pos.y-(pos.y-base.y % unit);
if (new.x != base.x || new.y != base.y)
return new;
if (fabs(pos.x-base.x) > fabs(pos.y-base.y))
new.x += pos.x > base.x ? unit : -unit;
else
new.y += pos.y > base.y ? unit : -unit;
return new;
} }
@ -178,7 +187,7 @@ static struct pix_buf *drag_new_vec(struct draw_ctx *ctx,
struct pix_buf *buf; struct pix_buf *buf;
pos = inst_get_point(from); pos = inst_get_point(from);
gridify(pos, &to); to = gridify(pos, to);
status_set_type_x("dX ="); status_set_type_x("dX =");
status_set_type_y("dX ="); status_set_type_y("dX =");
status_set_x("%lg mm", units_to_mm(to.x-pos.x)); status_set_x("%lg mm", units_to_mm(to.x-pos.x));
@ -207,7 +216,7 @@ static int end_new_raw_vec(struct draw_ctx *ctx,
vec = new_vec(from); vec = new_vec(from);
pos = inst_get_point(from); pos = inst_get_point(from);
gridify(pos, &to); to = gridify(pos, to);
vec->x = new_num(make_mm(units_to_mm(to.x-pos.x))); vec->x = new_num(make_mm(units_to_mm(to.x-pos.x)));
vec->y = new_num(make_mm(units_to_mm(to.y-pos.y))); vec->y = new_num(make_mm(units_to_mm(to.y-pos.y)));
return 1; return 1;
@ -252,7 +261,7 @@ static int end_new_line(struct draw_ctx *ctx,
if (from == to) if (from == to)
return 0; return 0;
obj = new_obj(ot_line, from); obj = new_obj(ot_line, from);
obj->u.line.other = inst_get_ref(to); obj->u.line.other = inst_get_vec(to);
obj->u.line.width = NULL; obj->u.line.width = NULL;
return 1; return 1;
} }
@ -298,7 +307,7 @@ static int end_new_rect(struct draw_ctx *ctx,
if (from == to) if (from == to)
return 0; return 0;
obj = new_obj(ot_rect, from); obj = new_obj(ot_rect, from);
obj->u.rect.other = inst_get_ref(to); obj->u.rect.other = inst_get_vec(to);
obj->u.rect.width = NULL; obj->u.rect.width = NULL;
return 1; return 1;
} }
@ -321,7 +330,7 @@ static int end_new_pad(struct draw_ctx *ctx,
if (from == to) if (from == to)
return 0; return 0;
obj = new_obj(ot_pad, from); obj = new_obj(ot_pad, from);
obj->u.pad.other = inst_get_ref(to); obj->u.pad.other = inst_get_vec(to);
obj->u.pad.name = stralloc("?"); obj->u.pad.name = stralloc("?");
return 1; return 1;
} }
@ -367,8 +376,8 @@ static int end_new_circ(struct draw_ctx *ctx,
if (from == to) if (from == to)
return 0; return 0;
obj = new_obj(ot_arc, from); obj = new_obj(ot_arc, from);
obj->u.arc.start = inst_get_ref(to); obj->u.arc.start = inst_get_vec(to);
obj->u.arc.end = inst_get_ref(to); obj->u.arc.end = inst_get_vec(to);
obj->u.arc.width = NULL; obj->u.arc.width = NULL;
return 1; return 1;
} }
@ -417,16 +426,6 @@ struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
} }
static void replace(struct vec **anchor, struct vec *new)
{
if (*anchor)
(*anchor)->n_refs--;
*anchor = new;
if (new)
new->n_refs++;
}
void do_move_to_arc(struct inst *inst, struct vec *vec, int i) void do_move_to_arc(struct inst *inst, struct vec *vec, int i)
{ {
struct obj *obj = inst->obj; struct obj *obj = inst->obj;
@ -435,15 +434,15 @@ void do_move_to_arc(struct inst *inst, struct vec *vec, int i)
is_circle = obj->u.arc.start == obj->u.arc.end; is_circle = obj->u.arc.start == obj->u.arc.end;
switch (i) { switch (i) {
case 0: case 0:
replace(&obj->base, vec); obj->base = vec;
break; break;
case 1: case 1:
replace(&obj->u.arc.start, vec); obj->u.arc.start = vec;
if (!is_circle) if (!is_circle)
break; break;
/* fall through */ /* fall through */
case 2: case 2:
replace(&obj->u.arc.end, vec); obj->u.arc.end = vec;
break; break;
default: default:
abort(); abort();
@ -475,7 +474,7 @@ static int end_new_meas(struct draw_ctx *ctx,
if (from == to) if (from == to)
return 0; return 0;
obj = new_obj(ot_meas, from); obj = new_obj(ot_meas, from);
obj->u.meas.other = inst_get_ref(to); obj->u.meas.other = inst_get_vec(to);
obj->u.meas.offset = parse_expr("0mm"); obj->u.meas.offset = parse_expr("0mm");
return 1; return 1;
} }
@ -643,13 +642,8 @@ static int may_move_to(const struct drag_state *state, struct inst *curr)
static void do_move_to(struct drag_state *state, struct inst *curr) static void do_move_to(struct drag_state *state, struct inst *curr)
{ {
struct vec *old;
assert(may_move_to(state, curr)); assert(may_move_to(state, curr));
old = *state->anchors[state->anchor_i]; *state->anchors[state->anchor_i] = inst_get_vec(curr);
if (old)
old->n_refs--;
*state->anchors[state->anchor_i] = inst_get_ref(curr);
} }

12
inst.c
View File

@ -219,18 +219,6 @@ struct coord inst_get_point(const struct inst *inst)
} }
struct vec *inst_get_ref(const struct inst *inst)
{
if (inst->ops == &vec_ops) {
inst->vec->n_refs++;
return inst->vec;
}
if (inst->ops == &frame_ops)
return NULL;
abort();
}
struct vec *inst_get_vec(const struct inst *inst) struct vec *inst_get_vec(const struct inst *inst)
{ {
if (inst->ops == &vec_ops) if (inst->ops == &vec_ops)

1
inst.h
View File

@ -87,7 +87,6 @@ void inst_deselect(void);
struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos); struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos);
struct coord inst_get_point(const struct inst *inst); struct coord inst_get_point(const struct inst *inst);
int inst_anchors(struct inst *inst, struct vec ***anchors); int inst_anchors(struct inst *inst, struct vec ***anchors);
struct vec *inst_get_ref(const struct inst *inst);
struct vec *inst_get_vec(const struct inst *inst); struct vec *inst_get_vec(const struct inst *inst);
int inst_vec(struct vec *vec, struct coord base); int inst_vec(struct vec *vec, struct coord base);

18
obj.h
View File

@ -88,7 +88,6 @@ struct vec {
struct expr *x; struct expr *x;
struct expr *y; struct expr *y;
struct vec *base; /* NULL if frame */ struct vec *base; /* NULL if frame */
int n_refs;
struct vec *next; struct vec *next;
/* used during generation */ /* used during generation */
@ -174,23 +173,6 @@ extern struct frame *root_frame;
extern struct frame *active_frame; extern struct frame *active_frame;
static inline struct vec *get_vec(struct vec *vec)
{
if (vec)
vec->n_refs++;
return vec;
}
static inline void put_vec(struct vec *vec)
{
if (vec) {
assert(vec->n_refs);
vec->n_refs--;
}
}
int instantiate(void); int instantiate(void);
#endif /* !OBJ_H */ #endif /* !OBJ_H */