Max 5 API Reference
00001 /* 00002 jit.qtcomponent.c 00003 00004 Copyright 2001-2005 - Cycling '74 00005 Jeremy Bernstein jeremy@bootsquad.com 00006 Joshua Kit Clayton jkc@cycling74.com 00007 */ 00008 00009 #include "jit.common.h" 00010 00011 static unsigned long _jit_qt_component_uid = 0; 00012 00013 typedef struct _jit_qt_component 00014 { 00015 t_jit_object ob; 00016 Component c; 00017 struct _jit_qt_component_instance *instance; 00018 long instance_count; 00019 t_symbol *name; 00020 t_symbol *owner_instance_name; 00021 } t_jit_qt_component; 00022 00023 typedef struct _jit_qt_component_instance 00024 { 00025 ComponentInstance ci; 00026 t_symbol *instance_name; 00027 struct _jit_qt_component_instance *prev; 00028 struct _jit_qt_component_instance *next; 00029 struct _jit_qt_component_objlist *objlist; 00030 long objlist_count; // number of attached objects 00031 long misc; // general slot for a pointer 00032 } t_jit_qt_component_instance; 00033 00034 typedef struct _jit_qt_component_objlist 00035 { 00036 void *obj; 00037 struct _jit_qt_component_objlist *prev; 00038 struct _jit_qt_component_objlist *next; 00039 } t_jit_qt_component_objlist; 00040 00041 t_jit_err jit_qt_component_init(void); 00042 void jit_qt_component_access_notify(t_jit_qt_component *o, void *x); 00043 void *jit_qt_component_open(void *x, Component c, t_symbol *instance_name); 00044 t_jit_err jit_qt_component_close(void *x, void *o); 00045 void *jit_qt_component_new(Component c, t_symbol *instance_name); 00046 t_jit_err jit_qt_component_free(t_jit_qt_component *x); 00047 ComponentInstance jit_qt_component_getinstance(t_jit_qt_component *o, void *x); 00048 t_symbol *jit_qt_component_getinstancename(t_jit_qt_component *o, void *x); 00049 GWorldPtr jit_qt_component_getgworld(t_jit_qt_component *o, void *x); 00050 void jit_qt_component_clear_misc(t_jit_qt_component *o, void *x); 00051 long jit_qt_component_count(t_jit_qt_component *x); 00052 t_jit_qt_component_instance *jit_qt_component_instance_new(t_jit_qt_component *o, t_symbol *instance_name); 00053 t_jit_qt_component_objlist *jit_qt_component_objlist_new(void *x); 00054 t_symbol *jit_qt_component_instance_name_unique(void); 00055 long jit_qt_component_getcount(t_jit_qt_component *o, void *x); 00056 long jit_qt_component_is_owner(t_jit_qt_component *o, void *x); 00057 t_symbol *jit_qt_component_getowner(t_jit_qt_component *o); 00058 00059 void *_jit_qt_component_class; 00060 00061 t_jit_err jit_qt_component_init(void) 00062 { 00063 void *attr; 00064 long attrflags = 0; 00065 00066 _jit_qt_component_class = jit_class_new("jit_qt_component",(method)jit_qt_component_new,(method)jit_qt_component_free, 00067 sizeof(t_jit_qt_component),A_CANT,0L); //A_CANT = untyped 00068 00069 attrflags = JIT_ATTR_SET_OPAQUE_USER | JIT_ATTR_GET_OPAQUE_USER; 00070 attr = jit_object_new(_jit_sym_jit_attr_offset,"name",_jit_sym_symbol,attrflags, 00071 (method)0L,(method)0L,calcoffset(t_jit_qt_component,name)); 00072 jit_class_addattr(_jit_qt_component_class,attr); 00073 00074 jit_class_addmethod(_jit_qt_component_class, (method)jit_method_true, "class_jit_qt_component" , A_CANT, 0L); 00075 jit_class_addmethod(_jit_qt_component_class, (method)jit_object_register, "register", A_CANT, 0L); //can register 00076 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_getowner, "getowner", A_CANT, 0L); 00077 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_is_owner, "is_owner", A_CANT, 0L); 00078 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_getinstance, "getinstance", A_CANT, 0L); 00079 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_getcount, "getcount", A_CANT, 0L); 00080 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_getinstancename, "getinstancename", A_CANT, 0L); 00081 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_getgworld, "getgworld", A_CANT, 0L); 00082 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_access_notify, "access", 0L); 00083 jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_clear_misc, "clear_misc", 0L); 00084 // jit_class_addmethod(_jit_qt_component_class, (method)jit_qt_component_count, "count", 0L); 00085 00086 jit_class_register(_jit_qt_component_class); 00087 return JIT_ERR_NONE; 00088 } 00089 00090 long jit_qt_component_getcount(t_jit_qt_component *o, void *x) 00091 { 00092 t_jit_qt_component_instance *instance; 00093 t_jit_qt_component_objlist *list; 00094 00095 if (x && o) { 00096 instance = o->instance; 00097 while (instance) { 00098 list = instance->objlist; 00099 while (list) { 00100 if (list->obj == x) { // object is registered 00101 return instance->objlist_count; 00102 } 00103 list = list->next; 00104 } 00105 instance = instance->next; 00106 } 00107 } 00108 return 0L; 00109 } 00110 00111 long jit_qt_component_is_owner(t_jit_qt_component *o, void *x) 00112 { 00113 t_symbol *owner_name; 00114 t_symbol *instance_name; 00115 t_jit_qt_component_instance *instance; 00116 t_jit_qt_component_objlist *list; 00117 00118 00119 if (x && o) { 00120 owner_name = o->owner_instance_name; 00121 00122 instance = o->instance; 00123 while (instance) { 00124 list = instance->objlist; 00125 while (list) { 00126 if (list->obj == x) { // object is registered 00127 instance_name = instance->instance_name; 00128 goto compare; 00129 } 00130 list = list->next; 00131 } 00132 instance = instance->next; 00133 } 00134 00135 compare: 00136 // jit_object_post((t_object *)x,"owner_name: %s, instance_name: %s", owner_name->s_name, instance_name->s_name); 00137 if (owner_name == instance_name) 00138 return 1; 00139 else 00140 return 0; 00141 } 00142 return -1; 00143 } 00144 00145 t_symbol *jit_qt_component_getowner(t_jit_qt_component *o) 00146 { 00147 if (o) { 00148 return o->owner_instance_name; 00149 } 00150 return NULL; 00151 } 00152 00153 00154 t_symbol *jit_qt_component_getinstancename(t_jit_qt_component *o, void *x) 00155 { 00156 t_jit_qt_component_instance *instance; 00157 t_jit_qt_component_objlist *list; 00158 00159 if (x && o) { 00160 instance = o->instance; 00161 while (instance) { 00162 list = instance->objlist; 00163 while (list) { 00164 if (list->obj == x) { // object is registered 00165 return instance->instance_name; 00166 } 00167 list = list->next; 00168 } 00169 instance = instance->next; 00170 } 00171 } 00172 return NULL; 00173 } 00174 00175 ComponentInstance jit_qt_component_getinstance(t_jit_qt_component *o, void *x) 00176 { 00177 t_jit_qt_component_instance *instance; 00178 t_jit_qt_component_objlist *list; 00179 00180 if (x && o) { 00181 instance = o->instance; 00182 while (instance) { 00183 list = instance->objlist; 00184 while (list) { 00185 if (list->obj == x) { // object is registered 00186 // jit_object_post((t_object *)x,"found object"); 00187 return instance->ci; 00188 } 00189 list = list->next; 00190 } 00191 instance = instance->next; 00192 } 00193 } 00194 return NULL; 00195 } 00196 00197 GWorldPtr jit_qt_component_getgworld(t_jit_qt_component *o, void *x) 00198 { 00199 t_jit_qt_component_instance *instance; 00200 t_jit_qt_component_objlist *list; 00201 00202 if (x && o) { 00203 instance = o->instance; 00204 while (instance) { 00205 list = instance->objlist; 00206 while (list) { 00207 if (x == list->obj) { // object is registered 00208 if (instance->ci && !instance->misc) 00209 QTVideoOutputGetGWorld(instance->ci, (GWorldPtr *)(&instance->misc)); 00210 return (GWorldPtr)instance->misc; 00211 } 00212 list = list->next; 00213 } 00214 instance = instance->next; 00215 } 00216 } 00217 return NULL; 00218 } 00219 00220 void jit_qt_component_clear_misc(t_jit_qt_component *o, void *x) 00221 { 00222 t_jit_qt_component_instance *instance; 00223 t_jit_qt_component_objlist *list; 00224 00225 if (x && o) { 00226 instance = o->instance; 00227 while (instance) { 00228 list = instance->objlist; 00229 while (list) { 00230 if (x == list->obj) { // object is registered 00231 instance->misc = 0L; 00232 return; 00233 } 00234 list = list->next; 00235 } 00236 instance = instance->next; 00237 } 00238 } 00239 } 00240 00241 void jit_qt_component_access_notify(t_jit_qt_component *o, void *x) 00242 { 00243 t_jit_qt_component_instance *instance; 00244 t_jit_qt_component_objlist *list; 00245 00246 if (x && o) { 00247 instance = o->instance; 00248 while (instance) { 00249 list = instance->objlist; 00250 while (list) { 00251 if (list->obj == x) { // object is registered 00252 o->owner_instance_name = instance->instance_name; 00253 } 00254 list = list->next; 00255 } 00256 instance = instance->next; 00257 } 00258 } 00259 00260 jit_object_notify(o, gensym("qtcomponent_accessed"),NULL); 00261 } 00262 /* 00263 long jit_qt_component_count(t_jit_qt_component *x) 00264 { 00265 void *o=NULL; 00266 00267 o = jit_robject_findbyptr(x); 00268 00269 if (o) { 00270 return jit_attr_getlong(o, gensym("refcount")); 00271 } 00272 else return 0; 00273 } 00274 */ 00275 00276 t_symbol *jit_qt_component_instance_name_unique(void) 00277 { 00278 char s[256]; 00279 00280 sprintf(s,"c%03d%06d",jit_rand()%1000,++_jit_qt_component_uid); //randomize the first 3 digits for better hashing 00281 00282 return gensym(s); 00283 } 00284 00285 void *jit_qt_component_open(void *x, Component c, t_symbol *instance_name) 00286 { 00287 char str[256]; 00288 void *o; 00289 t_symbol *s; 00290 t_jit_qt_component *qtc; 00291 t_jit_qt_component_instance *instance; 00292 t_jit_qt_component_objlist *list; 00293 t_jit_qt_component_objlist *newlist; 00294 00295 if (!c) 00296 return NULL; 00297 00298 if (!instance_name) 00299 instance_name = _jit_sym_nothing; 00300 if (instance_name == gensym("unique")) 00301 instance_name = jit_qt_component_instance_name_unique(); 00302 00303 sprintf(str, "_qtcomponent%x", c); 00304 s = gensym(str); 00305 00306 o = jit_object_findregistered(s); 00307 if (o) { 00308 if (jit_object_method(o, gensym("class_jit_qt_component"))) { 00309 jit_object_register(o, s); 00310 jit_object_attach(s, x); 00311 // jit_object_post((t_object *)x,"found registered"); 00312 00313 qtc = o; 00314 instance = qtc->instance; 00315 while (instance) { 00316 if (instance->instance_name == instance_name) 00317 break; 00318 else { 00319 if (instance->next) 00320 instance = instance->next; 00321 else { // we're at the last entry. make a new instance 00322 t_jit_qt_component_instance *new_instance; 00323 00324 new_instance = jit_qt_component_instance_new(qtc, instance_name); 00325 if (new_instance) { 00326 instance->next = new_instance; 00327 new_instance->prev = instance; 00328 qtc->instance_count++; 00329 } 00330 else { 00331 error("jit.qt.component: could not create component instance"); 00332 goto failed; 00333 } 00334 00335 instance = new_instance; // and make a new objlist 00336 list = jit_qt_component_objlist_new(x); 00337 if (list) { 00338 instance->objlist = list; 00339 instance->objlist_count = 1; 00340 } 00341 else { 00342 error("jit.qt.component: could not create object list"); 00343 goto badinstance; 00344 } 00345 return o; 00346 } 00347 } 00348 } 00349 00350 if (instance) { // we're requesting a connection to this instance 00351 list = instance->objlist; 00352 while (list->next) 00353 list = list->next; // go to end of the object list 00354 newlist = jit_qt_component_objlist_new(x); 00355 if (newlist) { 00356 newlist->prev = list; 00357 list->next = newlist; 00358 instance->objlist_count++; 00359 } 00360 else { 00361 error("jit.qt.component: could not create object list"); 00362 goto failed; 00363 } 00364 } 00365 } 00366 else { 00367 error("jit.qt.component: wrong object type"); 00368 return NULL; 00369 } 00370 } 00371 else { 00372 o = jit_object_new(gensym("jit_qt_component"), c, instance_name); // new instance will be created 00373 if (o) { 00374 jit_attr_setsym(o,_jit_sym_name,s); 00375 jit_object_register(o, s); 00376 jit_object_attach(s, x); 00377 00378 qtc = o; 00379 instance = qtc->instance; 00380 00381 list = jit_qt_component_objlist_new(x); 00382 if (list) { 00383 instance->objlist = list; 00384 instance->objlist_count = 1; 00385 } 00386 else { 00387 error("jit.qt.component: could not create object list"); 00388 goto badinstance; 00389 } 00390 } 00391 } 00392 00393 return o; 00394 00395 badinstance: // only happens with a new object, but what the hell 00396 if (instance) { 00397 jit_freebytes(instance, sizeof(t_jit_qt_component_instance)); 00398 qtc->instance_count--; 00399 } 00400 00401 failed: // don't kill the instance -- it was preexisting 00402 if (s && o) { 00403 jit_object_free(o); 00404 jit_object_detach(s, x); 00405 o = NULL; 00406 return o; 00407 } 00408 return NULL; 00409 } 00410 00411 t_jit_err jit_qt_component_close(void *x, void *o) 00412 { 00413 t_symbol *s = NULL; 00414 t_jit_qt_component *qtc; 00415 t_jit_qt_component_instance *instance, *prev, *next; 00416 t_jit_qt_component_objlist *list, *listprev, *listnext; 00417 long err = 0; 00418 00419 if (x && o) { 00420 qtc = o; 00421 instance = qtc->instance; 00422 00423 // jit_object_post((t_object *)x,"instance_count: %d, objlist_count: %d", qtc->instance_count, instance->objlist_count); 00424 while (instance) { 00425 list = instance->objlist; 00426 while (list) { 00427 if (list->obj == x) { // object is registered, remove it 00428 listprev = list->prev; 00429 listnext = list->next; 00430 00431 if (listprev) 00432 listprev->next = list->next; 00433 else 00434 instance->objlist = list->next; 00435 if (listnext) 00436 listnext->prev = list->prev; 00437 jit_freebytes(list, sizeof(t_jit_qt_component_objlist)); 00438 // jit_object_post((t_object *)x,"object removed"); 00439 00440 if (!(--(instance->objlist_count))) { // kill the instance, too 00441 prev = instance->prev; 00442 next = instance->next; 00443 if (prev) 00444 prev->next = instance->next; 00445 else 00446 qtc->instance = instance->next; 00447 if (next) 00448 next->prev = instance->prev; 00449 err = CloseComponent(instance->ci); 00450 // if (err) jit_object_post((t_object *)x,"error closing qtcomponent: %d", err); 00451 jit_freebytes(instance, sizeof(t_jit_qt_component_instance)); 00452 qtc->instance_count--; 00453 // jit_object_post((t_object *)x,"instance closed"); 00454 } 00455 00456 goto detach; 00457 } 00458 list = list->next; 00459 } 00460 instance = instance->next; 00461 } 00462 00463 detach: 00464 s = jit_attr_getsym(o,_jit_sym_name); 00465 jit_object_free(o); 00466 jit_object_detach(s, x); 00467 } 00468 return err; 00469 } 00470 00471 t_jit_err jit_qt_component_free(t_jit_qt_component *x) 00472 { 00473 // jit_object_post((t_object *)x,"freeing jit_qt_component"); 00474 return JIT_ERR_NONE; 00475 } 00476 00477 t_jit_qt_component_objlist *jit_qt_component_objlist_new(void *x) 00478 { 00479 t_jit_qt_component_objlist *list = NULL; 00480 00481 if (x) { 00482 list = (t_jit_qt_component_objlist *)jit_getbytes(sizeof(t_jit_qt_component_objlist)); // attach object to instance list 00483 if (list) { 00484 list->obj = x; 00485 list->prev = NULL; 00486 list->next = NULL; 00487 } 00488 } 00489 return list; 00490 } 00491 00492 t_jit_qt_component_instance *jit_qt_component_instance_new(t_jit_qt_component *o, t_symbol *instance_name) 00493 { 00494 ComponentInstance ci; 00495 t_jit_qt_component_instance *instance = NULL; 00496 00497 if (o && o->c) { 00498 ci = OpenComponent(o->c); 00499 if (ci) { 00500 instance = (t_jit_qt_component_instance *)jit_getbytes(sizeof(t_jit_qt_component_instance));//jit_object_new(gensym("jit_qt_component_instance"), ci); 00501 if (instance) { 00502 instance->ci = ci; 00503 instance->next = NULL; 00504 instance->prev = NULL; 00505 // instance->share = 1; 00506 instance->misc = 0L; 00507 instance->objlist_count = 0; 00508 instance->objlist = NULL; 00509 instance->instance_name = instance_name; 00510 } 00511 else { 00512 error("jit.qt.qtcomponent: out of memory"); 00513 CloseComponent(ci); 00514 } 00515 } 00516 } 00517 return instance; 00518 } 00519 00520 void *jit_qt_component_new(Component c, t_symbol *instance_name) 00521 { 00522 t_jit_qt_component *x; 00523 ComponentInstance ci; 00524 00525 if (x=(t_jit_qt_component *)jit_object_alloc(_jit_qt_component_class)) { 00526 x->c = c; 00527 x->instance = jit_qt_component_instance_new(x, instance_name); 00528 if (x->instance) { 00529 x->instance_count = 1; 00530 } 00531 else { // must have at least one instance 00532 jit_object_free(x); 00533 x = NULL; 00534 return x; 00535 } 00536 } 00537 else { 00538 jit_object_free(x); 00539 x = NULL; 00540 } 00541 return x; 00542 }
Copyright © 2008, Cycling '74