Max 5 API Reference
00001 /** 00002 @file 00003 urner - a max object shell 00004 jeremy bernstein - jeremy@bootsquad.com 00005 00006 @ingroup examples 00007 */ 00008 00009 // The standard random() function is not standard on Windows. 00010 // We need to do this to setup the rand_s() function. 00011 #ifdef WIN_VERSION 00012 #define _CRT_RAND_S 00013 #endif 00014 00015 #include "ext.h" // standard Max include, always required 00016 #include "ext_obex.h" // required for new style Max object 00017 00018 00019 ////////////////////////// object struct 00020 typedef struct _urner 00021 { 00022 t_object ob; // the object itself (must be first) 00023 char *table; // lookup table for urn values 00024 long count; // number of values already picked 00025 00026 void *bangout; // bang when urn is empty 00027 void *out; // random num 00028 } t_urner; 00029 00030 ///////////////////////// function prototypes 00031 //// standard set 00032 void *urner_new(t_symbol *s, long argc, t_atom *argv); 00033 void urner_free(t_urner *x); 00034 void urner_assist(t_urner *x, void *b, long m, long a, char *s); 00035 //// additional methods 00036 void urner_bang(t_urner *x); // incoming bang message 00037 void urner_reset(t_urner *x); // incoming reset message 00038 00039 //////////////////////// global class pointer variable 00040 void *urner_class; 00041 00042 00043 int main(void) 00044 { 00045 t_class *c; 00046 00047 c = class_new("urner", (method)urner_new, (method)urner_free, (long)sizeof(t_urner), 0L, A_GIMME, 0); 00048 00049 class_addmethod(c, (method)urner_bang, "bang", 0); 00050 class_addmethod(c, (method)urner_reset, "reset", 0); 00051 class_addmethod(c, (method)urner_assist, "assist", A_CANT, 0); 00052 00053 class_register(CLASS_BOX, c); 00054 urner_class = c; 00055 00056 post("I am the urner object"); 00057 return 0; 00058 } 00059 00060 void urner_assist(t_urner *x, void *b, long m, long a, char *s) 00061 { 00062 if (m == ASSIST_INLET) { //inlet 00063 sprintf(s, "I am inlet %ld", a); 00064 } 00065 else { // outlet 00066 sprintf(s, "I am outlet %ld", a); 00067 } 00068 } 00069 00070 void urner_reset(t_urner *x) 00071 { 00072 long i; 00073 long size = sysmem_ptrsize(x->table); 00074 00075 for (i = 0; i < size; i++) { 00076 x->table[i] = 0; // zero table 00077 } 00078 x->count = 0; 00079 } 00080 00081 void urner_bang(t_urner *x) 00082 { 00083 long rand; 00084 long size = sysmem_ptrsize(x->table); // RETURNS SIZE OF POINTER IN BYTES 00085 00086 #ifdef WIN_VERSION 00087 rand_s(&rand); 00088 #else 00089 rand = random(); 00090 #endif 00091 00092 rand = rand % size; 00093 00094 if (x->count == size) { 00095 outlet_bang(x->bangout); // SEND A BANG WHEN WE'VE HIT MAXIMUM 00096 return; 00097 } 00098 00099 if (x->table[rand] != 0) { // NUMBER HAS ALREADY BEEN CHOSEN 00100 do { 00101 #ifdef WIN_VERSION 00102 rand_s(&rand); 00103 #else 00104 rand = random(); 00105 #endif 00106 rand = rand % size; 00107 } while (x->table[rand] != 0); 00108 } 00109 00110 // WE GOT A NUMBER 00111 x->table[rand] = 1; // MARK THIS VALUE AS USED 00112 x->count++; // INCREMENT OUR COUNT 00113 outlet_int(x->out, rand); 00114 } 00115 00116 00117 void urner_free(t_urner *x) 00118 { 00119 sysmem_freeptr(x->table); // FREE ALLOCED MEMORY 00120 } 00121 00122 void *urner_new(t_symbol *s, long argc, t_atom *argv) 00123 { 00124 t_urner *x = NULL; 00125 long size; 00126 00127 if (argc < 1) return NULL; 00128 00129 size = atom_getlong(argv); // SIZE OF OUR URN 00130 if (size < 1) return NULL; // CHECK FOR INVALID DATA 00131 00132 if (x = (t_urner *)object_alloc(urner_class)) { 00133 x->table = (char *)sysmem_newptrclear(size); // size BYTES for the alloced pointer 00134 urner_reset(x); // initializes x->count 00135 00136 x->bangout = outlet_new(x, NULL); // rightmost outlet first 00137 x->out = outlet_new(x, NULL); // then to the left 00138 } 00139 return (x); 00140 }
Copyright © 2008, Cycling '74