TU.mesa
Last modified by D. Swinehart, June 19, 1984 7:48:16 am PDT
DIRECTORY
Atom USING [ MakeAtom ],
BasicTime USING [ Now, nullGMT ],
Commander USING [ CommandProc, Register ],
CommandToolExtras USING [ ArgN ],
IO,
Log,
Nice,
Rope USING [ Cat, Substr ],
SafeStorage USING [ GetCanonicalReferentType, NarrowRefFault, Type, unspecType ],
Thrush USING [
Epoch, H, nullHandle, ROPE, ServerProblem, ThHandle],
ThNet,
ThParty USING [ DescribeParty ],
ThPartyPrivate USING [ PartyData, SmartsData ],
ThSmartsPrivate USING [ SmartsInfo ],
Triples USING [
Any, Erase, Foreach, ForeachProc, Item, Make, Select, SelectCandidate ],
TU
;
TUImpl: CEDAR MONITOR
IMPORTS
Atom,
BasicTime,
IO,
Nice,
Log,
Rope,
ThParty,
SafeStorage,
Thrush,
Triples,
Commander,
CommandToolExtras
EXPORTS Thrush, ThNet, TU = {
Obligatory concrete
epoch: PUBLIC Thrush.Epoch;
ePoch: Thrush.Epoch;
ServerError: PUBLIC ERROR[code: Thrush.ServerProblem] = CODE;
pERROR: PUBLIC ERROR = CODE;
pd: PUBLIC REF ThNet.PDNEW[ThNet.PD←[
debug: FALSE,
encryptionRequested: TRUE,
encryptVoice: TRUE
]];
Copies
ThHandle: TYPE = Thrush.ThHandle;
nullHandle: ThHandle = Thrush.nullHandle;
ROPE: TYPE = Thrush.ROPE;
ThHandle types and procedures
HandleRef: TYPE = REF HandleValue;
HandleValue: TYPE = RECORD [
epoch: Thrush.Epoch,
type: SafeStorage.Type -- concrete type -- ];
Enhandle: PUBLIC ENTRY PROC[r: REF] RETURNS [Thrush.ThHandle] = TRUSTED {
ENABLE UNWIND=>NULL;
h: HandleRef;
IF r=NIL THEN RETURN[Thrush.nullHandle];
h ← NARROW[Triples.Select[$Handle, r, Triples.Any!
SafeStorage.NarrowRefFault=>ERROR HandleFault[LOOPHOLE[h]]]];
IF h=NIL THEN {
h ← NEW[HandleValue ← [epoch: ePoch,
type: SafeStorage.GetCanonicalReferentType[ref: r]]];
Triples.Make[$Handle, r, h]; };
RETURN[LOOPHOLE[r]]; };
Rehandle, H: PUBLIC PROC[r: REF] RETURNS [ThHandle] = INLINE
{ RETURN[LOOPHOLE[r]]; };
Can be used if one obtained r from Dehandle, or knows it was obtained that way. The next Dehandle will check the handle's validity again.
Validates type if not RTTypesBasic.unspecType, then returns REF as unspecified.
Virtually any Handle value may be supplied to this procedure without breaking the
RTTypes system!! Handles that are or were once valid are preferred!
Fails with ERROR if insist is TRUE, else by returning NIL.
Dehandle: PUBLIC ENTRY PROC[h: ThHandle, type: SafeStorage.Type, insist: BOOLEAN]
RETURNS [LONG UNSPECIFIED] = {
ENABLE UNWIND=>NULL;
RETURN[DoDehandle[h, type, insist]];
};
DoDehandle: INTERNAL PROC[h: ThHandle, type: SafeStorage.Type, insist: BOOLEAN]
RETURNS [REF] = TRUSTED {
r, hrc: REF;
hr: HandleRef;
NoGood: PROC RETURNS[REF]=TRUSTED{
IF insist THEN ERROR HandleFault[h];
RETURN[NIL]; };
IF h=nullHandle THEN RETURN[NIL];
[r, hrc] ← Triples.SelectCandidate[$Handle, h];
IF hrc=NIL THEN RETURN[NoGood[]];
hr←NARROW[hrc!SafeStorage.NarrowRefFault=>CONTINUE];
IF hr=NIL OR ePoch # hr.epoch OR
type#hr.type AND type#SafeStorage.unspecType
THEN RETURN[NoGood[]];
RETURN[r];
};
KillHandle makes the handle invalid, but does not eliminate it. PurgeHandle does that.
KillHandle: PUBLIC ENTRY PROC[h: ThHandle, type: SafeStorage.Type] = TRUSTED {
OPEN Triples;
ENABLE UNWIND=>NULL;
r: REF;
hr: HandleRef;
IF h=nullHandle THEN RETURN;
r ← DoDehandle[h, type, TRUE]; -- blows up if not of correct type.
hr ← NARROW[Select[$Handle, r, -- hr--]];
hr.epoch�sicTime.nullGMT; -- no longer a valid-looking handle.
Erase[$Handle, r, hr]; };
HandleFault: PUBLIC ERROR[h: ThHandle] = CODE;
Miscellaneous routines
MakeUnique: PUBLIC PROC [att, obj, val: Triples.Item] = TRUSTED {
Triples.Erase[att, obj, Triples.Any];
Triples.Make[att, obj, val]; };
Procedures for debugging only
DH: PUBLIC PROC[h: ThHandle] RETURNS [REF] = TRUSTED {
RETURN[Dehandle[h, SafeStorage.unspecType, FALSE]]; }; -- for debugging
Any: Triples.Item = Triples.Any;
gsI: INT𡤀
World: PUBLIC PROC [o: IO.STREAM] = TRUSTED {
OPEN IO;
Country: Triples.ForeachProc= TRUSTED {
IF trip.att#$iD
THEN o.PutF["%g[ %g ] = %g\n", RefAddr[trip.att], RefAddr[trip.obj], RefAddr[trip.val]]; };
gsI𡤀
Triples.Erase[$iD, Any, Any]; -- from last time!
o.PutF["------- World as of %g -------\n", time[]];
Triples.Foreach[Any, Any, Any, Country];
o.PutRope["--------------\n\n"]; };
Show: PUBLIC PROC[o: IO.STREAM, iD: ATOM] = TRUSTED {
OPEN IO;
obj: REF←Triples.Select[$iD, --obj--, iD];
IF obj=NIL THEN obj←iD; -- assume we want to talk about the id itself.
o.PutF["%g (%d):\n %g\n", refAny[iD], card[LOOPHOLE[obj]],
refAny[obj]!SafeStorage.NarrowRefFault=>{o.PutRope["...failed...\n"];CONTINUE}]; };
Ref: PUBLIC PROC[iD: ATOM] RETURNS [r: REF] = {
OPEN IO;
r←Triples.Select[$iD, --obj--, iD];
IF r=NIL THEN r←iD; -- assume we want to talk about the id itself.
};
RefFromRope: PUBLIC PROC[iD: ROPE] RETURNS [REF] = {
RETURN[Ref[Atom.MakeAtom[iD]]];
};
RefAddr: PUBLIC PROC[r: REF] RETURNS [IO.Value] = TRUSTED {
id: ATOMNIL;
IF r=NIL THEN RETURN[IO.refAny[NIL]];
id←NARROW[r!SafeStorage.NarrowRefFault=>CONTINUE]; -- not an atom, get its id.
IF id=NIL THEN id←NARROW[Triples.Select[$iD, r, --id--]];
IF id=NIL THEN { id←Gensym[r, 'R]; Triples.Make[$iD, r, id]; };
RETURN [IO.atom[id]]; };
Gensym: PROC[r: REF, c: CHAR] RETURNS [ATOM] = TRUSTED {
OPEN IO;
symName: ROPEWITH r SELECT FROM
party: ThPartyPrivate.PartyData => Party[party],
smarts: ThPartyPrivate.SmartsData => Smarts[smarts],
info: ThSmartsPrivate.SmartsInfo => Smarts[info.smarts, "si"],
ENDCASE=>NIL;
IF symName=NIL THEN symName←IO.PutFR["%c%02d", char[c], int[gsI←gsI+1]];
RETURN[Atom.MakeAtom[symName]];
};
Smarts: PROC[smarts:ThPartyPrivate.SmartsData,qual: ROPE←"sm"]RETURNS[name:ROPENIL]= TRUSTED {
party: ThPartyPrivate.PartyData ← NARROW[Triples.Select[$VoiceTerminal, Any, smarts]];
IF party#NIL THEN name←Party[party, qual];
RETURN[name];
};
Party: PROC[party: ThPartyPrivate.PartyData, qual: ROPE←"pt"] RETURNS[name: ROPENIL] = TRUSTED {
OPEN IO;
moreQual: ROPE←".";
SELECT party.type FROM
trunk => {
party ← NARROW[Triples.Select[$TrunkParty, --owner--, party]];
moreQual←".k";
};
recording => name ← IO.PutFR["Rec%02d", int[gsI←gsI+1]];
ENDCASE;
IF name=NIL THEN {
name←ThParty.DescribeParty[partyID: Thrush.H[party]];
name←name.Substr[len: 3];
};
IF name=NIL THEN RETURN;
name←name.Cat[moreQual, qual];
};
Initialization
WorldCmd: Commander.CommandProc = TRUSTED {
World[Log.FindWhere[$Cmd, NIL]];
};
ShowCmd: Commander.CommandProc = TRUSTED {
Show[Log.FindWhere[$Cmd, NIL], Atom.MakeAtom[CommandToolExtras.ArgN[cmd,1]]];
};
epoch�sicTime.Now[];
ePoch ← epoch;
Commander.Register["world", WorldCmd, "Print Thrush World"];
Commander.Register["show", ShowCmd, "Describe Item"];
Debugging nonsense
Nice.View[pd, "Thrush-wide PD"];
Nice.View[Log.pd, "Log PD"];
}.