mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-25 19:02:29 +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:
parent
08b788b929
commit
68b4fec921
3
README
3
README
@ -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
|
||||
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
160
delete.c
@ -41,9 +41,16 @@ static struct deletion {
|
||||
struct obj *prev;
|
||||
} obj;
|
||||
} u;
|
||||
int group;
|
||||
struct deletion *next;
|
||||
} *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)
|
||||
{
|
||||
@ -51,6 +58,7 @@ static struct deletion *new_deletion(enum del_type type)
|
||||
|
||||
del = alloc_type(struct deletion);
|
||||
del->type = type;
|
||||
del->group = groups;
|
||||
del->next = deletions;
|
||||
deletions = del;
|
||||
return del;
|
||||
@ -60,38 +68,64 @@ static struct deletion *new_deletion(enum del_type type)
|
||||
/* ----- vectors ----------------------------------------------------------- */
|
||||
|
||||
|
||||
static void dereference_vec(struct vec *vec)
|
||||
{
|
||||
assert(!vec->n_refs);
|
||||
put_vec(vec->base);
|
||||
}
|
||||
|
||||
|
||||
static void destroy_vec(struct vec *vec)
|
||||
{
|
||||
assert(!vec->n_refs);
|
||||
free_expr(vec->x);
|
||||
free_expr(vec->y);
|
||||
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 deletion *del;
|
||||
|
||||
if (vec->n_refs) {
|
||||
fail("vector has %d reference%s", vec->n_refs,
|
||||
vec->n_refs == 1 ? "" : "s");
|
||||
return;
|
||||
}
|
||||
delete_vecs_by_ref(vec->frame->vecs, vec);
|
||||
delete_objs_by_ref(&vec->frame->objs, vec);
|
||||
|
||||
prev = NULL;
|
||||
for (walk = vec->frame->vecs; walk != vec; walk = walk->next)
|
||||
prev = walk;
|
||||
@ -99,13 +133,19 @@ void delete_vec(struct vec *vec)
|
||||
prev->next = vec->next;
|
||||
else
|
||||
vec->frame->vecs = vec->next;
|
||||
dereference_vec(vec);
|
||||
del = new_deletion(dt_vec);
|
||||
del->u.vec.ref = vec;
|
||||
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)
|
||||
{
|
||||
if (prev) {
|
||||
@ -115,42 +155,12 @@ static void undelete_vec(struct vec *vec, struct vec *prev)
|
||||
assert(vec->next == vec->frame->vecs);
|
||||
vec->frame->vecs = vec;
|
||||
}
|
||||
rereference_vec(vec);
|
||||
}
|
||||
|
||||
|
||||
/* ----- 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)
|
||||
{
|
||||
switch (obj->type) {
|
||||
@ -179,36 +189,7 @@ static void destroy_obj(struct obj *obj)
|
||||
}
|
||||
|
||||
|
||||
static void rereference_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)
|
||||
static void do_delete_obj(struct obj *obj)
|
||||
{
|
||||
struct obj *walk, *prev;
|
||||
struct deletion *del;
|
||||
@ -220,13 +201,19 @@ void delete_obj(struct obj *obj)
|
||||
prev->next = obj->next;
|
||||
else
|
||||
obj->frame->objs = obj->next;
|
||||
dereference_obj(obj);
|
||||
del = new_deletion(dt_obj);
|
||||
del->u.obj.ref = obj;
|
||||
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)
|
||||
{
|
||||
if (prev) {
|
||||
@ -236,7 +223,6 @@ static void undelete_obj(struct obj *obj, struct obj *prev)
|
||||
assert(obj->next == obj->frame->objs);
|
||||
obj->frame->objs = obj;
|
||||
}
|
||||
rereference_obj(obj);
|
||||
}
|
||||
|
||||
|
||||
@ -260,6 +246,7 @@ void delete_frame(struct frame *frame)
|
||||
{
|
||||
struct deletion *del;
|
||||
|
||||
groups++;
|
||||
delete_references(frame);
|
||||
|
||||
del = new_deletion(dt_frame);
|
||||
@ -318,7 +305,7 @@ int destroy(void)
|
||||
}
|
||||
|
||||
|
||||
int undelete(void)
|
||||
static int undelete_one(void)
|
||||
{
|
||||
struct deletion *del;
|
||||
|
||||
@ -342,3 +329,16 @@ int undelete(void)
|
||||
free(del);
|
||||
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
2
dump.c
@ -114,8 +114,6 @@ static int n_vec_refs(const struct vec *vec)
|
||||
const struct vec *walk;
|
||||
int n;
|
||||
|
||||
if (!vec->n_refs)
|
||||
return 0;
|
||||
n = 0;
|
||||
for (walk = vec->frame->vecs; walk; walk = walk->next)
|
||||
if (walk->base == vec)
|
||||
|
5
fpd.y
5
fpd.y
@ -345,7 +345,6 @@ vec:
|
||||
$$->base = $2;
|
||||
$$->x = $4;
|
||||
$$->y = $6;
|
||||
$$->n_refs = 0;
|
||||
$$->frame = curr_frame;
|
||||
$$->next = NULL;
|
||||
last_vec = $$;
|
||||
@ -366,7 +365,6 @@ base:
|
||||
yyerrorf(". without predecessor");
|
||||
YYABORT;
|
||||
}
|
||||
$$->n_refs++;
|
||||
}
|
||||
| ID
|
||||
{
|
||||
@ -375,7 +373,6 @@ base:
|
||||
yyerrorf("unknown vector \"%s\"", $1);
|
||||
YYABORT;
|
||||
}
|
||||
$$->n_refs++;
|
||||
}
|
||||
;
|
||||
|
||||
@ -406,7 +403,7 @@ obj:
|
||||
$$ = new_obj(ot_arc);
|
||||
$$->base = $2;
|
||||
$$->u.arc.start = $3;
|
||||
$$->u.arc.end = get_vec($3);
|
||||
$$->u.arc.end = $3;
|
||||
$$->u.arc.width = $4;
|
||||
}
|
||||
| TOK_ARC base base base opt_expr
|
||||
|
2
fped.c
2
fped.c
@ -54,7 +54,7 @@ int main(int argc, char **argv)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
// dump(stdout);
|
||||
dump(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
60
gui_tools.c
60
gui_tools.c
@ -80,8 +80,7 @@ static struct vec *new_vec(struct inst *base)
|
||||
|
||||
vec = alloc_type(struct vec);
|
||||
vec->name = NULL;
|
||||
vec->base = inst_get_ref(base);
|
||||
vec->n_refs = 0;
|
||||
vec->base = inst_get_vec(base);
|
||||
vec->next = NULL;
|
||||
vec->frame = active_frame;
|
||||
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->type = type;
|
||||
obj->frame = active_frame;
|
||||
obj->base = inst_get_ref(base);
|
||||
obj->base = inst_get_vec(base);
|
||||
obj->next = NULL;
|
||||
obj->lineno = 0;
|
||||
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 --------------------------------------------------------------- */
|
||||
|
||||
|
||||
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));
|
||||
pos->y -= fmod(pos->y-base.y, mm_to_units(0.1));
|
||||
struct coord new;
|
||||
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;
|
||||
|
||||
pos = inst_get_point(from);
|
||||
gridify(pos, &to);
|
||||
to = gridify(pos, to);
|
||||
status_set_type_x("dX =");
|
||||
status_set_type_y("dX =");
|
||||
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);
|
||||
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->y = new_num(make_mm(units_to_mm(to.y-pos.y)));
|
||||
return 1;
|
||||
@ -252,7 +261,7 @@ static int end_new_line(struct draw_ctx *ctx,
|
||||
if (from == to)
|
||||
return 0;
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
@ -298,7 +307,7 @@ static int end_new_rect(struct draw_ctx *ctx,
|
||||
if (from == to)
|
||||
return 0;
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
@ -321,7 +330,7 @@ static int end_new_pad(struct draw_ctx *ctx,
|
||||
if (from == to)
|
||||
return 0;
|
||||
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("?");
|
||||
return 1;
|
||||
}
|
||||
@ -367,8 +376,8 @@ static int end_new_circ(struct draw_ctx *ctx,
|
||||
if (from == to)
|
||||
return 0;
|
||||
obj = new_obj(ot_arc, from);
|
||||
obj->u.arc.start = inst_get_ref(to);
|
||||
obj->u.arc.end = inst_get_ref(to);
|
||||
obj->u.arc.start = inst_get_vec(to);
|
||||
obj->u.arc.end = inst_get_vec(to);
|
||||
obj->u.arc.width = NULL;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
switch (i) {
|
||||
case 0:
|
||||
replace(&obj->base, vec);
|
||||
obj->base = vec;
|
||||
break;
|
||||
case 1:
|
||||
replace(&obj->u.arc.start, vec);
|
||||
obj->u.arc.start = vec;
|
||||
if (!is_circle)
|
||||
break;
|
||||
/* fall through */
|
||||
case 2:
|
||||
replace(&obj->u.arc.end, vec);
|
||||
obj->u.arc.end = vec;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -475,7 +474,7 @@ static int end_new_meas(struct draw_ctx *ctx,
|
||||
if (from == to)
|
||||
return 0;
|
||||
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");
|
||||
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)
|
||||
{
|
||||
struct vec *old;
|
||||
|
||||
assert(may_move_to(state, curr));
|
||||
old = *state->anchors[state->anchor_i];
|
||||
if (old)
|
||||
old->n_refs--;
|
||||
*state->anchors[state->anchor_i] = inst_get_ref(curr);
|
||||
*state->anchors[state->anchor_i] = inst_get_vec(curr);
|
||||
}
|
||||
|
||||
|
||||
|
12
inst.c
12
inst.c
@ -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)
|
||||
{
|
||||
if (inst->ops == &vec_ops)
|
||||
|
1
inst.h
1
inst.h
@ -87,7 +87,6 @@ void inst_deselect(void);
|
||||
struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos);
|
||||
struct coord inst_get_point(const struct inst *inst);
|
||||
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);
|
||||
|
||||
int inst_vec(struct vec *vec, struct coord base);
|
||||
|
18
obj.h
18
obj.h
@ -88,7 +88,6 @@ struct vec {
|
||||
struct expr *x;
|
||||
struct expr *y;
|
||||
struct vec *base; /* NULL if frame */
|
||||
int n_refs;
|
||||
struct vec *next;
|
||||
|
||||
/* used during generation */
|
||||
@ -174,23 +173,6 @@ extern struct frame *root_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);
|
||||
|
||||
#endif /* !OBJ_H */
|
||||
|
Loading…
Reference in New Issue
Block a user