DIRECTORY Atom, FS, GGError, GGInterfaceTypes, GGModelTypes, GGSessionLog, GGUserInput, IO, Rope; GGSessionLogImpl: CEDAR PROGRAM IMPORTS Atom, FS, GGError, GGUserInput, IO, Rope EXPORTS GGSessionLog = BEGIN CharClass: TYPE = IO.CharClass; GargoyleData: TYPE = GGInterfaceTypes.GargoyleData; Point: TYPE = GGModelTypes.Point; globalStream: IO.STREAM; SetStream: PUBLIC PROC [stream: IO.STREAM] = { globalStream _ stream; }; EnterAction: PUBLIC PROC [point: Point, action: LIST OF REF ANY, mouseEvent: BOOL] = { IF mouseEvent THEN globalStream.PutF["* [%g, %g] ", [real[point[1]]], [real[point[2]]] ]; FOR actionList: LIST OF REF ANY _ action, actionList.rest UNTIL actionList = NIL DO WITH actionList.first SELECT FROM atom: ATOM => globalStream.PutF["%g", [rope[Atom.GetPName[atom]]]]; n: REF INT => globalStream.PutF["%g", [integer[n^]]]; r: REF REAL => globalStream.PutF["%g", [real[r^]]]; ENDCASE => ERROR; IF actionList.rest = NIL THEN globalStream.PutChar[IO.CR] ELSE globalStream.PutChar[IO.SP]; ENDLOOP; }; OpenFile: PROC [name: Rope.ROPE] RETURNS [f: IO.STREAM, success: BOOL] = { success _ TRUE; f _ FS.StreamOpen[name ! FS.Error => { IF error.group = user THEN { success _ FALSE; GGError.Append["Picture file problem: ", oneLiner]; GGError.Append[error.explanation, oneLiner]; } ELSE ERROR; CONTINUE}]; }; PlaybackFromFile: PUBLIC PROC [name: Rope.ROPE, gargoyleData: GargoyleData] = { wdir, fullName: Rope.ROPE; success: BOOL; f: IO.STREAM; wdir _ gargoyleData.originalWorkingDirectory; success _ TRUE; [fullName,,] _ FS.ExpandName[name, wdir ! FS.Error => IF error.group = user THEN { success _ FALSE; CONTINUE; } ]; IF NOT success THEN RETURN; [f, success] _ OpenFile[fullName]; IF NOT success THEN RETURN; WHILE success DO success _ PlayAction[f, gargoyleData]; ENDLOOP; }; AppendAtom: PROC [atom: ATOM, list: LIST OF REF ANY] RETURNS [newList: LIST OF REF ANY] = { l: LIST OF REF ANY _ list; IF l = NIL THEN RETURN[LIST[atom]]; UNTIL l.rest = NIL DO l _ l.rest ENDLOOP; l.rest _ CONS[atom, NIL]; newList _ list; }; AppendToken: PROC [token: REF ANY, list: LIST OF REF ANY] RETURNS [newList: LIST OF REF ANY] = { l: LIST OF REF ANY _ list; IF l = NIL THEN RETURN[LIST[token]]; UNTIL l.rest = NIL DO l _ l.rest ENDLOOP; l.rest _ CONS[token, NIL]; newList _ list; }; PlayAction: PROC [f: IO.STREAM, gargoyleData: GargoyleData] RETURNS [success: BOOL] = { c: CHAR; mouseEvent: BOOL; point: Point; good: BOOL; token: REF ANY; action: LIST OF REF ANY; success _ TRUE; c _ IO.GetChar[f !IO.EndOfStream => {success _ FALSE; CONTINUE}]; IF NOT success THEN RETURN; IF c = '* THEN { good _ ReadHorizontalBlank[f]; IF NOT good THEN ERROR; point _ ReadPoint[f]; mouseEvent _ TRUE } ELSE { mouseEvent _ FALSE; IO.Backup[f, c]; }; token _ $Start; UNTIL token = $EndOfLine DO [token] _ ReadSpacesAndAtomOrNum[f]; IF token = $EndOfLine THEN LOOP ELSE action _ AppendToken[token, action] ENDLOOP; GGUserInput.PlayAction[point, action, mouseEvent, gargoyleData]; }; ReadPoint: PUBLIC PROC [f: IO.STREAM] RETURNS [point: Point] = { ReadRope[f, "["]; point[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point[2] _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadBlankAndReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { ReadBlank[f]; r _ ReadReal[f]; }; ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { realRope: Rope.ROPE; end: BOOL _ FALSE; [realRope, ----] _ IO.GetTokenRope[f, RealBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {r _ 0.0; RETURN}; IF Rope.Find[realRope, ".", 0, FALSE] = -1 THEN realRope _ Rope.Concat[realRope, ".0"]; r _ IO.GetReal[IO.RIS[realRope]]; }; RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], ', => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; ReadBlankAndNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { ReadBlank[f]; n _ ReadNAT[f]; }; ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = { whiteSpace: Rope.ROPE; c: CHAR; end: BOOL _ FALSE; good _ TRUE; [whiteSpace, ----] _ IO.GetTokenRope[f, HorizontalBlankProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; c _ Rope.Fetch[whiteSpace, 0]; SELECT c FROM IO.CR => {good _ FALSE; RETURN}; IO.TAB, IO.SP => {good _ TRUE; RETURN}; ENDCASE => {good _ TRUE; IO.Backup[f, c]; RETURN}; }; HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [CharClass] = { SELECT char FROM IO.TAB, IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; IsDigit: PROC [c: CHAR] RETURNS [BOOL] = { RETURN[c IN ['0..'9]]; }; ReadSpacesAndAtomOrNum: PUBLIC PROC [f: IO.STREAM] RETURNS [token: REF ANY] = { word: Rope.ROPE; good: BOOL; int: INT; real: REAL; good _ ReadHorizontalBlank[f]; IF NOT good THEN { token _ $EndOfLine; RETURN; }; word _ ReadWord[f]; IF IsDigit[Rope.Fetch[word, 0]] THEN { IF Rope.Find[word, "."] = -1 THEN { -- an integer int _ IO.GetInt[IO.RIS[word]]; token _ NEW[INT _ int]; } ELSE { real _ IO.GetReal[IO.RIS[word]]; token _ NEW[REAL _ real]; }; } ELSE { token _ Atom.MakeAtom[word]; }; }; ReadBlankAndWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ReadBlank[f]; word _ ReadWord[f]; }; ReadBlankAndRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { ReadBlank[f]; ReadRope[f, rope]; }; ReadBlank: PUBLIC PROC [f: IO.STREAM] = { [] _ IO.SkipWhitespace[f, TRUE]; }; ReadWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { [word, ----] _ IO.GetTokenRope[f, WordBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; WordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ', => RETURN [break]; '] => RETURN [break]; ') => RETURN [break]; ENDCASE => RETURN [other]; }; ReadNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { end: BOOL _ FALSE; intRope: Rope.ROPE; [intRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ IO.GetInt[IO.RIS[intRope]]; }; NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; ReadRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { c: CHAR; endofstream: BOOL _ FALSE; FOR i: INT IN[1..Rope.Length[rope]] DO c _ IO.GetChar[f ! IO.EndOfStream => {endofstream _ TRUE; CONTINUE}]; IF endofstream THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], NIL, rope]; IF NOT c = Rope.Fetch[rope,i-1] THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], Rope.FromChar[c], rope]; ENDLOOP; }; END. ΊGGSessionLogImpl.mesa Last edited by Bier on August 20, 1985 3:08:55 pm PDT. Contents: Routines for saving TIP Table atoms in a file to aid in interface evaluation and for playback. Two possiblilities 1) File doesn't exist. Print error message. 2) File does exist. File it in. Succeed. Assumes the next rope on the stream will be of the form "[,]". A convenience function. Equivalent to ReadBlank[f]; r _ ReadReal[f]; Reads digits up to the next ], , or . Leaves these terminators on the stream. A convenience function. Equivalent to ReadBlank[f]; n _ ReadNAT[f]; Reads 's, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else A convenience function. Equivalent to ReadBlank[f]; word _ ReadWord[f]; Reads, 's, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space. Reads a rope until , , or are encountered. Used to read in a rope which is data. ie the name of a coordinate system from a 3d file. Reads digits up to the next ], , . Leaves these terminators on the stream. Removes the given rope from the top of the stream. Used to remove formatting words and phrases from 3d files. We are not interested in these strings but only in the data in between them. Signals RopeNotOnTop if some other rope is on top. Κ …˜Ihead1™J™6Jšœi™išΟk ˜ Jšœœ8œ œ˜W—J˜šœœ˜Jšœœ œ œ˜0Jšœ˜—Jš˜J˜Iprocšœ œœ ˜Jšœœ!˜3Jšœœ˜!J˜Jšœœœ˜J˜š Οn œœœ œœ˜.Jšœ˜J˜—šž œœœœœœœœ˜VJšœ œG˜Yšœ œœœœœœ˜SJšœœ˜!Jšœœ9˜CJšœœœ+˜5Jšœœœ(˜3Jšœœ˜Jš œœœœœ˜9Jšœœœ˜!—Jšœ˜J˜—J˜šžœœ œœœœ œ˜JLšœ œ˜L˜šœ™Lšœ-™-Lšœ+™+—šœœ˜šœœ ˜šœœ˜Lšœ œ˜Lšœ3˜3Lšœ,˜,Lšœ˜—Lšœœ˜ Lšœ˜ —L˜L˜——šžœœœ œ!˜OJšœœ˜Jšœ œ˜Jšœœœ˜ Jšœ-˜-Jšœ œ˜šœœ˜'šœœ œœ˜*Jšœ œ˜Jšœ˜ J˜—Jšœ˜—Jšœœ œœ˜Jšœ"˜"Jšœœ œœ˜˜Jšœ&˜&—J˜Jšœ˜J˜—šž œœœœœœœœ œœœœ˜[Jš œœœœœ˜Jš œœœœœ˜#Jšœ œœ œ˜)Jšœ œœ˜Jšœ˜J˜—šž œœ œœœœœœ œœœœ˜`Jš œœœœœ˜Jš œœœœœ ˜$Jšœ œœ œ˜)Jšœ œœ˜Jšœ˜J˜J˜J˜J˜J˜—š ž œœœœœ œ˜WJšœœ˜Jšœ œ˜J˜ Jšœœ˜ J˜Jš œœœœœ˜Jšœ œ˜šœœ ˜Jšœœœœ˜0—Jšœœ œœ˜šœœ˜J˜Jšœœœœ˜J˜Jšœ ˜J˜—šœ˜Jšœ œ˜J˜J˜—J˜šœ˜J˜$Jšœœ˜Jšœ$˜(—Jšœ˜Jšœ@˜@J˜J˜—š ž œœœœœœ˜@LšœL™LLšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜—šžœœœœœœœ˜BLšœE™ELšœ ˜ Lšœ˜Lšœ˜—šžœœœœœœœ˜:Lšœa™aLšœœ˜Lšœœœ˜šœ Οcœœ˜3Lšœœœœ˜+—Lšœœ œ˜Lšœœœ(˜WLšœœ œœ ˜!Lšœ˜—šž œœœœœœœ˜Hšœ˜Lšœ œ ˜Lšœœœ ˜Lšœœœ ˜Lšœœ ˜—Lšœ˜—šžœœœœœœœ˜@LšœD™DLšœ ˜ Lšœ˜Lšœ˜—šžœœœœœœœ˜HLšœ„™„Lšœœ˜Lšœœ˜Lšœœœ˜Lšœœ˜ šœ Ÿœœ$˜;Lšœœœœ˜+—Lšœœ œœ˜#Lšœ˜šœ˜ Lšœœ œœ˜ Lš œœœœ œœ˜'Lšœ œœœ˜2—Lšœ˜—š žœœœœœ˜Cšœ˜Lš œœœœœ ˜ Lšœœ ˜—Lšœ˜L˜—š žœœœœœ˜*Lšœœ ˜L˜L˜—šžœœœœœœ œœ˜OLšœ œ˜Lšœœ˜ Lšœœ˜ Lšœœ˜ Lšœ˜šœœœ˜Lšœ˜Lšœ˜L˜—Lšœ˜šœœ˜&šœœŸ ˜1Lšœœœœ˜Lšœœœ˜L˜—šœ˜Lšœœ œœ˜ Lšœœœ ˜L˜—L˜—šœ˜Lšœ˜L˜—Lšœ˜—šžœœœœœœ œ˜JLšœH™HLšœ ˜ Lšœ˜Lšœ˜—š žœœœœœ œ˜ALšœ ˜ Lšœ˜Lšœ˜—š ž œœœœœ˜)Lšœ‘™‘Lšœœœ˜ Lšœ˜—šžœœœœœœ œ˜BLšœž™žšœŸœœ˜/Lšœœœœ˜+—Lšœ˜—šž œœœœœœœ˜Hšœ˜Lšœœœ ˜Lšœœœ ˜Lšœœœ ˜Lšœœ ˜Lšœœ ˜Lšœœ ˜Lšœœ ˜—Lšœ˜—šžœœœœœœœ˜8LšœV™VLšœœœ˜Lšœœ˜šœ Ÿœœ˜1Lšœœœœ˜+—Lšœœ œ˜Lšœœœœ ˜Lšœ˜—šž œœœœœœœ˜Gšœ˜Lš œœœœœ œ ˜+Lšœœ ˜—Lšœ˜L˜—Lš œœœ œœœœ˜]š žœœœœœ œ˜9Lšœ»™»Lšœ2™2Lšœœ˜Lšœ œœ˜šœœœ˜&šœœ ˜LšœΟrœœ œ˜4—šœ œ˜Lšœœœ˜0—šœœœ˜%Lšœœ&˜=——Lšœ˜Lšœ˜—J˜J˜Jšœ˜J˜J˜J˜—…—"-a