It turns out we *do* support the use of anonymous commands
(while it is not clear yet if we really need this feature).
Basically, client code may either create and register a new
instance from another command used as prototype, by invoking
Command::storeDef(ID). Or, alternatively it may just invoke
newInstance() on the command, which creates a new handle
and a valid new implementation (managed by the handle as
smart-ptr), but never stores this implementation into the
CommandRegistry. In that case, client code may use such a
command just fine, as long as it cares to hold onto that
handle; but it is not possible to retrieve this command
instance later by symbolic ID.
In the light of this (possible) usage pattern, it doesn't
make sense to throw when accessing a command-ID. Rather, we
now return a placeholder-Symbol ("_anonymous_")
after reading some related code, I am leaning towards a design
to mirror the way command messages are sent over the UI-Bus.
Unfortunately this pretty much abandons the possibility to
invoke these operations from a client written in C or any
other hand made language binding. Which pretty much confirms
my initial reservation towards such an excessively open
and generic interface system.
...this means to turn Looper into a state machine.
Yet it seems more feasible, since the DispatcherLoop has a nice
checkpoint after each iteration through the while loop, and we'd
keep that whole builder-dirty business completely confined within
the Looper (with a little help of the DispatcherLoop)
Let's see if the state transition logic can actually be implemented
based just on such a checkpoint....?
...it occurred to me that very likely a casual reader of the code
will encounter here the first instance of such a diff binding function.
I am well aware this looks intimidating (and it is a tricky technical detail)
Even more so, if what you expect is just some access to a shared data model,
you might be completely puzzled by this code and nor recognise its importance.
Damn sideeffect of the suppport for move-only types: since we're
moving our binding now into place /after/ construction, in some cases
the end() iterator (embedded in RangeIter) becomes invalid. Indeed this
was always broken, but didn't hurt, as long as we only used vectors.
Solution: use a dedicated init() hook, which needs to be invoked
*after* the TreeMutator has been constructed and moved into the final
location in the stack buffer.
unintentionally we used copy construction in the builder expression,
wenn passing in the CollectionBinding to the ChildCollectionMutator.
The problem is that CollectionBinding owns a shaddow buffer, where
the contents of the target collection are moved temporarily while
applying the diff. The standard implementation of copy construction
would cause a copy of that shaddow buffer, which boils down to
a copy of the storage of the target collection.
If we want to support move-only types in the collection, most notably
std::unique_ptr, we can thus only use the move constructor. Beyond that
there is no problem, since we're only ever moving elements, and new
elements will be move constructed via emplace() or emplace_back()
...this is the first attempt to integrate the Diff-Framework into (mock) UI code.
Right now there is a conceptual problem with the representation of attributes;
I tend to reject idea of binding to an "attribute map"
the generic typing to DiffMutatble does not make much sense,
since the desired implementation within gui::ctrl::Nexus
is bound to work on Tangibles only, since that is what
the UI-Bus stores in the routing table
at first, this seemed like a good idea, but it caused already
numerous quirks and headache all over the place. And now, with
the intent to switch to the TreeMutator based implementation,
it would be damn hard to retain these features, if at all
possible.
Thus let's ditch those in time and forget about it!