4 * Copyright (c) Tuomo Valkonen 1999-2004.
6 * You may distribute and modify this library under the terms of either
7 * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
19 ClassDescr CLASSDESCR(Obj)={"Obj", NULL, 0, NULL, NULL};
22 static void do_watches(Obj *obj, bool call);
28 void destroy_obj(Obj *obj)
32 if(OBJ_IS_BEING_DESTROYED(obj))
37 do_watches(obj, TRUE);
42 if(d->destroy_fn!=NULL){
49 do_watches(obj, FALSE);
61 bool obj_is(const Obj *obj, const ClassDescr *descr)
79 bool obj_is_str(const Obj *obj, const char *str)
83 if(obj==NULL || str==NULL)
89 if(strcmp(d->name, str)==0)
97 const void *obj_cast(const Obj *obj, const ClassDescr *descr)
118 /*{{{ Dynamic functions */
121 /* This function is called when no handler is found.
123 static void dummy_dyn()
128 static int comp_fun(const void *a, const void *b)
130 void *af=(void*)((DynFunTab*)a)->func;
131 void *bf=(void*)((DynFunTab*)b)->func;
133 return (af<bf ? -1 : (af==bf ? 0 : 1));
137 DynFun *lookup_dynfun(const Obj *obj, DynFun *func,
142 /*DynFunTab dummy={NULL, NULL};*/
150 for(; descr!=&Obj_classdescr; descr=descr->ancestor){
151 if(descr->funtab==NULL)
154 if(descr->funtab_n==-1){
155 /* Need to sort the table. */
158 while(df->func!=NULL){
163 if(descr->funtab_n>0){
164 qsort(descr->funtab, descr->funtab_n, sizeof(DynFunTab),
170 if(descr->funtab_n==0)
173 df=(DynFunTab*)bsearch(&dummy, descr->funtab, descr->funtab_n,
174 sizeof(DynFunTab), comp_fun);
181 /* Using custom bsearch instead of the one in libc is probably
182 * faster as the overhead of calling a comparison function would
183 * be significant given that the comparisons are simple and
184 * funtab_n not that big.
187 int min=0, max=descr->funtab_n-1;
192 if((void*)df[ndx].func==(void*)func){
194 return df[ndx].handler;
196 if((void*)df[ndx].func<(void*)func)
209 bool has_dynfun(const Obj *obj, DynFun *func)
212 lookup_dynfun(obj, func, &funnotfound);
223 bool watch_setup(Watch *watch, Obj *obj, WatchHandler *handler)
225 if(OBJ_IS_BEING_DESTROYED(obj))
230 watch->handler=handler;
231 LINK_ITEM(obj->obj_watches, watch, next, prev);
237 void do_watch_reset(Watch *watch, bool call)
239 WatchHandler *handler=watch->handler;
247 UNLINK_ITEM(obj->obj_watches, watch, next, prev);
250 if(call && handler!=NULL)
255 void watch_reset(Watch *watch)
257 do_watch_reset(watch, FALSE);
261 bool watch_ok(Watch *watch)
263 return watch->obj!=NULL;
267 static void do_watches(Obj *obj, bool call)
271 watch=obj->obj_watches;
275 do_watch_reset(watch, call);
281 void watch_call(Obj *obj)
283 do_watches(obj, FALSE);
287 void watch_init(Watch *watch)