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
......@@ -343,12 +343,42 @@ void glist_init(t_glist *x)
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
it appears as a "text" object in another window (canvas_getcurrent()
tells us which.) */
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);
rm_end->rm_canvas = x;
t_canvas *owner = canvas_getcurrent();
t_symbol *s = &s_;
int vis = 0, width = GLIST_DEFCANVASWIDTH, height = GLIST_DEFCANVASHEIGHT;
......@@ -876,7 +906,7 @@ void canvas_free(t_canvas *x)
if (x->gl_magic_glass)
magicGlass_free(x->gl_magic_glass);
canvas_noundo(x);
//canvas_noundo(x);
canvas_undo_free(x);
if (canvas_editing == x)
......@@ -889,8 +919,10 @@ void canvas_free(t_canvas *x)
if (x == glist_getcanvas(x))
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));
}
if (x->gl_env)
{
freebytes(x->gl_env->ce_argv, x->gl_env->ce_argc * sizeof(t_atom));
......
......@@ -46,17 +46,17 @@ extern "C" {
canvases/abstractions rather than individual objects. the queue
is destructed in m_glob.c quit call (when pd exits) */
/*
typedef struct _redundant_mem
{
int rm_what;
//int rm_what;
t_canvas *rm_canvas;
struct _redundant_mem *rm_next;
} t_redundant_mem;
t_redundant_mem *rm_start;
t_redundant_mem *rm_end;
*/
/* --------------------- geometry ---------------------------- */
#define IOWIDTH 7 /* width of an inlet/outlet in pixels */
......
......@@ -11,9 +11,16 @@
/* 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 *x;
t_pd *x = NULL;
t_pd *y = NULL;
if (!c)
bug ("pd_new: apparently called before setup routine");
......@@ -31,41 +38,47 @@ t_pd *pd_new(t_class *c)
a random additional amount of memory and then resize allocation to the original
size
duplicate: -1 initial state
0 all is ok
duplicate: -1 enable check state
0 all is ok (or we are not allocating canvas memory)
1 found a duplicate
*/
/*
int duplicate = 0; //change to -1 to enable redundant_mem resizing
int random_extra = 0;
//int random_extra = 0;
//int random_offset = 1;
while (duplicate != 0) {
while (canvas_check_duplicate != 0) {
if (duplicate == -1) {
//fprintf(stderr,"alloc %d %d\n", duplicate, (int)c->c_size);
if (canvas_check_duplicate == -1) {
//fprintf(stderr,"alloc %d %d\n", canvas_check_duplicate, (int)c->c_size);
x = (t_pd *)t_getbytes(c->c_size);
} else if (duplicate == 1) {
random_extra = rand () + 1;
//fprintf(stderr,"alloc %d %d %d\n", duplicate, (int)c->c_size, (int)c->c_size + random_extra);
x = (t_pd *)t_getbytes(c->c_size + random_extra);
} else if (canvas_check_duplicate == 1) {
//random_extra = rand () + random_offset;
//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);
//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) {
t_redundant_mem *tmp = rm_start;
while (tmp->rm_next) {
if ((int)tmp->rm_canvas == (int)x) {
duplicate = 1;
//fprintf(stderr,"compare %lx %lx\n", (t_int)tmp->rm_canvas, (t_int)x);
if ((t_int)tmp->rm_canvas == (t_int)x) {
canvas_check_duplicate = 1;
break;
}
tmp = tmp->rm_next;
}
if (tmp && (int)tmp->rm_canvas == (int)x)
duplicate = 1;
if (tmp && (t_int)tmp->rm_canvas == (t_int)x)
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");
if (!random_extra)
t_freebytes(x, sizeof(c->c_size));
......@@ -73,13 +86,13 @@ t_pd *pd_new(t_class *c)
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);
}
break;
}*/
}
*/
x = (t_pd *)t_getbytes(c->c_size);
if (!x) x = (t_pd *)t_getbytes(c->c_size);
*x = c;
if (c->c_patchable)
{
......@@ -193,6 +206,7 @@ void pd_bind(t_pd *x, t_symbol *s)
{
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_bindelem *e = (t_bindelem *)getbytes(sizeof(t_bindelem));
e->e_next = b->b_list;
......@@ -201,6 +215,7 @@ void pd_bind(t_pd *x, t_symbol *s)
}
else
{
//fprintf(stderr,"pd_unbind option 1B %lx\n", (t_int)x);
t_bindlist *b = (t_bindlist *)pd_new(bindlist_class);
t_bindelem *e1 = (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)
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)
{
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)
{
/* bindlists always have at least two elements... if the number
goes down to one, get rid of the bindlist and bind the symbol
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_bindelem *e, *e2;
if ((e = b->b_list)->e_who == x)
{
b->b_list = e->e_next;
freebytes(e, sizeof(t_bindelem));
//fprintf(stderr,"success B1a\n");
}
else for (e = b->b_list; e2 = e->e_next; e = e2)
if (e2->e_who == x)
{
e->e_next = e2->e_next;
freebytes(e2, sizeof(t_bindelem));
//fprintf(stderr,"success B1b\n");
break;
}
if (!b->b_list->e_next)
......@@ -243,6 +268,7 @@ void pd_unbind(t_pd *x, t_symbol *s)
s->s_thing = b->b_list->e_who;
freebytes(b->b_list, sizeof(t_bindelem));
pd_free(&b->b_pd);
///fprintf(stderr,"success B3\n");
}
}
else pd_error(x, "%s: couldn't unbind", s->s_name);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment