Jamoma API  0.6.0.a19
j.pass.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.pass : Pass messages if they match our criteria
6  *
7  * @details
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright © 2005 by Tim Place @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "JamomaForMax.h"
18 
19 #define MAX_ARGCOUNT 100
20 #define MAX_MESS_SIZE 2048
21 
22 typedef struct _pass{ // Data Structure for this object
23  t_object ob; // REQUIRED: Our object
24  void *outlets[MAX_ARGCOUNT]; // my outlet array
25  void *outlet_overflow; // this outlet doubles as the dumpout outlet
26  t_atom arguments[MAX_ARGCOUNT];
27  short num_args;
28  long attr_strip; // ATTRIBUTE: 1 = strip leading slash off any messages
29  long attr_stripnonmatches; // ATTRIBUTE: 1 = strip leading slash off overflow
30 } t_pass;
31 
32 // Prototypes for our methods:
33 void *pass_new(t_symbol *s, long argc, t_atom *argv);
34 void pass_assist(t_pass *x, void *b, long msg, long arg, char *dst);
35 void pass_int(t_pass *x, long n);
36 void pass_float(t_pass *x, double f);
37 void pass_symbol(t_pass *x, t_symbol *msg, long argc, t_atom *argv);
38 void pass_list(t_pass *x, t_symbol *msg, long argc, t_atom *argv);
39 
40 // Globals
41 t_class *pass_class; // Required: Global pointer for our class
42 
43 
44 /************************************************************************************/
45 // Main() Function
46 
47 int JAMOMA_EXPORT_MAXOBJ main(void)
48 {
49  long attrflags = 0;
50  t_class *c;
51  t_object *attr;
52 
53  common_symbols_init();
54 
55  // Define our class
56  c = class_new("j.pass",(method)pass_new, (method)0L, sizeof(t_pass), (method)0L, A_GIMME, 0);
57 
58  // Make methods accessible for our class:
59  class_addmethod(c, (method)pass_int, "int", A_DEFLONG, 0L);
60  class_addmethod(c, (method)pass_float, "float", A_DEFFLOAT, 0L);
61  class_addmethod(c, (method)pass_list, "list", A_GIMME, 0L);
62  class_addmethod(c, (method)pass_symbol, "anything", A_GIMME, 0L);
63  class_addmethod(c, (method)pass_assist, "assist", A_CANT, 0L);
64  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT,0);
65 
66  // ATTRIBUTE: strip
67  attr = attr_offset_new("strip", _sym_long, attrflags,
68  (method)0, (method)0, calcoffset(t_pass, attr_strip));
69  class_addattr(c, attr);
70 
71  // ATTRIBUTE: stripnonmatches
72  attr = attr_offset_new("stripnonmatches", _sym_long, attrflags,
73  (method)0, (method)0, calcoffset(t_pass, attr_stripnonmatches));
74  class_addattr(c, attr);
75 
76  // Finalize our class
77  class_register(CLASS_BOX, c);
78  pass_class = c;
79  return 0;
80 }
81 
82 
83 /************************************************************************************/
84 // Object Life
85 
86 void *pass_new(t_symbol *s, long argc, t_atom *argv)
87 {
88  short i;
89  char argument[MAX_MESS_SIZE]; // temporary container for arguments
90  t_pass *x = (t_pass *)object_alloc(pass_class);
91  long attrstart = attr_args_offset(argc, argv);
92 
93  if (x) {
94  x->outlet_overflow = outlet_new(x, 0); // overflow outlet
95  object_obex_store((void *)x, _sym_dumpout, (object *)x->outlet_overflow); // dumpout
96 // x->num_args = argc;
97  x->num_args = attrstart;
98 
99  for (i=x->num_args-1; i >= 0; i--) {
100  x->outlets[i] = outlet_new(x, 0); // Create Outlet
101  switch(argv[i].a_type) {
102  case A_LONG:
103  atom_setlong(&(x->arguments[i]), atom_getlong(argv+i));
104  break;
105  case A_FLOAT:
106  atom_setfloat(&(x->arguments[i]), atom_getfloat(argv+i));
107  break;
108  case A_SYM:
109  strcpy(argument, atom_getsym(argv+i)->s_name);
110  if (argument[0] == '/')
111  atom_setsym(&(x->arguments[i]), gensym(argument+1));
112 // else if (argument[0] == '@') // This is the start of our attributes
113 // goto out;
114  else
115  atom_setsym(&(x->arguments[i]), gensym(argument));
116  break;
117  }
118  }
119 //out:
120  x->attr_strip = 1; // set default
121  x->attr_stripnonmatches = 0;
122  attr_args_process(x, argc, argv); //handle attribute args
123  }
124  return (x); // return the pointer to our new instantiation
125 }
126 
127 
128 /************************************************************************************/
129 // Methods bound to input/inlets
130 
131 // Method for Assistance Messages
132 void pass_assist(t_pass *x, void *b, long msg, long arg, char *dst)
133 {
134  if (msg==1) // Inlet
135  strcpy(dst, "Input");
136  else if (msg==2) { // Outlets
137  if (arg < x->num_args) {
138  t_symbol *argname;
139  char tempstring[200];
140  switch(x->arguments[arg].a_type) {
141  case A_LONG:
142  snprintf(tempstring, 200, "%ld", atom_getlong(&x->arguments[arg]));
143  strcpy(dst, tempstring);
144  break;
145  case A_FLOAT:
146  snprintf(tempstring, 200, "%f", atom_getfloat(&x->arguments[arg]));
147  strcpy(dst, tempstring);
148  break;
149  case A_SYM:
150  argname = atom_getsym(&x->arguments[arg]);
151  strcpy(dst, argname->s_name);
152  break;
153  }
154  }
155  else
156  strcpy(dst, "dumpout / overflow from non-matching input");
157  }
158 }
159 
160 
161 // INT INPUT
162 void pass_int(t_pass *x, long n)
163 {
164  short i;
165 
166  for (i=0; i< x->num_args; i++) {
167  if (x->arguments[i].a_type == A_LONG) {
168  if (n == atom_getlong(&x->arguments[i])) {
169  outlet_int(x->outlets[i], n);
170  return;
171  }
172  }
173  }
174  outlet_int(x->outlet_overflow, n);
175 }
176 
177 
178 // FLOAT INPUT
179 void pass_float(t_pass *x, double f)
180 {
181  short i;
182 
183  for (i=0; i< x->num_args; i++) {
184  if (x->arguments[i].a_type == A_FLOAT) {
185  if (f == atom_getfloat(&x->arguments[i])) {
186  outlet_float(x->outlets[i], f);
187  return;
188  }
189  }
190  }
191  outlet_float(x->outlet_overflow, f);
192 }
193 
194 
195 // SYMBOL INPUT
196 void pass_symbol(t_pass *x, t_symbol *msg, long argc, t_atom *argv)
197 {
198  short i;
199  t_symbol *message;
200  char *input = msg->s_name;
201 
202  // strip any leading slashes
203  if (*input == '/')
204  input++;
205  message = gensym(input);
206 
207  // parse and send
208  for (i=0; i< x->num_args; i++) {
209  if (message == atom_getsym(&x->arguments[i])) {
210  if (x->attr_strip != 0)
211  outlet_anything(x->outlets[i], message, argc , argv);
212  else
213  outlet_anything(x->outlets[i], msg, argc , argv);
214  return;
215  }
216  }
217  if (x->attr_stripnonmatches !=0)
218  outlet_anything(x->outlet_overflow, message, argc , argv);
219  else
220  outlet_anything(x->outlet_overflow, msg, argc , argv);
221 }
222 
223 
224 // LIST INPUT
225 void pass_list(t_pass *x, t_symbol *msg, long argc, t_atom *argv)
226 {
227  short i;
228  t_symbol *message;
229 
230  // strip any leading slashes
231  if (x->attr_strip != 0) {
232  char *input = msg->s_name;
233  if (*input == '/')
234  input++;
235  message = gensym(input);
236  }
237 
238  // parse and send
239  switch(argv[0].a_type) {
240  case A_LONG:
241  for (i=0; i< x->num_args; i++) {
242  if (x->arguments[i].a_type == A_LONG) {
243  if (atom_getlong(argv) == atom_getlong(&x->arguments[i])) {
244  outlet_list(x->outlets[i], 0L, argc , argv);
245  return;
246  }
247  }
248  }
249  outlet_list(x->outlet_overflow, 0L, argc , argv);
250  break;
251  case A_FLOAT:
252  for (i=0; i< x->num_args; i++) {
253  if (x->arguments[i].a_type == A_FLOAT) {
254  if (atom_getfloat(argv) == atom_getfloat(&x->arguments[i])) {
255  outlet_list(x->outlets[i], 0L, argc , argv);
256  return;
257  }
258  }
259  }
260  outlet_list(x->outlet_overflow, 0L, argc , argv);
261  break;
262  case A_SYM:
263  for (i=0; i< x->num_args; i++) {
264  if (atom_getsym(argv) == atom_getsym(&x->arguments[i])) {
265  outlet_anything(x->outlets[i], message, argc , argv);
266  return;
267  }
268  }
269  outlet_list(x->outlet_overflow, 0L, argc , argv);
270  break;
271  default:
272  outlet_list(x->outlet_overflow, 0L, argc , argv);
273  break;
274  }
275 }
Various utilities for interfacing with Max that are not specific to JamomaModular as such...
int JAMOMA_EXPORT_MAXOBJ main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
Definition: j.pass.cpp:47