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
)