2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Class for interface objects.
9 #include <proto/exec.h>
10 #include <exec/memory.h>
11 #include <proto/utility.h>
12 #include <proto/oop.h>
23 #include <aros/debug.h>
25 #define OOPBase ((struct Library *)cl->UserData)
27 static IPTR
StdCallIF(OOP_Interface
*iface
, OOP_Msg msg
);
31 /* First part of the interface object's instance data is
32 public, and may be accesesd directly.
36 /* The pointer to the interface's methods should indeed not
39 struct IFMethod
*methodtable
;
43 struct interface_object
45 /* All objects has a pointer to their class at ((VOID **)o)[-1] */
48 /* When getting a interface ojject, you will get a pointer to
49 &(intifobject->Inst.PublicPart)
51 struct interface_data data
;
55 /***********************
56 ** Interface::New() **
57 ***********************/
58 static OOP_Object
*interface_new(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
63 struct IFMethod
*if_mtab
;
65 struct interface_object
*ifo
;
67 /* Parse parameters */
69 /* What target object does the user want an interface object for ? */
70 if_obj
= (OOP_Object
*)GetTagData(aInterface_TargetObject
, NULL
, msg
->attrList
);
72 /* What interface does he want from the object ? */
73 if_id
= (STRPTR
)GetTagData(aInterface_InterfaceID
, NULL
, msg
->attrList
);
75 EnterFunc(bug("Interface::New(if_obj=%p, if_id=%s)\n", if_obj
, if_id
));
77 /* We MUST have those two parameters, to be able to
78 create an interface object */
79 if ( !(if_obj
&& if_id
) )
80 ReturnPtr("Interface::New", Object
*, NULL
);
83 D(bug("Trying to find interface: %s\n", if_id
));
85 /* Try to find interface in the target object's class*/
86 if_mtab
= findinterface(OOP_OCLASS(if_obj
), if_id
);
89 /* Not supported. Failed. */
90 ReturnPtr("Interface::New", OOP_Object
*, NULL
);
92 D(bug("mtab found: %p\n", if_mtab
));
94 /* Allocate mem for the interface object */
95 ifo
= AllocMem( sizeof (struct interface_object
), MEMF_ANY
);
99 D(bug("obj alloced\n"));
101 /* The interface object remebers it's target object.
102 Convenience for the user + he can store interface
103 objects instead of a pointer to the object itself.
104 (He doesn't have to store both)
107 ifo
->data
.public.targetObject
= if_obj
;
110 /* Function for calling a method on an interface obect.
111 Just use a standard one, but we could add support
112 for letting the user override the function with his own.
114 ifo
->data
.public.callMethod
= StdCallIF
;
116 /* The interface object must have some methods to call :-) */
117 ifo
->data
.methodtable
= if_mtab
;
119 /* Initialize OCLASS(interfaceobject) */
122 ReturnPtr ("Interface::New", OOP_Object
*, (OOP_Object
*)&(ifo
->data
.public));
124 ReturnPtr ("Interface::New", OOP_Object
*, NULL
);
131 static VOID
interface_dispose(OOP_Class
*cl
, OOP_Interface
*ifobj
, OOP_Msg msg
)
133 EnterFunc(bug("Interface::Dispose()\n"));
135 /* Just free the thing */
136 FreeMem(_OOP_OBJECT(ifobj
), sizeof (struct interface_object
));
138 ReturnVoid("Interface::Dispose");
142 /************************
143 ** Support functions **
144 ************************/
147 /* Default way to call a interface objects' method.
148 (Inserted into the Interface struct's CallIF() field
150 static IPTR
StdCallIF(OOP_Interface
*iface
, OOP_Msg msg
)
152 /* Mask off the method offset */
153 register ULONG midx
= msg
->MID
& METHOD_MASK
;
155 register struct IFMethod
*method
;
157 /* Get the correct method from the correct offset */
158 method
= &( ((struct interface_data
*)iface
)->methodtable
[midx
] );
160 /* ... and call the method on the interface object's target object */
161 return ( method
->MethodFunc(method
->mClass
, iface
->targetObject
, msg
) );
167 /* Well, initalize the interface class. Self explainatory */
168 OOP_Class
*init_interfaceclass(struct Library
*OOPBase
)
171 struct OOP_MethodDescr methods
[] =
173 {(IPTR (*)())interface_new
, moRoot_New
},
174 {(IPTR (*)())interface_dispose
, moRoot_Dispose
},
178 struct OOP_InterfaceDescr ifdescr
[] =
180 { methods
, IID_Root
, 2},
184 struct TagItem tags
[] =
186 {aMeta_SuperID
, (IPTR
)NULL
},
187 {aMeta_InterfaceDescr
, (IPTR
)ifdescr
},
188 {aMeta_ID
, (IPTR
)CLID_Interface
},
189 {aMeta_InstSize
, (IPTR
)sizeof (struct interface_data
)},
196 EnterFunc(bug("init_interfaceclass()\n"));
198 cl
= (OOP_Class
*)OOP_NewObject(NULL
, CLID_MIMeta
, tags
);
201 cl
->UserData
= OOPBase
;
205 ReturnPtr ("init_interfaceclass", OOP_Class
*, cl
);