2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <exec/memory.h>
12 #include <proto/utility.h>
13 #include <proto/oop.h>
23 #include <aros/debug.h>
25 #define OOPBase GetOBase(((OOP_Class *)cl)->UserData)
27 /* This class creates method objects. Method objects are objects
28 you can obtain for a single method of some object,
29 and lets you invoke that particular method on
30 that particular object almost as fast as
31 a function call. Nice if you do many invocations of a method on
32 the same object many times, and need it to be fast.
38 /* Every object has its class at ((VOID **)obj)[-1] */
42 /* The app gets a pointer to &(intmethod->PublicPart).
43 The public part is a readonly public struct.
53 #define IS_METHOD_ATTR(attr, idx) ((idx = attr - MethodAttrBase) < num_Method_Attrs)
57 static OOP_Object
*method_new(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
60 OOP_Object
*m_obj
= NULL
;
62 struct TagItem
*tag
, *tstate
;
70 EnterFunc(bug("Method::New()\n"));
73 /* Parse the createion-time attributes passed to the object */
74 tstate
= msg
->attrList
;
76 while ((tag
= NextTagItem(&tstate
)))
78 if (IS_METHOD_ATTR(tag
->ti_Tag
, idx
))
82 case aoMethod_TargetObject
:
83 /* The object from which we get the method */
84 m_obj
= (OOP_Object
*)tag
->ti_Data
;
88 case aoMethod_Message
:
89 /* The message to pass with the method */
90 m_msg
= (OOP_Msg
)tag
->ti_Data
;
93 case aoMethod_MethodID
:
94 /* The ID of the method to pass */
95 mid
= (ULONG
)tag
->ti_Data
;
104 /* User MUST supply methodID, message and target object to get a method object */
105 if ( !(mid
&& m_msg
&& m_obj
) )
106 ReturnPtr("Method::New", OOP_Object
*, NULL
);
108 /* Try to find methodfunc */
109 D(bug("trying to find method, oclass=%p, oclass(oclass)=%p\n",
110 OOP_OCLASS(m_obj
), OOP_OCLASS(OOP_OCLASS(m_obj
)) ));
111 D(bug("oclass(oclass)=%s\n", OOP_OCLASS(OOP_OCLASS(m_obj
))->ClassNode
.ln_Name
));
113 ifm
= meta_findmethod((OOP_Object
*)OOP_OCLASS(m_obj
), mid
, (struct Library
*)OOPBase
);
114 D(bug("found method: %p\n", ifm
));
116 /* If method isn't supported by target object, exit gracefully */
117 ReturnPtr("Method::New", OOP_Object
*, NULL
);
119 /* Allocate mem for the method object */
120 m
= AllocMem( sizeof (struct intmethod
), MEMF_ANY
);
123 D(bug("Method object allocated\n"));
125 /* Initialize message's method ID. (User convenience) */
128 /* Target object is stored for user convenience */
129 m
->public.targetObject
= m_obj
;
131 /* The message is stored for user convenience */
132 m
->public.message
= m_msg
;
134 /* Store method implemetation func and the class that will
135 receive the method call. (We skip unimplemented class calls)
137 m
->public.methodFunc
= ifm
->MethodFunc
;
138 m
->public.methodClass
= ifm
->mClass
;
140 /* Initialize OCLASS(methodobject) */
143 /* Return pointer to the public part */
144 ReturnPtr ("Method::New", OOP_Object
*, (OOP_Object
*)&(m
->public));
146 ReturnPtr ("Method::New", OOP_Object
*, NULL
);
150 /************************
151 ** Method::Dispose() **
152 ************************/
153 static VOID
method_dispose(OOP_Class
*cl
, OOP_Method
*m
, OOP_Msg msg
)
155 EnterFunc(bug("Method::Dispose()\n"));
157 /* Well, free the method object */
158 FreeMem(_OOP_OBJECT(m
), sizeof (struct intmethod
));
160 ReturnVoid("Method::Dispose");
163 /************************
164 ** Support functions **
165 ************************/
169 /* Self-explainatory */
170 OOP_Class
*init_methodclass(struct IntOOPBase
*OOPBase
)
173 struct OOP_MethodDescr methods
[] =
175 {(IPTR (*)())method_new
, moRoot_New
},
176 {(IPTR (*)())method_dispose
, moRoot_Dispose
},
180 struct OOP_InterfaceDescr ifdescr
[] =
182 { methods
, IID_Root
, 2},
186 struct TagItem tags
[] =
188 {aMeta_SuperID
, (IPTR
)NULL
},
189 {aMeta_InterfaceDescr
, (IPTR
)ifdescr
},
190 {aMeta_ID
, (IPTR
)CLID_Method
},
191 {aMeta_InstSize
, (IPTR
)sizeof (struct method_data
)},
198 EnterFunc(bug("init_methodclass()\n"));
200 cl
= (OOP_Class
*)OOP_NewObject(NULL
, CLID_MIMeta
, tags
);
203 D(bug("Method class successfully created\n"));
204 cl
->UserData
= OOPBase
;
208 ReturnPtr ("init_methodclass", OOP_Class
*, cl
);