[PD] variable receive objects?
Jonathan Wilkes
jancsika at yahoo.com
Sun Jun 24 02:50:39 CEST 2012
----- Original Message -----
> From: Ivica Ico Bukvic <ico at vt.edu>
> To: Miller Puckette <msp at ucsd.edu>
> Cc: pd-list at iem.at
> Sent: Saturday, June 23, 2012 6:36 PM
> Subject: Re: [PD] variable receive objects?
>
>
>
> Miller Puckette <msp at ucsd.edu> wrote:
>
>> Hmm.. I'm still looking for a solution that doesn't require adding
>> extra
>> stuff to bindlist_bang() etc.
>
> In the meantime for those eager to work with dynamic receives, the fix below is
> now in the pd-l2otk trunk on the github.
>
> Coming up next in the land o' pd-l2ork, universal presets ;-)
Sounds neat!
-Jonathan
>
> Best wishes,
>
> Ico
>
>>
>> cheers
>> M
>>
>> On Wed, Jun 20, 2012 at 06:09:22PM -0400, Ivica Ico Bukvic wrote:
>>> On 06/20/2012 05:38 PM, Miller Puckette wrote:
>>> >[snip]
>>> >I'm just saying that the automatic varable t_bindelem *e should
> be
>> declared
>>> >at the beginning of the block - no worries about
>> change_bindlist_via_graph.
>>> Ah, now I get it :-). Fixed.
>>> >I think bindlist_bang() etc are more critical than pd_unbind as
> they
>> naturally
>>> >get called many times while a patch is running whereas pd_unbind is
>> typically
>>> >called only when objects are deleted. So moving checks from
>> pd_unbind()
>>> >to bindlist_bang() etc decreases pd's run-time efficiency.
>>> >
>>> >cheers
>>> >M
>>> OK, how about the attached patch where now I use the
>>> change_bindlist_via_graph variable and increment it by one every
>>> time something needs to be unbound so when you return back to the
>>> bindlist_bang() or whatever call was issued, only if
>>> change_bindlist_via_graph > 1 should it call unbind. Now it avoids
>>> entering the bindlist_cleanup unless it absolutely has to...
>>>
>>> Attached is also a patch that illustrates your case presented
>>> earlier which crashed pd-l2ork prior to applying this latest version
>>> of the patch.
>>>
>>> Cheers!
>>>
>>> --
>>> Ivica Ico Bukvic, D.M.A
>>> Composition, Music Technology
>>> Director, DISIS Interactive Sound& Intermedia Studio
>>> Director, L2Ork Linux Laptop Orchestra
>>> Head, ICAT IMPACT Studio
>>> Virginia Tech
>>> Department of Music
>>> Blacksburg, VA 24061-0240
>>> (540) 231-6139
>>> (540) 231-5034 (fax)
>>> disis.music.vt.edu
>>> l2ork.music.vt.edu
>>> ico.bukvic.net
>>>
>>
>>> --- m_pd.c.old 2012-06-20 17:51:43.845040884 -0400
>>> +++ m_pd.c 2012-06-20 18:06:02.047009570 -0400
>>> @@ -146,48 +146,101 @@
>>> 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)
>>> {
>>> t_bindelem *e;
>>> + change_bindlist_via_graph = 1;
>>> for (e = x->b_list; e; e = e->e_next)
>>> - pd_bang(e->e_who);
>>> + if (e->e_who != NULL) pd_bang(e->e_who);
>>> + if (change_bindlist_via_graph > 1)
>>> + bindlist_cleanup(x);
>>> + change_bindlist_via_graph = 0;
>>> }
>>>
>>> static void bindlist_float(t_bindlist *x, t_float f)
>>> {
>>> t_bindelem *e;
>>> + change_bindlist_via_graph = 1;
>>> for (e = x->b_list; e; e = e->e_next)
>>> - pd_float(e->e_who, f);
>>> + if (e->e_who != NULL) pd_float(e->e_who, f);
>>> + if (change_bindlist_via_graph > 1)
>>> + bindlist_cleanup(x);
>>> + change_bindlist_via_graph = 0;
>>> }
>>>
>>> static void bindlist_symbol(t_bindlist *x, t_symbol *s)
>>> {
>>> t_bindelem *e;
>>> + change_bindlist_via_graph = 1;
>>> for (e = x->b_list; e; e = e->e_next)
>>> - pd_symbol(e->e_who, s);
>>> + if (e->e_who != NULL) pd_symbol(e->e_who, s);
>>> + if (change_bindlist_via_graph > 1)
>>> + bindlist_cleanup(x);
>>> + change_bindlist_via_graph = 0;
>>> }
>>>
>>> static void bindlist_pointer(t_bindlist *x, t_gpointer *gp)
>>> {
>>> t_bindelem *e;
>>> + change_bindlist_via_graph = 1;
>>> for (e = x->b_list; e; e = e->e_next)
>>> - pd_pointer(e->e_who, gp);
>>> + if (e->e_who != NULL) pd_pointer(e->e_who, gp);
>>> + if (change_bindlist_via_graph > 1)
>>> + bindlist_cleanup(x);
>>> + change_bindlist_via_graph = 0;
>>> }
>>>
>>> static void bindlist_list(t_bindlist *x, t_symbol *s,
>>> int argc, t_atom *argv)
>>> {
>>> t_bindelem *e;
>>> + change_bindlist_via_graph = 1;
>>> for (e = x->b_list; e; e = e->e_next)
>>> - pd_list(e->e_who, s, argc, argv);
>>> + if (e->e_who != NULL) pd_list(e->e_who, s, argc, argv);
>>> + if (change_bindlist_via_graph > 1)
>>> + bindlist_cleanup(x);
>>> + change_bindlist_via_graph = 0;
>>> }
>>>
>>> static void bindlist_anything(t_bindlist *x, t_symbol *s,
>>> int argc, t_atom *argv)
>>> {
>>> t_bindelem *e;
>>> + change_bindlist_via_graph = 1;
>>> for (e = x->b_list; e; e = e->e_next)
>>> - pd_typedmess(e->e_who, s, argc, argv);
>>> + if (e->e_who != NULL) pd_typedmess(e->e_who, s, argc,
> argv);
>>> + if (change_bindlist_via_graph > 1)
>>> + bindlist_cleanup(x);
>>> + change_bindlist_via_graph = 0;
>>> }
>>>
>>> void m_pd_setup(void)
>>> @@ -204,6 +257,7 @@
>>>
>>> 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 +271,7 @@
>>> }
>>> 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 +291,7 @@
>>>
>>> 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 +302,56 @@
>>> 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) {
>>> + 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) {
>>> + 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);
>
>
> Ivica Ico Bukvic, D.M.A
> Composition, Music Technology
> Director, DISIS Interactive Sound & Intermedia Studio
> Director, L2Ork Linux Laptop Orchestra
> Head, ICAT IMPACT Studio
> Virginia Tech
> Department of Music
> Blacksburg, VA 24061-0240
> (540) 231-6139
> (540) 231-5034 (fax)
> disis.music.vt.edu
> l2ork.music.vt.edu
> ico.bukvic.net
>
> _______________________________________________
> Pd-list at iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
More information about the Pd-list
mailing list