As more and more people are using and asking for features in libchamplain, I face a difficult challenge getting the current design to do new extraordinary things.
Here are the top features that can (or can’t) only be hacked into the current design:
- To be able to replace the Clutter front end;
- To have a global state for the library (ie. loading or done);
- To have the tiles rendered on demand;
- To have our own map sources;
- To have a smooth animation when recentering the map;
- To have a zoom in/out animation.
The first feature is really the one that calls for a new architecture. The current design relays heavily on Clutter, even for internal data representation. This breaks the golden MVC rule and it is my first goal in this redesign.
Having the tile loading code interweaved with the model really makes it more ugly to have feature #2 and #3. With a controler actually building the model, the tiles could come from elsewhere without making the model much more complex and the loading code can be placed together resulting in less places where the states change.
And finaly, since the view is also the controler which modifies the model, having the animations code inside the view makes some animations tricky.
While at it, why not take into account some special requirements, such a non blocking calls. Clicking on the zoom in button should call the zoom in function, which should return as fast as possible not to block the UI.
First design steps
First I thought about the visibility of each objects. Since I want minimal impact on the current API, I will keep the View as the main interaction point between an application and libchamplain. To fulfill feature #4, a ChamplainMapSource interface will be created. This is how it works internally right now, but instead of an interface, there is a struct of function pointers.
The whole data model will be available to an application wishing to implement its own map source. It will have helper controler classes such as a map loader, and eventually a map renderer.
The view should be sending the user’s actions to the main controler, which will be called ChamplainEngine. This engine will be in charge of keeping the global settings, state and a reference to the model. When the model changes, the view will be informe through different signals and notifications on properties’ changes.
Trying the design on paper
So I went on use this very good online sequence diagram generator to define precisely who will be responsible for instanciating objects, notifying the view and loading stuff. I tried to stick to this rule: all model changes should happen from ChamplainEngine.
So here some of the diagrams I created.
Those diagrams enabled me to test the task division and define very precisely how the view will get informed of the model’s changes. Implementing this design should now be very fast, granted I don’t run into unattended issues!