So, I actually managed to squeeze out a few rare slices of ‘me’ time this week in between other things, and put some of it into my elusive ‘Tool Project’. I’ve basically made little outward progress on this for a while for two reasons - one, a glut of business talks (some of which have turned into real project work, some of which haven’t yet) has meant time has been very, very short, and two, some knotty design issues. My inability to decide how precisely to tackle certain aspects of this project, especially when given only small windows of time to ponder it, has left me frequently frustrated and sometimes feeling like the ‘Tool’ in question. Generally I think I’m pretty competent at software design, but there have been a few aspects on this one that have had me second-guessing and changing tack more often than a schizophrenic at a buffet.
Part of the reason has been my need to have a design which is probably a little more abstract than might strictly be necessary (hey, this is me we’re talking about), but the other part is that I’ve really never had to do something quite like this before. I’ll talk here about just one of the more minor design issues I’ve tackled - in fact there have been a cluster of them, all rather interrelated so teasing them apart has also been part of the issue.
For reasons I’m not willing to go into in detail right now, I need to have completely ‘pluggable’ UI idioms - that is at no point can I assume precisely how the UI will work in a given context. There will obviously be a defined structure underlying it, but up to a certain point absolutely nothing can be assumed about what goes on in those viewports in response to clicks, drags, keypresses etc. That means you could click on ‘Clever Tool A’ and in the viewer panes you get a completely different way of working, be that key bindings, mouse processing, overlaid feedback visuals, and widgets (in 3D and flat panel). I’m sure all tools like XSI have to tackle this sort of problem too, but it’s new to me.
Now, for obvious reasons my tool is already structured along Model-View-Controller pattern lines. Whenever I’ve used this pattern in the past, the Model and View components are always the most obvious to identify. The Controller is also easy to identify in a web system, and Martin Fowler explictly identifies such uses as their own subpatterns, such as the Page Controller. Otherwise, the Controller is often rather overlooked, and indeed Fowler makes the claim that it’s often just subsumed into the View because it has a 1:1 relationship with the View, beyond cases such as supporting editable and non-editable behaviour. I’d originally followed this approach too.
However, in tackling the above scenario, I quickly realised that having far more granular Controller objects was the only neat way to manage not being able to predict precisely how a given UI works. Beyond just about having customised visual elements, the fact that the user should be able to switch back and forth between tools which may respond entirely differently to input in the view panes meant being able to plug in Controller instances for given contexts was invaluable. As a test, I basically refactored all of my basic inbuilt tools (selection, camera tools etc) to use this same basis; so rather than the input system knowing that you were in ‘Select Mode’, or ‘Orbit Camera Mode’ for example and processing mouse input based on that, instead SelectController or OrbitCamController instances are plugged in, without the surrounding systems ever knowing anything is different. Works pretty well. I believe I may also need to explore ‘stacks’ of controllers for when incrementally combining behaviour too, and for temporarily swapping behaviours, but that can come later.
It’s a shame that manipulation of the Controller element of the MVC pattern is often overlooked by most books / articles, beyond the typical web routing / navigation / front controller patterns, because it can be very useful in contexts like this. This approach gives me a platform on which I can start addressing the other more specific design challenges. Unfortunately for this project (but fortunately for my often dubious cashflow), I’m just about fully booked on client work next week so I’ll have to put this down again until time permits. Grabbing small isolated slots of time isn’t the most effective way of doing stuff like this, but needs must 😀