We have a winner! :D
static void entry_save(t_gobj *z, t_binbuf *b) { t_entry *x = (t_entry *)z; t_symbol *classname = atom_getsymbol(binbuf_getvec(x-
x_obj.te_binbuf));
binbuf_addv(b, "ssiisiiss", gensym("#X"),gensym("obj"), x->x_obj.te_xpix, x->x_obj.te_ypix, classname, x->x_width, x->x_height, x->x_bgcolour, x->x_fgcolour); binbuf_addv(b, ";"); }
.hc
On Oct 29, 2007, at 12:51 PM, Miller Puckette wrote:
So you can probably just use x->x_obj.ob_binbuf -- that's the text the object is "created" with.
On Mon, Oct 29, 2007 at 12:36:16PM -0400, Hans-Christoph Steiner wrote:
I want to get the full classname that an object was instantiated with. Basically, lots of GUI objects use gensym("nbx") in the binbuf_addv() in the save function. This means that if they were instantiated with a namespace prefix, i.e. [iemgui/nbx], the "save" function will save it as [nbx].
The "new" function gets the correct classname in the t_symbol it's passed. So the question is how to get this from the object's struct. I understand the concepts, just not how the the data structures are organized.
.hc
On Oct 29, 2007, at 12:28 PM, Miller Puckette wrote:
Hmm, well, the way Pd gets it is looking in the binbuf. But perhaps you need to look in the binbuf for the object you're looking at, not that of the containing canvas, no? Or, on the other hand. perhaps you're trying to get the name of the abstraction the object is part of?
cheers M
On Sun, Oct 28, 2007 at 10:57:52PM -0400, Hans-Christoph Steiner wrote:
It sounds like this isn't the way to do it then. But somewhere the whole classname with the namespace prefix must be stored for every single object instantiated, since it will get written out to the file. How do I access that?
.hc
On Oct 28, 2007, at 10:50 PM, Miller Puckette wrote:
I think the binbuf is always present, but in the case of a top- level canvas, it might be empty; binbuf_getnatom() tells you how many atoms there are.
cheers Miller
On Sun, Oct 28, 2007 at 10:14:48PM -0400, Hans-Christoph Steiner wrote:
On Oct 28, 2007, at 8:47 PM, Martin Peach wrote:
> Hans-Christoph Steiner wrote: >> >> I tried this in entry_new() and entry_save(), and in both, >> "binbuf" ends being nothing useful (i.e. segfault): >> >> t_glist *glist = (t_glist *) canvas_getcurrent(); >> t_canvas *canvas = (t_canvas*) glist_getcanvas(glist); >> t_binbuf *binbuf = canvas->gl_obj.te_binbuf; >> t_atom *ap = binbuf_getvec(binbuf); >> t_symbol *classname = atom_getsymbol(ap); >> >> What's going on here? Am I doing something wrong? >> > I don't know what you're trying to do but it's normal to > check for > NULL pointers after each of the above statements. That should > give > you a clue. > I suspect that the binbuf doesn't exist if you didn't > allocate it > yourself.
I am just following IOhannes' code, which he says works (I haven't tested it...)
http://pure-data.cvs.sourceforge.net/pure-data/externals/iem/ iemguts/ src/saveargs.c?view=markup
Somehow, he magically gets a binbuf with contents in it! ;)
.hc
--
There is no way to peace, peace is the way. -A.J. Muste
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
--
You can't steal a gift. Bird gave the world his music, and if you can hear it, you can have it. - Dizzy Gillespie
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
All information should be free. - the hacker ethic
------------------------------------------------------------------------ ----
"[W]e have invented the technology to eliminate scarcity, but we are deliberately throwing it away to benefit those who profit from scarcity." -John Gilmore
I think this should be part of the standard save mechanism, so I just committed the change to a bunch of externals. I didn't touch externals/iem since I know you guys like to handle stuff yourself. It actually makes sense like this (from entry.c):
static void entry_save(t_gobj *z, t_binbuf *b) { t_entry *x = (t_entry *)z;
binbuf_addv(b, "ssiisiiss", gensym("#X"),gensym("obj"), x->x_obj.te_xpix, x->x_obj.te_ypix, atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)), x->x_width, x->x_height, x->x_bgcolour, x-
x_fgcolour);
binbuf_addv(b, ";"); }
Perhaps atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)) could be defined in m_pd.h as something like "class_getclassname"
.hc
On Oct 29, 2007, at 2:12 PM, IOhannes m zmoelnig wrote:
Hans-Christoph Steiner wrote:
We have a winner! :D
darn, i just finished an example that works as well....
fmasdr. IOhannes
/******************************************************
- myname - implementation file
- copyleft (c) IOhannes m zm-bölnig-A
- 2007:forum::f-bür::umläute:2007-A
- institute of electronic music and acoustics (iem)
- license: GNU General Public License v.2
******************************************************/
/*
- this object is an example on how to retrieve the object's own name
- usage:
- bang to print the object's name to the console
*/
#include "m_pd.h"
/* ------------------------- myname ---------------------------- */
static t_class *myname_class;
typedef struct _myname { t_object x_obj; } t_myname;
static void myname_bang(t_myname *x) { t_text t=(t_text)x->x_obj; t_binbuf*b=t.te_binbuf; if(b!=0) { t_atom*ap=binbuf_getvec(b); post("my name is '%s'", atom_getsymbol(ap)->s_name); } else { post("hmm, i don't know my name"); } }
static void *myname_new(void) { t_myname *x = (t_myname *)pd_new(myname_class);
t_text t=(t_text)x->x_obj; t_binbuf*b=t.te_binbuf; if(b!=0) { t_atom*ap=binbuf_getvec(b); post("my name is '%s'", atom_getsymbol(ap)->s_name); } else { post("i don't know my name yet..."); }
return (x); }
void myname_setup(void) { myname_class = class_new(gensym("myname"), (t_newmethod)myname_new, 0, sizeof(t_myname), 0, 0); class_addbang(myname_class, myname_bang); }
------------------------------------------------------------------------ ----
Terrorism is not an enemy. It cannot be defeated. It's a tactic. It's about as sensible to say we declare war on night attacks and expect we're going to win that war. We're not going to win the war on terrorism. - retired U.S. Army general, William Odom
Hans-Christoph Steiner wrote:
Perhaps atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)) could be defined in m_pd.h as something like "class_getclassname"
this is along the lines of what i tried to suggest in my initial reply to this thread (in the sf-ticket)
in addition to that i would like to have something like:
static void myobj_nicesavefn(t_myobj*x, t_symbol**name, int*argc, t_atom**argv) { }
and the developer can decide to set (name) and/or (argc,argv) or leave them to their initial state. all the binbuf-bibabo with the typestrings should really be hidden behind this.
mfgas.dr IOhannes
On Oct 29, 2007, at 3:16 PM, IOhannes m zmoelnig wrote:
Hans-Christoph Steiner wrote:
Perhaps atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)) could be defined in m_pd.h as something like "class_getclassname"
this is along the lines of what i tried to suggest in my initial reply to this thread (in the sf-ticket)
in addition to that i would like to have something like:
static void myobj_nicesavefn(t_myobj*x, t_symbol**name, int*argc, t_atom**argv) { }
and the developer can decide to set (name) and/or (argc,argv) or leave them to their initial state. all the binbuf-bibabo with the typestrings should really be hidden behind this.
mfgas.dr IOhannes
If you had class_getclassname(), then it would be used in the existing savefn API, in the binbuf_addv(). I don't know enough to say how useful your proposal would be.
I ran into a problem applying this to the iemgui (footils/knob and moonlib/mknob both use the iemgui API). Basically, in iemgui, the use "t_iemgui x_gui" instead of "t_object x_obj". x_gui then has "t_object x_obj". That means adding an extra layer:
atom_getsymbol(binbuf_getvec(x->x_gui.x_obj.te_binbuf)),
.hc
------------------------------------------------------------------------ ----
¡El pueblo unido jamás será vencido!
Hans-Christoph Steiner wrote:
If you had class_getclassname(), then it would be used in the existing savefn API, in the binbuf_addv(). I don't know enough to say how useful your proposal would be.
obviously it would work with the current savefn API. it already does so, even without the class_getclassname().
i am rather thinking of an API that does not require you to think with a knot in your head. (for me the binbuf-shit is the weird stuff, not how to get the classname)
and even if (or somebody else) would think of a very nice api for savefn, i would prefer to have to old one lying still around, as you can do weird (and great) things with it, which you couldn't do with a simple wrapper api.
fmasdr IOhannes
On Oct 29, 2007, at 4:23 PM, IOhannes m zmoelnig wrote:
Hans-Christoph Steiner wrote:
If you had class_getclassname(), then it would be used in the existing savefn API, in the binbuf_addv(). I don't know enough to say how useful your proposal would be.
obviously it would work with the current savefn API. it already does so, even without the class_getclassname().
i am rather thinking of an API that does not require you to think with a knot in your head. (for me the binbuf-shit is the weird stuff, not how to get the classname)
and even if (or somebody else) would think of a very nice api for savefn, i would prefer to have to old one lying still around, as you can do weird (and great) things with it, which you couldn't do with a simple wrapper api.
I am all for adding an easier API, sounds like a worthwhile project.
.hc
------------------------------------------------------------------------ ----
Access to computers should be unlimited and total. - the hacker ethic
On Mon, 29 Oct 2007, IOhannes m zmoelnig wrote:
i am rather thinking of an API that does not require you to think with a knot in your head. (for me the binbuf-shit is the weird stuff, not how to get the classname)
t_binbuf is only a type of resizable atom array. If you've used STL in the past, you may think of it as vaguely like vector<t_atom*>, plus a bunch of methods related to parsing and unparsing.
and even if (or somebody else) would think of a very nice api for savefn, i would prefer to have to old one lying still around, as you can do weird (and great) things with it, which you couldn't do with a simple wrapper api.
It's required for backwards compatibility anyway, and yes, I know what you mean by weird and great things.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
On Mon, 29 Oct 2007, Hans-Christoph Steiner wrote:
I ran into a problem applying this to the iemgui (footils/knob and moonlib/mknob both use the iemgui API). Basically, in iemgui, the use "t_iemgui x_gui" instead of "t_object x_obj". x_gui then has "t_object x_obj". That means adding an extra layer: atom_getsymbol(binbuf_getvec(x->x_gui.x_obj.te_binbuf)),
I always use pointer casts so that I don't have to think about the name of the magic prefixes used to access superclass fields. OTOH this makes it easier to make type mistakes, in theory, but I haven't seen that happening much in practice for this kind of cast.
Using a cast, you can take any subtype of t_object, and no matter how it decides to call its t_object part, and no matter how many levels of nestedness it takes, you always get to the t_object part by casting like (t_object *).
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
On Mon, 29 Oct 2007, Hans-Christoph Steiner wrote:
static void entry_save(t_gobj *z, t_binbuf *b) { t_entry *x = (t_entry *)z; binbuf_addv(b, "ssiisiiss", gensym("#X"),gensym("obj"), x->x_obj.te_xpix, x->x_obj.te_ypix, atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)), x->x_width, x->x_height, x->x_bgcolour, x->x_fgcolour); binbuf_addv(b, ";"); }
calls to binbuf_addv can be merged in the same way as fprintf calls can: keep the same first arg, concatenate the two second args, and then append the rest of the latter rest of arguments to the first. So, you never need a separate call for ";".
they can also be split in any way. For example you can do "ssiis" first and then do "iiss;", as long as the rest of arguments are also split in the same way. You could make a function like:
void obj_saveheader(t_binbuf *b, t_object *x) { binbuf_addv(b,"ssiis", gensym("#X"), gensym("obj"), x->te_xpix, x->te_ypix, atom_getsymbol(binbuf_getvec(x->te_binbuf))); }
and then use it at the beginning of every save function that fits with that pattern (which is every one of them, so far).
Perhaps atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)) could be defined in m_pd.h as something like "class_getclassname"
its naming does not work. as it doesn't give you the class _name_, don't make it end in "_getclassname", and as it doesn't start from (nor use) a t_class *, don't make it start in "class_".
i think that it should be a obj_...() name, but then, if you do that, make sure to handle the special case in which one puts a float and only a float in an object box, because that would crash the above code. you never hit this case with savefn, but you are making a generic-sounding obj_...() call so it should accept any obj_... and imho it should also accept top-level canvases as arguments... as well as incomplete objects (objects that don't have a binbuf yet, while they are created).
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
On Oct 30, 2007, at 11:31 AM, Mathieu Bouchard wrote:
On Mon, 29 Oct 2007, Hans-Christoph Steiner wrote:
static void entry_save(t_gobj *z, t_binbuf *b) { t_entry *x = (t_entry *)z; binbuf_addv(b, "ssiisiiss", gensym("#X"),gensym("obj"), x->x_obj.te_xpix, x->x_obj.te_ypix, atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)), x->x_width, x->x_height, x->x_bgcolour, x-
x_fgcolour);
binbuf_addv(b, ";"); }
calls to binbuf_addv can be merged in the same way as fprintf calls can: keep the same first arg, concatenate the two second args, and then append the rest of the latter rest of arguments to the first. So, you never need a separate call for ";".
they can also be split in any way. For example you can do "ssiis" first and then do "iiss;", as long as the rest of arguments are also split in the same way. You could make a function like:
void obj_saveheader(t_binbuf *b, t_object *x) { binbuf_addv(b,"ssiis", gensym("#X"), gensym("obj"), x->te_xpix, x->te_ypix, atom_getsymbol(binbuf_getvec(x-
te_binbuf)));
}
This looks good. How about storing the symbols somewhere to save some symbol table lookups?
t_symbol *poundx_symbol = gemsym("#X"); t_symbol *obj_symbol = gemsym("obj");
void obj_saveheader(t_binbuf *b, t_object *x) { binbuf_addv(b,"ssiis", poundx_symbol, obj_symbol, x->te_xpix, x->te_ypix, atom_getsymbol(binbuf_getvec(x-
te_binbuf)));
}
.hc
and then use it at the beginning of every save function that fits with that pattern (which is every one of them, so far).
Perhaps atom_getsymbol(binbuf_getvec(x->x_obj.te_binbuf)) could be defined in m_pd.h as something like "class_getclassname"
its naming does not work. as it doesn't give you the class _name_, don't make it end in "_getclassname", and as it doesn't start from (nor use) a t_class *, don't make it start in "class_".
i think that it should be a obj_...() name, but then, if you do that, make sure to handle the special case in which one puts a float and only a float in an object box, because that would crash the above code. you never hit this case with savefn, but you are making a generic-sounding obj_...() call so it should accept any obj_... and imho it should also accept top-level canvases as arguments... as well as incomplete objects (objects that don't have a binbuf yet, while they are created).
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
------------------------------------------------------------------------ ----
'You people have such restrictive dress for women,’ she said, hobbling away in three inch heels and panty hose to finish out another pink-collar temp pool day. - “Hijab Scene #2", by Mohja Kahf
Hans-Christoph Steiner wrote:
This looks good. How about storing the symbols somewhere to save some symbol table lookups?
??? why not?
(one could also implement the storage function in MMX (or SSE2) to save another 3 cycles :-))
not that the idea is bad or something, but i don't think that this is something one should worry about now.
fasdr IOhannes
On Wed, 31 Oct 2007, Hans-Christoph Steiner wrote:
This looks good. How about storing the symbols somewhere to save some symbol table lookups? t_symbol *poundx_symbol = gemsym("#X"); t_symbol *obj_symbol = gemsym("obj");
There is already &s__X for the first one, but really, I don't think that Pd uses savefn enough to warrant bothering with that kind of non-issue. In Dd, however, savefn is used MUCH more often than in Pd, so, I could change it if there wasn't any 1000-times-more-important optimisation I could work on.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
On Oct 31, 2007, at 10:21 AM, Mathieu Bouchard wrote:
On Wed, 31 Oct 2007, Hans-Christoph Steiner wrote:
This looks good. How about storing the symbols somewhere to save some symbol table lookups? t_symbol *poundx_symbol = gemsym("#X"); t_symbol *obj_symbol = gemsym("obj");
There is already &s__X for the first one, but really, I don't think that Pd uses savefn enough to warrant bothering with that kind of non-issue. In Dd, however, savefn is used MUCH more often than in Pd, so, I could change it if there wasn't any 1000-times-more- important optimisation I could work on.
Yes, this is small, but it can't hurt, it's quite simple, and I think its often makes for more readable code. This kind of thing seems pretty common in Max/MSP externals.
.hc
------------------------------------------------------------------------ ----
All mankind is of one author, and is one volume; when one man dies, one chapter is not torn out of the book, but translated into a better language; and every chapter must be so translated.... -John Donne
On Wed, 31 Oct 2007, Hans-Christoph Steiner wrote:
Yes, this is small, but it can't hurt, it's quite simple, and I think its often makes for more readable code.
I don't see any difference in readability... well, the only small one is that one has to lookup obj_symbol to make sure that it's a t_symbol *... but that's more in favour of not doing the change.
This kind of thing seems pretty common in Max/MSP externals.
I'm not much in favour of imitation for its own sake...
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada