Commit 4372acd9 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

Fixed crash when trying to do dynamic change of receives on iemgui objects...

Fixed crash when trying to do dynamic change of receives on iemgui objects (affects also all objects that allow for dynamic changing of the bindlist)
parent 5f19c3e7
......@@ -146,48 +146,95 @@ typedef struct _bindlist
t_bindelem *b_list;
} t_bindlist;
static int change_bindlist_via_graph = 0;
static void bindlist_cleanup(t_bindlist *x)
{
//fprintf(stderr,"bindlist_cleanup\n");
t_bindelem *e, *e2;
if (x->b_list->e_who == NULL)
{
e = x->b_list;
x->b_list = e->e_next;
freebytes(e, sizeof(t_bindelem));
//fprintf(stderr,"success B1a\n");
}
for (e = x->b_list; e2 = e->e_next; e = e2)
if (e2->e_who == NULL)
{
e->e_next = e2->e_next;
freebytes(e2, sizeof(t_bindelem));
//fprintf(stderr,"success B1b\n");
break;
}
if (!x->b_list->e_next)
{
freebytes(x->b_list, sizeof(t_bindelem));
pd_free(&x->b_pd);
//fprintf(stderr,"success B2\n");
}
}
static void bindlist_bang(t_bindlist *x)
{
change_bindlist_via_graph = 1;
t_bindelem *e;
for (e = x->b_list; e; e = e->e_next)
pd_bang(e->e_who);
bindlist_cleanup(x);
change_bindlist_via_graph = 0;
}
static void bindlist_float(t_bindlist *x, t_float f)
{
change_bindlist_via_graph = 1;
t_bindelem *e;
for (e = x->b_list; e; e = e->e_next)
pd_float(e->e_who, f);
bindlist_cleanup(x);
change_bindlist_via_graph = 0;
}
static void bindlist_symbol(t_bindlist *x, t_symbol *s)
{
change_bindlist_via_graph = 1;
t_bindelem *e;
for (e = x->b_list; e; e = e->e_next)
pd_symbol(e->e_who, s);
bindlist_cleanup(x);
change_bindlist_via_graph = 0;
}
static void bindlist_pointer(t_bindlist *x, t_gpointer *gp)
{
change_bindlist_via_graph = 1;
t_bindelem *e;
for (e = x->b_list; e; e = e->e_next)
pd_pointer(e->e_who, gp);
bindlist_cleanup(x);
change_bindlist_via_graph = 0;
}
static void bindlist_list(t_bindlist *x, t_symbol *s,
int argc, t_atom *argv)
{
change_bindlist_via_graph = 1;
t_bindelem *e;
for (e = x->b_list; e; e = e->e_next)
pd_list(e->e_who, s, argc, argv);
bindlist_cleanup(x);
change_bindlist_via_graph = 0;
}
static void bindlist_anything(t_bindlist *x, t_symbol *s,
int argc, t_atom *argv)
{
change_bindlist_via_graph = 1;
t_bindelem *e;
for (e = x->b_list; e; e = e->e_next)
pd_typedmess(e->e_who, s, argc, argv);
bindlist_cleanup(x);
change_bindlist_via_graph = 0;
}
void m_pd_setup(void)
......@@ -204,6 +251,7 @@ void m_pd_setup(void)
void pd_bind(t_pd *x, t_symbol *s)
{
//fprintf(stderr,"pd_bind %s\n", s->s_name);
if (s->s_thing)
{
if (*s->s_thing == bindlist_class)
......@@ -217,7 +265,7 @@ void pd_bind(t_pd *x, t_symbol *s)
}
else
{
//fprintf(stderr,"pd_unbind option 1B %lx\n", (t_int)x);
//fprintf(stderr,"pd_bind 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));
......@@ -237,6 +285,7 @@ void pd_bind(t_pd *x, t_symbol *s)
void pd_unbind(t_pd *x, t_symbol *s)
{
//fprintf(stderr,"pd_unbind %s\n", s->s_name);
if (s->s_thing == x) {
//fprintf(stderr,"pd_unbind option A %lx\n", (t_int)x);
s->s_thing = 0;
......@@ -247,30 +296,54 @@ void pd_unbind(t_pd *x, t_symbol *s)
goes down to one, get rid of the bindlist and bind the symbol
straight to the remaining element. */
/* in pd-l2ork, we however also check whether changes to the bindlist
occur via graph (through code execution, e.g. dynamic change of receives)
and if so, we do not deallocate memory until the entire bindlist_<datatype>
function is complete with its execution, after which we call
bindlist_cleanup(). we control the execution via static int variable
change_bindlist_via_graph */
//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));
if (change_bindlist_via_graph)
e->e_who = NULL;
else {
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));
if (change_bindlist_via_graph)
e2->e_who = NULL;
else {
e->e_next = e2->e_next;
freebytes(e2, sizeof(t_bindelem));
}
//fprintf(stderr,"success B1b\n");
break;
}
if (!b->b_list->e_next)
int count_valid = 0;
for (e = b->b_list; e; e = e->e_next)
{
if (e->e_who != NULL)
count_valid++;
}
if (count_valid == 1) {
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");
if (!change_bindlist_via_graph) {
freebytes(b->b_list, sizeof(t_bindelem));
pd_free(&b->b_pd);
}
//fprintf(stderr,"success B2\n");
}
}
else pd_error(x, "%s: couldn't unbind", s->s_name);
......
Supports Markdown
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