In our case, an objectclass should be created, that prints the line ``hello world!!'' to the standarderror everytime it is triggered witha ``bang''-message.
#include "m_pd.h"
static t_class *helloworld_class; typedef struct _helloworld { t_object x_obj; } t_helloworld;
hello_worldclass
is going to be a pointer to the new class.
The structure t_helloworld
(of the type _helloworld
) is
the dataspace of the class.
An absolutely necessary element of the dataspace is a variable of the type
t_object
, which is used to store internal object-properties like
the graphical presentation of the object or data about inlets and outlets.
t_object
has to be the first entry in the structure !
Because a simple ``hello world''-application needs no variables,
the structure is empty apart from the t_object
.
If a message is sent to an instance of our class, a method is called.
These methods are the interfaces to the messagesystem of pd.
On principal they have no return argument and are therefore are of the
type void
.
void helloworld_bang(t_helloworld *x) { post("Hello world !!"); }
This method has an argument of the type t_helloworld
,
which would enable us to manipulate the dataspace.
Since we only want to output ``Hello world!'' (and, by the way, our dataspace is quite sparse), we renounce a manipulation.
The command post(char *c,...)
sends a string to the standarderror.
A carriage return is added automatically.
Apart from this, the post
-command works like the C-command printf()
.
On loading a new library ``my_lib'', pd tries to call a function ``my_lib_setup()''. This function (or functions called by it) declares the new classes and their properties. It is only called once, when the library is loaded. If the function-call fails (e.g., because no functionn of the specified name is present) no external of the library will be loaded.
void helloworld_setup(void) { helloworld_class = class_new(gensym("helloworld"), (t_newmethod)helloworld_new, 0, sizeof(t_helloworld), CLASS_DEFAULT, 0); class_addbang(helloworld_class, helloworld_bang); }
The function class_new
creates a new class and returns a pointer to this prototype.
The first argument is the symbolic name of the class.
Das erste Argument ist der symbolische Name der Klasse.
The next two arguments define the constructor and dstructor of the class.
Whenever a classobject is created in a pd-patch,
the class-constructor (t_newmethod)helloworld_new
instantiates the object
and initializes the dataspace.
Whenever an object is destroyed (either by closing the containing patch or by deleting the object from the patch) the destructor frees the dynamically reserved memory. The allocated memory for the static dataspace is automatically reserved and freed.
Therefore we do not have to provide a destructor in this example, the argument is set to ``0''.
To enable pd to reserve and free enough memory for the static dataspace, the size of the datastructure has to be passed as the fourth argument.
The fifth argument has influence on the graphical representaion of the classobjects.
The default-value is CLASS_DEFAULT
or simply ``0''.
The remaining arguments define the arguments of an object and its type.
Up to six numeric and symbolic object-arguments can be defined via
A_DEFFLOAT
and A_DEFSYMBOL
.
If more arguments are to be passed to the object
or if the order of atomtypes should by more flexible,
A_GIMME
can be used for passing an arbitrary list of atoms.
The list of object-arguments is terminated by ``0''. In this example we have no object-arguments at all for the class.
class_addbang
adds a method for a ``bang''-message to the class that is
defined in the first argument.
The added method is defined in the second argument.
class_new
-command,
generates a new instance of the class.
The constructor has to be of type void *
.
void *helloworld_new(void) { t_helloworld *x = (t_helloworld *)pd_new(helloworld_class); return (void *)x; }
The arguments of the constructor-method depend on the object-arguments
defined with class_new
.
class_new -argument |
constructor-argument |
A_DEFFLOAT |
t_floatarg f |
A_DEFSYMBOL |
t_symbol *s |
A_GIMME |
t_symbol *s, int argc, t_atom *argv |
Because there are no object-arguments for our ``hello world''-class, the constructor has anon too.
The function pd_new
reserves memory for the dataspace,
initializes the variables that are internal to the object and
returns a pointer to the dataspace.
The type-cast to the dataspace is necessary.
Normally, the constructor would initialize the object-variables. However, since we have none, this is not necessary.
The constructor has to return a pointer to the instantiated dataspace.
#include "m_pd.h" static t_class *helloworld_class; typedef struct _helloworld { t_object x_obj; } t_helloworld; void helloworld_bang(t_helloworld *x) { post("Hello world !!"); } void *helloworld_new(void) { t_helloworld *x = (t_helloworld *)pd_new(helloworld_class); return (void *)x; } void helloworld_setup(void) { helloworld_class = class_new(gensym("helloworld"), (t_newmethod)helloworld_new, 0, sizeof(t_helloworld), CLASS_DEFAULT, 0); class_addbang(helloworld_class, helloworld_bang); }