Well, I realize that we have recently been in touch regarding your latest Canvas efforts, and that I certainly have provided more feedback than you were anticipating, so please take the following with a good grain of salt, because I am obviously biased when it comes to the MapStructure/NavDisplay frameworks and the Canvas system in general, having been involved in these efforts to some degree.
Basically, the ND/MapStructure frameworks came to be out of a certain degree of disagreement with other MFD/glass cockpit efforts using the Canvas system.
That was primarily because many of those lacked support for:
- truly independent instances
- reuse (other aircraft/use-cases, e.g. sharing common logic between aircraft displays and GUI dialogs)
- customization (think styling)
Especially, we found it hugely frustrating to see awesome avionics like the Avidyne Entegra R9 being developed for aircraft like the extra500, that were impossible to reuse for other aircraft cockpits, but that also contained features/code that would have been useful elsewhere (think mapping/charting displays).
So that more often than not, copy & paste was the only option to "reuse" useful code elsewhere.
Thus, the idea was to grow a library of generic building blocks that live in $FG_ROOT and that are sufficiently generic and customizable to basically enable people to collaborate more properly by providing a strong incentive via compelling functionality that can be easily maintained/updated in the future. The thinking was that all aircraft/GUI dialogs using a single back-end would automatically benefit from significant updates to the back-end that way (think performance, features etc).
Our strategy was to adopt a MVC (model/view/controller) approach, where the model would represent what is to be rendered, the view would map the Canvas system and its primitives (elements) and underlying APIs, whereas the controller would usually be use-case specific (think cockpit vs. GUI dialog).
Looking back in time, we did accomplish these goals only partially - mainly because while we actually have many aircraft using these building blocks today (think NavDisplay and MapStructure-based avionics) - the number of actual contributors, and contributions, however flowing back into the NavDisplay/MapStructure efforts has actually been marginal in comparison. As a matter of fact, only a handful of people have made working modifications to the NavDisplay/MapStructure framework, and most of these still live outside fgdata.
In contrast however, efforts like the extra500/Avidyne Entegra R9 have actually adopted /some/ of the techniques used by the MapStructure framework, while having seen more updates over time, despite still not supporting any form of "reuse".
While providing such a degree of reusability and customizability may seem like overkill, it is actually hard to beat the flexibility provided by this approach:
http://wiki.flightgear.org/Howto:Protot ... play_Style Thus, given how much time has passed and looking back at the lessons learnt during the porting efforts of Gijs' original NavDisplay code, and how we came up with the MapStructure framework subsequently vs. the number of other glass cockpit efforts (including those that actually proved to be successful, e.g. Richard's MFD framework), the best advice I can give to people wanting to implement new avionics using Nasal and the Canvas system can be distilled to be the following:
- absolutely do all prototyping/development of your MFD/avionics using a standalone GUI dialog - this won't just be much faster (compared to doing cockpit-centric development), but this is also crucial to actually making sure that you don't end up adding all sorts of hard-coded assumptions about the use-case or the aircraft the instrument is going to be used on. Which sooner or later will translate into more people/aircraft using your work, and contributing to it, or maintaining/updating it - possibly years after you may have moved on to other things.
- if you find that you need custom logic to support a certain use-case/aircraft (think GUI dialog), structure your code to encapsulate such logic using delegates, i.e. function callbacks that can be passed to the underlying code to accomplish IOC (Inversion of Control).
- for the ND/MapStructure, we ended up moving all these assumptions into a configuration hash, so that there are no hard-coded properties in the ND/MapStructure code, which is to say that -with a corresponding "driver hash", the ND/MapStructure code could just as well be driven by an AI/MP node from /ai/models instead of using /properties, /orientation etc in a hard-coded fashion
- if it is foreseeable that you need to switch a set of APIs, encapsulate those, too - we were facing that dilemma, when people wanted to use navigraph data directly instead of the built-in navdb/navcache, by using a driver hash, we can do away with all built-in navcache queries and use a different navdb source.
- do structure your MFD (and even a PFD) using something like Richard's MFD framework, i.e. using abstraction for pages, page items, menus and public state
- keep the multi-pilot (dual-control) and multi-instance (multiplayer vs. FSWeekend/LinuxTag) use-cases in mind, which is to say that MFD building blocks like a map should publish element specific public state that can be shared between fgfs instances to selectively propagate/replicate relevant state to other fgfs instances running the same code, which means that even complex avionics like a G1000 could be kept in sync in a multiplayer or multi-instance use case by only replicating a fraction of crucial key state, rather than sync'ing low-level Canvas primitives at the Canvas::Element level.
- For pretty much the same reason, I would strongly suggest to look at Richard's Emesary framework, and maybe get in touch with him in private to see if it's feasible to integrate his MFD/Emesary frameworks in a sane fashion, to actually "have our cake and eat it" - I would not underestimate the power of using this approach, it has taken us quite a bit of effort to accomplish this degree of loose coupling in the NavDisplay code, and had we had access to Richard's groundwork back then, things could have become much simpler and much more efficient.
- do permanently profile/benchmark (stress-test) your avionics (which is another good reason for supporting N independent instances), so that you are aware of where performance is spent - and if something shows up as a bottleneck, do document/share your findings, so that we can augment/extend the underlying C++ code.
- encapsulate all uses of timers and listeners that primarily animate MFD stuff, so that a more proper method can be easily adopted once it is made available
Apart from that, some of the more recent, and more successful Canvas related efforts involving the NavDisplay/MapStructure frameworks is certainly the Airbus related work done by artix and omega95 a while ago - however, I don't think any of that code actually made it back upstream (unfortunately).
And then, there's obviously the awesome extra500 avionics stack that is likely to contain very useful code - besides, Thorsten also mentioned on and off that he was hoping to -eventually- refactor some of his own shuttle drawing routines to grow a library of helpers for procedurally creating avionics.
Finally, regarding MapStructure specifically:
I believe that the framework is relatively well documented these days, and while it is true that most of these "docs" are indeed copied from the forum, I do believe it is still better than having no docs at all or than telling people to "just search the archives". Also, there is a fair number of working layers meanwhile, and these can usually be adapted easily to come up with new layers.
That being said, it is however true that there still is some legacy code pre-dating the MapStructure framework, originating from the days when I helped generalize Gijs' ND code, it can be identified easily by looking for *.draw files in $FG_ROOT/Nasal/canvas/map
And while I think that it's only the airports.xml dialog that you once created, that is still using the legacy back-end, it is still true that some of the more complex "layers" (=drawing routines) have not yet been ported at all (think taxiways).
Regarding your OverlayLayer idea, that seems like a good idea to me (and I think it's actually mentioned somewhere inn MapStructure.nas ?) - it would also seem useful for features like these:
Looking at your posting here and the questions you are posing, it is obvious that you have already looked at the MapStructure framework and actually read up on its internals, so kudos to you for that - however, it is also important to note that it isn't actually "finished" in the sense that it implements everything we were originally planning to implement.
Also, to be perfectly honest, we faced quite a few challenges over the last 5+ years using the Canvas system, and especially creating the NavDisplay/MapStructure, some of which are summarized at:
http://wiki.flightgear.org/Canvas_Devel ... FlightGearFor instance, vertical layers are not implemented/supported at all (e.g. VSD drawing) - omega95 ended up implementing his own VSD code to do this, not using the MapStructure framework.
Then again, everything you said about PFD related symbology (compass rose, airport diagram, lat/lon grid) is also something that we previously discussed, and it is not just referenced in the wiki article, but also in MapStructure.nas itself.
As a matter of fact, that kind of work would be useful in and of itself, because James (and I believe you yourself) mentioned previously that the map-canvas.xml dialog was missing those features (e.g. the lat/lon grid?).
James was actually hoping to phase out the hard-coded map dialog in favor of the Canvas version sooner or later:
http://wiki.flightgear.org/Canvas_MapSt ... map_dialogThus, I believe that these features could be easily prototyped, and tested, by extending the map-canvas.xml dialog - if a layer works there, it will also work elsewhere.
Regarding projection handling in general, I can only re-iterate my previous suggestion to look at James' hard-coded Map dialog and its commit logs - you will find that some of the most recent changes were contributed by Gijs, implementing support for a new/better projection without causing performance issues (see the referenced bug tracker ticket to read up on the details).
Besides, that would also be the right place to implement support for vertical projections, i.e. the stuff required to implement a VSD or approach profile without going through tons of Nasal code (which is something that would also be useful for the tutorial/flight instructor use-cases):
I guess, looking back at my own "advice", my suggestion would be to use the map-canvas.xml dialog as a testbed to implement some of the stuff that you need for the G1000 - it can also be trivially changed to render to a native Canvas GUI dialog, e.g. see:
http://wiki.flightgear.org/Canvas_Snipp ... o_a_CanvasEqually, it is relatively straightforward to review $FG_ROOT/Nasal/canvas/widgets to come up with an actual Canvas widget wrapping the MapStructure framework, that works for both, PUI as well as the Canvas GUI: