Skip to content
Snippets Groups Projects
Commit c6d88933 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

added redundant memory remapping when creating new embedded canvases to avoid...

added redundant memory remapping when creating new embedded canvases to avoid double-entry bug which has resurfaced since the introduction of the infinite undo.
parent 79305cc3
No related branches found
No related tags found
No related merge requests found
...@@ -343,12 +343,42 @@ void glist_init(t_glist *x) ...@@ -343,12 +343,42 @@ void glist_init(t_glist *x)
x->gl_ylabel = (t_symbol **)t_getbytes(0); x->gl_ylabel = (t_symbol **)t_getbytes(0);
} }
/* global var used by pd_new() to work with redundant memory, originally defined in m_pd.c */
extern int canvas_check_duplicate;
/* make a new glist. It will either be a "root" canvas or else /* make a new glist. It will either be a "root" canvas or else
it appears as a "text" object in another window (canvas_getcurrent() it appears as a "text" object in another window (canvas_getcurrent()
tells us which.) */ tells us which.) */
t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv) t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
{ {
/* first alloc one byte or redundant memory to prevent creation of objects with the same "name"
which leads to double-action invoked from every single action and eventually possible crashes
we keep a list of these redundant allocations and destroy them when pd quits */
//if (x->gl_owner && x->gl_env) {
t_redundant_mem *new_rm = (t_redundant_mem *)t_getbytes(sizeof(*new_rm));
//new_rm->rm_what = (int)getbytes(1);
if (rm_start == NULL) {
//fprintf(stderr,"first allocation\n");
rm_start = new_rm;
rm_end = new_rm;
}
else if (rm_start == rm_end) {
//fprintf(stderr,"second allocation\n");
rm_end = new_rm;
rm_start->rm_next = rm_end;
}
else {
//fprintf(stderr,"allocation\n");
rm_end->rm_next = new_rm;
rm_end = new_rm;
}
//}
canvas_check_duplicate = -1;
t_canvas *x = (t_canvas *)pd_new(canvas_class); t_canvas *x = (t_canvas *)pd_new(canvas_class);
rm_end->rm_canvas = x;
t_canvas *owner = canvas_getcurrent(); t_canvas *owner = canvas_getcurrent();
t_symbol *s = &s_; t_symbol *s = &s_;
int vis = 0, width = GLIST_DEFCANVASWIDTH, height = GLIST_DEFCANVASHEIGHT; int vis = 0, width = GLIST_DEFCANVASWIDTH, height = GLIST_DEFCANVASHEIGHT;
...@@ -876,7 +906,7 @@ void canvas_free(t_canvas *x) ...@@ -876,7 +906,7 @@ void canvas_free(t_canvas *x)
if (x->gl_magic_glass) if (x->gl_magic_glass)
magicGlass_free(x->gl_magic_glass); magicGlass_free(x->gl_magic_glass);
canvas_noundo(x); //canvas_noundo(x);
canvas_undo_free(x); canvas_undo_free(x);
if (canvas_editing == x) if (canvas_editing == x)
...@@ -889,8 +919,10 @@ void canvas_free(t_canvas *x) ...@@ -889,8 +919,10 @@ void canvas_free(t_canvas *x)
if (x == glist_getcanvas(x)) if (x == glist_getcanvas(x))
canvas_vis(x, 0); canvas_vis(x, 0);
if (strcmp(x->gl_name->s_name, "Pd")) if (strcmp(x->gl_name->s_name, "Pd")) {
//fprintf(stderr,"canvas_free calling pd_unbind\n");
pd_unbind(&x->gl_pd, canvas_makebindsym(x->gl_name)); pd_unbind(&x->gl_pd, canvas_makebindsym(x->gl_name));
}
if (x->gl_env) if (x->gl_env)
{ {
freebytes(x->gl_env->ce_argv, x->gl_env->ce_argc * sizeof(t_atom)); freebytes(x->gl_env->ce_argv, x->gl_env->ce_argc * sizeof(t_atom));
......
...@@ -46,17 +46,17 @@ extern "C" { ...@@ -46,17 +46,17 @@ extern "C" {
canvases/abstractions rather than individual objects. the queue canvases/abstractions rather than individual objects. the queue
is destructed in m_glob.c quit call (when pd exits) */ is destructed in m_glob.c quit call (when pd exits) */
/*
typedef struct _redundant_mem typedef struct _redundant_mem
{ {
int rm_what; //int rm_what;
t_canvas *rm_canvas; t_canvas *rm_canvas;
struct _redundant_mem *rm_next; struct _redundant_mem *rm_next;
} t_redundant_mem; } t_redundant_mem;
t_redundant_mem *rm_start; t_redundant_mem *rm_start;
t_redundant_mem *rm_end; t_redundant_mem *rm_end;
*/
/* --------------------- geometry ---------------------------- */ /* --------------------- geometry ---------------------------- */
#define IOWIDTH 7 /* width of an inlet/outlet in pixels */ #define IOWIDTH 7 /* width of an inlet/outlet in pixels */
......
...@@ -11,9 +11,16 @@ ...@@ -11,9 +11,16 @@
/* FIXME no out-of-memory testing yet! */ /* FIXME no out-of-memory testing yet! */
int canvas_check_duplicate = 0;
extern t_redundant_mem *rm_start;
extern t_redundant_mem *rm_end;
t_pd *pd_new(t_class *c) t_pd *pd_new(t_class *c)
{ {
t_pd *x; t_pd *x = NULL;
t_pd *y = NULL;
if (!c) if (!c)
bug ("pd_new: apparently called before setup routine"); bug ("pd_new: apparently called before setup routine");
...@@ -31,41 +38,47 @@ t_pd *pd_new(t_class *c) ...@@ -31,41 +38,47 @@ t_pd *pd_new(t_class *c)
a random additional amount of memory and then resize allocation to the original a random additional amount of memory and then resize allocation to the original
size size
duplicate: -1 initial state duplicate: -1 enable check state
0 all is ok 0 all is ok (or we are not allocating canvas memory)
1 found a duplicate 1 found a duplicate
*/ */
/* //int random_extra = 0;
int duplicate = 0; //change to -1 to enable redundant_mem resizing //int random_offset = 1;
int random_extra = 0;
while (duplicate != 0) { while (canvas_check_duplicate != 0) {
if (duplicate == -1) { if (canvas_check_duplicate == -1) {
//fprintf(stderr,"alloc %d %d\n", duplicate, (int)c->c_size); //fprintf(stderr,"alloc %d %d\n", canvas_check_duplicate, (int)c->c_size);
x = (t_pd *)t_getbytes(c->c_size); x = (t_pd *)t_getbytes(c->c_size);
} else if (duplicate == 1) { } else if (canvas_check_duplicate == 1) {
random_extra = rand () + 1; //random_extra = rand () + random_offset;
//fprintf(stderr,"alloc %d %d %d\n", duplicate, (int)c->c_size, (int)c->c_size + random_extra); //fprintf(stderr,"alloc %d %d %d\n", canvas_check_duplicate, (int)c->c_size, (int)c->c_size + random_extra);
x = (t_pd *)t_getbytes(c->c_size + random_extra); //x = (t_pd *)t_getbytes(c->c_size + random_extra);
//fprintf(stderr,"duplicate\n");
y = x;
y = (t_pd *)t_resizebytes(x, c->c_size, 1);
x = (t_pd *)t_getbytes(c->c_size);
t_freebytes(y, sizeof(1));
} }
duplicate = 0;
canvas_check_duplicate = 0;
if (rm_start) { if (rm_start) {
t_redundant_mem *tmp = rm_start; t_redundant_mem *tmp = rm_start;
while (tmp->rm_next) { while (tmp->rm_next) {
if ((int)tmp->rm_canvas == (int)x) { //fprintf(stderr,"compare %lx %lx\n", (t_int)tmp->rm_canvas, (t_int)x);
duplicate = 1; if ((t_int)tmp->rm_canvas == (t_int)x) {
canvas_check_duplicate = 1;
break; break;
} }
tmp = tmp->rm_next; tmp = tmp->rm_next;
} }
if (tmp && (int)tmp->rm_canvas == (int)x) if (tmp && (t_int)tmp->rm_canvas == (t_int)x)
duplicate = 1; canvas_check_duplicate = 1;
} }
//fprintf(stderr,"done alloc %d\n", duplicate);
if (duplicate == 1) { //fprintf(stderr,"done alloc %d\n", canvas_check_duplicate);
/*if (canvas_check_duplicate == 1) {
//fprintf(stderr,"duplicate\n"); //fprintf(stderr,"duplicate\n");
if (!random_extra) if (!random_extra)
t_freebytes(x, sizeof(c->c_size)); t_freebytes(x, sizeof(c->c_size));
...@@ -73,13 +86,13 @@ t_pd *pd_new(t_class *c) ...@@ -73,13 +86,13 @@ t_pd *pd_new(t_class *c)
t_freebytes(x, sizeof(c->c_size+random_extra)); t_freebytes(x, sizeof(c->c_size+random_extra));
} }
if (!duplicate && random_extra) { if (!canvas_check_duplicate && random_extra) {
x = (t_pd *)t_resizebytes(x, c->c_size+random_extra, c->c_size); x = (t_pd *)t_resizebytes(x, c->c_size+random_extra, c->c_size);
} break;
}*/
} }
*/
x = (t_pd *)t_getbytes(c->c_size); if (!x) x = (t_pd *)t_getbytes(c->c_size);
*x = c; *x = c;
if (c->c_patchable) if (c->c_patchable)
{ {
...@@ -193,6 +206,7 @@ void pd_bind(t_pd *x, t_symbol *s) ...@@ -193,6 +206,7 @@ void pd_bind(t_pd *x, t_symbol *s)
{ {
if (*s->s_thing == bindlist_class) if (*s->s_thing == bindlist_class)
{ {
//fprintf(stderr,"pd_bind option 1A %lx\n", (t_int)x);
t_bindlist *b = (t_bindlist *)s->s_thing; t_bindlist *b = (t_bindlist *)s->s_thing;
t_bindelem *e = (t_bindelem *)getbytes(sizeof(t_bindelem)); t_bindelem *e = (t_bindelem *)getbytes(sizeof(t_bindelem));
e->e_next = b->b_list; e->e_next = b->b_list;
...@@ -201,6 +215,7 @@ void pd_bind(t_pd *x, t_symbol *s) ...@@ -201,6 +215,7 @@ void pd_bind(t_pd *x, t_symbol *s)
} }
else else
{ {
//fprintf(stderr,"pd_unbind option 1B %lx\n", (t_int)x);
t_bindlist *b = (t_bindlist *)pd_new(bindlist_class); t_bindlist *b = (t_bindlist *)pd_new(bindlist_class);
t_bindelem *e1 = (t_bindelem *)getbytes(sizeof(t_bindelem)); t_bindelem *e1 = (t_bindelem *)getbytes(sizeof(t_bindelem));
t_bindelem *e2 = (t_bindelem *)getbytes(sizeof(t_bindelem)); t_bindelem *e2 = (t_bindelem *)getbytes(sizeof(t_bindelem));
...@@ -212,30 +227,40 @@ void pd_bind(t_pd *x, t_symbol *s) ...@@ -212,30 +227,40 @@ void pd_bind(t_pd *x, t_symbol *s)
s->s_thing = &b->b_pd; s->s_thing = &b->b_pd;
} }
} }
else s->s_thing = x; else {
//fprintf(stderr,"pd_bind option 2 %lx\n", (t_int)x);
s->s_thing = x;
}
} }
void pd_unbind(t_pd *x, t_symbol *s) void pd_unbind(t_pd *x, t_symbol *s)
{ {
if (s->s_thing == x) s->s_thing = 0; if (s->s_thing == x) {
//fprintf(stderr,"pd_unbind option A %lx\n", (t_int)x);
s->s_thing = 0;
}
else if (s->s_thing && *s->s_thing == bindlist_class) else if (s->s_thing && *s->s_thing == bindlist_class)
{ {
/* bindlists always have at least two elements... if the number /* bindlists always have at least two elements... if the number
goes down to one, get rid of the bindlist and bind the symbol goes down to one, get rid of the bindlist and bind the symbol
straight to the remaining element. */ straight to the remaining element. */
//fprintf(stderr,"pd_unbind option B %lx\n", (t_int)x);
t_bindlist *b = (t_bindlist *)s->s_thing; t_bindlist *b = (t_bindlist *)s->s_thing;
t_bindelem *e, *e2; t_bindelem *e, *e2;
if ((e = b->b_list)->e_who == x) if ((e = b->b_list)->e_who == x)
{ {
b->b_list = e->e_next; b->b_list = e->e_next;
freebytes(e, sizeof(t_bindelem)); freebytes(e, sizeof(t_bindelem));
//fprintf(stderr,"success B1a\n");
} }
else for (e = b->b_list; e2 = e->e_next; e = e2) else for (e = b->b_list; e2 = e->e_next; e = e2)
if (e2->e_who == x) if (e2->e_who == x)
{ {
e->e_next = e2->e_next; e->e_next = e2->e_next;
freebytes(e2, sizeof(t_bindelem)); freebytes(e2, sizeof(t_bindelem));
//fprintf(stderr,"success B1b\n");
break; break;
} }
if (!b->b_list->e_next) if (!b->b_list->e_next)
...@@ -243,6 +268,7 @@ void pd_unbind(t_pd *x, t_symbol *s) ...@@ -243,6 +268,7 @@ void pd_unbind(t_pd *x, t_symbol *s)
s->s_thing = b->b_list->e_who; s->s_thing = b->b_list->e_who;
freebytes(b->b_list, sizeof(t_bindelem)); freebytes(b->b_list, sizeof(t_bindelem));
pd_free(&b->b_pd); pd_free(&b->b_pd);
///fprintf(stderr,"success B3\n");
} }
} }
else pd_error(x, "%s: couldn't unbind", s->s_name); else pd_error(x, "%s: couldn't unbind", s->s_name);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment