X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffileio.cpp;h=b64e5bd200fa05ac1223dd337133abe522c19896;hb=70297ac8ec7453e4196f4b58056bcfe4b04f2aca;hp=fedddea4fea6729a917fe15510420aa829bef802;hpb=eb0057e8a8145032152e4c417fcd102ef5a21484;p=architektonas diff --git a/src/fileio.cpp b/src/fileio.cpp index fedddea..b64e5bd 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -24,8 +24,87 @@ #include "dimension.h" #include "line.h" -enum ObjectType { OTContainer, OTContainerEnd, OTLine, OTCircle, OTArc, OTDimension, - OTPolygon, OTText, OTImage, OTBlock, OTEndOfFile }; +/* +How to handle connected objects +------------------------------- + +Every Object has a vector which enumerates all Objects connected to +the one we're looking at. So it looks like we'll have to take a two pass +approach to loading and saving. + +Basically, in the saving case, first we write out all objects, keeping a +pointer-to-index-number record. Second, we loop through all the objects we +wrote out, writing connection lists. Format (indices are 1-based): + +CONNECTIONS +1: 12 3 +3: 1 +12: 1 +ENDCONNECTIONS + +In the reading case, we do pretty much the same: we construct pointer-to-index- +number list, then read the connection list. The PTIN connects the index to the +Object pointers we've created. Then we simply call the Object's Connect() +function to connect the objects. + +Small problem though: How does a Dimension know which points on a Line it's +connected to? This approach tells the Dimension it's connected to the Line and +the Line that it's connected to the Dimension, but not which points. + +How to handle them then? Do we list the point with the Object pointed at? A +Line can contain an infinite number of points to connect with besides its +endpoints. + +So with each connection Object in the vector, there would also have to be a +corresponding point to go with it, that would be gotten from the other Object's +Connect() function. Or, instead of a point, a parameter value? + +Doing that, with the Line and a parameter "t", if t == 0 we have endpoint 1. +if t == 1, then we have endpoint 2. With a Circle, the parameter is a number +between 0 and 1 (scaled to 0 to 2π). With an Arc, the parameter goes from 0 to +1, 0 being enpoint 1 and 1 being endpoint 2. + +How does this work for moving objects that are connected? Again, with the Line +and Dimension. The Line's connections looks like this: + +Object *: dim1, t = 0 +Object *: dim1, t = 1 + +Dimension looks like this: + +Object *: line1, t = 0 +Object *: line1, t = 1 + +For Dimensions, it can query the connected object (if any) using something like +GetPointForParameter(). That way it can figure out where its endpoints are. If +there is no connected point, then it uses its internal point. + + +Dimensions are special cases of lines: They have exactly *two* points and none +in between. Therefore, the Dimension object only needs to have two points. But +those points can be connected to multiple objects. The can also be connected to +no points/Objects too. + +How to describe them and their connections (or lack thereof)? + +Would have to be a 2nd pass, after all objects have been written out in order. +Then you could do something like: + +DIMCONNECTIONS +8 (the Dimension #): 1 (the Object # for point 1) 1 (the Object # for point 2) +ENDDIMCONNECTIONS + + + +Connection attributes: E.g., between a Line a Circle, it can be tangent, +perpendicular, or an arbitrary angle. How to encode that information? It's not +intrinsic to either the Line or the Circle, but is a function of the +relationship between them by virtue of their connection. + +*/ + +enum ObjectTypeFile { OTFContainer, OTFContainerEnd, OTFLine, OTFCircle, OTFArc, OTFDimension, + OTFPolygon, OTFText, OTFImage, OTFBlock, OTFEndOfFile }; /*static*/ bool FileIO::SaveAtnsFile(FILE * file, Container * object) @@ -78,17 +157,17 @@ enum ObjectType { OTContainer, OTContainerEnd, OTLine, OTCircle, OTArc, OTDimens // where the return value tells if it's a valid object, Object * returns the // reconstructed object and ObjectType * returns the object type. - if (objectType == OTEndOfFile) + if (objectType == OTFEndOfFile) { printf("Load: container size = %li\n", drawing->objects.size()); return true; } - else if (objectType == OTContainer) + else if (objectType == OTFContainer) { containerStack.push_back(currentTopContainer); currentTopContainer = new Container(Vector(0, 0), currentTopContainer); } - else if (objectType == OTContainerEnd) + else if (objectType == OTFContainerEnd) { Container * containerToAdd = currentTopContainer; currentTopContainer = containerStack.back(); @@ -124,7 +203,7 @@ printf("Load: Adding object. Container size = %li (%li)\n", drawing->objects.siz fscanf(file, "(%lf,%lf) (%lf,%lf)", &v1.x, &v1.y, &v2.x, &v2.y); //printf(" Number of params recognized: %i\n", n); *object = new Line(v1, v2, parent); - *objectType = OTLine; + *objectType = OTFLine; } else if (strcmp(buffer, "CIRCLE") == 0) { @@ -133,7 +212,7 @@ printf("Load: Adding object. Container size = %li (%li)\n", drawing->objects.siz double r; fscanf(file, "(%lf,%lf) %lf", &v.x, &v.y, &r); *object = new Circle(v, r, parent); - *objectType = OTCircle; + *objectType = OTFCircle; } else if (strcmp(buffer, "ARC") == 0) { @@ -142,7 +221,7 @@ printf("Load: Adding object. Container size = %li (%li)\n", drawing->objects.siz double r, a1, a2; fscanf(file, "(%lf,%lf) %lf, %lf, %lf", &v.x, &v.y, &r, &a1, &a2); *object = new Arc(v, r, a1, a2, parent); - *objectType = OTArc; + *objectType = OTFArc; } else if (strcmp(buffer, "DIMENSION") == 0) { @@ -151,22 +230,22 @@ printf("Load: Adding object. Container size = %li (%li)\n", drawing->objects.siz DimensionType type; fscanf(file, "(%lf,%lf) (%lf,%lf) %i", &v1.x, &v1.y, &v2.x, &v2.y, &type); *object = new Dimension(v1, v2, type, parent); - *objectType = OTDimension; + *objectType = OTFDimension; } else if (strcmp(buffer, "CONTAINER") == 0) { recognized = true; - *objectType = OTContainer; + *objectType = OTFContainer; } else if (strcmp(buffer, "ENDCONTAINER") == 0) { recognized = true; - *objectType = OTContainerEnd; + *objectType = OTFContainerEnd; } else if (strcmp(buffer, "END") == 0) { recognized = true; - *objectType = OTEndOfFile; + *objectType = OTFEndOfFile; } return recognized;