Jamoma API  0.6.0.a19
j.oscinstance.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.oscinstance - retrieve instance numbers or ids from OSC messages
6  *
7  * @details
8  *
9  * @authors Trond Lossius
10  *
11  * @copyright Copyright © 2005 Trond Lossius @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_MESS_SIZE 2048
20 
21 typedef struct _oscinstance{ ///< Data Structure for this object
22  t_object ob; ///< REQUIRED: Our object
23  void *outlet0; ///< Leftmost outlet, passing osc messages
24  void *outlet1; ///< 2nd outlet, passing instance number or ID
25  void *outlet2; ///< 3rd outlet, passing the arguments of incomming OSC messages
26  void *outlet_overflow; ///< The rightmost outlet: This outlet doubles as the dumpout outlet
27 } t_oscinstance;
28 
29 /** The j.oscinstance constructor */
30 void *oscinstance_new(t_symbol *s, long argc, t_atom *argv);
31 
32 /** Provide assistance strings in the patcher window. */
33 void oscinstance_assist(t_oscinstance *x, void *b, long msg, long arg, char *dst);
34 
35 /** Method for bang input. */
36 void oscinstance_bang(t_oscinstance *x);
37 
38 /** Method for int input. */
39 void oscinstance_int(t_oscinstance *x, long n);
40 
41 /** Method for int float. */
42 void oscinstance_float(t_oscinstance *x, double f);
43 
44 /** Method for anything else, including OSC messages. */
45 void oscinstance_symbol(t_oscinstance *x, t_symbol *msg, long argc, t_atom *argv);
46 //void oscinstance_list(t_oscinstance *x, t_symbol *msg, long argc, t_atom *argv);
47 
48 // Globals
49 t_class *oscinstance_class; // Required: Global pointer for our class
50 
51 
52 /************************************************************************************/
53 // Main() Function
54 
55 int JAMOMA_EXPORT_MAXOBJ main(void)
56 {
57  t_class *c;
58 
59  jamoma_init();
60  common_symbols_init();
61 
62  c = class_new("j.oscinstance",(method)oscinstance_new, (method)0L, sizeof(t_oscinstance), (method)0L, A_GIMME, 0);
63 
64  class_addmethod(c, (method)oscinstance_bang, "bang", 0);
65  class_addmethod(c, (method)oscinstance_int, "int", A_DEFLONG, 0L);
66  class_addmethod(c, (method)oscinstance_float, "float", A_DEFFLOAT, 0L);
67  class_addmethod(c, (method)oscinstance_symbol, "list", A_GIMME, 0L);
68  class_addmethod(c, (method)oscinstance_symbol, "anything", A_GIMME, 0L);
69  class_addmethod(c, (method)oscinstance_assist, "assist", A_CANT, 0L);
70  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT,0);
71 
72  // Finalize our class
73  class_register(CLASS_BOX, c);
74  oscinstance_class = c;
75  return 0;
76 }
77 
78 
79 /************************************************************************************/
80 // Object Life
81 
82 void *oscinstance_new(t_symbol *s, long argc, t_atom *argv)
83 {
84  t_oscinstance *x = (t_oscinstance *)object_alloc(oscinstance_class);
85 
86  if (x) {
87  x->outlet_overflow = outlet_new(x, 0); // overflow outlet
88  object_obex_store((void *)x, _sym_dumpout, (object *)x->outlet_overflow); // dumpout
89  x->outlet2 = outlet_new(x, 0); // Create Outlet
90  x->outlet1 = outlet_new(x, 0); // Create Outlet
91  x->outlet0 = outlet_new(x, 0); // Create Outlet
92  }
93  return (x); // return the pointer to our new instantiation
94 }
95 
96 
97 /************************************************************************************/
98 // Methods bound to input/inlets
99 
100 // Method for Assistance Messages
101 void oscinstance_assist(t_oscinstance *x, void *b, long msg, long arg, char *dst)
102 {
103  if (msg==1) // Inlet
104  strcpy(dst, "Input");
105  else if (msg==2) { // Outlets
106  if (arg == 0)
107  strcpy(dst, "OSC message with instance info stripped");
108  else if (arg == 1)
109  strcpy(dst, "OSC instance number or ID");
110  else if (arg == 2)
111  strcpy(dst, "parameter value");
112  else
113  strcpy(dst, "dumpout / overflow from non-matching input");
114  }
115 }
116 
117 
118 void oscinstance_bang(t_oscinstance *x)
119 {
120  outlet_bang(x->outlet_overflow);
121 }
122 
123 
124 // INT INPUT
125 void oscinstance_int(t_oscinstance *x, long n)
126 {
127  outlet_int(x->outlet_overflow, n);
128 }
129 
130 
131 // FLOAT INPUT
132 void oscinstance_float(t_oscinstance *x, double f)
133 {
134  outlet_float(x->outlet_overflow, f);
135 }
136 
137 
138 // SYMBOL INPUT
139 void oscinstance_symbol(t_oscinstance *x, t_symbol *msg, long argc, t_atom *argv)
140 {
141  char input[MAX_MESS_SIZE]; // our input string
142  char *input2 = input; // pointer to our input string
143  char *dot;
144  char *slash;
145  t_symbol *instance;
146  char *instanceEnd;
147  t_symbol *output;
148  t_symbol *osc = NULL;
149  long i;
150  bool leadingSlash;
151 
152  strcpy(input, msg->s_name);
153 
154  /* to -- the introduction of relative address feature
155  in modular0.6 make this test useless
156 
157 
158  // This object only deals with OSC messages
159  if (!(*input2 == '/')) {
160  goto spillover;
161  }
162  */
163  leadingSlash = *input2 == '/';
164  if (leadingSlash)
165  input2++; // jump past the leading slash
166 
167  dot = strchr(input2, '.'); // look for dot
168  if (dot == NULL)
169  goto spillover;
170 
171  slash = strchr(input2, '/'); // checking for additional osc branches
172 
173  if ( slash == 0) {
174  *dot = NULL;
175  osc = gensym(input2 - leadingSlash);// reintroduce the leading slash if needed
176  instance = gensym(dot+1);
177  }
178  else {
179  if ( slash<dot )
180  goto spillover; // there are instances, but not in the leading branch
181  *dot = NULL;
182  *slash = NULL; // temporarily remove the slash
183  instance = gensym(dot+1);
184  *slash = '/'; // put slash back in
185  strcat(input, slash); // remove the instance part and concatenate
186  osc = gensym(input2 - leadingSlash); // reintroduce the leading slash if needed
187  }
188 
189  // Output from 3rd outlet: The arguments of the OSC message
190 
191  // We have to check what message to return.
192  // The message received has no arguments:
193  if (argc == 0) {
194  outlet_bang(x->outlet2);
195  }
196  // The message received has one argument only:
197  else if (argc==1) {
198  // int argument
199  if (argv->a_type==A_LONG)
200  outlet_int(x->outlet2,argv->a_w.w_long);
201  // float argument
202  else if (argv->a_type==A_FLOAT)
203  outlet_float(x->outlet2,argv->a_w.w_float);
204  // something else
205  else if (argv->a_type==A_SYM)
206  outlet_anything(x->outlet2,argv->a_w.w_sym,0,0);
207  }
208  // There are two or more arguments: check if first is A_SYM
209  else {
210  if (argv->a_type==A_SYM) {
211  output = argv->a_w.w_sym;
212  argc--;
213  argv++;
214  }
215  else
216  output = _sym_list;
217  outlet_anything(x->outlet2, output, argc , argv);
218  }
219 
220  // Output from 2nd outlet: Instance. Check if the instance is an integer (long):
221  i = strtol (instance->s_name,&instanceEnd,10);
222  if (instance->s_name[0] != '\n' && (*instanceEnd == '\n' || *instanceEnd == '\0'))
223  outlet_int(x->outlet1, i);
224  else
225  outlet_anything(x->outlet1, instance, NULL, 0L);
226 
227  // Output from 1st outlet: OC name with instance removed
228  outlet_anything(x->outlet0, osc, NULL, 0L);
229  return;
230 
231  spillover:
232  outlet_anything(x->outlet_overflow, msg, argc , argv);
233  return;
234 }
235 
236 
void oscinstance_symbol(t_oscinstance *x, t_symbol *msg, long argc, t_atom *argv)
Method for anything else, including OSC messages.
void * oscinstance_new(t_symbol *s, long argc, t_atom *argv)
The j.oscinstance constructor.
void oscinstance_bang(t_oscinstance *x)
Method for bang input.
void oscinstance_assist(t_oscinstance *x, void *b, long msg, long arg, char *dst)
Provide assistance strings in the patcher window.
void oscinstance_float(t_oscinstance *x, double f)
Method for int float.
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.
void oscinstance_int(t_oscinstance *x, long n)
Method for int input.