home *** CD-ROM | disk | FTP | other *** search
-
- (*
- * 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!
- *
- * To use this modules, inform Objects about your types in all
- * modules via
- *
- * ...
- * MyObject = POINTER TO MyObjectDesc;
- * MyObjectDesc = RECORD ... END;
- * ...
- * x: MyObject;
- * ...
- * NEW(x); Objects.AddObject(x,"MyModule.MyObject"); x := NIL;
- * ...
- *
- * Future versions of Amiga Oberon will probalby do this initialisations
- * automatically.
- *
- *)
-
- MODULE Objects;
-
- IMPORT B * := BasicTypes,
- F * := FileSystem,
- A := AVLTrees,
- BI := BinaryTrees,
- GC := GarbageCollector,
- ol := OberonLib,
- SYSTEM;
-
- TYPE
- Object * = POINTER TO ObjectDesc;
-
- ObjectDesc * = RECORD (B.ANYDesc) END;
-
- TypDesc = STRUCT
- (* $IF GarbageCollector *)
- gctype: GC.InternalObjectTypePtr;
- (* $ELSE *)
- size : LONGINT;
- (* $END *)
- typedesc: LONGINT;
- END;
-
- Name = POINTER TO NameDesc;
- NameDesc = RECORD (A.SNodeDesc)
- typ: TypDesc;
- END;
-
- Obj = POINTER TO ObjDesc;
- ObjDesc = RECORD (A.NodeDesc)
- name : Name;
- END;
-
- ObjRoot = POINTER TO ObjRootDesc;
- ObjRootDesc = RECORD (A.RootDesc)
- findtypedesc: LONGINT;
- END;
-
- VAR
- names: A.SRoot;
- objects: ObjRoot;
-
- PROCEDURE (x: Object) Load * (VAR f: F.File); (* is deferred *) END Load;
- PROCEDURE (x: Object) Store * (VAR f: F.File); (* is deferred *) END Store;
-
- PROCEDURE GetTyp(x: B.ANY): TypDesc;
- (* low-level routine to get ptr to typedesc and gctype *)
- TYPE Typ = UNTRACED POINTER TO TypDesc;
- BEGIN
- RETURN SYSTEM.VAL(Typ,SYSTEM.VAL(LONGINT,SYSTEM.ADR(x^))-4)^;
- END GetTyp;
-
- PROCEDURE ObjToName * (x: B.ANY; VAR name: ARRAY OF CHAR);
- BEGIN
- objects.findtypedesc := GetTyp(x).typedesc;
- COPY(objects.Find()(Obj).name.name,name);
- END ObjToName;
-
- PROCEDURE NameToObj * (name: ARRAY OF CHAR; VAR x: B.ANY);
- VAR
- adrPtr: UNTRACED POINTER TO SYSTEM.ADDRESS;
- namestr: A.String;
- n: Name;
- BEGIN
- adrPtr := SYSTEM.ADR(x);
- COPY(name,namestr);
- n := names.SFind(namestr)(Name);
- (* $IF GarbageCollector *)
- GC.New(adrPtr^,n.typ.gctype);
- (* $ELSE *)
- ol.New(adrPtr^,n.typ.size);
- (* $END *)
- adrPtr := SYSTEM.ADR(x^);
- adrPtr^ := n.typ.typedesc;
- END NameToObj;
-
- PROCEDURE AddObject * (x: B.ANY; name: ARRAY OF CHAR);
- VAR
- n: Name;
- o: Obj;
- BEGIN
- NEW(n); NEW(o);
- o.name := n;
- n.typ := GetTyp(x);
- COPY(name,n.name);
- names .Add(n); IF ~ names .addOk THEN HALT(20) END;
- objects.Add(o); IF ~ objects.addOk THEN HALT(20) END;
- END AddObject;
-
- PROCEDURE (obj: Obj) Compare * (b: B.COMPAREABLE): LONGINT;
- BEGIN
- RETURN obj.name.typ.typedesc - b(Obj).name.typ.typedesc;
- END Compare;
-
- PROCEDURE (obj: Obj) Find * (r: BI.Root): LONGINT;
- BEGIN
- RETURN obj.name.typ.typedesc - r(ObjRoot).findtypedesc;
- END Find;
-
- BEGIN
- NEW(names);
- NEW(objects);
- END Objects.
-