]> Shamusworld >> Repos - architektonas/blob - src/fileio.cpp
In the middle of refactoring objects for loading/saving.
[architektonas] / src / fileio.cpp
1 //
2 // fileio.cpp: Architektonas file save/load support
3 //
4 // Part of the Architektonas Project
5 // (C) 2013 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
7 //
8 // JLH = James Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -------------------------------------------------------------
12 // JLH  02/20/2013  Created this file
13 //
14
15 #include "fileio.h"
16
17 //#include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <vector>
21 #include "arc.h"
22 #include "circle.h"
23 #include "container.h"
24 #include "dimension.h"
25 #include "line.h"
26
27 enum ObjectType { OTContainer, OTContainerEnd, OTLine, OTCircle, OTArc, OTDimension,
28         OTPolygon, OTText, OTImage, OTBlock, OTEndOfFile };
29
30
31 /*static*/ bool FileIO::SaveAtnsFile(FILE * file, Container * object)
32 {
33         /* Approach: loop through the container, doing a depth-first traversal. Any extra
34            containers found are looped through until there aren't any more down, then
35            ordinary objects are described. This can be handled by a virtual Object function
36            that reports the object by itself if it's a non-Container, otherwise it
37            enumerates all objects within itself. */
38
39         fprintf(file, "ARCHITEKTONAS DRAWING V1.0\n");
40 #if 1
41         object->Enumerate(file);
42         fprintf(file, "END\n");
43         return true;
44 #else
45         return false;
46 #endif
47 }
48
49
50 /*static*/ bool FileIO::LoadAtnsFile(FILE * file, Container * drawing)
51 {
52 //      char buffer[256];
53         float version;
54
55         fscanf(file, "ARCHITEKTONAS DRAWING V%f", &version);
56
57 //printf("Load: version = %f\n", version);
58         if (version != 1.0)
59                 return false;
60         /* Approach: read each object in the file, one by one. If the object is a Container,
61            add objects to it until an "endContainer" marker is found. This will require a
62            stack to maintain the current Container. */
63
64 #if 1
65         std::vector<Container *> containerStack;
66         Container * currentTopContainer = drawing;//new Container(Vector(0, 0));
67         Object * object;
68 //      ObjectType objectType;
69         int objectType;
70
71         while (!feof(file))
72         {
73                 if (FileIO::GetObjectFromFile(file, currentTopContainer, &object, &objectType) == false)
74                         return false;
75
76                 // object->type down below can be replaced with objType.
77                 // Above could be: bool FileIO::GetObjectFromFile(FILE *, Object *, ObjectType *);
78                 // where the return value tells if it's a valid object, Object * returns the
79                 // reconstructed object and ObjectType * returns the object type.
80
81                 if (objectType == OTEndOfFile)
82                 {
83 printf("Load: container size = %li\n", drawing->objects.size());
84                         return true;
85                 }
86                 else if (objectType == OTContainer)
87                 {
88                         containerStack.push_back(currentTopContainer);
89                         currentTopContainer = new Container(Vector(0, 0), currentTopContainer);
90                 }
91                 else if (objectType == OTContainerEnd)
92                 {
93                         Container * containerToAdd = currentTopContainer;
94                         currentTopContainer = containerStack.back();
95                         containerStack.pop_back();
96                         currentTopContainer->Add(containerToAdd);
97                 }
98                 else
99                 {
100                         currentTopContainer->Add(object);
101 printf("Load: Adding object. Container size = %li (%li)\n", drawing->objects.size(), currentTopContainer->objects.size());
102                 }
103         }
104
105         return false;
106 #else
107         return false;
108 #endif
109 }
110
111
112 /*static*/ bool FileIO::GetObjectFromFile(FILE * file, Object * parent, Object ** object, int * objectType)
113 {
114         char buffer[256];
115         fscanf(file, "%s ", buffer);
116         bool recognized = false;
117 //printf("Load: buffer = \"%s\"\n", buffer);
118
119         if (strcmp(buffer, "LINE") == 0)
120         {
121 //printf("      Found LINE.\n");
122                 recognized = true;
123                 Vector v1, v2;
124                 fscanf(file, "(%lf,%lf) (%lf,%lf)", &v1.x, &v1.y, &v2.x, &v2.y);
125 //printf("      Number of params recognized: %i\n", n);
126                 *object = new Line(v1, v2, parent);
127                 *objectType = OTLine;
128         }
129         else if (strcmp(buffer, "CIRCLE") == 0)
130         {
131                 recognized = true;
132                 Vector v;
133                 double r;
134                 fscanf(file, "(%lf,%lf) %lf", &v.x, &v.y, &r);
135                 *object = new Circle(v, r, parent);
136                 *objectType = OTCircle;
137         }
138         else if (strcmp(buffer, "ARC") == 0)
139         {
140                 recognized = true;
141                 Vector v;
142                 double r, a1, a2;
143                 fscanf(file, "(%lf,%lf) %lf, %lf, %lf", &v.x, &v.y, &r, &a1, &a2);
144                 *object = new Arc(v, r, a1, a2, parent);
145                 *objectType = OTArc;
146         }
147         else if (strcmp(buffer, "DIMENSION") == 0)
148         {
149                 recognized = true;
150                 Vector v1, v2;
151                 DimensionType type;
152                 fscanf(file, "(%lf,%lf) (%lf,%lf) %i", &v1.x, &v1.y, &v2.x, &v2.y, &type);
153                 *object = new Dimension(v1, v2, type, parent);
154                 *objectType = OTDimension;
155         }
156         else if (strcmp(buffer, "CONTAINER") == 0)
157         {
158                 recognized = true;
159                 *objectType = OTContainer;
160         }
161         else if (strcmp(buffer, "ENDCONTAINER") == 0)
162         {
163                 recognized = true;
164                 *objectType = OTContainerEnd;
165         }
166         else if (strcmp(buffer, "END") == 0)
167         {
168                 recognized = true;
169                 *objectType = OTEndOfFile;
170         }
171
172         return recognized;
173 }
174