To be honest, I can fully relate to Thorstens point of view - but I don't think this is a fair summary of the events, also like I said, the approaches/nature of the code in question is very different.
We kinda had the same discussion about the shuttle draw helpers in the context of rleibner's original work.
Also, to be fair, this isn't exactly a first either - for instance, the shuttle's trajectory map could have also been implemented using the existing Canvas "Map" API, i.e. by adding to it, rather than coding it from scratch (the corresponding postings can still be found on the forum, so I fully get your point for not getting involved there).
Likewise, there are people now doing their own NDs, rather than adding to the existing ND stuff, and other people creating their own mapping frameworks, rather than using "MapStructure".
So I think the shuttle, or you (Thorsten), have been on both ends of this, so you can certainly also relate to using/not using a certain approach.
Like I said, as far as I remember, the shuttle helpers were fairly generic/simple, and strictly procedural - i.e. there was no support for customizing things, or support for IoC by passing an options hash and/or delegates into the corresponding function - also, to be fair, the MapStructure 2D drawing helpers even predate the shuttle by several years...
So all of us have experience being on both sides of the dilemma - especially the Extra500 contains a ton of great code, that is hardly reusable, and some of it was written from scratch, despite existing code having been around for years.
To be honest, I don't think there is any real "solution" available - other than encouraging people to use a library/framework-centric approach so that they're able to factor out useful stuff, so that it can be eventually added to the base package.
Other than that, the real problem lies elsewhere, and isn't specific to the Canvas system, like you said: it's Nasal and its "free-form-nature" that supports a plethora of pathways to get functionality added, and more often than not, people are not enormously experienced contributors, so that the whole notion of "inversion-of-control", "injection of heuristics", "passing delegates" or "options hashes", or doing proper OOP, let alone "MVC" is obviously very far-fetched ...
This is something where Emesary could help people implement generic solutions that can be easily reused, unfortunately that's another undocumented thing, and people will need a strong programming background to see the merits of pursuing that route. I believe, so far, Stuart is the only one (except for Richard himself obviously) to use Emesary for some actual project, i.e. the FG1000.
In my eyes, by and large this is primarily a way of how we've come to expose the Canvas system via Nasal to scripting space, it would have been far better to use encourage a framework-centric paradigm, where higher level drawing primitives can be created on top of lower level primitives (think canvas elements like path, text, image, group), with well-defined I/O properties to manipulate those.
This is how the existing Canvas.Widget system works, i.e. the one implemented by TheTom back in 2012 - and it supports inheritance, too - analogous to how effects can inherit from each other - that way, we could create a dedicated canvas element named "HSI" that would inherit from "compass rose", which would in turn inherit from a lower level draw framework.
This kind of setup would then also make it trivial to get rid of the legacy 2D panels code, at the mere cost of writing a parser to interpret/map 2D panels to canvas gauges (analogous to how pui2canvas works).
Once we encourage an element-based extension mechanism, where new drawing primitives can be prototyped/implemented and registered in scripting space, we will also see more work flowing back in a generic form, i.e. without being specific to certain aircraft/avionics. This is something where we as a project failed, because nobody could foresee the impact of the Canvas system back in 2012.
The implication of this, as well as the major benefits of pursuing such a decoupled approach, are magnified by looking at multi-instance use-cases, i.e. those having to use multiple instances of a single instruments/screen (device), but also multiple inter-linked fgfs instances (think multiplayer/multi-pilot, but also LinuxTag/FSWeekend).
What we're currently doing doesn't scale at all - besides, we don't currently provide a good mechanism to easily wrap/re-implement performance-critical functionality in native code/C++ - and that, too, would change immediately once all future Canvas MFDs/avionics would be implement as stacked elements implemented in scripting space, using lower-level elements implemented in native code. Whenever a certain scripted element (think HSI or PFD) should become an issue, it could be easily re-implemented in native code, without people having to update their code.
This is a long-standing issue, and it has been repeatedly discussed here and on the mailing list - so, what's needed is allowing frameworks and elements to be scripted in Nasal, so that they can be registered as scripted canvas elements, with their own well-defined I/O properties that are "element" specific (think hsi-heading, vor-obs, station-station etc).
At that point, it would also become a piece of cake to inter-link multiple fgfs instances, regardless of the purpose (multiplayer/dual-pilot or multi-instance setups showing different screens)
http://wiki.flightgear.org/Canvas_Devel ... FlightGear