/****************************************************** * * findbrokenobject - implementation file * * copyleft (c) IOhannes m zmölnig * * 2007:forum::für::umläute:2007 * * institute of electronic music and acoustics (iem) * ****************************************************** * * license: GNU General Public License v.2 (or later) * ******************************************************/ /* * find broken objects (objects that could not be created) * these objects are of class 'text_class' objsrc = pd_checkobject(&src->g_pd); if (objsrc && pd_class(&src->g_pd) == text_class && objsrc->te_type == T_OBJECT) { // 'src' is a broken object } */ #include "m_pd.h" #include "g_canvas.h" #include "m_imp.h" #include int glist_getindex(t_glist *x, t_gobj *y); /* ------------------------- findbrokenobject ---------------------------- */ static t_class *findbrokenobject_class; typedef struct _findbrokenobject { t_object x_obj; t_outlet *x_out; t_canvas *x_parent; // the canvas we are acting on } t_findbrokenobject; extern t_class *text_class; extern t_class *canvas_class; static void print_obj(const char*prefix, t_object *obj) { int ntxt; char *txt; t_binbuf*bb=obj->te_binbuf; binbuf_gettext(bb, &txt, &ntxt); pd_error(obj, "%s%p\t%s", prefix, obj, txt); } static void findbrokenobject_doit(t_canvas*cnv) { t_gobj*src; for (src = cnv->gl_list; src; src = src->g_next) { /* traverse all objects in canvas */ t_object*obj=pd_checkobject(&src->g_pd); if (obj && (pd_class(&src->g_pd) == text_class && obj->te_type == T_OBJECT)) { // found broken object print_obj("broken:\t", obj); } } } static void fbo_iterate(t_canvas*x) { // iterate over all top-level canvases if(!(x && x->gl_name && x->gl_name->s_name)) return; t_gobj*g=0; for(g=x->gl_list;g;g=g->g_next) { // iterate over all objects on the canvas t_object*ob=pd_checkobject(&g->g_pd); t_class*cls=0; if(!(ob && ob->te_type == T_OBJECT)) continue; cls=pd_class(&g->g_pd); //const char*classname=cls->c_name->s_name; if (cls == canvas_class) { // this is just another abstraction, recurse into it fbo_iterate(ob); } else if (cls == text_class) { /* broken object */ int ntxt; char *txt; t_binbuf*bb=ob->te_binbuf; binbuf_gettext(bb, &txt, &ntxt); pd_error(ob, "[%s] broken object!", txt); freebytes(txt, ntxt); } } } static void findbrokenobject_bang(t_findbrokenobject *x) { // find all broken objects in the current patch if(x->x_parent) { fbo_iterate(x->x_parent); } else { t_canvas *x; for (x = pd_getcanvaslist(); x; x = x->gl_next) { const char*name=x->gl_name->s_name; /* only allow names ending with '.pd' * (reject template canvases) */ const int len=strlen(name); if(len>3 && name[len-3]=='.' && name[len-2]=='p' && name[len-1]=='d') { fbo_iterate(x); } //else post("canvas: %s", name); } } } static void findbrokenobject_free(t_findbrokenobject *x) { outlet_free(x->x_out); } static void *findbrokenobject_new(t_symbol*s, int argc, t_atom*argv) { t_findbrokenobject *x = (t_findbrokenobject *)pd_new(findbrokenobject_class); x->x_parent=0; if(argc==1 && argv->a_type == A_FLOAT) { int depth=atom_getint(argv); t_glist *glist=(t_glist *)canvas_getcurrent(); if(depth>=0) { t_canvas *canvas=(t_canvas*)glist_getcanvas(glist); while(depth && canvas) { canvas=canvas->gl_owner; depth--; } if(canvas) x->x_parent = canvas; } } post("findbrokenobj @ %p", x->x_parent); x->x_out = outlet_new(&x->x_obj, &s_float); return (x); } static char fbo_file[]; static void fbo_persist(void) { static t_pd*fbo_canvas=0; if(fbo_canvas) return; t_binbuf *b = binbuf_new(); glob_setfilename(0, gensym("_deken_workspace"), gensym(".")); binbuf_text(b, fbo_file, strlen(fbo_file)); binbuf_eval(b, &pd_canvasmaker, 0, 0); fbo_canvas = s__X.s_thing; vmess(s__X.s_thing, gensym("pop"), "i", 0); glob_setfilename(0, &s_, &s_); binbuf_free(b); } void findbrokenobject_setup(void) { findbrokenobject_class = class_new(gensym("findbrokenobject"), (t_newmethod)findbrokenobject_new, (t_method)findbrokenobject_free, sizeof(t_findbrokenobject), 0, A_GIMME, 0); class_addbang (findbrokenobject_class, (t_method)findbrokenobject_bang); fbo_persist(); } static char fbo_file[] = "\ canvas 0 0 300 200;\n\ #X obj 20 20 receive __deken_findbroken_objects;\n\ #X obj 20 60 findbrokenobject;\n\ #X obj 20 80 list prepend plugin-dispatch deken;\n\ #X msg 20 40 unique;\n\ #X obj 20 100 list trim;\n\ #X obj 20 120 s pd;\n\ #X connect 0 0 3 0;\n\ #X connect 1 0 2 0;\n\ #X connect 2 0 4 0;\n\ #X connect 3 0 1 0;\n\ #X connect 4 0 5 0;\n\ ";