2 ** Amiga Workbench® Replacement
4 ** (C) Copyright 1999,2000 Aliendesign
5 ** Stefan Sommerfeld, Jörg Rebenstorf
7 ** Redistribution and use in source and binary forms are permitted provided that
8 ** the above copyright notice and this paragraph are duplicated in all such
9 ** forms and that any documentation, advertising materials, and other
10 ** materials related to such distribution and use acknowledge that the
11 ** software was developed by Aliendesign.
12 ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
13 ** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
14 ** MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 #include <proto/alib.h>
18 #include <proto/exec.h>
19 #include <proto/powerpc.h>
20 #include <proto/utility.h>
21 #include <intuition/classusr.h>
22 #include <exec/ports.h>
25 #include "ScalosIntern.h"
26 #include "MethodSenderClass.h"
27 #include "SubRoutines.h"
28 #include "scalos_protos.h"
29 #include "CompilerSupport.h"
30 #include "ThreadRootClass.h"
32 /****** MethodSender.scalos/--background ************************************
34 * MethodSender class is used to send methods to objects that run on a
37 *****************************************************************************
40 ULONG
PutMethod(struct MethodSenderInst
*inst
, Msg msg
, struct MsgPort
*replyport
)
44 struct SCMSGP_Method
*smsg
;
45 struct SC_MethodData
*mdata
;
46 struct SC_Class
*curcl
= SCOCLASS(inst
->destobject
);
47 struct SC_MethodData
*usemdata
= NULL
;
51 if ((mdata
= (struct SC_MethodData
*) curcl
->Methods
))
53 while (mdata
->MethodID
!= SCMETHOD_DONE
)
55 if ((mdata
->MethodID
== msg
->MethodID
) && mdata
->Size
)
64 while ( inst
->destobject
&& !(usemdata
) && (curcl
= curcl
->Super
));
66 if (usemdata
&& !(usemdata
->Flags
& SCMDF_DIRECTMETHOD
))
68 if ((smsg
= (struct SCMSGP_Method
*) SC_AllocMsg(SCMSG_METHOD
,sizeof(struct SCMSGP_Method
) + usemdata
->Size
)))
70 smsg
->scmsg
.execmsg
.mn_ReplyPort
= replyport
;
71 smsg
->methoddata
= usemdata
;
72 CopyMem(msg
,&smsg
->methodarg1
, usemdata
->Size
);
73 PutMsg(myThreadRootInst(inst
->destobject
)->msgport
, (struct Message
*) smsg
);
81 static ULONG
SendMethod(struct MethodSenderInst
*inst
, Msg msg
)
87 struct SCMSGP_Method
*smsg
;
88 struct SC_MethodData
*mdata
;
89 struct SC_Class
*curcl
= SCOCLASS(inst
->destobject
);
90 struct SC_MethodData
*usemdata
= NULL
;
91 struct MsgPort
*replyport
;
95 if ((mdata
= (struct SC_MethodData
*) curcl
->Methods
))
97 while (mdata
->MethodID
!= SCMETHOD_DONE
)
99 if ((mdata
->MethodID
== msg
->MethodID
) && mdata
->Size
)
108 while (!(usemdata
) && (curcl
= curcl
->Super
));
110 if ((usemdata
) && (usemdata
->Flags
& SCMDF_DIRECTMETHOD
))
111 return(SC_DoMethodA(inst
->destobject
,msg
));
113 if (usemdata
&& (replyport
= CreateMsgPort()))
115 if ((smsg
= (struct SCMSGP_Method
*) SC_AllocMsg(SCMSG_METHOD
,sizeof(struct SCMSGP_Method
) + usemdata
->Size
)))
117 smsg
->scmsg
.execmsg
.mn_ReplyPort
= replyport
;
118 smsg
->methoddata
= usemdata
;
119 CopyMem(msg
,&smsg
->methodarg1
, usemdata
->Size
);
120 PutMsg(myThreadRootInst(inst
->destobject
)->msgport
, (struct Message
*) smsg
);
121 while (!GetMsg(replyport
))
123 ret
= smsg
->scmsg
.returnvalue
;
124 SC_FreeMsg((struct SC_Message
*) smsg
);
126 DeleteMsgPort(replyport
);
133 SAVEDS ASM ULONG
MethodSenderDispatcher( REG(a0
) struct SC_Class
*cl
, REG(a1
) Msg msg
, REG(a2
) Object
*obj
)
135 struct MethodSenderInst
*inst
= SCINST_DATA(cl
,obj
);
137 switch (msg
->MethodID
)
140 if ((obj
= (Object
*) SC_DoSuperMethodA(cl
,obj
, msg
)))
142 inst
= SCINST_DATA(cl
,obj
);
143 inst
->senderid
= SCALOS_SENDERID
;
144 inst
->destobject
= (Object
*) GetTagData(SCCA_MethodSender_DestObject
,0,((struct opSet
*) msg
)->ops_AttrList
);
150 SendMethod(inst
,msg
);
153 return(SC_DoSuperMethodA(cl
, obj
, msg
));
156 if (((struct opGet
*) msg
)->opg_AttrID
== SCCA_MethodSender_DestObject
)
158 *(((struct opGet
*) msg
)->opg_Storage
) = (ULONG
) inst
->destobject
;
162 return(SendMethod(inst
,msg
));
165 inst
->destobject
= (Object
*) GetTagData(SCCA_MethodSender_DestObject
,(ULONG
) inst
->destobject
,((struct opSet
*) msg
)->ops_AttrList
);
167 return(SendMethod(inst
,msg
));