File: GGFileInImpl.mesa
Last edited by Bier on May 14, 1987 12:54:40 pm PDT
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, May 12, 1987 6:51:41 pm PDT
DIRECTORY
Atom, AtomButtonsTypes, Convert, FS, GGBasicTypes, Feedback, GGEvent, GGFileIn, GGInterfaceTypes, GGModelTypes, GGScene, GGParseIn, GGSegmentTypes, GGSlice, GGUtility, Imager, ImagerColor, IO, Rope, ViewerClasses;
GGFileInImpl:
CEDAR
PROGRAM
IMPORTS Atom, Convert, Feedback, GGEvent, GGScene, GGParseIn, GGSlice, GGUtility, IO, Rope
EXPORTS GGFileIn = BEGIN
Viewer: TYPE = ViewerClasses.Viewer;
Color: TYPE = Imager.Color;
FeedbackData: TYPE = AtomButtonsTypes.FeedbackData;
GGData: TYPE = GGInterfaceTypes.GGData;
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] = Feedback.Problem;
FileinSceneAndOptions:
PUBLIC
PROC [f:
IO.
STREAM, ggData: GGData] = {
sceneName: Rope.ROPE;
scene: Scene ← ggData.scene;
version: REAL;
count: NAT;
entity: Slice;
finger, newEntities:
LIST
OF Slice;
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, version, ggData];
Read in the scene entities
GGParseIn.ReadBlankAndRope[f, "Entities:"];
GGParseIn.ReadBlankAndRope[f, "["];
count ← GGParseIn.ReadBlankAndNAT[f];
GGParseIn.ReadBlankAndRope[f, "]:"]; GGParseIn.ReadWhiteSpace[f];
[newEntities, finger] ← GGUtility.StartSliceList[];
FOR i:
NAT
IN[1..count]
DO
entity ← FileinEntity[f, version, ggData.feedback];
IF entity#NIL THEN [newEntities, finger] ← GGUtility.AddSlice[entity, newEntities, finger];
ENDLOOP;
GGScene.AddSlices[scene, newEntities];
f.Close[];
};
ReadOptions:
PROC [f:
IO.
STREAM, version:
REAL, ggData: GGData] = {
keyWord, option: Rope.ROPE;
good: BOOL;
nextChar: CHAR;
twoCRsFound: BOOL ← FALSE;
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, version, ggData];
nextChar ← IO.PeekChar[f];
IF nextChar =
IO.
CR
THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
ENDLOOP;
};
ProcessOption:
PROC[keyWord, option: Rope.
ROPE, version:
REAL, ggData: GGData] = {
optionStream: IO.STREAM ← IO.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 ← Convert.RealFromRope[list.first];
GGEvent.AddSlopeInternal[ggData, 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 ← Convert.RealFromRope[list.first];
GGEvent.AddAngleInternal[ggData, 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 ← Convert.RealFromRope[list.first];
GGEvent.AddRadiusInternal[ggData, 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 ← Convert.RealFromRope[list.first];
GGEvent.AddDistanceInternal[ggData, value];
ENDLOOP;
};
Rope.Equal[keyWord, "Midpoints",
FALSE] => {
on, good: BOOL;
[on, good] ← GGParseIn.ReadBOOL[optionStream, version];
GGEvent.SetMidpointsInternal[ggData, 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: Slice;
finger, newEntities:
LIST
OF Slice;
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 SkipOptions[f];
Read in the scene entities
GGParseIn.ReadBlankAndRope[f, "Entities:"];
GGParseIn.ReadBlankAndRope[f, "["];
count ← GGParseIn.ReadBlankAndNAT[f];
GGParseIn.ReadBlankAndRope[f, "]:"];
[newEntities, finger] ← GGUtility.StartSliceList[];
FOR i:
NAT
IN[1..count]
DO
entity ← FileinEntity[f, version, NIL];
IF entity#NIL THEN [newEntities, finger] ← GGUtility.AddSlice[entity, newEntities, finger];
ENDLOOP;
GGScene.AddSlices[scene, newEntities];
f.Close[];
};
SkipOptions:
PROC [f:
IO.
STREAM] = {
keyWord, option: Rope.ROPE;
good: BOOL;
nextChar: CHAR;
twoCRsFound: BOOL ← FALSE;
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, ggData];
nextChar ← IO.PeekChar[f];
IF nextChar =
IO.
CR
THEN {
[] ← IO.GetChar[f];
twoCRsFound ← TRUE;
};
ENDLOOP;
};
FileinEntity:
PROC [f:
IO.
STREAM, version:
REAL, feedback: FeedbackData]
RETURNS [entity: Slice] = {
nextWord: Rope.ROPE;
IF version > 8605.22
THEN {
IF version >= 8705.14
THEN {
entity ← FileinSlice[f, version, feedback];
}
ELSE {
nextWord ← GGParseIn.ReadBlankAndWord[f];
SELECT
TRUE
FROM
Rope.Equal[nextWord, "Outline:"] => {
class: SliceClass ← GGSlice.FetchSliceClass[$Outline];
entity ← class.filein[f, version, feedback];
};
Rope.Equal[nextWord, "Slice"] => {
entity ← FileinSlice[f, version, feedback];
};
ENDCASE => ERROR
}
}
ELSE {
nextWord ← GGParseIn.ReadBlankAndWord[f];
SELECT
TRUE
FROM
Rope.Equal[nextWord, "Outline:"] => {
class: SliceClass ← GGSlice.FetchSliceClass[$Outline];
entity ← class.filein[f, version, feedback];
};
Rope.Equal[nextWord, "Cluster"] => {
entity ← FileinSlice[f, version, feedback];
};
ENDCASE => ERROR;
};
};
FileinSlice:
PROC [f:
IO.
STREAM, version:
REAL, feedback: FeedbackData]
RETURNS [slice: Slice] = {
className: Rope.ROPE;
type: ATOM;
class: SliceClass;
IF version >= 8705.14
THEN {
className ← GGParseIn.ReadBlankAndWord[f];
}
ELSE {
childCount: NAT;
GGParseIn.ReadBlankAndRope[f, "(class:"];
className ← GGParseIn.ReadBlankAndWord[f];
GGParseIn.ReadBlankAndRope[f, ")"];
GGParseIn.ReadBlankAndRope[f, "["];
childCount ← GGParseIn.ReadBlankAndNAT[f];
GGParseIn.ReadBlankAndRope[f, "]:"];
GGParseIn.ReadBlankAndRope[f, "Data:"];
};
type ← SliceClassFromRope[className];
class ← GGSlice.FetchSliceClass[type];
slice ← class.filein[f, version, feedback];
};
SliceClassFromRope:
PROC [className: Rope.
ROPE]
RETURNS [type:
ATOM] = {
RETURN[Atom.MakeAtom[className] ];
};
END.