2 Copyright © 1997-98, The AROS Development Team. All rights reserved.
5 Desc: Demo of new OOP system
22 /**************************************************/
25 Class
*MakeClass(STRPTR classID
, STRPTR superID
, struct InterfaceDescr
*ifDescr
,
27 VOID
FreeClass(Class
* cl
);
29 /* could go into a library base */
30 // struct SignalSemaphore ClassListSema;
32 struct OOPBase oopbasemem
;
33 struct OOPBase
*oopbase
= &oopbasemem
;
35 /******************************************************************/
37 /* The oop system code */
39 BOOL
AllocDispatchTables(Class
*cl
, struct InterfaceDescr
*iDescr
);
40 VOID
FreeDispatchTables(Class
*cl
);
45 Class
*MakeClass(STRPTR classID
, STRPTR superID
, struct InterfaceDescr
*cl_Descr
,
48 #define UB(x) ((UBYTE *)x)
50 #define UnlockCL ReleaseSemaphore( &ClassListSema )
51 #define LockCLShared ObtainSemaphoreShared( &ClassListSema )
52 #define LockCL ObtainSemaphore( &ClassListSema )
54 #define ClassID ClassNode.ln_Name
59 EnterFunc(bug("MakeClass(classID=%s, superID=%s, ifDescr=%p, instDataSize=%ld)\n",
60 classID
, superID
, cl_Descr
, instDataSize
));
63 supercl
= (Class
*)FindName( &(oopbase
->ClassList
), superID
);
66 /* Mark the class as busy, so it isn't freed while we are allocating
67 ** stuff for our class
69 supercl
->SubClassCount
++;
76 D(bug("Found superclass %s\n", supercl
->ClassID
));
78 /* Allocate class structure */
79 D(bug("Allocating class of size %d\n", sizeof (Class
) ));
80 cl
= malloc(sizeof (Class
));
84 D(bug("Allocated class structure\n"));
86 cl
->ClassID
= malloc( strlen(classID
) + 1);
89 D(bug("Allocated class id\n"));
90 strcpy(cl
->ClassID
, classID
);
93 /* Must do this before calling AllocDispatchTables(), so that
94 ** it knows from where to copy dispatch tables.
96 cl
->SuperClass
= supercl
;
97 if (AllocDispatchTables(cl
, cl_Descr
))
100 /* Update instance data info */
101 cl
->InstOffset
= supercl
->InstOffset
+ supercl
->InstSize
;
102 cl
->InstSize
= instDataSize
;
104 ReturnPtr("MakeClass", Class
*, cl
);
116 /* Initalization failed, free lock on superclass */
117 supercl
->SubClassCount
--;
119 ReturnPtr ("MakeClass", Class
*, NULL
);
129 VOID
FreeClass(Class
*cl
)
132 EnterFunc(bug("FreeClass(classID=%s)\n", cl
->ClassID
));
137 /* What level are we ? */
138 if (cl
->SuperClass
== NULL
) /* Someone trying to remove the rootclass */
139 ReturnVoid("FreeClass (Someone trying to remove rootclass)");
141 FreeDispatchTables(cl
);
144 D(bug("Freeing class ID %s\n", cl
->ClassID
));
147 ReturnVoid("FreeClass");
150 /************************
151 ** Rootclass methods **
152 ************************/
158 #define NUMROOTMETHODS 2
160 Object
*_Root_New(Class
*root_cl
, Class
*cl
, APTR param
)
163 struct RootData
*data
;
165 EnterFunc(bug("Root::New(cl=%s, param = %p)\n",
166 cl
->ClassNode
.ln_Name
, param
));
168 /* Allocate memory for the object */
169 D(bug("Object size: %ld\n", cl
->InstOffset
+ cl
->InstSize
+ sizeof (struct _Object
)));
170 o
= malloc(cl
->InstOffset
+ cl
->InstSize
+ sizeof (struct _Object
));
173 D(bug("Mem allocated: %p\n", o
));
176 data
= (struct RootData
*)BASEOBJECT(o
);
180 ReturnPtr ("Root::New", Object
*, BASEOBJECT(o
) );
183 ReturnPtr ("Root::New", Object
*, NULL
);
186 VOID
_Root_Dispose(Class
*cl
, Object
*o
, Msg msg
)
188 EnterFunc(bug("Root::Dispose(o=%p, oclass=%s)\n", o
, _OBJECT(o
)->o_Class
->ClassNode
.ln_Name
));
190 _OBJECT(o
)->o_Class
->ObjectCount
--;
191 D(bug("Object mem: %p, size: %ld\n", _OBJECT(o
), ((ULONG
*)_OBJECT(o
))[-1] ));
194 ReturnVoid("Root::Dispose");
206 struct MethodDescr mdescr
[]=
208 { (IPTR (*)())_Root_New
, M_New
},
209 { (IPTR (*)())_Root_Dispose
, M_Dispose
}
212 struct InterfaceDescr _Root_Descr
[] =
219 #if (HASHED_IFS || HASHED_METHODS)
220 IPTR (*_Root_MTab
[])() =
222 (IPTR (*)())_Root_New
,
223 (IPTR (*)())_Root_Dispose
226 struct InterfaceDescr _Root_Descr
[] =
228 {_Root_MTab
, I_Root
, 2},
233 Class
*RootClass
= &RootClassMem
;
235 InitSemaphore(&ClassListSema
);
236 NEWLIST(&(oopbase
->ClassList
));
238 EnterFunc(bug("InitOOP()\n"));
240 /* Initialize rootclass */
241 RootClass
->SuperClass
= NULL
;
242 if (AllocDispatchTables(RootClass
, _Root_Descr
))
244 RootClass
->ClassID
= ROOTCLASS
;
245 RootClass
->InstOffset
= 0UL;
246 RootClass
->InstSize
= 0UL;
247 RootClass
->SubClassCount
= 0UL;
248 RootClass
->ObjectCount
= 0UL;
251 RootClass
->NumInterfaces
= 1UL;
256 ReturnBool ("InitOOP", TRUE
);
261 ReturnBool ("InitOOP", FALSE
);
270 Class
*RootClass
= &RootClassMem
;
272 EnterFunc(bug("CleanupOOP()\n"));
274 FreeDispatchTables(RootClass
);
276 ReturnVoid("CleanupOOP");
283 Object
*NewObject(Class
*cl
, STRPTR classID
, Msg msg
)
292 cl
= (Class
*)FindName(&(oopbase
->ClassList
), classID
);
294 cl
->ObjectCount
++; /* We don't want the class to be freed while we work on it */
301 /* Create a new instance */
303 p
.MethodID
= (IPTR
)M_New
;
306 o
= (Object
*)CoerceMethodA(cl
, (Object
*)cl
, (Msg
)&p
);
309 cl
->ObjectCount
--; /* Object creation failed, release lock */
314 VOID
DisposeObject(Object
*o
)
316 IPTR methodid
= (IPTR
)M_Dispose
;
319 Class
*cl
= OCLASS(o
);
321 DoMethodA(o
, (Msg
)&methodid
);
331 VOID
AddClass(Class
*cl
)
335 AddTail(&(oopbase
->ClassList
), &(cl
->ClassNode
) );
343 VOID
RemoveClass(Class
*cl
)
346 Remove(&(cl
->ClassNode
) );