File: GGFileInImpl.mesa
Last edited by Bier on January 13, 1987 10:18:06 pm PST
Copyright © 1986 by Xerox Corporation. All rights reserved.
Contents: Recreates a gargoyle database from a text file of the sort produced by GGFileOut.mesa.
Pier, October 29, 1986 8:31:16 pm PST
DIRECTORY
Atom, FS, GGBasicTypes, GGError, GGEvent, GGFileIn, GGInterfaceTypes, GGModelTypes, GGObjects, GGOutline, GGParseIn, GGSegmentTypes, GGSlice, GGTraj, GGUtility, Imager, ImagerColor, IO, Rope, ViewerClasses;
GGFileInImpl: CEDAR PROGRAM
IMPORTS Atom, GGError, GGEvent, GGObjects, GGOutline, GGParseIn, GGSlice, GGTraj, GGUtility, Imager, IO, Rope
EXPORTS GGFileIn = BEGIN
Viewer: TYPE = ViewerClasses.Viewer;
Color: TYPE = Imager.Color;
GargoyleData: TYPE = GGInterfaceTypes.GargoyleData;
Outline: TYPE = GGModelTypes.Outline;
Point: TYPE = GGBasicTypes.Point;
Scene: TYPE = GGModelTypes.Scene;
Segment: TYPE = GGSegmentTypes.Segment;
SegmentClass: TYPE = GGSegmentTypes.SegmentClass;
Slice: TYPE = GGModelTypes.Slice;
SliceClass: TYPE = GGModelTypes.SliceClass;
StrokeEnd: TYPE = Imager.StrokeEnd;
Traj: TYPE = GGModelTypes.Traj;
Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = GGError.Problem;
FileinSceneAndOptions: PUBLIC PROC [f: IO.STREAM, gargoyleData: GargoyleData] = {
sceneName: Rope.ROPE;
scene: Scene ← gargoyleData.scene;
version: REAL;
count: NAT;
entity: REF ANY;
finger, newEntities: LIST OF REF ANY;
Read in the Header
GGParseIn.ReadBlankAndRope[f, "Gargoyle file for scene:"];
sceneName ← GGParseIn.ReadBlankAndWord[f];
GGParseIn.ReadBlankAndRope[f, "Produced by version"];
version ← GGParseIn.ReadBlankAndReal[f];
Read in the alignment objects, etc.
IF version >= 8607.17 THEN ReadOptions[f, gargoyleData];
Read in the scene entities
GGParseIn.ReadBlankAndRope[f, "Entities:"];
GGParseIn.ReadBlankAndRope[f, "["];
count ← GGParseIn.ReadNAT[f];
GGParseIn.ReadRope[f, "]:"]; GGParseIn.ReadWhiteSpace[f];
[newEntities, finger] ← GGUtility.StartList[];
FOR i: NAT IN[1..count] DO
entity ← FileinEntity[f, version, gargoyleData.feedback];
IF entity#NIL THEN [newEntities, finger] ← GGUtility.AddEntity[entity, newEntities, finger];
ENDLOOP;
GGObjects.AddEntities[scene, newEntities];
f.Close[];
};
ReadOptions: PROC [f: IO.STREAM, gargoyleData: GargoyleData] = {
keyWord, option: Rope.ROPE;
good: BOOL;
nextChar: CHAR;
twoCRsFound: BOOLFALSE;
GGParseIn.ReadBlank[f];
UNTIL twoCRsFound DO
[keyWord, good] ← GGParseIn.ReadKeyWord[f];
IF NOT good THEN {
nextChar ← IO.PeekChar[f];
IF nextChar = IO.CR THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
LOOP};
good ← GGParseIn.ReadHorizontalBlank[f];
IF NOT good THEN {
nextChar ← IO.PeekChar[f];
IF nextChar = IO.CR THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
LOOP};
option ← GGParseIn.ReadLine[f];
ProcessOption[keyWord, option, gargoyleData];
nextChar ← IO.PeekChar[f];
IF nextChar = IO.CR THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
ENDLOOP;
};
ProcessOption: PROC[keyWord, option: Rope.ROPE, gargoyleData: GargoyleData] = {
optionStream: IO.STREAMIO.RIS[option];
optionList: LIST OF Rope.ROPE;
value: REAL;
SELECT TRUE FROM
Rope.Equal[keyWord, "Slope", FALSE] => {
optionList ← GGParseIn.ReadListOfRope[optionStream];
FOR list: LIST OF Rope.ROPE ← optionList, list.rest UNTIL list = NIL DO
value ← GGParseIn.ReadReal[IO.RIS[list.first]];
GGEvent.AddSlopeInternal[gargoyleData, value];
ENDLOOP;
};
Rope.Equal[keyWord, "Angle", FALSE] => {
optionList ← GGParseIn.ReadListOfRope[optionStream];
FOR list: LIST OF Rope.ROPE ← optionList, list.rest UNTIL list = NIL DO
value ← GGParseIn.ReadReal[IO.RIS[list.first]];
GGEvent.AddAngleInternal[gargoyleData, value];
ENDLOOP;
};
Rope.Equal[keyWord, "Radius", FALSE] => {
optionList ← GGParseIn.ReadListOfRope[optionStream];
FOR list: LIST OF Rope.ROPE ← optionList, list.rest UNTIL list = NIL DO
value ← GGParseIn.ReadReal[IO.RIS[list.first]];
GGEvent.AddRadiusInternal[gargoyleData, value];
ENDLOOP;
};
Rope.Equal[keyWord, "LineDistance", FALSE] => {
optionList ← GGParseIn.ReadListOfRope[optionStream];
FOR list: LIST OF Rope.ROPE ← optionList, list.rest UNTIL list = NIL DO
value ← GGParseIn.ReadReal[IO.RIS[list.first]];
GGEvent.AddDistanceInternal[gargoyleData, value];
ENDLOOP;
};
Rope.Equal[keyWord, "Midpoints", FALSE] => {
on, good: BOOL;
GGParseIn.ReadBlank[optionStream];
[on, good] ← GGParseIn.ReadBOOL[optionStream];
GGEvent.SetMidpointsInternal[gargoyleData, on AND good];
};
ENDCASE => SIGNAL Problem[msg: "Unknown keyword in gargoyle file."];
}; -- end ProcessOption
FileinSceneOnly: PUBLIC PROC [f: IO.STREAM, scene: Scene] = {
sceneName: Rope.ROPE;
version: REAL;
count: NAT;
entity: REF ANY;
finger, newEntities: LIST OF REF ANY;
Read in the Header
GGParseIn.ReadRope[f, "Gargoyle file for scene:"];
GGParseIn.ReadBlank[f];
sceneName ← GGParseIn.ReadWord[f];
GGParseIn.ReadWhiteSpace[f];
GGParseIn.ReadRope[f, "Produced by version"];
GGParseIn.ReadBlank[f];
version ← GGParseIn.ReadReal[f];
GGParseIn.ReadWhiteSpace[f];
Read in the alignment objects, etc.
IF version >= 8607.17 THEN SkipOptions[f];
Read in the scene entities
GGParseIn.ReadRope[f, "Entities:"];
GGParseIn.ReadBlank[f];
GGParseIn.ReadRope[f, "["];
count ← GGParseIn.ReadNAT[f];
GGParseIn.ReadRope[f, "]:"]; GGParseIn.ReadWhiteSpace[f];
[newEntities, finger] ← GGUtility.StartList[];
FOR i: NAT IN[1..count] DO
entity ← FileinEntity[f, version, NIL];
IF entity#NIL THEN [newEntities, finger] ← GGUtility.AddEntity[entity, newEntities, finger];
ENDLOOP;
GGObjects.AddEntities[scene, newEntities];
f.Close[];
};
SkipOptions: PROC [f: IO.STREAM] = {
keyWord, option: Rope.ROPE;
good: BOOL;
nextChar: CHAR;
twoCRsFound: BOOLFALSE;
GGParseIn.ReadBlank[f];
UNTIL twoCRsFound DO
[keyWord, good] ← GGParseIn.ReadKeyWord[f];
IF NOT good THEN {
nextChar ← IO.PeekChar[f];
IF nextChar = IO.CR THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
LOOP};
good ← GGParseIn.ReadHorizontalBlank[f];
IF NOT good THEN {
nextChar ← IO.PeekChar[f];
IF nextChar = IO.CR THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
LOOP};
option ← GGParseIn.ReadLine[f];
ProcessOption[keyWord, option, gargoyleData];
nextChar ← IO.PeekChar[f];
IF nextChar = IO.CR THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
ENDLOOP;
};
FileinEntity: PROC [f: IO.STREAM, version: REAL, feedback: Viewer] RETURNS [entity: REF ANY] = {
nextWord: Rope.ROPE;
nextWord ← GGParseIn.ReadBlankAndWord[f];
IF version > 8605.22 THEN
SELECT TRUE FROM
Rope.Equal[nextWord, "Outline:"] => {
entity ← FileinOutline[f, version];
};
Rope.Equal[nextWord, "Slice"] => {
entity ← FileinSlice[f, version, feedback];
};
ENDCASE => ERROR
ELSE
SELECT TRUE FROM
Rope.Equal[nextWord, "Outline:"] => {
entity ← FileinOutline[f, version];
};
Rope.Equal[nextWord, "Cluster"] => {
entity ← FileinSlice[f, version, feedback];
};
ENDCASE => ERROR;
};
FileinSlice: PROC [f: IO.STREAM, version: REAL, feedback: Viewer] RETURNS [slice: Slice] = {
className: Rope.ROPE;
type: ATOM;
childCount: NAT;
GGParseIn.ReadBlankAndRope[f, "(class:"];
className ← GGParseIn.ReadBlankAndWord[f];
GGParseIn.ReadBlankAndRope[f, ")"];
GGParseIn.ReadBlankAndRope[f, "["];
GGParseIn.ReadBlank[f];
childCount ← GGParseIn.ReadNAT[f];
GGParseIn.ReadBlankAndRope[f, "]:"];
GGParseIn.ReadBlankAndRope[f, "Data:"];
type ← SliceClassFromRope[className];
slice ← FileinSliceData[f, type, version, feedback];
};
FileinSliceData: PROC [f: IO.STREAM, type: ATOM, version: REAL, feedback: Viewer] RETURNS [slice: Slice] = {
class: SliceClass;
class ← GGSlice.FetchSliceClass[type];
slice ← class.filein[f, version, feedback];
};
FileinOutline: PROC [f: IO.STREAM, version: REAL] RETURNS [outline: Outline] = {
fillColor: Color;
strokeEnd: StrokeEnd;
count: NAT;
fence, hole: Traj;
hasCircle: BOOLFALSE;
GGParseIn.ReadBlankAndRope[f, "fillColor:"];
GGParseIn.ReadBlank[f];
fillColor ← GGParseIn.ReadColor[f];
GGParseIn.ReadBlankAndRope[f, "strokeEnd:"];
GGParseIn.ReadBlank[f];
strokeEnd ← GGParseIn.ReadStrokeEnd[f];
GGParseIn.ReadBlankAndRope[f, "Trajectories:"];
GGParseIn.ReadBlankAndRope[f, "["];
GGParseIn.ReadBlank[f];
count ← GGParseIn.ReadNAT[f];
GGParseIn.ReadBlankAndRope[f, "]"];
[fence, hasCircle] ← GGTraj.Filein[f, version];
IF hasCircle THEN fillColor ← NIL; -- needed for the transition from circle/disc class
outline ← GGOutline.CreateOutline[fence, strokeEnd, fillColor];
FOR i: NAT IN [1..count-1] DO
[hole, ----] ← GGTraj.Filein[f, version];
outline ← GGOutline.AddHole[outline, hole];
ENDLOOP;
};
SliceClassFromRope: PROC [className: Rope.ROPE] RETURNS [type: ATOM] = {
RETURN[Atom.MakeAtom[className] ];
};
END.