2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
11 #include <proto/exec.h>
12 #include <exec/memory.h>
13 #include <exec/lists.h>
15 #include <proto/oop.h>
27 #include <aros/debug.h>
30 #define UB(x) ((UBYTE *)x)
32 #define ClassID PPart.ClassNode.ln_Name
41 /* Used to do several string interface ID to numeric interface ID mappings in one call */
42 BOOL
GetIDs(struct IDDescr
*idDescr
, struct IntOOPBase
*OOPBase
)
46 *(idDescr
->Storage
) = OOP_ObtainAttrBase(idDescr
->ID
);
47 if (0UL == *(idDescr
->Storage
))
55 /*********************
57 *********************/
59 BOOL
hasinterface(OOP_Class
*cl
, CONST_STRPTR interface_id
)
61 ULONG num_methods
= 0UL;
62 return (meta_getifinfo((OOP_Object
*)cl
, interface_id
, &num_methods
) != NULL
) ? TRUE
: FALSE
;
65 /**********************
67 **********************/
68 struct IFMethod
*findinterface(OOP_Class
*cl
, CONST_STRPTR interface_id
)
70 ULONG num_methods
= 0UL;
72 return meta_getifinfo((OOP_Object
*)cl
, interface_id
, &num_methods
);
75 /***************************
76 ** init_mi_methodbase() **
77 ***************************/
78 /* Intializes a methodbase to be used for the classes supporting multiple
79 interfaces (MI), ie. objects of th IFMeta class.
81 BOOL
init_mi_methodbase(CONST_STRPTR interface_id
, ULONG
*methodbase_ptr
, struct IntOOPBase
*OOPBase
)
85 EnterFunc(bug("init_mi_methodbase(interface_id=%s)\n", interface_id
));
87 mbase
= OOPBase
->ob_CurrentMethodBase
++;
88 mbase
<<= NUM_METHOD_BITS
;
89 success
= init_methodbase(interface_id
, mbase
, methodbase_ptr
, OOPBase
);
92 if (*methodbase_ptr
!= mbase
)
94 /* Methodbase had allready been inited, reset current ID */
95 OOPBase
->ob_CurrentMethodBase
--;
98 ReturnBool ("init_mi_methodbase", success
);
102 /************************
103 ** init_methodbase() **
104 ************************/
106 /* Adds the local ID equivalent to the global string ID
110 BOOL
init_methodbase(CONST_STRPTR interface_id
, ULONG methodbase
, ULONG
*methodbase_ptr
, struct IntOOPBase
*OOPBase
)
113 struct iid_bucket
*idb
= NULL
;
114 struct HashTable
*iidtable
= OOPBase
->ob_IIDTable
;
117 EnterFunc(bug("init_methodbase(interface_id=%s, methodbase=%ld)\n",
118 interface_id
, methodbase
));
120 ObtainSemaphore(&OOPBase
->ob_IIDTableLock
);
122 /* Has ID allready been mapped to a methodbase ? */
123 idb
= (struct iid_bucket
*)iidtable
->Lookup(iidtable
, (IPTR
)interface_id
, (struct IntOOPBase
*)OOPBase
);
126 if (idb
->methodbase
== (ULONG
)-1)
128 idb
->methodbase
= methodbase
;
131 *methodbase_ptr
= idb
->methodbase
;
138 D(bug("Initing methodbase...\n"));
141 /* If not, then map it and create a new bucket in the
142 ** hashtable to store it
144 idb
= AllocMem(sizeof (struct iid_bucket
), MEMF_ANY
);
147 idb
->interface_id
= AllocVec(strlen(interface_id
) + 1, MEMF_ANY
);
148 if (idb
->interface_id
)
150 D(bug("Allocated bucket\n"));
151 strcpy(idb
->interface_id
, interface_id
);
153 /* Get next free ID, and increase the free ID to mark it as used */
155 idb
->methodbase
= methodbase
;
156 *methodbase_ptr
= methodbase
;
158 /* Leave attrbase field unitialized */
159 idb
->attrbase
= (ULONG
)-1;
161 /* Insert bucket into hash table */
162 InsertBucket(iidtable
, (struct Bucket
*)idb
, (struct IntOOPBase
*)OOPBase
);
167 FreeMem(idb
, sizeof (struct iid_bucket
));
176 ReleaseSemaphore(&OOPBase
->ob_IIDTableLock
);
178 ReturnBool ("init_methodbase", inited
);
182 /* Release a interface bucket */
183 VOID
release_idbucket(CONST_STRPTR interface_id
, struct IntOOPBase
*OOPBase
)
186 struct iid_bucket
*idb
;
187 struct HashTable
*iidtable
= GetOBase(OOPBase
)->ob_IIDTable
;
189 ObtainSemaphore(&OOPBase
->ob_IIDTableLock
);
190 /* Has ID allready been mapped to a numeric ID ? */
191 idb
= (struct iid_bucket
*)iidtable
->Lookup(iidtable
, (IPTR
)interface_id
, OOPBase
);
194 /* Reduce interface bucket's refcount */
197 /* Last ref released ? */
198 if (idb
->refcount
== 0)
200 /* Remove and free the bucket */
201 RemoveBucket(iidtable
, (struct Bucket
*)idb
);
202 FreeVec(idb
->interface_id
);
203 FreeMem(idb
, sizeof (struct iid_bucket
));
207 ReleaseSemaphore(&OOPBase
->ob_IIDTableLock
);
209 ReturnVoid ("ReleaseAttrBase");
212 /* Increase an idbucket's refcount, to lock it.
213 Calling this function MUST ONLY be used for IFs
214 that are known to exist in the IID table
216 VOID
obtain_idbucket(CONST_STRPTR interface_id
, struct IntOOPBase
*OOPBase
)
218 struct iid_bucket
*idb
;
219 struct HashTable
*iidtable
= GetOBase(OOPBase
)->ob_IIDTable
;
221 ObtainSemaphore(&OOPBase
->ob_IIDTableLock
);
222 /* Has ID allready been mapped to a numeric ID ? */
223 idb
= (struct iid_bucket
*)iidtable
->Lookup(iidtable
, (IPTR
)interface_id
, OOPBase
);
224 /* Reduce interface bucket's refcount */
226 ReleaseSemaphore(&OOPBase
->ob_IIDTableLock
);