From fac506d1fe49dd52c9105bd2baf8cec123273fe9 Mon Sep 17 00:00:00 2001 From: Guillem <guillembartrina@gmail.com> Date: Sat, 15 Aug 2020 14:11:31 +0200 Subject: [PATCH] ab private abstractions clone integration [abclone]. first approach --- pd/src/g_canvas.c | 12 ++++++--- pd/src/g_canvas.h | 1 + pd/src/g_clone.c | 67 +++++++++++++++++++++++++++++++++++++++++++---- pd/src/g_editor.c | 31 +++++++++++++++++----- 4 files changed, 97 insertions(+), 14 deletions(-) diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index f2c717241..b7b6d5ad1 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -1926,7 +1926,8 @@ static t_pd *do_create_ab(t_ab_definition *abdef, int argc, t_atom *argv) canvas_popabstraction((t_canvas *)(s__X.s_thing)); canvas_setargs(0, 0); - canvas_vis((t_canvas *)newest, !glist_amreloadingabstractions + canvas_vis((t_canvas *)newest, !glist_amreloadingabstractions + && !abdef->ad_numinstances && binbuf_getnatom(abdef->ad_source) == 3); return(newest); @@ -1935,8 +1936,10 @@ static t_pd *do_create_ab(t_ab_definition *abdef, int argc, t_atom *argv) /* get root canvas crossing ab boundaries, where ab definitions are stored */ static t_canvas *canvas_getrootfor_ab(t_canvas *x) { - if (!x->gl_owner || (canvas_isabstraction(x) && !x->gl_isab)) + if ((!x->gl_owner && !x->gl_isclone) || (canvas_isabstraction(x) && !x->gl_isab)) return (x); + else if (x->gl_isab) + return (x->gl_absource->ad_owner); else return (canvas_getrootfor_ab(x->gl_owner)); } @@ -1963,7 +1966,7 @@ static int canvas_register_ab(t_canvas *x, t_ab_definition *a) { t_canvas *r = canvas_getrootfor_ab(x), *c = x; - while(c != r) + while(c && c != r) { if(c->gl_isab) { @@ -1993,6 +1996,7 @@ static int canvas_register_ab(t_canvas *x, t_ab_definition *a) { a->ad_deprefs[i-1]++; } + return (1); } c = c->gl_owner; } @@ -2034,6 +2038,7 @@ static int canvas_deregister_ab(t_canvas *x, t_ab_definition *a) } } else bug("canvas_deregister_ab"); + return (1); } c = c->gl_owner; } @@ -2076,6 +2081,7 @@ static t_ab_definition *canvas_add_ab(t_canvas *x, t_symbol *name, t_binbuf *sou abdef->ad_name = name; abdef->ad_source = source; abdef->ad_numinstances = 0; + abdef->ad_owner = c; abdef->ad_numdep = 0; abdef->ad_dep = (t_ab_definition **)getbytes(0); abdef->ad_deprefs = (int *)getbytes(0); diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 4daffab62..dc4ce7f22 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -172,6 +172,7 @@ typedef struct _ab_definition t_binbuf *ad_source; /* binbuf where source is stored */ int ad_numinstances; /* the num of instances of this abstraction */ struct _ab_definition *ad_next; /* next ab definition */ + t_canvas *ad_owner; /* dependency graph stuff */ int ad_numdep; /* number of other ab definitions that it depends on */ diff --git a/pd/src/g_clone.c b/pd/src/g_clone.c index 2529161e6..c58c33f3d 100644 --- a/pd/src/g_clone.c +++ b/pd/src/g_clone.c @@ -63,6 +63,7 @@ typedef struct _clone int x_phase; int x_startvoice; /* number of first voice, 0 by default */ int x_suppressvoice; /* suppress voice number as $1 arg */ + t_canvas *x_owner; } t_clone; int clone_match(t_pd *z, t_symbol *name, t_symbol *dir) @@ -74,6 +75,36 @@ int clone_match(t_pd *z, t_symbol *name, t_symbol *dir) canvas_getdir(x->x_vec[0].c_gl) == dir); } +int clone_isab(t_pd *z) +{ + t_clone *x = (t_clone *)z; + if (!x->x_n) + return (0); + return (x->x_vec[0].c_gl->gl_isab); +} + +int clone_matchab(t_pd *z, t_ab_definition *source) +{ + t_clone *x = (t_clone *)z; + return (clone_isab(z) && x->x_vec[0].c_gl->gl_absource == source); +} + +int clone_getncopies(t_pd *z) +{ + t_clone *x = (t_clone *)z; + return (x->x_n); +} + +t_glist **clone_getglists(t_pd *z) +{ + t_clone *x = (t_clone *)z; + t_glist **glists = (t_glist *)getbytes(sizeof(t_glist *)*x->x_n); + int i; + for(i = 0; i < x->x_n; i++) + glists[i] = x->x_vec[i].c_gl; + return glists; +} + void obj_sendinlet(t_object *x, int n, t_symbol *s, int argc, t_atom *argv); static void clone_in_list(t_in *x, t_symbol *s, int argc, t_atom *argv) @@ -175,6 +206,8 @@ static void clone_free(t_clone *x) for (i = 0; i < x->x_n; i++) { canvas_closebang(x->x_vec[i].c_gl); + if(x->x_vec[i].c_gl->gl_isab) //only for abs? + x->x_vec[i].c_gl->gl_owner = x->x_owner; pd_free(&x->x_vec[i].c_gl->gl_pd); t_freebytes(x->x_outvec[i], x->x_nout * sizeof(*x->x_outvec[i])); @@ -228,7 +261,7 @@ void clone_setn(t_clone *x, t_floatarg f) { t_canvas *c; t_out *outvec; - SETFLOAT(x->x_argv, x->x_startvoice + i); + SETFLOAT((x->x_vec[0].c_gl->gl_isab ? x->x_argv+1 : x->x_argv), x->x_startvoice + i); if (!(c = clone_makeone(x->x_s, x->x_argc - x->x_suppressvoice, x->x_argv + x->x_suppressvoice))) { @@ -354,6 +387,7 @@ static void clone_dsp(t_clone *x, t_signal **sp) } } +static int clone_newab = 0; static void *clone_new(t_symbol *s, int argc, t_atom *argv) { t_clone *x = (t_clone *)pd_new(clone_class); @@ -393,10 +427,24 @@ static void *clone_new(t_symbol *s, int argc, t_atom *argv) else goto usage; /* store a copy of the argmuents with an extra space (argc+1) for supplying an instance number, which we'll bash as we go. */ - x->x_argc = argc - 1; - x->x_argv = getbytes(x->x_argc * sizeof(*x->x_argv)); - memcpy(x->x_argv, argv+1, x->x_argc * sizeof(*x->x_argv)); - SETFLOAT(x->x_argv, x->x_startvoice); + if(clone_newab) + { + x->x_argc = argc; + x->x_argv = getbytes(x->x_argc * sizeof(*x->x_argv)); + memcpy(x->x_argv, argv, x->x_argc * sizeof(*x->x_argv)); + SETSYMBOL(x->x_argv, x->x_s); + SETFLOAT(x->x_argv+1, x->x_startvoice); + x->x_s = gensym("ab"); + x->x_owner = canvas_getcurrent(); + clone_newab = 0; + } + else + { + x->x_argc = argc - 1; + x->x_argv = getbytes(x->x_argc * sizeof(*x->x_argv)); + memcpy(x->x_argv, argv+1, x->x_argc * sizeof(*x->x_argv)); + SETFLOAT(x->x_argv, x->x_startvoice); + } if (!(c = clone_makeone(x->x_s, x->x_argc - x->x_suppressvoice, x->x_argv + x->x_suppressvoice))) goto fail; @@ -444,10 +492,19 @@ fail: return (0); } +static void *abclone_new(t_symbol *s, int argc, t_atom *argv) +{ + clone_newab = 1; + return clone_new(s, argc, argv); +} + void clone_setup(void) { clone_class = class_new(gensym("clone"), (t_newmethod)clone_new, (t_method)clone_free, sizeof(t_clone), CLASS_NOINLET, A_GIMME, 0); + + class_addcreator((t_newmethod)abclone_new, gensym("abclone"), A_GIMME, 0); + class_addmethod(clone_class, (t_method)clone_click, gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(clone_class, (t_method)clone_loadbang, gensym("loadbang"), diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index c78cc7b14..ff61bbd60 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -1401,17 +1401,27 @@ void canvas_reload(t_symbol *name, t_symbol *dir, t_gobj *except) canvas_resume_dsp(dspwas); } +int clone_isab(t_pd *z); +int clone_matchab(t_pd *z, t_ab_definition *source); +int clone_getncopies(t_pd *z); +t_glist **clone_getglists(t_pd *z); + /* recursive ab reload method */ void canvas_reload_ab_rec(t_canvas *x, t_ab_definition *a, t_gobj *e) { t_gobj *g; int i, nobj = glist_getindex(x, 0); int hadwindow = x->gl_havewindow, found = 0; + int remakeit = 0; for (g = x->gl_list, i = 0; g && i < nobj; i++) { - if(g != e && pd_class(&g->g_pd) == canvas_class && canvas_isabstraction((t_canvas *)g) - && ((t_canvas *)g)->gl_isab && ((t_canvas *)g)->gl_absource == a) + remakeit = (g != e && pd_class(&g->g_pd) == canvas_class && canvas_isabstraction((t_canvas *)g) + && ((t_canvas *)g)->gl_isab && ((t_canvas *)g)->gl_absource == a); + + remakeit = remakeit || (pd_class(&g->g_pd) == clone_class && clone_matchab(&g->g_pd, a)); + + if(remakeit) { canvas_create_editor(x); @@ -1439,11 +1449,20 @@ void canvas_reload_ab_rec(t_canvas *x, t_ab_definition *a, t_gobj *e) for (g = x->gl_list, i = 0; g && i < nobj; i++) { - if(pd_class(&g->g_pd) == canvas_class - && (!canvas_isabstraction((t_canvas *)g) - || (((t_canvas *)g)->gl_isab - && (((t_canvas *)g)->gl_absource != a)))) + if(pd_class(&g->g_pd) == canvas_class && (!canvas_isabstraction((t_canvas *)g) + || (((t_canvas *)g)->gl_isab && (((t_canvas *)g)->gl_absource != a)))) canvas_reload_ab_rec((t_canvas *)g, a, e); + + if(pd_class(&g->g_pd) == clone_class + && clone_isab(&g->g_pd) && !clone_matchab(&g->g_pd, a)) + { + int numglists = clone_getncopies(&g->g_pd), j; + t_glist **glists = clone_getglists(&g->g_pd); + for(j = 0; j < numglists; j++) + canvas_reload_ab_rec((t_canvas *)glists[j], a, e); + freebytes(glists, sizeof(t_glist *)*numglists); + } + g = g->g_next; } if (!hadwindow && x->gl_havewindow) -- GitLab