Re-introduced the fix which should make it possible to
[AROS-Contrib.git] / ScalosV2 / MethodSenderClass.c
blobd52be065e2646fe9e017b7df1fb628119e7b51dd
1 /*
2 ** Amiga Workbench® Replacement
3 **
4 ** (C) Copyright 1999,2000 Aliendesign
5 ** Stefan Sommerfeld, Jörg Rebenstorf
6 **
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>
24 #include "Scalos.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
35 * different thread.
37 *****************************************************************************
40 ULONG PutMethod(struct MethodSenderInst *inst, Msg msg, struct MsgPort *replyport)
42 if (inst->destobject)
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)
57 usemdata = mdata;
58 break;
60 mdata++;
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);
74 return(TRUE);
78 return(FALSE);
81 static ULONG SendMethod(struct MethodSenderInst *inst, Msg msg)
83 ULONG ret = 0;
85 if (inst->destobject)
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)
101 usemdata = mdata;
102 break;
104 mdata++;
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))
122 WaitPort(replyport);
123 ret = smsg->scmsg.returnvalue;
124 SC_FreeMsg((struct SC_Message *) smsg);
126 DeleteMsgPort(replyport);
129 return(ret);
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)
139 case OM_NEW :
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);
145 return((ULONG) obj);
147 return(NULL);
149 case OM_DISPOSE :
150 SendMethod(inst,msg);
151 case SCCM_Init :
152 case SCCM_Exit :
153 return(SC_DoSuperMethodA(cl, obj, msg));
155 case OM_GET :
156 if (((struct opGet *) msg)->opg_AttrID == SCCA_MethodSender_DestObject)
158 *(((struct opGet *) msg)->opg_Storage) = (ULONG) inst->destobject;
159 return(TRUE);
161 else
162 return(SendMethod(inst,msg));
164 case OM_SET :
165 inst->destobject = (Object *) GetTagData(SCCA_MethodSender_DestObject,(ULONG) inst->destobject,((struct opSet *) msg)->ops_AttrList);
166 default :
167 return(SendMethod(inst,msg));