DIRECTORY DB, DBNames, Nut, Rope, ViewerOps; NutImpl: CEDAR MONITOR IMPORTS DBNames, Rope, ViewerOps EXPORTS Nut = BEGIN OPEN Nut, DB; implementations: PUBLIC NutList _ NIL; NutList: TYPE = LIST OF NutRecord _ NIL; NutRecord: TYPE = REF NutRecordObject; NutRecordObject: TYPE = RECORD[domain: ROPE, segment: DB.Segment, procList: ProcList]; ProcList: TYPE = LIST OF ProcRecord _ NIL; ProcRecord: TYPE = REF ProcRecordObject; ProcRecordObject: TYPE = RECORD[display: NutProc, edit: NutProc]; NoRegistration: PUBLIC ERROR = CODE; Display: PUBLIC ENTRY PROC[eName, domain: ROPE, segment: DB.Segment, parent: Viewer_ NIL] RETURNS[v: Viewer] = BEGIN ENABLE UNWIND => NULL; implRec: ProcRecord = FindImpl[domain, segment]; lastSpawned: Viewer = IF parent = NIL THEN NIL ELSE GetSpawnedProperty[parent]; IF implRec = NIL THEN RETURN WITH ERROR NoRegistration[]; v _ implRec.display[eName, domain, segment, lastSpawned ! ABORTED => CONTINUE]; IF v # NIL AND NOT v.destroyed THEN { [] _ SetSpawnedProperty[parent, v]; IF v.iconic THEN ViewerOps.OpenIcon[v] } END; Edit: PUBLIC ENTRY PROC[eName, domain: ROPE, segment: DB.Segment, parent: Viewer_ NIL] RETURNS[v: Viewer] = BEGIN ENABLE UNWIND => NULL; implRec: ProcRecord = FindImpl[domain, segment]; lastSpawned: Viewer = IF parent = NIL THEN NIL ELSE GetSpawnedProperty[parent]; IF implRec = NIL THEN RETURN WITH ERROR NoRegistration[]; v _ implRec.edit[eName, domain, segment, lastSpawned ! ABORTED => CONTINUE]; IF v # NIL AND NOT v.destroyed THEN { [] _ SetSpawnedProperty[parent, v]; IF v.iconic THEN ViewerOps.OpenIcon[v] } END; Register: PUBLIC ENTRY PROC[domain: ROPE, segment: DB.Segment, display: NutProc _ NIL, edit: NutProc _ NIL] = BEGIN implRec: ProcRecord = FindImpl[domain, segment]; procs: ProcRecord = NEW[ProcRecordObject _ [display, edit]]; IF display = NIL THEN procs.display _ IF implRec = NIL THEN NIL ELSE implRec.display; IF edit = NIL THEN procs.edit _ IF implRec = NIL THEN NIL ELSE implRec.edit; SetEntry[domain, segment, procs]; END; Push: PUBLIC ENTRY PROC[ domain: ROPE, segment: DB.Segment, display: NutProc _ NIL, edit: NutProc _ NIL] = BEGIN implRec: ProcRecord = FindImpl[domain, segment]; procs: ProcRecord = NEW[ProcRecordObject _ [display, edit]]; IF display = NIL THEN procs.display _ IF implRec = NIL THEN NIL ELSE implRec.display; IF edit = NIL THEN procs.edit _ IF implRec = NIL THEN NIL ELSE implRec.edit; PushEntry[domain, segment, procs]; END; SetSpawnedProperty: PUBLIC PROC [v: Viewer, new: Viewer] RETURNS [previous: Viewer] ~ { IF v = NIL OR v.destroyed THEN RETURN[NIL]; previous _ NARROW[ViewerOps.FetchProp[v, $LastSpawned]]; ViewerOps.AddProp[v, $LastSpawned, new] }; GetSpawnedProperty: PUBLIC PROC [v: Viewer] RETURNS [current: Viewer] ~ { current _ NARROW[ViewerOps.FetchProp[v, $LastSpawned]]; IF GetFrozenProperty[current] THEN RETURN[NIL] }; SetFrozenProperty: PUBLIC PROC [v: Viewer, new: BOOL] RETURNS [previous: BOOL] ~ { IF v = NIL THEN RETURN[TRUE]; -- the non-existent viewer is always frozen {refFrozen: REF BOOL = NARROW[ViewerOps.FetchProp[v, $Frozen]]; IF refFrozen = NIL THEN {previous _ FALSE; ViewerOps.AddProp[v, $Frozen, NEW[BOOL _ new]] } ELSE {previous _ refFrozen^; refFrozen^ _ new} } }; GetNutInfo: PUBLIC PROC[v: Viewer] RETURNS[segment: Segment, domain, entity: ROPE] = { entity _ NARROW[ViewerOps.FetchProp[v, $EntityName]]; segment _ NARROW[ViewerOps.FetchProp[v, $Segment]]; domain _ NARROW[ViewerOps.FetchProp[v, $DomainName]] }; CopyNutInfo: PUBLIC PROC[from: Viewer, to: Viewer] = { ViewerOps.AddProp[from, $EntityName, ViewerOps.FetchProp[to, $EntityName]]; ViewerOps.AddProp[from, $Segment, ViewerOps.FetchProp[to, $Segment]]; ViewerOps.AddProp[from, $DomainName, ViewerOps.FetchProp[to, $DomainName]] }; SetNutInfo: PUBLIC PROC[v: Viewer, segment: Segment, domain, entity: ROPE] = { ViewerOps.AddProp[v, $EntityName, entity]; ViewerOps.AddProp[v, $Segment, segment]; ViewerOps.AddProp[v, $DomainName, domain] }; ChangeName: PUBLIC PROC[v: Viewer, newName: ROPE] = { ViewerOps.AddProp[v, $EntityName, newName] }; EntityNameForViewer: PUBLIC PROC [v: Viewer] RETURNS [entityName: ROPE] ~ { segment: DB.Segment; entity, domain: ROPE; [segment, domain, entity] _ GetNutInfo[v]; RETURN[DBNames.MakeName[segment, domain, entity]] }; GetFrozenProperty: PUBLIC PROC [v: Viewer] RETURNS [current: BOOL] ~ { IF v = NIL THEN RETURN[TRUE]; -- the non-existent viewer is always frozen { refFrozen: REF BOOL = NARROW[ViewerOps.FetchProp[v, $Frozen]]; IF refFrozen = NIL THEN current _ FALSE ELSE current _ refFrozen^ } }; SetEntry: INTERNAL PROC[domain: ROPE, segment: DB.Segment, procs: ProcRecord] = BEGIN nut: NutRecord = GetNut[domain, segment]; IF nut = NIL THEN implementations _ CONS[NEW[NutRecordObject _ [domain, segment, LIST[procs]]], implementations] ELSE nut.procList _ LIST[procs] END; PushEntry: INTERNAL PROC[domain: ROPE, segment: DB.Segment, procs: ProcRecord] = BEGIN nut: NutRecord = GetNut[domain, segment]; IF nut = NIL THEN implementations _ CONS[NEW[NutRecordObject _ [domain, segment, LIST[procs]]], implementations] ELSE nut.procList _ CONS[procs, nut.procList] END; DeRegister: PUBLIC ENTRY PROC[domain: ROPE, segment: DB.Segment] = BEGIN nut: NutRecord = GetNut[domain, segment]; IF nut = NIL THEN RETURN; nut.procList _ NIL; END; Pop: PUBLIC ENTRY PROC[domain: ROPE, segment: DB.Segment] = BEGIN nut: NutRecord = GetNut[domain, segment]; IF nut = NIL THEN RETURN; nut.procList _ IF nut.procList # NIL THEN nut.procList.rest ELSE NIL END; FindImpl: INTERNAL PROC[d: ROPE, seg: Segment] RETURNS[ProcRecord] = BEGIN nut: NutRecord = GetNut[d, seg]; IF nut = NIL THEN RETURN[NIL] ELSE IF nut.procList = NIL THEN RETURN[NIL] ELSE RETURN[nut.procList.first] END; GetNut: INTERNAL PROC[d: ROPE, seg: Segment] RETURNS[NutRecord] = BEGIN FOR iL: NutList _ implementations, iL.rest UNTIL iL=NIL DO IF Rope.Equal[iL.first.domain, d] AND (seg = iL.first.segment) THEN RETURN[iL.first]; ENDLOOP; RETURN[NIL]; END; END. Change Log: Cattell on January 16, 1984 12:12 pm: passing NIL in for segment when registering means will take any segment. Butler on June 4, 1984: Users can register their own defaults. They are no longer built in. NIL in the place of the domain and/or segment will register a default for a domain and/or segment. Cattell on January 16, 1984 12:12 pm: passing NIL in for segment when registering means will take any segment. Butler on June 4, 1984: Users can register their own defaults. They are no longer built in. NIL in the place of the domain and/or segment will register a default for a domain and/or segment. Butler on June 26, 1984: Major Revision of code has been completed. Dependencies between Squirrel and Nut and whiteboards have been altered. Nut is now independent of Squirrel. The creation of all viewers is now done through NutViewer. Donahue on July 12, 1984: NutImpl is now a free standing implementation of Nut; it can be run independently of any other piece of Squirrel. úFile: NutImpl.mesa Contents: Implementation of Nut.mesa. Created by: Rick Cattell on January, 1982 Last edited by: Cattell on July 27, 1983 8:14 pm Willie-Sue on July 11, 1984 4:22:36 pm PDT Widom on June 14, 1984 2:02:54 pm PDT Donahue on September 13, 1984 4:36:18 pm PDT Last Edited by: Butler, July 11, 1984 4:34:54 pm PDT Types and global variables the procList contains a stack of procedures for this domain Exported procedures Registers a display, create for given domain. These will supersede any previous non-NIL registrations for this domain. Registers a display, create, query, and/or notify proc for given domain. These will supersede any previous non-NIL registrations for this domain. Actually inserts new records into the implementation list Actually inserts new records into the implementation list Deregisters all procs for this domain Deregisters top procs for this domain Support procedures Try to find an implementation for domain d in segment seg. Looks for an exact match for d and seg. Ê •˜Jšœ™Jšœ%™%Jšœ)™)Jšœ™Jšœ ™ Jšœ*™*Jšœ%™%Jšœ,™,Jšœ4™4J˜šÏk ˜ Jšœ˜J˜J˜J˜J˜ J˜—šœ œ˜Jšœ˜ Jšœ˜ J˜—Jšœœœ˜J˜Jšœ™J˜Jšœœ œ˜&J˜Jš œ œœœ œ˜(Jšœ œœ˜&š œœœ œ œ˜VJšœ;™;—J˜Jš œ œœœœ˜*Jšœ œœ˜(Jšœœœ"˜AJ˜Jšœœœœ˜$J˜Jšœ™J˜šÏnœœœœœ œœœ ˜nš˜Jšœœœ˜Jšœ0˜0Jš œœ œœœœ˜OJš œ œœœœœ˜9Jšœ:œœ˜Oš œœœœ œ˜%Jšœ$œ œ˜M——Jšœ˜J˜—šžœœœœœ œœœ ˜kš˜Jšœœœ˜Jšœ0˜0Jš œœ œœœœ˜OJš œ œœœœœ˜9Jšœ7œœ˜Lš œœœœ œ˜%Jšœ$œ œ˜M——Jšœ˜J˜—šžœœœœ œ œœœ˜mšœw™wš˜Jšœ0˜0Jšœœ%˜