home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 5
/
amigaformatcd05.iso
/
mui
/
developer
/
oberon
/
txt
/
rootclass.mod
< prev
next >
Wrap
Text File
|
1996-08-13
|
8KB
|
277 lines
(*(***********************************************************************
:Program. RootClass.mod
:Contents. Oberon-like interface to BOOPSI's rootclass
:Author. hartmut Goebel [hG]
:Address. Aufseßplatz 5, D-8500 Nürnberg 40
:Address. UseNet: hartmut@oberon.nbg.sub.org
:Address. Z-Netz: hartmut@asn.zer Fido: 2:246/81.1
:Copyright. Copyright © 1993 by hartmut Goebel
:Language. Oberon-2
:Translator. Amiga Oberon 3.0
:Imports. need Interfaces 40.15+
:Version. $VER: RootClass.mod 36.2 (10.9.93) Copyright © 1993 by hartmut Goebel
(****i* RootClass/--history-- ***************************************
*
* ATTENTION:
* This modules is really implementation dependand! It will not work
* with any compiler but Amiga Oberon. It does a lot of assumptions
* on how records are represented and how type information (and
* Garbage-Collector) information is stored!
*
*
* V36.2 compiles with AmigaOberon 3.0, too (removed call of SYSTEM.MOVE(),
* which is only available in 3.01+)
* V36.1 oberon object is now created before the boopsi object and
* copied into the boopsi obj's instance data when New() has
* been successfull
* V36.0 initial version
*
*********************************************************************)*)*)
MODULE RootClass;
(* $StackChk- $NilChk- $RangeChk- $CaseChk- $OvflChk- $ReturnChk- $ClearVars- *)
IMPORT
BT:= BasicTypes,
cf:= Classface,
I := Intuition,
e := Exec,
u := Utility,
y := SYSTEM;
CONST
versionString = "$VER: RootClass 36.2 (10.9.93) Copyright © 1993 by hartmut Goebel";
emptySize = 4;
TYPE
Root = UNTRACED POINTER TO RootClass;
RootClass * = RECORD (BT.ANYDesc);
object -: I.ObjectPtr; (* boopsi object *)
class -: I.IClassPtr; (* boopsi class *)
userData *: e.APTR;
END;
DispatcherPROC * = PROCEDURE (cl: I.IClassPtr; obj: I.ObjectPtr; msg: I.MsgPtr): e.APTR;
(*
** one oberon method for each boopsi message
*)
PROCEDURE (VAR r: RootClass) New * (VAR msg: I.OpSet): e.APTR;
BEGIN
msg.msg.methodID := I.new;
r.object := cf.DoSuperMethodA(r.class,r.object,msg); (* boopsi object *)
RETURN r.object;
END New;
PROCEDURE (VAR r: RootClass) Dispose * (VAR msg: I.Msg): e.APTR;
BEGIN
msg.methodID := I.dispose;
RETURN cf.DoSuperMethodA(r.class,r.object,msg);
END Dispose;
PROCEDURE (VAR r: RootClass) AddTail * (VAR msg: I.OpAddTail): e.APTR;
BEGIN
msg.msg.methodID := I.addTail;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END AddTail;
PROCEDURE (VAR r: RootClass) Remove * (VAR msg: I.Msg): e.APTR;
BEGIN
msg.methodID := I.remove;
RETURN cf.DoSuperMethodA(r.class,r.object,msg);
END Remove;
PROCEDURE (VAR r: RootClass) AddMember * (VAR msg: I.OpMember): e.APTR;
BEGIN
msg.msg.methodID := I.addMember;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END AddMember;
PROCEDURE (VAR r: RootClass) RemMember * (VAR msg: I.OpMember): e.APTR;
BEGIN
msg.msg.methodID := I.remMember;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END RemMember;
PROCEDURE (VAR r: RootClass) Get * (VAR msg: I.OpGet): e.APTR;
BEGIN
msg.msg.methodID := I.get;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END Get;
PROCEDURE (VAR r: RootClass) Set * (VAR msg: I.OpSet): e.APTR;
BEGIN
msg.msg.methodID := I.set;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END Set;
PROCEDURE (VAR r: RootClass) Update * (VAR msg: I.OpUpdate): e.APTR;
BEGIN
msg.msg.methodID := I.update;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END Update;
PROCEDURE (VAR r: RootClass) Notify * (VAR msg: I.OpUpdate): e.APTR;
BEGIN
msg.msg.methodID := I.notify;
RETURN cf.DoSuperMethodA(r.class,r.object, msg);
END Notify;
PROCEDURE BoopsiToObj * {"Classface.InstData"} (cl{8}: I.IClassPtr;
obj{9}: I.ObjectPtr): Root;
PROCEDURE SetTypeDesc (r{8}: Root; cl{9}: I.IClassPtr);
TYPE
ANY = UNTRACED POINTER TO STRUCT
td: y.ADDRESS;
(* data: LONGINT; *)
END;
VAR
a: ANY;
BEGIN
a := y.VAL(ANY,r);
a.td := cl.userData;
END SetTypeDesc;
(*
** dispatcher for rootclass
** handles all yet (V36) defined rootclass messages and dispatches to
** the apropriate oberon method
*)
PROCEDURE Dispatch * (cl: I.IClassPtr; obj: I.ObjectPtr; msg: I.MsgPtr): e.APTR;
VAR
r: Root;
BEGIN
IF msg.methodID = I.new THEN
r := e.AllocMem(cl.instSize,LONGSET{e.memClear}); (* make oberon object *)
IF r # NIL THEN
SetTypeDesc(r,cl);
r.object := obj; (* here: objects real class *)
r.class := cl;
obj := r.New(msg^(I.OpSet)); (* init, object is now boopsi obj *)
IF obj # NIL THEN
e.CopyMemAPTR(r,cf.InstData(cl,obj),cl.instSize); (* copy into boopsi obj *)
(* y.MOVE(r,cf.InstData(cl,obj),cl.instSize); (* copy into boopsi obj *) *)
END;
e.FreeMem(r,cl.instSize);
RETURN obj;
END;
RETURN NIL;
(* old code, just to store it :-)
obj := cf.DoSuperMethodA(cl,obj,msg^); IF obj # NIL THEN
r := BoopsiToObj(cl,obj); SetTypeDesc(r,cl); r.object := obj;
r.class := cl; RETURN r.New(msg^(I.OpSet)); END; RETURN obj;
*)
ELSE
r := BoopsiToObj(cl,obj);
CASE msg.methodID OF
|I.dispose:
RETURN r.Dispose(msg^);
|I.set:
RETURN r.Set(msg^(I.OpSet));
|I.get:
RETURN r.Get(msg^(I.OpGet));
|I.addTail:
RETURN r.AddTail(msg^(I.OpAddTail));
|I.remove:
RETURN r.Remove(msg^);
|I.notify:
RETURN r.Notify(msg^(I.OpUpdate));
|I.update:
RETURN r.Update(msg^(I.OpUpdate));
|I.addMember:
RETURN r.AddMember(msg^(I.OpMember));
|I.remMember:
RETURN r.RemMember(msg^(I.OpMember));
ELSE
RETURN cf.DoSuperMethodA(cl,obj,msg^); (* for future methods *)
END;
END;
END Dispatch;
(* ---------------------------------------------------------------- *)
PROCEDURE GetUserDataANY * (VAR r: RootClass): BT.ANY;
BEGIN RETURN y.VAL(BT.ANY,r.userData); END GetUserDataANY;
(* ---------------------------------------------------------------- *)
PROCEDURE InitClass(cl{8}: I.IClassPtr;
dispatcher{9}: DispatcherPROC;
typeDesc{0}: y.ADDRESS);
BEGIN
IF cl # NIL THEN
cl.userData := typeDesc;
u.InitHook(cl,y.VAL(u.HookFunc,dispatcher));
END;
END InitClass;
PROCEDURE InitPrivFromName * (superClass: ARRAY OF CHAR; (* $CopyArrays- *)
dispatcher: DispatcherPROC;
size: INTEGER;
typeDesc: y.ADDRESS): I.IClassPtr;
VAR
cl: I.IClassPtr;
BEGIN
cl := I.MakeClass(NIL,superClass,NIL,size+emptySize,LONGSET{});
InitClass(cl,dispatcher,typeDesc);
RETURN cl;
END InitPrivFromName;
PROCEDURE InitPrivFromClass * (superClass: I.IClassPtr;
dispatcher: DispatcherPROC;
size: INTEGER;
typeDesc: y.ADDRESS): I.IClassPtr;
VAR
cl: I.IClassPtr;
BEGIN
cl := I.MakeClass(NIL,NIL,superClass,size+emptySize,LONGSET{});
InitClass(cl,dispatcher,typeDesc);
RETURN cl;
END InitPrivFromClass;
PROCEDURE InitPubFromName * (name: ARRAY OF CHAR;
superClass: ARRAY OF CHAR; (* $CopyArrays- *)
dispatcher: DispatcherPROC;
size: INTEGER;
typeDesc: y.ADDRESS): I.IClassPtr;
VAR
cl: I.IClassPtr;
BEGIN
cl := I.MakeClass(name,superClass,NIL,size+emptySize,LONGSET{});
IF cl # NIL THEN
InitClass(cl,dispatcher,typeDesc);
I.AddClass(cl);
END;
RETURN cl;
END InitPubFromName;
PROCEDURE InitPubFromClass * (name: ARRAY OF CHAR; (* $CopyArrays- *)
superClass: I.IClassPtr;
dispatcher: DispatcherPROC;
size: INTEGER;
typeDesc: y.ADDRESS): I.IClassPtr;
VAR
cl: I.IClassPtr;
BEGIN
cl := I.MakeClass(name,NIL,superClass,size+emptySize,LONGSET{});
IF cl # NIL THEN
InitClass(cl,dispatcher,typeDesc);
I.AddClass(cl);
END;
RETURN cl;
END InitPubFromClass;
END RootClass.