muimaster.library: it is possible to set NULL as entries. Make the code robust to...
[AROS.git] / rom / oop / rootclass.c
blob9689c4552744b532ba44fe7e0f1325515d5908a5
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: OOP rootclass
6 Lang: english
7 */
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>
14 #include <oop/oop.h>
15 #include <string.h>
17 #include "intern.h"
18 #include "private.h"
19 #include "basemetaclass.h"
21 #undef SDEBUG
22 #undef DEBUG
23 #define SDEBUG 0
24 #define DEBUG 0
25 #include <aros/debug.h>
27 /*****************************************************************************************
29 NAME
30 --background_root--
32 LOCATION
33 Root
35 NOTES
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 /*****************************************************************************************
43 NAME
44 moRoot_New
46 SYNOPSIS
47 See OOP_NewObject() doc.
49 FUNCTION
50 Creates a new object of some class. Class users should use OOP_NewObject() to
51 create an object.
53 *****************************************************************************************/
55 /*****************************************************************************************
57 NAME
58 moRoot_Dispose
60 SYNOPSIS
61 See OOP_DisposeObject() doc.
63 FUNCTION
64 Used internally to dispose of an object previously
65 created using the moRoot_New method.
67 *****************************************************************************************/
69 /*****************************************************************************************
71 NAME
72 moRoot_Set
74 SYNOPSIS
75 OOP_SetAttrs() (OOP_Object *object, struct TagItem *attrs);
77 FUNCTION
78 Set an attribute of an object.
80 *****************************************************************************************/
82 /*****************************************************************************************
84 NAME
85 moRoot_Get
87 SYNOPSIS
88 OOP_GetAttr(OOP_Object *object, ULONG attrID, IPTR *storage);
90 FUNCTION
91 Get the value for an object attribute.
92 The attribute value will be stored in *storage.
94 EXAMPLE
96 ULONG num_members;
98 OOP_GetAttr(list, aList_NumMembers, &num_members);
100 *****************************************************************************************/
102 /************************
103 ** Rootclass methods **
104 ************************/
106 /************
107 ** New() **
108 ************/
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);
119 if (o)
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);
133 /****************
134 ** Dispose() **
135 ****************/
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)
151 *msg->storage = 0UL;
152 D(bug("!!! Get() METHOD REACHED ROOTCLASS !!!\n"));
153 return;
156 /**********************
157 ** init_rootclass() **
158 **********************/
159 BOOL init_rootclass(struct IntOOPBase *OOPBase)
162 struct rootclassobject *rco;
163 OOP_Class *rootclass;
165 BOOL success;
166 ULONG mbase = 0UL;
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);
211 if (success)
213 /* Make it public */
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)
236 register Class *cl;
237 cl = OCLASS(o);
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);