<br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 14, 2012 at 1:17 AM, Jonathan Wilkes <span dir="ltr"><<a href="mailto:jancsika@yahoo.com" target="_blank">jancsika@yahoo.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I have three classes:<br>
foo, bar, bow<br>
<br>
Foo has a function:<br>
<br>
void foo_blah(t_foo *x, t_symbol *s, t_int argc, t_atom *argv)<br>
{<br>
if(x->x_member == 1) do_something...<br>
}<br>
<br>
Bar and bow both have x->x_member, too, and I want all three<br>
to use the same function so I don't have to copy it two more times.<br>
Is there a way to do this:<br>
<br>
void foo_blah(t_pd *x, t_symbol *s, t_int argc, t_atom *argv)<br>
{<br>
if we can cast x to t_foo, t_bar or t_bow then<br>
check if x has x->member equal to 1, and if so then do_something...<br>
<br>
}<br>
<br>
which I can call by sending t_foo, t_bar or t_bow as the first<br>
arg to that function?<br></blockquote><div><br>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.<br>
<br>t_pd<-t_gobj<-t_text<br><br>You define the first element of your class struct as a t_object or t_text.<br>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 *<br>
<br>Now, in order to have foo, bar, and bow have the same data structure element "member", create this class:<br><br>struct _parent {<br>t_object my_object; //Does this name matter?<br>t_int member;<br>} t_parent;<br>
<br>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.<br><br>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,<br>
struct xyz {<br>int x;<br>int y;<br>int z;<br>} t_xyz;<br><br>t_xyz data;<br>t_xyz *instance=&data;<br><br>The compiler turns<br>instance->x into *((int *)instance)<br>instance->y into *((int *)instance + 1)<br>
instance->z into *((int *)instance + 2)<br><br>So you see why member needs to be in the same location in each class.<br> <br>Chuck <br></div></div></div>