I’ve started porting the Linkage software to the Macintosh (“Mac” for those of you who have never heard it called by its “real” name). So far, the only problems I’ve had are those related to the design being done wrong; The language changes are insignificant since I program in C++, C#, Java, and Swift all the time (and sometimes all on the same day). The design, however, is tricky. I’ll explain a few details in this post.
There is a C++ source code file named “geometry.cpp” that contains class definitions for elements such as points, lines, circles, arcs, and a few others. This is the first file I’m copying to swift. One of the first design choices I made is to use Swift structures instead of classes. This might be a bad choice because the Swift structures cannot be used in a hierarchy without a bit of a kludge that incolves creating a protocol and then implementing default functions in an extension of the protocol itself. Fortunately, only the Line and Segment structs need this sort of hierarchy so far. I suspect that Circle and Arc structs will also need to work in the same way where both of them are based on a common protocol that implements all functions common to both types. There is not much of a difference between a line and a line segment in the code except for the name of the structure and yet there is no simple way to handle this in Swift. But since the size of these types is so small, there only being four floating point values for a line and no other data, using a struct should improve performance quite a bit. I could use classes but I do not like the idea that a class object is always created on the heap and has reference counting. C++, on the other hand, allocates new local objects on the stack and does not have reference counting for those objects so using classes in C++ was not a performance issue. This makes C++ the clear winner when it comes to performance but the loser when it comes to my having to manage memory for objects that are not on the stack.
One of the other issues I’m dealing with is the lack of a good separation of the data and user interface code in my design. I wrote the Linkage app in C++ using Microsoft tools from 1992 and I separated the data from the User interface code using two basic classes, the document class, and the view class. The view class code in most cases doesn’t act directly on the data and passes on actions from the user interface, such as selecting an element, to the document itself. The document contains all of the data as well as all of the code to alter it. The issue I’m concerned about is that the document has functions for selecting elements within an area – it just doesn’t know anything about the area being visible to the user or being zoomed in or out. Well, it does know a tiny bit about the zoom since the zoom level is saved with the document data. That’s a weird oddity but not of real concern since it is only designed that way so that the zoom can be saved to the data file. I just wonder if I should try to separate these components more than they are already separated. One idea is to use the MVVM “pattern” which has a model (the data), a view, and a thing called a view model. I have not yet seen a good concrete example of a view model in anything I’ve read on this subject and most documentation just discusses what the view model might be without showing much in the way of clean meaningful and real-world code. When there is code, it is often in the context of an app that accesses a database and has example code to access that database; None of the examples seem to show how something like Microsoft Word might work in this regard. A lot of the examples and descriptions also talk about binding where changes to the data are propagated back to the view using background/hidden code that C++ doesn’t have. So in this regard, I may be stuck just porting my giant view and giant document classes to Swift as-is.
The User Interface is another point of concern. I used the Microsoft ribbon bar concept for the toolbar in the Linkage app. I think it works well and it replaces the main menu. There was hate for this when it was first introduced but not a single hater had any concerns of substance and they were just reacting to change itself – they really didn’t like their sacred menu going away. The one downside of the ribbon bar is its height, and in a word processing program, I might be concerned about the loss of visual height in the editor window. That’s not a real concern for the Linkage program from my extensive experience using it. Apple decided that they don’t like the idea of losing the menu and using only a tall toolbar, and there is no way to get multiple rows of buttons in what toolbar they do provide; There is no easy way to drop in a second toolbar below the first. I’m stuck changing things to suit this new UI model and I don’t know if I like it much because I like every feature to be one click away, not two clicks and a long mouse movement just to get the menu in the first place. Reducing mouse movements and clicks was one of the primary goals of the original Linkage projects since the UI is mostly mouse driven.
So far, I have maybe 75% of the geometry code ported. I’ll soon just move on and finish the unfinished work when it is needed. The next step will be to port the very large and complicated document class. I’ll start with porting the link, connector, and other data elements and then follow up that work with porting the XML parsing so I can open documents. From there, I’ll next move to porting the view class and try to get something drawn on the screen. I might forego finishing each file and just port what is needed to get to being able to draw in the window; Then I can add functionality one bit at a time until I’m done. I’m looking forward to being able to show screen shots in my blog but I’m sure that I’m six months away from that, at least.