2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <proto/oop.h>
11 #include <proto/utility.h>
12 #include <aros/atomic.h>
13 #include <exec/memory.h>
19 #include "basemetaclass.h"
25 #include <aros/debug.h>
27 /*****************************************************************************************
36 Root class is the base class of all classes.
37 One can create new baseclasses, but all classes must implement the root interface.
39 *****************************************************************************************/
41 /*****************************************************************************************
47 See OOP_NewObject() doc.
50 Creates a new object of some class. Class users should use OOP_NewObject() to
53 *****************************************************************************************/
55 /*****************************************************************************************
61 See OOP_DisposeObject() doc.
64 Used internally to dispose of an object previously
65 created using the moRoot_New method.
67 *****************************************************************************************/
69 /*****************************************************************************************
75 OOP_SetAttrs() (OOP_Object *object, struct TagItem *attrs);
78 Set an attribute of an object.
80 *****************************************************************************************/
82 /*****************************************************************************************
88 OOP_GetAttr(OOP_Object *object, ULONG attrID, IPTR *storage);
91 Get the value for an object attribute.
92 The attribute value will be stored in *storage.
98 OOP_GetAttr(list, aList_NumMembers, &num_members);
100 *****************************************************************************************/
102 /************************
103 ** Rootclass methods **
104 ************************/
109 OOP_Object
*root_new(OOP_Class
*root_cl
, OOP_Class
*cl
, struct pRoot_New
*param
)
111 struct _OOP_Object
*o
;
113 EnterFunc(bug("Root::New(cl=%s, param = %p)\n",
114 cl
->ClassNode
.ln_Name
, param
));
116 /* Allocate memory for the object */
117 D(bug("Object size: %ld\n", MD(cl
)->public.InstOffset
+ MD(cl
)->instsize
+ sizeof (struct _OOP_Object
)));
118 o
= AllocVec(MD(cl
)->public.InstOffset
+ MD(cl
)->instsize
+ sizeof (struct _OOP_Object
), MEMF_ANY
|MEMF_CLEAR
);
121 D(bug("Mem allocated: %p\n", o
));
122 o
->o_Class
= (OOP_Class
*)cl
;
124 /* Class has one more object */
125 AROS_ATOMIC_INC(MD(cl
)->objectcount
);
127 ReturnPtr ("Root::New", OOP_Object
*, OOP_BASEOBJECT(o
) );
130 ReturnPtr ("Root::New", OOP_Object
*, NULL
);
136 static VOID
root_dispose(OOP_Class
*root_cl
, OOP_Object
*o
, OOP_Msg msg
)
138 EnterFunc(bug("Root::Dispose(o=%p, oclass=%s)\n", o
, _OOP_OBJECT(o
)->o_Class
->ClassNode
.ln_Name
));
140 AROS_ATOMIC_DEC(MD(OOP_OCLASS(o
))->objectcount
);
141 D(bug("Object mem: %p, size: %ld\n", _OOP_OBJECT(o
), ((ULONG
*)_OOP_OBJECT(o
))[-1] ));
143 /* Free object's memory */
144 FreeVec(_OOP_OBJECT(o
));
146 ReturnVoid("Root::Dispose");
149 static VOID
root_get(OOP_Class
*root_cl
, OOP_Object
*p
, struct pRoot_Get
*msg
)
152 D(bug("!!! Get() METHOD REACHED ROOTCLASS !!!\n"));
156 /**********************
157 ** init_rootclass() **
158 **********************/
159 BOOL
init_rootclass(struct IntOOPBase
*OOPBase
)
162 struct rootclassobject
*rco
;
163 OOP_Class
*rootclass
;
168 EnterFunc(bug("init_rootclass()\n"));
170 rco
= &(OOPBase
->ob_RootClassObject
);
171 rootclass
= &(rco
->inst
.data
.public);
173 /* Its class is the metaobject */
174 rco
->oclass
= &(OOPBase
->ob_BaseMetaObject
.inst
.data
.public);
176 rco
->inst
.data
.public.ClassNode
.ln_Name
= CLID_Root
;
177 rco
->inst
.data
.public.OOPBasePtr
= OOPBase
;
178 rco
->inst
.data
.public.InstOffset
= 0;
179 rco
->inst
.data
.public.UserData
= (APTR
)OOPBase
;
181 rco
->inst
.data
.public.cl_DoSuperMethod
= basemeta_dosupermethod
;
182 rco
->inst
.data
.public.cl_CoerceMethod
= basemeta_coercemethod
;
183 rco
->inst
.data
.public.cl_DoMethod
= basemeta_domethod
;
185 D(bug("Root stuff: dosupermethod %p, coeremethod %p, domethod %p\n",
186 basemeta_dosupermethod
, basemeta_coercemethod
, basemeta_domethod
));
188 rco
->inst
.data
.public.superclass
= NULL
;
189 rco
->inst
.data
.subclasscount
= 0UL;
190 rco
->inst
.data
.objectcount
= 0UL;
191 rco
->inst
.data
.instsize
= 0UL;
192 rco
->inst
.data
.numinterfaces
= 1UL;
194 /* Initialize methodtable */
196 rco
->inst
.rootif
[moRoot_New
].MethodFunc
= (IPTR (*)())root_new
;
197 rco
->inst
.rootif
[moRoot_New
].mClass
= rootclass
;
199 rco
->inst
.rootif
[moRoot_Dispose
].MethodFunc
= (IPTR (*)())root_dispose
;
200 rco
->inst
.rootif
[moRoot_Dispose
].mClass
= rootclass
;
202 rco
->inst
.rootif
[moRoot_Get
].MethodFunc
= (IPTR (*)())root_get
;
203 rco
->inst
.rootif
[moRoot_Get
].mClass
= rootclass
;
205 /* Important: IID_Root interface ID MUST be the first one
206 initialized, so that it gets the value 0UL. This is
207 because it's used as rootclass both for IFMeta and HIDDMeta classes
210 success
= init_mi_methodbase(IID_Root
, &mbase
, OOPBase
);
214 OOP_AddClass(rootclass
);
217 ReturnBool ("init_rootclass", success
);
220 /* Below is rootclass DoMethod and CoerceMethod. They are hardly useful,
221 cause you would never create an object of rootclass
225 #define ROOT_CALLMETHOD(cl, o, m) \
227 register struct IFMethod *ifm; \
228 ifm = &(RI(cl)->rootif[msg->MethodID]); \
229 return ifm->MethodFunc(ifm->mClass, o, msg); \
232 #define RI(cl) ((struct rootinst *)cl)
234 static IPTR root_domethod(OOP_Object *o, OOP_Msg msg)
239 ROOT_CALLMETHOD(cl, o, msg);
242 static IPTR root_coercemethod(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
244 ROOT_CALLMETHOD(cl, o, msg);