[PD-dev] shared class data and functions

Charles Henry czhenry at gmail.com
Wed Nov 14 17:29:18 CET 2012


On Wed, Nov 14, 2012 at 1:17 AM, Jonathan Wilkes <jancsika at yahoo.com> wrote:

> I have three classes:
> foo, bar, bow
>
> Foo has a function:
>
> void foo_blah(t_foo *x, t_symbol *s, t_int argc, t_atom *argv)
> {
>     if(x->x_member == 1) do_something...
> }
>
> Bar and bow both have x->x_member, too, and I want all three
> to use the same function so I don't have to copy it two more times.
> Is there a way to do this:
>
> void foo_blah(t_pd *x, t_symbol *s, t_int argc, t_atom *argv)
> {
>     if we can cast x to t_foo, t_bar or t_bow then
>     check if x has x->member equal to 1, and if so then do_something...
>
> }
>
> which I can call by sending t_foo, t_bar or t_bow as the first
> arg to that function?
>

Pd classes are nested data structures.  To be consistent and use this trick
to your advantage, define your classes' data structures to have a parent
data structure.  Note that t_object is another name for t_text.  This is
all in m_pd.h.

t_pd<-t_gobj<-t_text

You define the first element of your class struct as a t_object or t_text.
Then, you can cast any pointer to an instance of your class as a t_text *.
Likewise, every t_text pointer can be cast as a g_obj *.  Same for t_gobj *
to t_pd *

Now, in order to have foo, bar, and bow have the same data structure
element "member", create this class:

struct _parent {
t_object my_object;  //Does this name matter?
t_int member;
} t_parent;

Then, your other classes work the same way: pointers to foo, bar and bow
can be cast as pointers to t_parent.  Then, you're absolutely sure that
((t_parent *)x)->member exists and can be read/written.

If you don't like that approach--just make sure the "t_int member" occurs
first after t_object in your class definitions to all three.  The compiler
turns accessing member into pointer arithmetic.  For example,
struct xyz {
int x;
int y;
int z;
} t_xyz;

t_xyz data;
t_xyz *instance=&data;

The compiler turns
instance->x into *((int *)instance)
instance->y into *((int *)instance + 1)
instance->z into *((int *)instance + 2)

So you see why member needs to be in the same location in each class.

Chuck
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-dev/attachments/20121114/236096fc/attachment.htm>


More information about the Pd-dev mailing list