2 Copyright © 1997-98, The AROS Development Team. All rights reserved.
5 Desc: Demo of new OOP system
10 #include "sysdep/hashed_ifs.h"
18 #define UB(x) ((UBYTE *)x)
20 #define ClassID ClassNode.ln_Name
22 VOID
FreeBucket(struct Bucket
*b
);
23 struct Bucket
*CopyBucket(struct Bucket
*old_b
, APTR data
);
26 static struct InterfaceBucket
*CreateBucket(struct InterfaceDescr
*ifDescr
);
32 static ULONG
CalcHTEntries(Class
*cl
, struct InterfaceDescr
*ifDescr
)
35 Class
*super
= cl
->SuperClass
;
37 EnterFunc(bug("CalcHTEntries(cl=%s, ifDescr=%p)\n", cl
->ClassID
, ifDescr
));
39 /* Count the number of interfaces of superclass */
43 num_if
= super
->NumInterfaces
;
45 /* Check if there are any new interfaces in this class */
46 for (; ifDescr
->MethodTable
; ifDescr
++)
48 if ( NULL
== HashLookupULONG((struct Bucket
**)super
->HashTable
, ifDescr
->InterfaceID
) )
53 } /* for (each interface in the description for the class) */
58 /* This is rootclass, count the interfaces */
59 for (; ifDescr
->MethodTable
; ifDescr
++)
63 } /* for (each interface in the description for the class) */
65 ReturnInt ("CalcHTEntries", ULONG
, num_if
);
70 /****************************
71 ** AllocDispatchTables() **
72 ****************************/
74 BOOL
AllocDispatchTables(Class
*cl
, struct InterfaceDescr
*ifDescr
)
78 EnterFunc(bug("AllocDispatchTables(cl=%s,ifDescr=%p)\n",
79 cl
->ClassID
, ifDescr
));
81 /* Get hash table size */
82 num_if
= CalcHTEntries(cl
, ifDescr
);
83 cl
->NumInterfaces
= num_if
;
85 cl
->HashTable
= (struct InterfaceBucket
**)NewHash(num_if
);
88 cl
->HashMask
= HashMask(cl
->HashTable
);
90 /* Copy parent interfaces into the new class */
91 if (cl
->SuperClass
) /* This test makes it work for initializong rootclass */
93 if (!CopyHash((struct Bucket
**)cl
->HashTable
94 ,(struct Bucket
**)cl
->SuperClass
->HashTable
102 /* Insert our own interfaces */
103 for (; ifDescr
->MethodTable
; ifDescr
++)
105 struct InterfaceBucket
*ifb
;
109 ifb
= (struct InterfaceBucket
*)HashLookupULONG((struct Bucket
**)cl
->HashTable
, ifDescr
->InterfaceID
);
111 /* Bucket doesn't exist, allocate it */
112 ifb
= CreateBucket(ifDescr
);
117 InsertBucket((struct Bucket
**)cl
->HashTable
, (struct Bucket
*)ifb
);
119 for (i
= 0; i
< ifb
->NumMethods
; i
++)
121 if (ifDescr
->MethodTable
[i
])
123 ifb
->MethodTable
[i
].MethodFunc
= ifDescr
->MethodTable
[i
];
124 ifb
->MethodTable
[i
].mClass
= cl
;
126 } /* for (each method in the interface) */
128 } /* for (each interface to add to class) */
130 ReturnBool ("AllocDispatchTables", TRUE
);
133 FreeHash((struct Bucket
**)cl
->HashTable
, FreeBucket
);
134 ReturnBool ("AllocDispatchTables", FALSE
);
137 /***************************
138 ** FreeDispatchTables() **
139 ***************************/
140 VOID
FreeDispatchTables(Class
*cl
)
142 FreeHash((struct Bucket
**)cl
->HashTable
, FreeBucket
);
148 /*********************
150 *********************/
151 static struct InterfaceBucket
*CreateBucket(struct InterfaceDescr
*ifDescr
)
153 struct IFMethod
*ifm
= NULL
;
154 ULONG numentries
= ifDescr
->NumMethods
;
155 ULONG mtab_size
= UB (&ifm
[numentries
]) - UB( &ifm
[0]);
157 /* Allocate bucket */
158 struct InterfaceBucket
*ifb
;
160 ifb
= (struct InterfaceBucket
*)malloc( sizeof (struct InterfaceBucket
) );
163 ifb
->MethodTable
= (struct IFMethod
*)malloc(mtab_size
);
164 if (ifb
->MethodTable
)
166 ifb
->InterfaceID
= ifDescr
->InterfaceID
;
167 ifb
->NumMethods
= ifDescr
->NumMethods
;
177 /***********************
178 ** Hash table hooks **
179 ***********************/
180 #define IB(x) ((struct InterfaceBucket *)x)
182 VOID
FreeBucket(struct Bucket
*b
)
184 // D(bug("FreeBucket(b=%p)\n", b));
185 free(IB(b
)->MethodTable
);
186 // D(bug("Freeing bucket\n"));
189 // ReturnVoid("FreeBucket");
193 struct Bucket
*CopyBucket(struct Bucket
*old_b
, APTR data
)
195 struct InterfaceBucket
*new_b
;
197 EnterFunc(bug("CopyBucket(old_b=%p)\n", old_b
));
199 new_b
= (struct InterfaceBucket
*)malloc(sizeof (struct InterfaceBucket
) );
202 struct IFMethod
*ifm
= NULL
;
204 ULONG numentries
= IB(old_b
)->NumMethods
;
206 mtab_size
= UB(&ifm
[numentries
]) - UB(&ifm
[0]);
208 new_b
->MethodTable
= (struct IFMethod
*)malloc(mtab_size
);
209 if (new_b
->MethodTable
)
211 /* Copy methodtable */
212 memcpy(new_b
->MethodTable
, IB(old_b
)->MethodTable
, mtab_size
);
214 /* Initialize bucket */
215 new_b
->InterfaceID
= IB(old_b
)->InterfaceID
;
216 new_b
->NumMethods
= IB(old_b
)->NumMethods
;
218 ReturnPtr ("CopyBucket", struct Bucket
*, (struct Bucket
*)new_b
);
223 ReturnPtr ("CopyBucket", struct Bucket
*, NULL
);