Commit graph

2880 commits

Author SHA1 Message Date
7145d0d9ce Timeline: ZoomWindow implementation draft
implement the first test case: nudge the zoom factor
⟹ scale factor doubled
⟹ visible window reduced to half size
⟹ visible window placed in the middle of the overall range
2022-10-30 01:31:25 +02:00
b3fe6e16c6 Timeline: requirement analysis to define the ZoomWindow (see #1196) 2022-10-29 01:59:42 +02:00
f393780845 Lib: fix a bug with diagnostic output
The header "format-cout.hpp" offers a convenience function
to print pretty much any object or data in human readable form.
However, the formatter for pointers used within this framework
switched std::cout into hexadecimal display of numbers and failed
to clean-up this state.

Since the "stickyness" of IOS stream manipulators is generally a problem,
we now provide a RAII helper to capture the previous stream state and
automatically restore it when leaving the scope.
2022-09-27 01:51:21 +02:00
ed7e3b4b32 ElementBox: extract builder qualifier support as library implementation
Complete the investigation and turn the solution into a generic
mix-in-template, which can be used in flexible ways to support
this qualifier notation.

Moreover, recapitulate requirements for the ElementBoxWidget
2022-08-28 23:36:27 +02:00
e15e893a01 Util: use case-insensitive matching for parsing bool values 2021-08-20 14:33:59 +02:00
4caf790339 Library: verify PlantingHandle's extended capabilities
- move construct into the buffer
- directly invoke the payload constructor through PlantingHandle
- reconsider type signature and size constraint
- extend the unit test
- document a corner case of c++ "perfect forwarding",
  which caused me some grief here
2021-05-07 22:50:13 +02:00
5a37bce855 Lib/Diff: extend PlantingHandle to allow for placment-new
...this extension was spurred by the previeous refactoring.
Since 'emplace' now clearly denotes an operation to move-embed an existing object,
we could as well offer a separate 'create' API, which would take forwarding
arguments as usual and just delegates to the placement-new operation 'create'
already available in the InPlaceBuffer class.

Such would be a convenience shortcut and is not strictly necessary,
since move-construction is typically optimised away; yet it would also
allow to support strictly non-copyable payload types.

This refactoring also highlights a fuzziness in the existing design,
where we just passed the interface type, while being sloppy about the
DEFAULT type. In fact this *is* relevant, since any kind of construction
might fail, necessitating to default-construct a placeholder, since
InPlaceBuffer was intended for zero-overhead usage and thus has in itself
no means to know about the state of its buffer's contents. Thus the
only sane contract is that there is always a valid object emplaced
into the buffer, which in turn forces us to provide a loophole for
class hierarchies with an abstract base class -- in such a case the
user has to provide a fallback type explicitly.
2021-05-02 19:40:11 +02:00
5aa41accfc Lib/Diff: prefer the name "emplace" over "build"
...for the operation on a PlantingHandle, which allows
to implant a sub type instance into the opaque buffer.

 * "create" should be used for a constructor invocation
 * "emplace" takes an existing object and move-constructs
2021-05-02 18:31:47 +02:00
73740a24e3 Clip-Drag: refactor into sub-component of TimelineLayout
this allows to avoid multi-step indirection
when translating mouse dragging pixel coordinates
into a time offset for the dragged clip widget.

Moreover this also improves the design,
since the handling of canvas metric is pretty much
a self contained, separate concern
2021-04-30 19:46:32 +02:00
db3a525d6e Clip-Drag: get the gesture logic to work
some bugfixes,
but also a notable change: detect the completion of the gesture
directly when the button is released; this is necessary, because
seemingly we do not get motion_events when no button is pressed,
at least not in this test setup based on a Gtk::Button widget.
2021-04-17 22:32:26 +02:00
b5cf8b2303 Clip-Drag: draft the dragging controller logic
direct implementation with state flags in-class
Intention is to refactor this into a state machine eventually
2021-04-17 19:43:29 +02:00
453ee08803 Clip: investigate how to enforce a fixed horizontal extension
GTK doesn't expose a first-class API for this,
since -- by design -- the extension of a widget is negotiated.
Thus I'm looking for some kind of workaround for our specific use-case,
where a clip widget must be rendered with a well defined horizontal size,
corresponding to its length.

Thus far, we're only able to increase the size of the Button widget
used as placeholder, but we can not forcibly shrink that button,
probably because the embedded Gtk::Lable requires additional extension.
2021-02-05 00:21:08 +01:00
2e4cd56f4f Relative-Hook: rectify the design
Partially as a leftover from the way more ambitious initial design,
we ended up with CanvasHook as an elaboration/specialisation of the
ViewHook abstraction. However, as it stands, this design is tilted,
since CanvasHook is not just an elaboration, but rather a variation
of the same basic idea.

And this is now more like a building pattern and less of a generic
framework, it seems adequate to separate these two variations completely,
even if this incurs a small amount of code duplication.


Actually this refactoring is necessary to resolve a bug, where
we ended up with the same Clip widgets attached two times to the
same Canvas control, one time through the ViewHook baseclass,
and a second time by the ctor of the "derived" CanvasHook
2021-01-30 13:29:50 +01:00
acb674a9d2 Project: update and clean-up Doxygen configuration
...in an attempt to clarify why numerous cross links are not generated.
In the end, this attempt was not very successful, yet I could find some breadcrumbs...

- file comments generally seem to have a problem with auto link generation;
  only fully qualified names seem to work reliably

- cross links to entities within a namespace do not work,
  if the corresponding namespace is not documented in Doxygen

- documentation for entities within anonymous namespaces
  must be explicitly enabled. Of course this makes only sense
  for detailed documentation (but we do generate detailed
  documentation here, including implementation notes)

- and the notorious problem: each file needs a valid @file comment

- the hierarchy of Markdown headings must be consistent within each
  documentation section. This entails also to individual documented
  entities. Basically, there must be a level-one heading (prefix "#"),
  otherwise all headings will just disappear...

- sometimes the doc/devel/doxygen-warnings.txt gives further clues
2021-01-24 19:35:45 +01:00
06dbb9fad5 DiffFramework: simplify existing bindings
...by relying on the newly implemented automatic standard binding
Looks like a significant improvement for me, now the actual bindings
only details aspects, which are related to the target, and no longer
such technicalitis like how to place a Child-Mutator into a buffer handle
2021-01-23 12:55:10 +01:00
05b5ee9a7e Diff-Framework: investigate simplification for the most common case
After this long break during the "Covid Year 2020",
I pick this clean-up task as a means to fresh up my knowledge about the code base

The point to note is, when looking at all the existing diff bindings,
seemingly there is a lot of redundancy on some technical details,
which do not cary much meaining or relevance at the usage site:

- the most prominent case is binding to a collection of DiffMutables hold by smart-ptr
- all these objects expose an object identity (getID() function), which can be used as »Matcher«
- and all these objects can just delegate to the child's buildMutator() function
  for entering a recursive mutation.
2021-01-22 12:38:45 +01:00
657b94a4e3 ++ a strange year passed by ++
read the code, documentation and mindmap to find out
at what point I was when this story unfolded
2021-01-20 08:05:30 +01:00
e33eae729b Relative-Hook: complete refactoring down to tracks and clips (see #1213)
...and the result was very much worth the effort,
leading to more focused and cleaner code.

 - all the concerns of moving widgets and translating coordinates
   are now confined to the second abstraction layer (CanvasHook)

 - while the ViewHook now deals exclusively with attachment, detachment
   and reordering of attachment sequence
2020-03-23 04:16:10 +01:00
f956f27ff4 Relative-Hook: build CanvasHook abstraction based on ViewHook
this refactoring was expedient, as the code becomes
way more legible within each of the two levels of abstraction
2020-03-23 02:02:06 +01:00
dd016667ad Diff-Listener: add a variant to trigger also on value assignment (see #1206)
As it turned out, it is rather easy to extend the existing listener
for structural changes to detect also value assignments. Actually
it seems we'd need both flavours, so be it.
2020-03-15 23:11:14 +01:00
0f6f09180e Lib: simplified optional access to nested record attributes
Yeah, C++17, finally!

...not totally sure if we want to go that route.
However, the noise reduction in terms of code size at call site looks compelling
2020-03-14 23:52:04 +01:00
c7d157e295 Library: integrate generic min/max function
...built while investigating type deduction problems on PtrDerefIter
...also allow PtrDerefIter to work with std::unique_ptr
2020-03-08 02:05:39 +01:00
0837498cc0 Relative-Hook: proof-of-concept based on ViewHook (see #1207)
this draft commit reshifts the (meanwhile broken) test code from:
03c358fe86

Now the marker Buttons are injected again, but without any detailed
positioning code at call site. This demonstrates the viability of the
Structure-Change / ViewHook refactoring.

To make this change viable, it was necessary to remove the ViewHooked<>
marker template from the rehook() callback. As it turns out, this was
added rather for logical reasons, and is in fact not necessary in
any of the existing ViewHook implementations (and I don't expect any
other implementations to come)

BUT the actual positioning coordinates are still wrong (which seems
to re related to other conceptual problems in coordinate offset handling)
2020-02-27 21:03:46 +01:00
b2b5cf0f6d MERGE: upgrade to Debian/Buster and to C++17 2020-02-22 02:16:25 +01:00
421a2ed49a C++17: some related clean-up 2020-02-21 23:55:09 +01:00
00c9ecb659 C++17: fix detector for function signatures
failure was likewise caused by `noexcept` being part of the signature type now
2020-02-21 20:16:59 +01:00
8c12e88fd3 C++17: fix detector for STL container iterability
the reason for the failure, as it turned out,
is that 'noexcept' is part of the function signature since C++17

And, since typically a STL container has const and non-const variants
of the begin() and end() function, the match to a member function pointer
became ambuguous, when probing with a signature without 'noexcept'

However, we deliberately want to support "any STL container like" types,
and this IMHO should include types with a possibly throwing iterator.
The rationale is, sometimes we want to expose some element *generator*
behind a container-like interface.

At this point I did an investigation if we can emulate something
in the way of a Concept -- i.e. rather than checking for the presence
of some functions on the interface, better try to cover the necessary
behaviour, like in a type class.

Unfortunately, while doable, this turns out to become quite technical;
and this highlights why the C++20 concepts are such an important addition
to the language.

So for the time being, we'll amend the existing solution
and look ahead to C++20
2020-02-21 18:57:49 +01:00
577592c66e C++17: isolate problematic code segments (see Ticket #1138)
as it turns out, "almost" the whole codebase compiles in C++17 mode.

with the exception of two metaprogramming-related problems:

 - our "duck detector" for STL containers does not trigger anymore
 - the Metafunction to dissect Function sigantures (meta::_Fun) flounders
2020-02-18 04:16:03 +01:00
3cfe5a13b1 fix failing test - boost::format is getting better
"%broken" is not broken anymore, but renders a boolean,
and we configured the formatter not to complain on missing values.

Fortunately "%madness" is still broken ;-)
2020-02-17 03:32:43 +01:00
38837da65e Timehandling: choose safer representation for fractional seconds (closes #939)
When drafting the time handling framework some years ago,
I foresaw the possible danger of mixing up numbers relating
to fractional seconds, with other plain numbers intended as
frame counts or as micro ticks. Thus I deliberately picked
an incompatible integer type for FSecs = boost::rational<long>

However, using long is problematic in itself, since its actual
bit length is not fixed, and especially on 32bit platforms long
is quite surprisingly defined to be the same as int.

However, meanwhile, using the new C++ features, I have blocked
pretty much any possible implicit conversion path, requiring
explicit conversions in the relevant ctor invocations. So,
after weighting in the alternatives, FSecs is now defined
as boost::rational<int64_t>.
2020-02-17 03:13:36 +01:00
cef7917d8e Diff-Listener: finished and unit test pass (closes: #1206) 2019-12-15 21:40:09 +01:00
d8b20ae497 Diff-Listener: fill in implementation
...basically just need to intercept three TreeMutator-operations
2019-12-15 04:04:25 +01:00
a33e236630 Diff-Listener: define API 2019-12-14 23:35:16 +01:00
806d569e06 Diff-Framework: resolve lurking problems with specific STL containers
basically the solution was a bit too naive and assumed everything is similar to a vector.
It is not, and this leads to some insidious problems with std::map, which hereby
are resolved by introducing ContainerTraits
2019-12-14 01:29:21 +01:00
8a5f1bc8d7 Diff-Listener: add a similar simplistic demo for opaque binding
based on a TreeMutator binding to a STL vector

...because this is probably the most frequently used case
2019-12-13 01:05:04 +01:00
3321e5bc6b Diff-Listener: need a really basic test
All of the existing "simple" tests for the »Diff Framework« are way to much low-level;
they might indeed be elementary, but not introductory and simple to grasp.
We need a very simplistic example to show off the idea of mutation by diff,
and this simple example can then be used to build further usage test cases.

My actual goal for #1206 to have such a very basic usage demonstration and then
to attach a listener to this setup, and verify it is actually triggered.

PS: the name "GenNodeBasic_test" is somewhat pathetic, this test covers a lot
of ground and is anything but "basic". GenNode in fact became a widely used
fundamental data structure within Lumiera, and -- admittedly -- the existing
implementation might be somewhat simplistic, while the whole concept as such
is demanding, and we should accept that as the state of affairs
2019-12-12 23:41:26 +01:00
c86f914915 Structure-Change: re-order entity naming
ViewHookable -> ViewHook
ViewHook -> ViewHooked
2019-12-12 17:02:24 +01:00
c501a38590 Structure-Change: fix test after refactoring / add lifecycle warning
now the lifecycle of widget and hook are tightly interwoven.
Indeed the test uncovered a situation where a call into the
already destroyed Canvas might halt the application.
2019-12-09 01:24:51 +01:00
0a20d18242 Structure-Change: implement the changed API and memory layout
NOTE: 2 test failures
2019-12-08 23:57:43 +01:00
99e367f33b Structure-Change: draft other API for hooking up widgets
...basically it occurred to me that in practice we will never have to deal
with isolated ViewHooks, rather with widgets-combinded-with-a-hook.
So the idea is to combine both into a template ViewHooked<W>
2019-12-08 21:09:25 +01:00
ffcac2ea1e Structure-Change: implement a simplistic implementation of re-ordering
...verified by the rather conceptual unit test
2019-12-06 23:19:09 +01:00
305ff8e6cc Structure-Change: draft API for re-ordering attached widgets
basically this attempts to work around an "impedance mismatch" caused by relying on Lumiera's Diff framework.
Applying a diff might alter the structural order of components, without those componets
being aware of the change. If especially those components are attached into some
UI layout, or otherwise delegate to display widgets, we need a dedicated mechanism
to reestablish those display elements in proper order after applying the change.

The typical examples is a sequence of sub-Tracks, which might have been reordert due
to applying rules down in the Steam Layer. The resulting diff will propagate the
new order of sub-Tracks up into the UI, yet now all of the elaborate layout and
space allocation done in the presentation code needs to be adjusted or even
recomputed to accomodate the change.
2019-12-06 21:53:43 +01:00
37d2e52c1e ClipDisplay: also verify invocation of widget relocation via ViewHook
...obviously this is just a dummy implementation and serves only to verify the design
2019-11-08 21:37:09 +01:00
bdf3351f55 ClipDisplay: basic implementation of ViewHook helper 2019-11-08 20:49:37 +01:00
f9d8f6eb55 ClipDisplay: draft desired properties of the ViewHook helper
...which serves to solve the problem with Canvas access.
Basically we do not want each and every Clip widget to be aware of the concrete canvas implementation widget;
and in addition, automated removal of widgets from the Canvas seems desirable
2019-09-30 02:49:02 +02:00
ec50407167 Timeline: start implementing some bits of the drawing code
Use a "catchy" style definition with lime background to make the drawing visible
2019-07-14 17:53:21 +02:00
6b4bf0a6ea Library: allow to check if Advice was explicitly given
For context: The »Advice System« was coined a long time ago, in 2010,
based on the vague impression that it might be useful for that kind of application
we are about to build here. And, as can be expected, none of the usage situations
envisioned at that time was brought to bear. Non the less, the facility came in
handy at times, precisely because it is cross-cutting and allows to pass
information without imposing any systematic relationship between the
communication partners.

And now we've got again such a situation.
The global style manager in the UI has to build a virtual CSS path,
which is needed by drawing code somewhere deep down, and we absolutely
do not want to pass a reference to the style manager over 20 recursive calls.

The alternatives would be
 (1) to turn the style manager into a public service
 (2) to have a static access function somewhere
 (3) to use a global variable.
For rationale, (1) would be overblown, because we do not actually request
a service to do work for us, rather we need some global piece of information.
(2) would be equivalent to (1), just more confusing. And (3) is basically
what the Advice system does, with the added benefit of a clear-cut service
access point and a well defined lifecycle.

This changeset adds the ability to check if actual Advice has been published,
which allows us to invoke the (possibly expensive) GTK path building and
style context building code only once.
2019-07-13 17:00:23 +02:00
8ffab2f002 Dependencies: get rid of boost-regexp (see #995)
Mostly, std::regexp can be used as a drop-in replacement.

Note: unfortunately ECMA regexps do not support lookbehind assertions.
This lookbehind is necesary here because we want to allow parsing values
from strings with additional content, which means we need explicitly to
exclude mismatches due to invalid syntax.

We can work around that issue like "either line start, or *not* one of these characters.


Alternatively we could consider to make the match more rigid,
i.e we would require the string to conain *only* the timecode spec to be parsed.
2019-06-24 02:41:02 +02:00
ab90d9c71d Functions-Commands: discard the ability to compare functors for equivalence (closes #294)
evil hack R.I.P
2019-06-23 19:45:30 +02:00
94edb5de86 BufferMetadata: likewise abandon use of function comparison for buffer handlers
The existing implementation created a Buffer-Type based on various traits,
including the constructor and destructor functions for the buffer content.
However, this necessitates calculating the hash_value of a std::function,
which (see #294) is generally not possible to implement.

So with this changeset we now store an additional identity hash value
right into the TypeHandler, based on the target type placed into the buffer
2019-06-23 18:57:21 +02:00
d57770ca89 Commands: disable equivalence-test on command equality
This was prompted by a test failing under Boost-1.65 (--> see #294)
When reviewed now, the whole idea of testing Steam-Layer Commands for
equivalence feels a bit sketchy.

Just the comparison for the command ''identity'' alone seems sufficient,
i.e. the test if a command-ID is associated with the same backend-handle
and thus the same functor binding.
2019-06-23 17:35:21 +02:00
f6e5886348 Library: complete test coverage of VerbPack 2019-06-11 02:40:20 +02:00
3d5a67ed14 Library: finish and clean-up the solution for VerbPack dispatch 2019-06-10 16:08:50 +02:00
8f43c2591e Library: investigate malfunction in metaprogramming
the template lib::PolymorphicValue seemingly picked the wrong
implementation strategy for "virtual copy support": In fact it is possible
to use the optimal strategy here, since our interface inherits from CloneSupport,
yet the metaprogramming logic picked the mix-in-adapter (which requires one additional "slot"
of storage plus a dynamic_cast at runtime).

The reason for this malfunction was the fact that we used META_DETECT_FUNCTION
to detect the presence of a clone-support-function. This is not correct, since
it can only detect a function in the *same* class, not an inherited function.

Thus, switching to META_DETECT_FUNCTION_NAME solves this problem
Well, this solution has some downsides, but since I intend to rewrite the
whole virtual copy support (#1197) anyway, I'll deem this acceptable for now


TODO / WIP: still some diagnostics code to clean up, plus a better solution for the EmptyBase
2019-05-10 02:19:01 +02:00
23c9da7c62 Library: solve the dilemma by inheriting from VerbToken
...which, in the end, can even be considered the more logical design choice,
since the "verb visitor" is a more elaborated and sophisiticated Verb-Token,
adding the special twist of embedded storage for variable function arguments
2019-05-09 23:40:47 +02:00
a530665769 Library: fix some reference passing errors
...but bad news on the main issue:
the workaround consumes the tuple and thus is not tenable!

And what is even worse: the textbook implementation of std::apply is
equivalent to our workaround and also consumes the argument tuple
2019-04-22 16:54:22 +02:00
e28635a11a Library: investigate copy behaviour in forwarding calls 2019-04-21 03:52:34 +02:00
5191073558 Library: continue Investigation with workaround, inconclusive yet
A simple yet weird workaround (and basically equivalent to our helper function)
is to wrap the argument tuple itself into std::forward<Args> -- which has the
effect of exposing RValue references to the forwarding function, thus silencing
the compiler.

I am not happy with this result, since it contradicts the notion of perfect forwarding.

As an asside, the ressearch has sorted out some secondary suspicions..
- it is *not* the Varargs argument pack as such
- it is *not* the VerbToken type as such

The problem clearly is related to exposing tuple elements to a forwarding function.
2019-04-20 17:27:47 +02:00
6fbd1021ba Library: first attempt to get the flexible VerbToken to work
...still not decided yet if this whole apporach is sound...
2019-04-17 18:32:21 +02:00
9b5fdd39b8 Library: draft for a visitor-like VerbToken
this is a generalisation of what we use in the diff framework;
typically you'd package the VerbToken into some kind of container,
together with the concrete invocation argument.

However, the specific twist here is that we want *variable arguments*,
depending on the actual operation called on the interpreter interface.
2019-04-16 18:21:51 +02:00
ec9b2388da Timeline: consider how to integrate the drawing code
...which leads to a specific twist here; while in the simple version
we still could hope to get away with a simple uniform uint argument,
the situation has changed altogether now. The canvas has turned into
some generic component, since it is instantiated two times, onece for
the time ruler and once for the actual body content. Thus all of the
specifics of the drawing code need to be pushed into a new, dedicated
renderer component. And this more or less forces us to pass all the
actual presentation variations through the invocation arguments of
the visitor.

So we're now off again for a digression, we need a more generalised visitor
2019-04-14 15:38:57 +02:00
116600b20a Timeline: draft a concept to attack the custom layout
the core question is: how to translate time into pixel coordinates
2018-12-10 00:12:52 +01:00
7b7ec310b3 Dispatcher: rename in accordance to the layer
so now we've got a "SteamDispatcher" ... cute ;-)
2018-12-10 00:12:52 +01:00
2ea89fcb54 Dispatcher: rework loop control logic
- we got occasional hangups when waiting for disabled state
- the builder was not triggered properly, sometimes redundant, sometimes without timeout

As it turned out, the loop control logic is more like a state machine,
and the state variables need to be separated from the external influenced variables.

As a consequence, the inChange_ variable was not calculated properly when disabled in a race,
and then the loop went into infinite wait state, without propagating this to
the externally waiting client, which caused the deadlock
2018-12-10 00:12:52 +01:00
48a829d544 Library: clarify usage of the basic time scale
effectively we rely in the micro tick timescale promoted by libGAVL,
but it seems indicated to introduce our own constant definition.
And also clarify some comments and tests.

(this changeset does not change any values or functionality)
2018-12-10 00:12:52 +01:00
b68d0f24cb Library: settle long standing confusion regarding time border conditions
basically we can pick just any convention here, and so we should pick the convention in a way
that makes most sense informally, for a *human reader*. But what we previously did, was to pick
the condition such as to make it simple in some situations for the programmer....

With the predictable result: even with the disappointingly small number of usages we have up to now,
we got that condition backwards several times.

OK, so from now on!!!

Time::NEVER == Time::MAX, because "never" is as far as possible into the future
2018-12-10 00:12:43 +01:00
d3d7ea35ad Global-Layer-Renaming: fix remaining textual usages and IDs in the code
- most notably the NOBUG logging flags have been renamed now
 - but for the configuration, I'll stick to "GUI" for now,
   since "Stage" would be bewildering for an occasional user
 - in a similar vein, most documentation continues to refer to the GUI
2018-12-10 00:09:56 +01:00
480104b945 Global-Layer-Renaming: adapt the build system to the new layer names
...with one exception: I'll retain the name "gui" for the final product to be built.
2018-11-16 15:25:28 +01:00
02c5809707 Global-Layer-Renaming: adjust namespace qualification 2018-11-15 23:59:23 +01:00
555ca0bff9 Global-Layer-Renaming: rename namespaces 2018-11-15 23:55:13 +01:00
72b15b8e45 Global-Layer-Renaming: transform header include guards
btw... we could change to #pragma once
2018-11-15 23:52:02 +01:00
2d5ebcd5fa Global-Layer-Renaming: adjust header includes 2018-11-15 23:42:43 +01:00
6261779531 Global-Layer-Renaming: rearrange directories
backend -> vault
proc -> steam
gui -> stage
2018-11-15 23:28:03 +01:00
9e951e1eeb Global-Layer-Renaming: adapt lots of documentation 2018-11-15 21:13:52 +01:00
8432420726 Library: fix unwanted implicit conversion
...it should have been explicit from start, since there is no point
in converting an EntryID into a plain flat string without further notice

this became evident, when the compiler picked the string overload on

MakeRec().genNode(specialID)

...which is in compliance to the rules, since string is a direct match,
while BareEntryID would be an (slicing) upcast. However, obviously we
want the BareEntryID here, and not an implicit string conversion,
thereby discarding the special hash value hidden within the ID
2018-11-09 23:09:28 +01:00
1bbe903202 GenNode: revert -- better not handle this problem on ETD level
...rather extend the "object builder" DSL notation to allow passing in a given EntryID literally.
Rationale is, we should handle the problem of unique IDs on the level of the domain model.
If we attempt to "fix" this within GenNode, the price would be to make the ETD creation stateful
2018-11-09 22:50:48 +01:00
572bd38fec DummySessionConnection: produce a simple population diff message
seems to work surprisingly well...
the diff application poceeds in the GUI up to the point
where the TrackPresenter need to be inserted into a two-fold display context
2018-10-15 02:54:42 +02:00
a77ecb6d5d change util::sanitise to filter out '
Only reatain chars, numbers and -_.+$()@
Allowing the appostroph seems entirely random and unjustified here
2018-10-12 23:45:49 +02:00
fa6ba76f85 investigate insidious ill-guided conversion
As it turns out, using the functional-notation form conversion
with *parentheses* will fall back on a C-style (wild, re-interpret) cast
when the target type is *not* a class. As in the case in question here, where
it is a const& to a class. To the contrary, using *curly braces* will always
attempt to go through a constructor, and thus fail as expected, when there is
no conversion path available.

I wasn't aware of that pitfall. I noticed it since the recently introduced
class TimelineGui lacked a conversion operator to BareEntryID const& and just
happily used the TimelineGui object itself and did a reinterpret_cast into BareEntryID
2018-10-12 23:42:56 +02:00
e81b0592d3 TreeMutator: combine no-op layer with selective other diff binding
...and complete unit test coverage.
This is complex stuff and we'd better be careful it actually works
2018-10-12 02:05:11 +02:00
fb93e349da TreeMutator: conjure up a black hole mutator
...which is a somewhat involved version of /dev/null
2018-10-11 23:56:33 +02:00
9894542bf9 Introduce predefined constants for magic IDs in UI communication
...these magical strings are already spreading dangerously throughout the code base


PS: also fixup for c6b8811af0  (broken whitespace in test definition)
2018-10-08 05:00:06 +02:00
12344ae9d8 NotificationDisplay: add an Error-State and implement signal to trigger on change
this is more or less gratitious functionality for now,
yet I consider it a proof-of-concept
2018-10-05 15:59:21 +02:00
c6b8811af0 Library: utility to interpret a text as bool value (yes/no)
...also fixes the problem with the "expand" mark in DemoGuiRoundtrip
2018-10-03 04:43:16 +02:00
4e94dfd4d9 FailureHandling: improved ZombieCheck
now capturing the Zombie's ID

==> surprise, its ClassLock<gui::interact::LocationQuery>
2018-10-01 05:51:21 +02:00
5a7a5a5720 DOC: fix syntax of some doxygen links
seemingly we really need the \ref in the link target expression
2018-09-21 14:33:12 +02:00
121d78e13b EventLog: now able to write the condition to verify doRevealYourself (#1162)
this initially (on 1.9.18) triggered this extended digression;
The initial naive implementation (without backtracking) did not allow
to express such a simple thing like "function XXX" not invoked (again) after "function XXX"
2018-09-19 03:27:48 +02:00
03a1d58198 EventLog: verify and complete the TestEventLog_test
can now cover all the cases as initially intended,
including backtracking
2018-09-19 02:52:38 +02:00
1683439b32 ChainSearch: backtracking verified -- finished 2018-09-16 01:08:49 +02:00
84399aa407 ChainSearch: verify proper interplay of two dynamic search conditions 2018-09-16 01:08:49 +02:00
38a1aad897 ChainSearch: bugfixes on reworked construction
...seems basically sane now.
Just we still need to wrap it one more time into IterableDecorator;
which means the overall scheme how to build and package the whole pipeline
is not correct yet.

Maybe it is not possible to get it packaged all into one single class?
2018-09-16 01:08:48 +02:00
05e6e7f316 ChainSearch: remould construction to get the logic correct
on closer investigation it turned out that the logic of the
first design attempt was broken altogether. It did not properly
support backtracking (which was the reason to start this whole
exercise) and it caused dangling references within the lambda
closure once the produced iterator pipeline was moved out
into the target location.

Reasoning from first principles then indicated that the only sane
way to build such a search evaluation component is to use *two*
closely collaborating layers. The actual filter configuration
and evaluation logic can not reside and work from within the
expander. Rather, it must sit in a layer on top and work in
a conventional, imperative way (with a while loop).

Sometimes, functional programming is *not* the natural way
of doing things, and we should then stop attempting to force
matters against their nature.
2018-09-16 01:08:45 +02:00
767156e912 TreeExplorer: unit test coverage for injected custom layer 2018-09-16 01:07:23 +02:00
8aae789b82 ChainSearch: test case to scrutinise chained filter reconfiguration
...and TADAA ... there we get an insidious bug:

we capture *this by reference into the expansion functor,
and then we move *this away, out from the builder into the target....
2018-09-14 21:06:15 +02:00
29d2c151b3 ChainSearch: add builder function just to replace the filter
Up to now, we had a very simplistic configuration option just
to search for a match, and we had the complete full-blown reconfiguration
builder option, which accepts a functor to work on and reconfigure the
embedded Filter chain.

It occurred to me that in many cases you'd rather want some intermediary
level of flexibility: you want to replace the filter predicate entirely
by some explicitly given functor, yet you don't need the full ability
to re-shape the Filter chain as a whole. In fact the intended use case
for IterChainSearch (which is the EventLog I am about to augment with
backtracking capabilities) will only ever need that intermediate level.


Thus wer're adding this intermediary level of configurability now.

The only twist is that doing so requires us to pass an "arbitrary function like thing"
(captured by universal reference) through a "layer of lambdas". Which means,
we have to capture an "arbitrary thingie" by value.

Fortunately, as I just found out today, C++14 allows something which comes
close to that requirement: the value capture of a lambda is allowe to have
an intialiser. Which means, we can std::forward into the value captured
by the intermediary lambda. I just hope I never need to know or understand
the actual type this captured "value" takes on.... :-)
2018-09-14 21:06:15 +02:00
10f21f77f8 ChainSearch: resolve the problems and get basic functionality to work
with the augmented TreeExplorer, we're now able to get rid of the
spurious base layer, and we're able to discard the filter and
continue with the unfiltered sequence starting from current position.
2018-09-14 21:06:15 +02:00
df7a9492b7 TreeExplorer: helper function so support ChainSearch::clearFilter()
build a special feature into the Explorer component of TreeExplorer,
causing it to "lock into" the current child sequence and discard
all previous sequences from the stack of child explorations
2018-09-14 21:06:15 +02:00
7cdd680e78 TreeExplorer: clean-up after refactoring
So we have now a reworked version of the internals of TreeExplorer in place.
It should be easier to debug template instantation traces now, since most
of the redundancy on the type parameters could be remove. Moreover, existing
pipelines can now be re-assigned with similarily built pipelines in many cases,
since the concrete type of the functor is now erased.

The price tag for this refactoring is that we have now to perform a call
through a function pointer on each functor invocation (due to the type erasure).
And seemingly the bloat in the debugging information has been increased slightly
(this overhead is removed by stripping the binary)
2018-09-14 21:06:15 +02:00
36d79be8b2 TreeExplorer: refactor Filter in a similar way 2018-09-14 21:06:15 +02:00
1e657acbff TreeExplorer: refactor Transformer to employ the improved wrapping style
...step by step switch over to the new usage pattern.
Transformer should be the blueprint for all other functor usages.


The reworked solutions behaves as expected;
we see two functor invocations; the outer functor, which does
the argument adaptation, is allocated in heap memory
2018-09-14 21:06:15 +02:00
e3ca8548a4 TreeExplorer: allow for a disabled filter
...considered as one of the building blocks to resolve Problems in the Design of ChainSearch
2018-09-14 21:06:15 +02:00
34b78fc47e ChainSearch: identify some possible problems
- as implemented now, we will finally backtrack into the unfiltered base iterator
- it is not possible to implement a clearFilter() operation
2018-09-14 21:06:15 +02:00
d923138d1c ChainSearch: configure the core of the chained search mechanism
...based on a monadic tree expansion: we define a single step,
which takes the current filter configuration and builds the next
filter configuration, based on a stored chain of configuration functions

The actual exhausting depth-first results just by the greedy application pattern,
and uses the stack embedded in the "Explorer" layer of TreeExplorer
2018-09-14 21:06:14 +02:00
d398177a71 ChainSearch: now actually build the processing pipeline in the ctor
..this resolves the most challenging part of the construction work;
we use the static helper functions to infer a type and construct a suitable
processing pipeline and we invoke the same helper to initialise the base class
in the ctor.

Incidentally... we can now drop all the placeholder stubs,
since we now inherit the full iterator and child explorer API.
The test now starts actually to work... we get spam and sausage!

TODO: now actually fill in the expand functor such as to pick the
concrete filter step in the chain from a sequence of preconfigured
filter bindings
2018-09-14 21:06:14 +02:00
9b0937bc63 ChainSearch: move into namespace iter
...seems to be a not-so-commonly used helper
2018-09-14 21:06:14 +02:00
a52ed91de0 ChainSearch: draft a solution how to construct the Expand functor type
...now matters start to get really nasty,
since we have to pick up an infered type from a partially built pipeline
and use it to construct the signature for a functor to bind into the more elaborate complete pipeline
2018-09-14 21:06:14 +02:00
6834c26470 ChainSearch: draft a solution how to construct the pipeline builder base type
this is a tricky undertaking, since our treeExplore() helper constructs
a complex wrapped type, depending on the actual builder expressions used.

Solution is to use decltype on the result of a helper function,
and let the _DecoratorTraits from TreeExplorer do the necessary type adaptations
2018-09-14 21:06:14 +02:00
4988153e15 Library: prevent implicit bool conversion on iterator-like objects
...it should have been this way all the time.
Generic code might otherwise be ill guided to assume a conversion
from the Iterator to its value type, while in fact an explicit dereferentiation is necessary
2018-09-14 21:06:14 +02:00
433543a2c7 DOC: some doxygen fixes 2018-09-14 21:06:14 +02:00
ec8d0557e8 ChainSearch: draft interface and possible implementation approach
The intention is to augment the iterator based (linear) search
used in EventLog to allow for real backtracking, based on a evaluation tree.
This should be rather staight forward to implement, relying on the
exploreChildren() functionality of TreeExplorer. The trick is to package
the chained search step as a monadic flatMap operation
2018-09-14 21:06:14 +02:00
604ffbf73c TreeExplorer: fix a bug and finish the feature
we did an unnecessary copy of the argument, which was uncovered
by the test case manipulating the state core.


Whew.
Now we have a beautiful new overengineered solution
2018-09-14 21:06:14 +02:00
be7f47d5b7 TreeExplorer: rework the solution to allow for arbitrary functor types
outift the Filter base class with the most generic form of the Functor
wrapper, and rather wrap each functor argument individually. This allows
then to combine various kinds of functors
2018-09-14 21:06:14 +02:00
90c0f43cfd TreeExplorer: code all the combination cases
...this solution works, but has a shortcoming:
the type of the passed lambdas is effectively pinned to conform
with the signature of the first lambda used initially when building the filter.

Well, this is the standard use case, but it kind of turns all the
tricky warpping and re-binding into a nonsense excercise; in this form
the filter can only be used in the monadic case (value -> bool).

Especially this rules out all the advanced usages, where the filter
collaborates with the internals of the source.
2018-09-14 21:06:14 +02:00
e29d9ae19e TreeExplorer: better package this very specific code as subclass
while this is basically just code code cosmetics,
at least it marks this as a very distinct special case,
and keeps the API for the standard Filter layer clean.
2018-09-14 21:06:14 +02:00
8f70b4e902 TreeExplorer: prototype for the extracted boilerplate helper
a quite convoluted construct built from several nested generic lambdas.
When investigated in the debugger, the observed addresses and the
invoked code looks sane and as expected.
2018-09-14 21:06:14 +02:00
94da0f627f TreeExplorer: draft ability to remould the filter
The intention is to switch from the itertools-based filter
to the filter available in the TreeExplorer framework.
Thus "basically" we just need to copy the solution over,
since both are conceptually equivalent.

However...... :-(
The TreeExplorer framework is designed to be way more generic
and accepts basically everything as argument and tries to adapt apropriately.

This means we have to use a lot of intricate boilerplate code,
just to get the same effect that was possible in Itertools with
a simple and elegant in-place lambda assignment
2018-09-14 21:06:14 +02:00
757258fb3a TreeExplorer: fix bug in Filter layer
Fillter needs to be re-evaluated, when an downstream entity requests
expandChildren() onto an upstream source. And obviously the ordering
of the chained calls was wrong here.

As it turns out, I had discovered that necessity to re-evaluate with
the Transformer layer. There is a dedicated test case for that, but
I cut short on verifying the filter in that situation as well, so
that piece of broken copy-n-paste code went through undetected.

This is in fact a rather esoteric corner case, because it is only
triggered when the expandChildren() call is passed through the filter.
When otoh the filter sits /after/ the entity generating the expandChildren()
calls, everything works as intended. And the latter is the typical standard
usage situation of an recursive evalutation algorithm: the filter is here
used as final part to drive the evaluation ahead and pick the solutions.
2018-09-14 21:06:14 +02:00
3fc5a94b87 TreeExplorer: investigate the backtracking abilities
There is a bug or shortcoming in the existing ErrorLog matcher implementation.
It is not really difficult to fix, however doing so would require us to intersperse
yet another helper facility into the log matcher. And it occurred to me, that
this helper would effectively re-implement the stack based backtracking ability,
which is already present in TreeExplorer (and was created precisely to support
this kind of recursive evaluation strategies).

Thus I intend to switch the implementation of the EventLog matcher from the
old IterTool framework to the newer TreeExplorer framework. And this intention
made me re-read the code, fixing several comments and re-thinking the design
2018-09-14 21:06:14 +02:00
2520ee82d1 EventLog: investigate failed match in EventLog
seemingly my quick-n-dirty implementation was to naiive.
We need real backtracking, if we want to support switches
in the search direction (match("y").after("x").before("z")

Up to now, I have cheated myself around this obvious problem :-/
2018-09-14 21:06:13 +02:00
1ab42b298d UiElement: add unit test to cover the doRevealYourself functionality
...which is now kind-of specified and we're providing a default implementation,
so it should be documented in AbstractTangible_test
2018-09-14 21:06:13 +02:00
026049a13c UiElement: likewise integrate the Revealer functor (#1162) 2018-09-14 21:06:13 +02:00
3f327b335a UiElement: switch MockElement to rely on the new functor based default impl
...which is implicit verified through AbstractTangible_test::markState()
2018-09-14 21:06:13 +02:00
a74dc596ce WLink: finished incl. exception handling guarantees and documentation 2018-09-14 21:06:12 +02:00
ae26012bf5 WLink: implement copy operations
swap-based implementation
not sure if attachTo() should be noexcept
2018-09-14 21:06:12 +02:00
baa3d2bff0 WLink: define expected copy behaviour 2018-09-14 21:06:12 +02:00
a15951b036 WLink: implement connecting / reconnecting 2018-09-14 21:06:12 +02:00
c47e3d0210 WLink: draft basic behaviour 2018-09-14 21:06:12 +02:00
e829a74edf NotificationDisplay: draft idea of managed link-to-widget
a smart-reference based on sigc::trackable
2018-09-14 21:06:12 +02:00
36abe4567e NotificationDisplay: define the actual controller behaviour to be implemented
this is specification work; for now the stubs are marked UNIMPLEMENTED
2018-09-14 21:06:12 +02:00
53c47a6fcc Assets: verify creation of ErrorLog meta-Asset 2018-09-14 21:06:12 +02:00
f872e22216 Assets: draft how the global ErrorLog asset could be created 2018-09-14 21:06:12 +02:00
928b4372e0 Assets: investigating the unclear distinction between asset::Struct and asset::Meta (#1156)
including a kind-of Bugfix: the ctor of TimeGrid erroneously categorised it as asset::Kind STRUCT
2018-09-14 21:06:12 +02:00
3b8965c0b6 Heisenbug hunt.... Segfault related to regular expression (#1158)
not yet able to reproduce these seemingly random segfaults
2018-09-14 21:04:25 +02:00
c5bdb89b5b BusTerm_test: obvious performance improvement on RegExp search
Greedy wildcard match .+ is unnecessary, since in case of a positive match,
the next given expression always follows immediately. We just want to skip
over some "syntactic noise"

This change makes the matching time linear in the size of the log.

But unfortunately, I still occasionally see an Segmentation Fault.
It seems to arise when compiling the regular expresions

e.g. the following RegExps cashed (right in the middle of the test)

after.+?_ATTRIBS_.+?ins.+?53 of 57 ≺358.gen010≻.+?mut.+?53 of 57 ≺358.gen010≻.+?ins.+?borgID.+?358.+?emu.+?53 of 57 ≺358.gen010≻
after.+?_ATTRIBS_.+?ins.+?53 of 63 ≺178.gen028≻.+?mut.+?53 of 63 ≺178.gen028≻.+?ins.+?borgID.+?178.+?emu.+?53 of 63 ≺178.gen028≻
after.+?_ATTRIBS_.+?ins.+?53 of 59 ≺498.gen038≻.+?mut.+?53 of 59 ≺498.gen038≻.+?ins.+?borgID.+?498.+?emu.+?53 of 59 ≺498.gen038≻
after.+?_ATTRIBS_.+?ins.+?53 of 60 ≺223.gen003≻.+?mut.+?53 of 60 ≺223.gen003≻.+?ins.+?borgID.+?223.+?emu.+?53 of 60 ≺223.gen003≻
after.+?_ATTRIBS_.+?ins.+?53 of 78 ≺121.gen015≻.+?mut.+?53 of 78 ≺121.gen015≻.+?ins.+?borgID.+?121.+?emu.+?53 of 78 ≺121.gen015≻
2018-09-14 21:04:09 +02:00
8097485dbf ViewSpec: integrate the simple View access case (Unit test PASS)
This finishes the first round of design drafts in this area.
Right now it seems difficult to get any further, since most of
the actual view creation and management in the UI is not yet coded.
2018-06-15 18:02:08 +02:00
800fc5915a ViewSpec: recast the ElementAccess API to work around the design problem
...it is not really solved, rather postponed.
But who knows. Maybe it's already good enough...
2018-06-15 16:42:51 +02:00
f55a8f606b ...one month later: pick up after the LAC.18 Berlin
...happened to be completely absorbed by the preparations
for my workshop about Yoshimi and musical presets
2018-06-14 17:02:34 +02:00
f64e01a20c GCC-7: minor adjustments to make the testsuite PASS again
The boost::hash documentation does not mention a significant change in that area,
yet the frequent collisions on identifiers with number suffix do not occur anymore
in Boost 1.65
2018-04-29 03:15:57 +02:00
f06038828c GCC-7: integrate recent clean-up and refactoring work (lib::Depend)
# Conflicts:
#	src/lib/error-exception.cpp
#	src/lib/error.hpp
#	src/lib/opaque-holder.hpp
#	src/lib/wrapper.hpp
#	src/proc/mobject/session/sess-manager-impl.hpp
2018-04-27 02:23:20 +02:00
3296148dad pre-C++17: remove remaining old-style (dynamic) exception specifications 2018-04-26 12:07:08 +02:00
5f0af2495b Test-Fix: possible race in test setup
On rare occasions, the test thread itself consumes faster than the producer threads feed new test data.
Make sure the test does not hangin such a situation
2018-04-26 10:54:13 +02:00
d0538a55ff ViewSpec: implement the generic access function in ViewLocator
still missing: internal wiring from the allocation token(s) of the DSL
into the ElementAccess service designed last week.
2018-04-15 03:07:54 +02:00
ba3d9e57b5 ViewSpec: draft a way to code an integration test for ViewLocator (#1129)
The original goal for #1129 (ViewSpecDSL_test) is impossible to accomplish,
at least within our existing test framework. Thus I'll limit myself to coding
a clean-room integration test with purely synthetic DSL definitions and mock widgets
2018-04-15 01:39:46 +02:00
86b1aac721 ElementAccess: somewhat improve the mock implementation to cover the standard case
...still quite braindead, but well....
2018-04-14 03:58:02 +02:00
4205511405 ElementAccess: change the way of mock element creation
...still quite braindead, but allows at least to cover the standard case as well.

A better mock element access service would at least traverse a GenNode-Tree,
and thus emulate the behaviour of the real service; yet both seems way beyond
scope right now, and all I need is some basic coverage of the Interface
2018-04-14 03:14:19 +02:00
a565fc3321 ElementAccess: rearrange files according to namespace 2018-04-14 02:06:31 +02:00
4071a58454 ElementAccess: fix first unit test case
ouch, the typedef Base /is/ already a pointer...
2018-04-14 01:59:41 +02:00
4c273d902c ElementAccess: add very simplistic mock implementation 2018-04-14 01:37:56 +02:00
22f50b1b00 ElementAccess: streamline error cases
My understanding is that in the standard use case, we precisely know what to expect
and just go ahead and perform the conversion. Thus it is pointless to introduce
fine grained distinctions. When the access fails, this always indicates some broken
application logic, and just raises an error.
2018-04-13 03:29:08 +02:00
ac4f0bc6db ElementAccess: possibly working solution based on lib::variant
With this solution, somewhere deep down within the implementation
the knowledge about the actual result type would be encoded into
the embedded VTable within a lib::variant. At interface level,
ther will be a double dispatch based on that result type
and the desired result type, leading either to a successful
access or an error response.
2018-04-13 02:39:46 +02:00
91b83f5ede ElementAccess: (WIP) unsuccessful attempt to solve the typing problem
the intention was to return disparate result types, just depending on the
actual position in the UI-Coordinates. The client knows what to expect
2018-04-09 01:14:12 +02:00
c245098d45 ElementAccess: (WIP) first draft for internal accessor function
...but can not work this way.
Since void* has not RTTI, no secure access with downcast is possible
2018-04-09 00:51:24 +02:00
20ecc3f0d0 DI: allow to trigger the lazy instantiation of a mock service instance directly
Basically the mocking mechanism just switches the configuration
and then waits for the service to be accessed in order to cause acutual
instantiation of the mock service implementation. But sometimes we want
to prepare and rig the mock instance prior to the first invocation;
in such cases it can be handy just to trigger the lazy creating process
2018-04-08 18:43:27 +02:00
e99ad7a3e6 ElementAccess: draft simple lookup interface 2018-04-08 18:43:27 +02:00
09359cf92a ElementAccess: initial brainstorming about the interface mechanics 2018-04-07 02:28:29 +02:00
dc97ab5546 ElementAccess: consider helper to encapsulte access to actual GTK structures (#1134) 2018-04-07 01:00:25 +02:00
2f899a921c ViewSpec: draft next steps to address
...should implement the generic invocation in ViewLocator,
without actually implementing the backing UI element allocation logic
2018-04-05 19:43:10 +02:00
18a552002d ViewSpec: use mocked LocationSolver to verify operation of the DSL 2018-04-05 01:09:13 +02:00
71bb2b48b6 ViewSpec: pick up with dependency-injection into the DSL tokens (#1126)
Attempt to find my way back to the point
where the digression regarding dependency-injection started.

As it turns out, this was a valuable digression, since we can rid ourselves
from lots of ad-hoc functionality, which basically does in a shitty way
what DependencyFactory now provides as standard solution


FIRST STEP is to expose the Navigator as generic "LocationQuery" service
through lib::Depend<LocationQuery>
2018-04-04 03:29:26 +02:00
4e0d99e928 Demote the Play-Facade to a in-language (C++) Interface to get rid of InterfaceFacadeLink
I am fully aware this change has some far reaching ramifications.
Effectively I am hereby abandoning the goal of a highly modularised Lumiera,
where every major component is mapped over the Interface-System. This was
always a goal I accepted only reluctantly, and my now years of experience
confirm my reservation: it will cost us lots of efforts just for the
sake of being "sexy".
2018-04-03 02:14:45 +02:00
be789bea59 Fix funny problem with C header stdbool.h
...which is so kind as to redefine bool, true and false as macros. Yessss!
2018-04-02 03:27:07 +02:00
89d93a13e4 Modernise Unknown Exception handler and Exception messages 2018-04-02 01:48:51 +02:00
21e47e014a Modernise Lumiera Error baseclass 2018-04-01 23:45:00 +02:00
bfbcc5de43 simplify ClassLock by use of Meyer's Singleton with zombie check
...and package the ZombieCheck as helper object.
Also rewrite the SyncClassLock_test to perform an
multithreaded contended test to prove the lock is shared and effective
2018-04-01 06:09:01 +02:00
992056ea69 reduce include dependencies of DelStash
...get rid of some further Boost includes and remove unnecessary disable_if
2018-04-01 00:37:58 +02:00
fc546f71b4 Reorganise some tests
Dependency-Injection rather fits into the "fundamentals" section.
It is more than a mere library facility
2018-03-31 17:12:45 +02:00
fe10ab92dc DI: adjust codebase to the new DependInject configuration API 2018-03-31 01:06:10 +02:00
80207ea224 DI: (WIP) switch to totally rewritten new implementation of lib::Depend (#1086)
- state-of-the-art implementation of access with Double Checked Locking + Atomics
- improved design for configuration of dependencies. Now at the provider, not the consumer
- support for exposing services with a lifecycle through the lib::Depend<SRV> front-end
2018-03-31 01:06:06 +02:00
5d0c2b6d2c DI: special solution for singletons with private default ctor
...which declare DependencyFactory as friend.
Yes, we want to encourrage that usage pattern.

Problem is, std::is_constructible<X> gives a misleading result in that case.
We need to do the instantiation check within the scope of DependencyFactory
2018-03-30 06:48:34 +02:00
b3d18c1a74 DI: rework dependency-injection configuration in terms of the new DependencyFactory
why is this so damn hard to get right?
2018-03-30 05:56:53 +02:00
5fc85df385 DI: inline into lib::Depend to obsolete InstanceHolder
but now we've got two factory functors.
So there is yet more potential for simplification & refactoring
2018-03-29 16:57:55 +02:00
c3e149028f DI: draft towards unified use of the singleton holder
ideally we want
 - just a plain unique_ptr
 - but with custom deleter delegating to lib::Depend
 - Depend can be made fried to support private ctor/dtor
 - reset the instance-ptr on deletion
 - always kill any instance
2018-03-28 03:27:05 +02:00
d6786870f3 DI: port the old Singleton unit tests
all these tests are ported by drop-in replacement
and should work afterwards exactly as before (and they do indeed)

A minor twist was spotted though (nice to have more unit tests indeed!):
Sometimes we want to pass a custom constructor *not* as modern-style lambda,
but rather as direct function reference, function pointer or even member
function pointer. However, we can not store those types into the closure
for later lazy invocation. This is basically the same twist I run into
yesterday, when modernising the thread-wrapper. And the solution is
similar. Our traits class _Fun<FUN> has a new typedef Functor
with a suitable functor type to be instantiated and copied. In case of
the Lambda this is the (anonymous) lamda class itself, but in case of
a function reference or pointer it is a std::function.
2018-03-26 07:54:16 +02:00
4d783770d0 Bugfix: CallQueue_test initialisation was not threadsafe (see also #1131)
...which showed up under high system load.
The initialisation of the member variables for the check sum
could be delayed while the corresponding thread was already running
2018-03-26 04:40:54 +02:00
685a9b84ee Library: replace boost::noncopyable by our own library solution
Benefits
 - get rid of yet another pervasive Boost dependency
 - define additional more fine grained policies (move only, clonable)
2018-03-24 05:35:13 +01:00
d9af3abb0f DI: implement creating singleton from arbitrary (user provided) closure/functor/lambda
this is quite an ugly feature, but I couldn't come up with
any convincing argument *not* to implement it (and its low hanging fruit)
2018-03-22 06:53:56 +01:00
5c39498929 DI: clean-up and document the TDD test
...written as byproduct from the reimplementation draft.

NOTE there is a quite similar test from 2013, DependencyFactory_test
For now I prefer to retain both, since the old one should just continue
to work with minor API adjustments (and thus prove this rewrite is a
drop-in replacement).

On the long run those two tests could be merged eventually...
2018-03-19 05:34:27 +01:00
957e7ff54c DI: extract testcode into new unit test 2018-03-19 03:46:43 +01:00
41b8d12b66 ViewSpec: reconsider how to build and structure the DSL (#1126)
...in the light of all the foundation components and frameworks created meanwhile
2018-02-23 05:07:39 +01:00
b6360b2e9c LocationSolver: automatically inject persp(UIC_ELIDED) (closes #1128)
decided to add a very specific preprocessing here, to make the DSL notation more natural.
My guess is that most people won't spot the presence of this tiny bit of magic,
and it would be way more surprising to have rules like

UICoord::currentWindow().panel("viewer").create()

fail in most cases, simply because there is a wildcard on the perspective
and the panel viewer does not (yet) exist. In such a case, we now turn the
perspective into a "existential quantified" wildcard, which is treated as if
the actually existing element was written explicitly into the pattern.
2018-02-17 05:11:34 +01:00
0f26f1e0f4 LocationSolver: Documentation and clean-up (#1127) 2018-02-17 03:45:07 +01:00
da8fd6a031 LocationSolver: use the "elided" marker for realistic create rules
...actually just more test coverage,
the feature is already implemented.

What *could* be done though is to inject that UIC_ELIDED marker
on missing perspective specs in create clauses automatically...
2018-02-16 07:34:48 +01:00
983c490644 LocationSolver: test coverage for existentially quantified elements (#1128)
...and again spotted some really insidious bugs
2018-02-16 06:37:43 +01:00
6665fb68d6 LocationSolver: decide not to implement match based on context (#1130)
This looks like YAGNI, and it would be non trivial to implement.
But since the feature looks important for slick UI behaviour,
I've made a new ticket and leave it for now
2018-02-16 03:24:37 +01:00
f3791297d6 LocationSolver: cover most standard usage situations
with the exception of some special situations,
which require additional features from the engine,
especially binding-on-context

Not sure though if I'll implement these or say YAGNI
2018-02-16 01:59:51 +01:00
60d40a6a6e LocationSolver: concept for standard usage situation test coverage
...using a fixed set of rules this time,
while injecting a different (simulated) UI tree for each testcase
2018-02-14 04:42:19 +01:00
98cab32a08 LocationSolver: several rule match test cases 2018-02-14 03:02:44 +01:00
9249c513a9 LocationSolver: wildcard match test cases 2018-02-13 03:13:53 +01:00
92bf317d29 LocationSolver: long explicit path test cases
...and here a bug was hiding. gotcha
2018-02-13 02:46:43 +01:00
9fe314ad04 LocationSolver: testcases regarding perspective
TODO support for existentially quantified perspective to match against
"just the" perspectice, disregarding the actual value
2018-02-13 02:26:03 +01:00
c11e557b45 LocationSolver: smallest possible query test cases
querying on window level (=root level)
2018-02-11 04:36:11 +01:00
e04f61fe0d LocationSolver: length discriminating test cases 2018-02-11 04:16:58 +01:00
820abe2bef LocationSolver: provide DSL notation to write "create clauses" 2018-02-11 04:00:59 +01:00
7a167c4c3a LocationSolver: draft pattern for writing those test cases
...which shows: we also need a DSL mechanism for writing "create clauses"
2018-02-11 02:34:56 +01:00
65a86bc426 LocationSolver: define extensive test coverage to be written (#1127) 2018-02-10 02:03:09 +01:00
6d0e8a35a6 LocationSolver: simple unit test PASS 2018-02-10 00:34:24 +01:00
66bbf146a6 LocationSolver: implement this additional resolving flavour
coverPartially() now computes coverage solution and moves
that solution into place, while retaining the extraneous, uncovered part
2018-02-09 03:30:45 +01:00
c88a68a2a0 LocationSolver: need yet another flavour of the coordinate resolving mechanism
...this happens when you design a subsystem bottom-up
You build five items just to find out that in fact you need only a sixth item....
2018-02-08 03:00:38 +01:00
6022a8afb1 LocationSolver: draft outline of the solving loop 2018-02-08 02:50:48 +01:00
bf314482da LocationSolver: draft the simple usage scenario (unit test) (#1127) 2018-02-08 00:37:02 +01:00
10d2cafba9 LocationSolver: draft entities involved in location solving (#1127)
basically this will be built on top of the path matching / resolving mechanism coded thus far.
but we'll need some additional flags and some DSL magic
2018-02-07 04:03:39 +01:00
136e78d023 DockAccess: decide on next steps towards integration (#1126) 2018-02-01 23:08:43 +01:00
22e823fad5 DockAccess: finish setup of allocation specifications within the DSL 2018-01-15 03:56:23 +01:00
ef74527f6b DOC: eliminate spurious mentions of tr1:: 2018-01-12 03:03:25 +01:00
7dd69003b5 Navigator: finish path matching resolver for UI coordinates (closes #1107) 2018-01-10 04:42:49 +01:00
722c49e5ff Navigator: finish coverage of path extension 2018-01-10 04:21:42 +01:00
2d66293c32 Navigator: test for path extension now basically working as intended 2018-01-09 02:12:00 +01:00
f10263c469 Navigator: fix insidious nesting error in test definition 2018-01-09 01:52:49 +01:00
55c196e5a2 Navigator: define test cases for path extension after coverage 2018-01-08 23:49:24 +01:00
d5209bfe1d Navigator: get the anchor() cases to work as intended 2018-01-07 07:20:41 +01:00
837aa81fc5 Navigator: cook up some interesting test cases for anchor mutation
...and yes,
even writing seemingly superfluous test cases will uncover yet another bug
2018-01-07 03:17:15 +01:00
2665ad5bf3 Navigator: supply another mutation operation to make anchorage explicit
...basically just a re-use of existing functionality.
Needs some test coverage though
2018-01-07 02:24:33 +01:00
c88747dc99 Navigator: cover selection from several possible solutions 2018-01-06 04:36:18 +01:00
e7ce82d17e Navigator: fix covering of an explicit UI-Coordinate
...especially to make the anchorage explicit
2018-01-06 03:32:42 +01:00
0ea5583b62 Navigator: explicitly reject solutions that did not bind all wildcards
...this makes most of the remaining test cases pass

only a plain anchor is not yet properly interpolated
2018-01-05 03:57:27 +01:00
d9db5f3917 Navigator: further unit tests for boundrary cases
NOTE not working yet; trailing wildcards not rejected
2018-01-05 02:14:22 +01:00
f4648c393f Navigator: unit test simple cases of coverage 2018-01-04 04:52:09 +01:00
f23b916f03 Navigator: rework and sharpen the API
- the default should be to look for total coverage
- the predicates should reflect the actual state of the path only
- the 'canXXX' predicates test for possible covering mutation
2018-01-03 02:46:12 +01:00
d2bbe9c61b TreeExplorer: define behaviour of new "delayed expansion" feature
...we need yet another feature to build the path matching for the Navigator
2018-01-01 17:43:49 +01:00
d5ae52e558 UI-Coordinates: design implementation of the patch matching algorithm
...which indicates that we need some additional functionality from TreeExplorer
2017-12-31 21:05:15 +01:00
b8047b3310 Navigator: LocationQuery interface now finished. Demo implementation unit test PASS (closes #1108)
I set out to "discover" what operations we actually need on the LocationQuery
interface, in order to build a "coordinate resolver" on top. It seems like
this set of operations is clear by now.

It comes somewhat as a surprise that this API is so small. This became possible
through the idea of a ''child iterator'' with the additional ability to delve down and
expand one level of children of the current element. Such can be ''implemented''
by relying on techniques similar to the "Monads" from functional programming.

Let's see if this was a good choice. The price to pay is a high level of ''formal precision''
when dealing with the abstraction barrier. We need to stick strictly to the notion of a
''logical path'' into a tree-like topology, and we need to be strong enough never to
give in and indulge with "the concrete, tangible". The concrete reality of a tree
processing algorithm with memory management plus backtracking is just to complex
to be handled mentally. So either stick to the rules or get lost.
2017-12-26 14:58:30 +01:00
a8e16a0f28 Navigator: identify and fix the bug
...which was basically harmless, no fundamental problem,
just a simple logical error on my behalf (using the wrong
depth level)
2017-12-26 14:40:51 +01:00
798b70f7f4 Navigator: add direct test coverage for child expansion
...et voila, it's broken!!

expansion at Perspective level yields "NIL", while it should yield "perspective-A"
2017-12-26 05:07:35 +01:00
2ea2d38cb2 Navigator: build iterator front-end based on the new TreeExploer capabilities
...but not yet switched into the main LocationQuery interface,
because that would also break the existing implementation;
recasting this implementation is the next step to do....
2017-12-24 04:48:07 +01:00
d653937465 TreeExplorer: allow to call through an IterSource based API for child-expansion
...which basically allows us to return any suitable implementation
for the child iterator, even to switch the concrete iteration on each level.
We need this flexibility when implementing navigation through a concrete UI
2017-12-24 03:28:40 +01:00
f05b3f56c0 Library/IterSource: allow for mix-in extension of the IterSource interface
...at least when using a wrapped Lumiera Iterator as source.
Generally speaking, this is a tricky problem, since real mix-in interfaces
would require the base interface (IterSource) to be declared virtual.

Which incurres a performance penalty on each and every user of IterSource,
even without any mix-in additions. The tricky part with this is to quantify
the relevance of such a performance penalty, since IterSource is meant
to be a generic library facility and is a fundamental building block
on several component interfaces within the architecture.
2017-12-23 18:55:26 +01:00
64ba7bf372 TreeExplorer: now able to pick up and wrap an IterSource 2017-12-23 18:32:25 +01:00
147aeb4049 TreeExplorer: draft immediate IterSource adaptor
This is just a temporary solution, until IterSource is properly refactored (#1125)
After that, IterSource is /basically a state core/ and the adaptor will be more or less trivial
2017-12-23 02:29:19 +01:00
95b5786798 Navigator: consider to work around problems with adapting IterSource
- as it stands currently, IterSource has a design problem, (see #1125)
- and due to common problems in C++ with mix-ins and extended super interfaces,
  it is surprisingly tricky to build on an extension of IterSource
- thus the idea is to draft a new solution "in green field"
  by allowing TreeExplorer to adapt IterSource automatically
- the new sholution should be templated on the concrete sub interface
  and ideally even resolve the mix-in-problem by re-linearising the
  inheritance line, i.e. replace WrappedLumieraIter by something
  able to wrap its source, in a similar vein as TreeExplorer does
2017-12-23 01:59:31 +01:00
1ca890d1b6 Navigator: decide how specifically to build on top of TreeExplorer
...this was a difficult piece of consideration and analysis.
In the end I've settled down on a compromise solution,
with the potential to be extended into the right direction eventually...
2017-12-22 19:35:36 +01:00
1fdeb08f19 TreeExplorer: finished and unit test PASS
several extensions and convenience features are conceivable,
but I'll postpone all of them for later, when actual need arises

Note especially there is one recurring design challenge, when creating
such a demand-driven tree evaluation: more often than not it turns out
that "downstream" will need some information about the nested tree structure,
even while, on the surfice, it looks as if the evaluation could be working
completely "linearised". Often, such a need arises from diagnostic features,
and sometimes we want to invoke another API, which in turn could benefit
from knowing something about the original tree structure, even if just
abstracted.

I have no real solution for this problem, but implementing this pipeline builder
leads to a pragmatic workaround: since the iterator already exposes a expandChildren(),
it may as well expose a depth() call, even while keeping anything beyond that
opaque. This is not the clean solution you'd like, but it comes without any
overhead and does not really break the abstraction.
2017-12-17 03:02:00 +01:00
7ed1948a89 TreeExplorer: refactor to make depth() reflect the logical expansion depth
...so sad.
The existing implementation was way more elegant,
just it discarded an exahusted parent element right while in expansion,
so effectively the child sequence took its place. Resolved that by
decomposing the iterNext() operation. And to keep it still readable,
I make the invariant of this class explicit and check it (which
caught yet another undsicovered bug. Yay!)
2017-12-16 19:21:22 +01:00
add5046c6e TreeExplorer: maybe pragmatic workaround for the remaining design problem
instead of building a very specific collaboration,
rather just pass the tree depth information over the extended iterator API.
This way, "downstream" clients *can* possibly react on nested scope exploration
2017-12-16 06:18:44 +01:00
53efdf6e2b TreeExplorer: investigate logical contradiction in this design
We get conflicting goals here:
 - either the child expansion happens within the opaque source data
   and is thus abstracted away
 - or the actual algorithm evaluation becomes aware of the tree structure
   and is thus able to work with nested evaluation contexts and a local stack
2017-12-15 00:32:30 +01:00
30775b2b32 TreeExplorer: draft demonstration example for a search algorithm
...build on top of the core features of TreeExplorer
- completely encapsulate and abstract the source data structure
- build an backtracking evaluation based on layered evaluation
  of this abstracted expandable data source

NOTE: test passes compilation, but doesn't work yet
2017-12-14 03:06:19 +01:00
46287dac0e TreeExplorer: Monads are of limited usefulnes
...and there is a point where to stop with the mere technicalities,
and return to a design in accordance with the inner nature of things.

Monads are a mere technology, without explicatory power as a concept or pattern

For that reason
 - discard the second expansion pattern implemented yesterday,
   since it just raises the complexity level for no given reason
 - write a summary of my findings while investigating the abilities
   of Monads during this design excercise.
 - the goal remains to abandon IterExplorer and use the now complete
   IterTreeEplorer in its place. Which also defines roughly the extent
   to wich monadic techniques can be useful for real world applications
2017-12-11 02:21:32 +01:00
4ef1801a6f TreeExplorer: draft how depth-first-to-leafs might be implemented
...it can sensibly only be done within the Expander itself.
Question: is this nice-to-have-feature worth the additional complexity
of essentially loading two quite distinct code paths into a single
implementation object?

As it stands, this looks totally confusing to me...
2017-12-11 02:20:15 +01:00
4d21baea6b Bugfix: rectify a moronic tuple type rebinding introduced with #988
At that time, our home-made Tuple type was replaced by std::tuple,
and then the command framework was extended to also allow command invocation
with arguments packaged as lib::diff::Record<GenNode>

With changeset 0e10ef09ec
A rebinding from std::tuple<ARGS...> to Types<ARGS> was introduced,
but unfortunately this was patched-in on top of the existing Types<ARGS...>
just as a partial specialisation.

Doing it this way is especially silly, since now this rebinding also kicks
in when std::tuple appears as regular payload type within Types<....>

This is what happened here: We have a Lambda taking a std::tuple<int, int>
as argument, yet when extracting the argument type, this rebinding kicks in
and transforms this argument into Types<int, int>
Oh well.
2017-12-11 02:20:15 +01:00
13d32916ee TreeExplorer: implement simple auto-expansion
...just expand children instead of normal iteration;
works out of the box, since expansion itself performs a iteration step.
2017-12-10 00:24:36 +01:00
fd5d44f6ca TreeExplorer: draft next case -- auto-expand children
this leads to either unfolding the full tree depth-first,
or, when expanding eagerly, to delve into each sub-branch down to the leaf nodes

Both patterns should be simple to implement on top of what we've built already...
2017-12-09 19:42:22 +01:00
e242053620 TreeExplorer: document wrapping into IterSource 2017-12-09 18:41:35 +01:00
c7e37c29e6 TreeExplorer / IterSource: document design mismatch (-> Ticket #1125)
IterSource should be refactored to have an iteration control API similar to IterStateWrapper.
This would resolve the need to pass that pos-pointer over the abstraction barrier,
which is the root cause for all the problems and complexities incurred here
2017-12-09 06:24:57 +01:00
f300545232 TreeExplorer: investigate wrong behaviour in test
turns out that -- again -- we miss some kind of refresh after expanding children.
But this case is more tricky; it indicates a design mismatch in IterSource:
we (ab)use the pos-pointer to communicate iteration state. While this might be
a clever trick for iterating a real container, it is more than dangerous when
applied to an opaque source state as in this case. After expanding children,
the pos-pointer still points into the cache buffer of the last transformer.
In fact, we miss an actualisation call, but the IterSource interface does not
support such a call (since it tries to get away with state hidden in the pos pointer)
2017-12-09 03:49:59 +01:00
7f6bfc1e45 TreeExplorer: implement wrapping opaquely into an IterSource 2017-12-09 01:17:50 +01:00
681cfbfd8c TreeExplorer: add warning due to the moving builder operations
this was a design decision, but now I myself run into that obvious mistake;
thus not sure if this is a good design, or if we need a dedicated operation
to finish the builder and retrieve the iterable result.
2017-12-08 05:34:28 +01:00
ce1ee71955 TreeExplorer: clarify base initialisation
as it turned out, when "inheriting" ctors, C++14 removes the base classes' copy ctors.
C++17 will rectify that. Thus for now we need to define explicitly that
we'll accept the base for initialising the derived. But we need do so
only on one location, namely the most down in the chain.
2017-12-08 05:32:04 +01:00
aa008d6d4a TreeExplorer: draft my requirements for packaging a TreeExplorer pipeline as IterSource
Since this now requires to import iter-adapter-stl.hpp and iter-source.hpp
at the same time, I decided to drop the convenience imports of the STL adapters
into namespace lib. There is no reason to prefer the IterSource-based adapters
over the iter-adapter-stl.hpp variants of the same functionality.
Thus better always import them explicitly at usage site.


...actual implementation of the planned IterSource packaging is only stubbed.
But I needed to redeclare a lot of ctors, which doesn't seem logical
And I get a bad function invocation from another test case which worked correct beforehand.
2017-12-07 05:48:36 +01:00
9b9dcb2b78 TreeExplorer: add yet another convoluted example
Yay!
...and all of this works flawless right away
2017-12-07 03:11:11 +01:00
160a5e5465 TreeExplorer: cover further flavours of predicate definition 2017-12-07 02:19:19 +01:00
2eacde7f2c TreeExplorer: draft the filter operation
should be low hanging fruit now....
2017-12-06 02:33:32 +01:00
085b304a38 TreeExplorer: finish test coverage of expand+transform 2017-12-06 02:02:22 +01:00
b8cf274de6 Refactoring: extract new duck detectors
due to switching from ADL extension points to member functions,
we now need to detect a "state core" type in a different fashion.
The specific twist is that we can not spell out the full signature
in all cases, since the result type will be formed as a consequence
of this type detection. Thus there are now additional detectors to
probe for the presence of a specific function name only, and the
distinction between members and member functions has been sharpened.
2017-12-05 06:05:33 +01:00
52edf7d930 Refactoring: switch IterStateWrapper to member function based API
Considering the fact that we are bound to introduce yet another iteration control function,
because there is literally no other way to cause a refresh within the IterTreeExplorer-Layers,
it is indicated to reconsider the way how IterStateWrapper attaches to the
iteration control API.

As it turns out, we'll never need an ADL-free function here;
and it seems fully adequate to require all "state core" objects to expose
the API as argument less member function. Because these reflect precisely
the contract of a "state core", so why not have them as member functions.
And as a nice extra, the implementation becomes way more concise in
all the cases refactored with this changeset!

Yet still, we stick to the basic design, *not* relying on virtual functions.
So this is a typical example of a Type Class (or "Concept" in C++ terminology)
2017-12-05 03:28:00 +01:00
81c6136509 TreeExplorer: define interaction between expand and transform-operation
good news: it (almost) works out-of-the-box as expected.

There is only one problem: expandChildren() alters the content of the
data source, yet downstream decorators aren't aware of that fact and
continue to present cached evaluations, until the next iterate() call
is issued. Yet unfortunately this iterate already consumes the first
of the expanded children, which thus gets shadowed by the cached
outcome of parent node already consumed and expanded at that point

See the first example:

"10-8-expand-8-4-2-6-4-2"
should be 6 ^^^
2017-12-04 06:11:08 +01:00
823848db37 TreeExplorer: document arcane special case
...which happens to be supported out of the box,
due to the generic adaptor magic shared with the explore-operation

Exploiting this feature, some functor could even subvert the layering order
2017-12-04 04:34:27 +01:00
ca270028a9 TreeExplorer: transform-operation implemented and covered in test 2017-12-04 04:34:27 +01:00
b5453cc429 TreeExplorer: reimplementation with simpler design
- always layer the TreeExplorer (builder) on top of the stack
- always intersperse an IterableDecorator in between adjacent layers
- consequently...
  * each layer implementation is now a "state core"
  * and the source is now always a Lumiera Iterator

This greatly simplifies all the type rebindings and avoids the
ambiguities in argument converison. Basically now we can always convert
down, and we just need to pick the result type of the bound functor.

Downside is we have now always an adaptation wrapper in between,
but we can assume the compiler is able to optimise such inline
accessors away without overhead.
2017-12-04 04:34:26 +01:00
e58e4553f4 TreeExplorer: make the Core -> Core design work, kind of
...yet this seems like a rather bad idea,
it breeds various problems and requires arcane trickery to make it fly

==> abandon this design
==> always intersperse an IterableDecorator between each pair of Layers
2017-12-04 04:34:24 +01:00
94d5801712 Library: add move-support to ItemWrapper
...especially relevant in the context of TreeExplorer,
where the general understanding is that the "Data Source" (whatever it is)
will be piggy-backed into the pipeline builder, and this wrapping is
conceived as being essentially a no-op.

It is quite possible we'll even start using such pipeline builders
in concert with move-only types. Just consider a UI-navigator state
hooked up with a massive implementation internal pointer tree attached
to all of the major widgets in the UI. Nothing you want to copy in passing by.
2017-12-04 04:26:43 +01:00
1df77cc4ff Library: investigate and fix an insidious problem with move-forwarding (util::join / transformIter)
As it turned out, we had two bugs luring in the code base,
with the happy result of one cancelling out the adverse effects of the other

:-D

 - a mistake in the invocation of the Itertools (transform, filter,...)
   caused them to move and consume any input passed by forwarding, instead
   of consuming only the RValue references.
 - but util::join did an extraneous copy on its data source, meaning that
   in all relevant cases where a *copy* got passed into the Itertools,
   only that spurious temporary was consumed by Bug #1.

(Note that most usages of Itertools rely on RValues anyway, since the whole
point of Itertools is to write concise in-line transformation pipelines...)

*** Added additional testcode to prove util::stringify() behaves correct
    now in all cases.
2017-12-04 04:23:30 +01:00
63a49bccfd Library: define string conversion trait more precisely
It is pointless to include pointers....
A pointer to string is not "basically a string",
and char is handled explicitly anyway.
2017-12-04 03:53:36 +01:00
e379ad82c6 Library: typeof obsoleted by decltype
Replace the remaining usages of the GNU extension 'typeof()'
by the now-standard 'decltype()' operator
2017-12-04 03:53:36 +01:00
b104508685 Library: extract type diagnostics test helpers 2017-12-01 03:51:54 +01:00
674201f5ea Library: finish new form of the type rebinding trait 2017-12-01 03:25:51 +01:00
1047f2f245 Library: decide on the overall shape of the type rebinding helper
- we do strip references
- we delegate to nested typedefs

Hoever, we do *not* treat const or pointers in any way special --
if the user want to strip or level these, he has to do so explicitly.
Initially it seemed like a good idea to do something clever here, but
on the long run, such "special treatment" is just good for surprises
2017-12-01 02:43:27 +01:00
6bb288bf20 Library: search for a way to rebind to nested definitions
...automatically whenever those are present.
Up to now, we hat that as base case, which limited usage to those cases
where we already know such nested definitions are actually present
2017-11-30 23:28:00 +01:00
d73b0b05b2 Library: attempt to get more explicit type diagnostics
...including the various reference and pointer adornments;
typeid() unfortunately strips those, so we'll have to add them manually
2017-11-30 23:23:54 +01:00
60301f7523 Library: need an augmented version of the iterator type rebinding helper
yet another quick-n-dirty hack turned into an useful everyday helper...

but at least I need it to be symmetric in and universally applyable
2017-11-30 21:02:36 +01:00
a3a64147c1 TreeExplorer: implementation draft for the transform-operation
attempt to re-use the same traits as much as possible

NOTE: new code not passing compiler yet, but refactored old code
      does, and still passes unit test
2017-11-30 03:52:32 +01:00
09a263431c TreeExplorer: note further functionality to supplement
- add a filter (should be low hanging fruit)
- wrap the result as IterSource
2017-11-28 03:53:38 +01:00
5b86b660ae TreeExplorer: draft functionality of transform-operation 2017-11-28 03:53:09 +01:00
134821ca15 DOC: document some of the language limitations highlighted by this research 2017-11-27 05:39:47 +01:00
d8f7a22123 TreeExplorer: cover all the remaining cases supported for the expansion functor 2017-11-27 05:07:06 +01:00
86856390e1 TreeExplorer: cover expansion using a different result type
here using a lambda with side-effect and returning a reference to
a STL collection with the children, which is managed elsewhere.
2017-11-27 05:07:06 +01:00
6667a51a61 TreeExplorer: cover another use case expand( Val -> iter<Val> )
...which uncovered an error in the test fixture
plus helped to spot the spurious copy when passing the argument to the expand functor

And my GDB crashed when loading the executable, YAY!
so we'll need to coment out some code from now on,
until we're able to switch to a more recent toolchain  (#1118)
2017-11-26 22:35:43 +01:00
bb948bff34 TreeExplorer: working solution to accept generic lambda
but possible only for the iterator -> iterator case

Since we can not "probe" a generic lambda, we get only one shot:
we can try to bind it into a std::function with the assumed signature
2017-11-25 02:16:21 +01:00
3614085ff7 Library: improve the function-signature detector to work as guard with enable_if
This is a consequence of the experiments with generic lambdas.
Up to now, lib::meta::_Fun<F> failed with a compilation error
when passing the decltype of such a generic lambda.

The new behaviour is to pick the empty specialisation (std::false_type) in such cases,
allowing to guard explicit specialisations when no suitable functor type
is passed
2017-11-24 23:48:56 +01:00
01937f9736 Research: possiblity to detect a generic Lambda? 2017-11-24 23:48:56 +01:00
18553f22b2 TreeExplorer: cover both variants of functor signature by unit test (PASS) 2017-11-23 03:29:26 +01:00
f10e66e4ae TreeExplorer: design a solution to handle expansion of children
this solution makes me feel somewhat queasy..
stacking several adaptors and wrappers and traits on top of each other.

Well, it type checks and passes the test, so let's trust functional programming
2017-11-20 01:03:44 +01:00
d10c5a4f77 TreeExplorer: draft the core (explore) operation
The plan is to use a monad-like scheme, but allow for a lot of leeway
with respect to the src and value types of the expand functor.
A key idea is to allow for a *different* state core than used in the source
2017-11-19 20:36:19 +01:00
cbb35d7161 TreeExplorer: add shortcut to adapt STL container automatically
...selecting the iterator or const iterator as apropriate
2017-11-19 17:35:00 +01:00
fd3d6fb60e TreeExplorer: first testcase, build either from Lumiera-Iterator or use StateCore
TODO: also wrap any suitable STL iterable.
we need a one-shot solution here
2017-11-19 02:28:48 +01:00
fe3feee67a Library: metafunction to detect support for a specific extension point
such a detector function can be used to enable some template specialisation
based on the fact that a target type exposes the desired extension point
2017-11-19 01:43:19 +01:00
2345d76138 Research: how to detect that a type in question exposes a free function extension point
The key trick is to form an expression with the free function, using a declval of the type to probe.
What is somewhat tricky is the fact that functions can be void, so we need just to pick up
the type and use it in another type expression
2017-11-19 00:35:38 +01:00
a7bdc05091 WIP: draft first testcase
...just wrapping various kinds of iterators
2017-11-18 18:40:30 +01:00
c3b04af76f TreeExplorer: decide upon the steps towards implementation
Here, the tricky question remains, how to relate this evalutaion scheme
to the well known monadic handling of collections and iterators.

It seems, we can not yet decide upon that question, rather we should
first try to build a concrete implementation of the envisioned algorithm
and then reconsider the question later, to what extent this is "monadic"
2017-11-18 03:00:59 +01:00
782b4f949f TreeExplorer: extended analysis regarding tree expanding and backtracking computation (#1117)
This can be seen as a side track, but the hope is
by relying on some kind of monadic evaluation pattern, we'll be
able to to reconcile the IterExplorer draft from 2012 with the requirement
to keep the implementation of "tree position" entirely opaque.

The latter is mandatory in the use case here, since we must not intermingle
the algorithm to resolve UI-coordinates in any way with the code actually
navigating and accessing GTK widgets. Thus, we're forced to build some kind
of abstraction barrier, and this turns out to be surprisingly difficult.
2017-11-17 21:43:50 +01:00
e035dbc54a UI-Coordinates: support for truncating a given spec
...implemented within the builder.
Will shorten and discard extraneous storage,
but not expand and allocate new one
2017-10-30 02:59:56 +01:00
5530bbede8 Navigator: decide upon the fine points of meaning
anchorage vs. coverage
partial vs total
possible anchorage
possible coverage
2017-10-30 01:47:29 +01:00
750b124f88 Library: complement the pseudo-iterator by a IterSource front-end 2017-10-29 15:31:34 +01:00
0682e449a3 Library: a pseudo-iterator to yield just a single value
...which can be helpful when a function usually returns a somewhat dressed-up iterator,
but needs to return a specific fixed value under some circumstances
2017-10-29 14:51:51 +01:00
7e241d9a11 Library: a little bit of modernising and overhaul
- fix some warnings due to uninitialised members
  (no real problem, since these members get assigned anyway)
- use a lambda as example function right in the test
- use move initialisation and the new util::join
2017-10-29 13:22:25 +01:00
c39442a287 LocationQuery: recast syntax for inline structure definitions
this fixes a silly mistake:
obviously we want named sub-nodes, aka. "Attributes",
but we used the anonymous sub-nodes instead, aka. "Children"

Incidentally, this renders the definitions also way more readable;
in fact the strange post-fix naming notation of the original version
was a clear indication of using the system backwards....
2017-10-28 00:17:56 +02:00
5f9b8eb18c LocationQuery: draft the other query functions as recursive drill-down
Note: Unit test still fails...
2017-10-23 04:13:38 +02:00
2c96fcd164 LocationQuery: draft unit test to cover the query API 2017-10-22 00:44:30 +02:00
0dd516a298 Navigator: consider how to approach path resolution
obviously, we get a trivial case, when the path is explicit,
and we need a tricky full blown resolution with backtracking
when forced to interpolate wildcards to cover a given UICoord
spec against the actual UI topology.

Do we need it?
 * actually not right now
 * but already a complete implementation of the ViewSpec concept
   requires such a resolution
2017-10-21 01:53:13 +02:00
2d5717bfd7 Navigator: continue draft of UI coordinate resolver 2017-10-18 03:40:26 +02:00
7b2c98474f Navigator: initial draft of a UI coordinate resolver
...which in turn will drive the design of the LoactionQuery API
2017-10-16 02:39:22 +02:00
121b13e665 Navigator: analysis indicates to limit mutations
...to limit them to the UI-Coordinates themselves,
while declining the possibility to mutate the target environment
through the PathResolver. Better handle changes within the
target environment by dedicated API calls on the target elements,
instead of creating some kind of "universal structure"
2017-10-16 01:28:49 +02:00
ed76151d14 UI-Coordinates: value representation finished and unit test PASS (#1106) 2017-10-03 00:57:23 +02:00
f23b02b841 UI-Coordinates: implement simple locally decideable predicates 2017-10-02 23:41:03 +02:00
d9555701ac UI-Coordinates: implement a partial "sub path" order 2017-10-02 23:06:23 +02:00
3d8d383ca8 UI-Coordinates: add relational operators for partial order
It is not possible to inherit through boost operators
and defining them explicitly is not that much fuss either.
Plus we avoid the boost include on widely used header
2017-10-02 22:18:00 +02:00
42277c5760 UI-Coordinates: need to spell out all ctors explicitly
the usual drill...
once there is one additional non explicit conversion ctor,
lots of preferred conversion paths are opened under various conditions.

The only remedy is to define all ctors explicitly, instead of letting the
compiler infer them (from the imported base class ctors). Because this way
we're able to indicate a yet-more-preferred initialisation path and thus
prevent the compiler from going the conversion route.

In the actual case, the coordinate Builder is the culprit; obviously
we need smooth implicit conversion from builder expressions, and obviously
we also want to restrict Builder's ctors to be used from UICoord solely.

Unfortunately this misleads the compiler to do implement a simple copy construction
from non const reference by going through the prohibited Builder ctor, or to
instantiate the vararg-ctor inherited from PathArray.

Thus better be explicit and noisy...
2017-10-02 22:17:56 +02:00
5127414773 UI-Coordinates: next steps to cover
- allow tab specification to be elided
- simple comparisons between UI coordinates
- local query predicates
2017-10-02 18:39:18 +02:00
18d1e7a280 UI-Coordinates: polish test and consider next steps
After completing the self-contained UICoord data elements,
the next thing to consider might be how to resolve UI coordinates
against an actual window topology. We need to define a suitable
command-and-query interface in order to build and verify this
intricate resolution process separated from the actual UI code.
2017-10-02 18:11:21 +02:00
5c113b058d UI-Coordinates: better name the local component UIC_PATH 2017-10-02 16:51:45 +02:00
286b1829fe UI-Coordinates: implement path split and appending of multiple components
Unit test passes thus far
2017-10-02 06:49:50 +02:00
835b964e63 UI-Coordinates: implement append / prepend mutation 2017-10-02 06:45:50 +02:00
7826d6dc24 UI-Coordinates: implement low-level data manipulation incl. storage expansion 2017-10-02 06:45:45 +02:00
5097637f0d UI-Coordinates: basic unit test PASS 2017-10-01 21:54:35 +02:00
3a8f639a12 UI-Coordinates: implement reverse lookup 2017-10-01 20:12:45 +02:00
6322f1bc3c UI-Coordinates: define next steps to cover 2017-10-01 20:04:12 +02:00
8c694b6ec0 UI-Coordinates: PathArray abstraction finished and unit test PASS 2017-10-01 06:08:54 +02:00
ebe74bcb53 UI-Coordinates: add further coverage for various boundary cases 2017-10-01 04:45:19 +02:00
107e9008e5 UI-Coordinates: bugfix to pass unit test thus far
whew!
2017-10-01 03:58:42 +02:00
5dfd135595 Library: remove redundant checks from IterAdapter implementation
Explicitly assuming that those functions are called solely from IterAdapter
and that they are implemented in a typical standard style, we're able to elide
two redundant calls to the checkPoint() function. Since checkPoint typically performs
some non-trivial checks, this has the potential of a significant performance improvement

- we check (and throw ITER_EXHAUST) anyway from operator++, so we know that pos is valid
- the iterate() function ensures checkPoint is invoked right after iterNext,
  and thus the typical standard implementation of iterNext need not do the same
2017-10-01 03:25:33 +02:00
a08fba5880 UI-Coordinates: establish contract 2017-10-01 01:30:53 +02:00
1138898989 UI-Coordinates: implement indexed access
...under the assumption that the content is normalised,
which means
- leading NULL is changed to Symbol::EMPTY
- missing elements in the middle are marked as "*"
- trailing NULL in extension storage is handled by adjusting nominal extension size
2017-09-30 02:48:25 +02:00
fcd8882206 Metaprogramming: finish variadic argument picker test 2017-09-29 03:21:47 +02:00
4348cd462c Metaprogramming: extend testcase and remould pickInit to support arbitrary arguments
as it turned out, the solution from yesterday works only with uniform argument lists,
but not with arbitrarily mixed types. Moreover the whole trickery with the
indices was shitty -- better use a predicate decision on template argument level.
This simple solution somehow just didn't occur to me...
2017-09-29 02:35:15 +02:00
636ab6e608 Metaprogramming: integrate the new facilities into the library 2017-09-29 00:51:13 +02:00
7296e60731 Metaprogramming: draft test for the new argument picker (WIP) 2017-09-28 16:28:15 +02:00
372512006f UI-Coordinates: use a recursive implementation layout
this is a more or less arbitrary guess regaring performance requirements
2017-09-25 00:26:19 +02:00
5e1c25aaf5 UI-Coordinates: extract PathArray base abstraction into a library class 2017-09-24 22:50:42 +02:00
4082526ec6 UI-Coordinates: stub basic path element iteration 2017-09-24 21:14:26 +02:00
6073dbfcaf UI-Coordinates: stub basic access operations (WIP) 2017-09-24 17:20:47 +02:00
08f70c068c UI-Coordinates: dream up some basic properties (WIP)
ZOMG... who is to code up all this stuff...?
2017-09-24 02:04:23 +02:00
78cbf0f57e UI-Coordinates: define basic design 2017-09-23 17:55:40 +02:00
feb8414016 UI-Coordinates: stub to pass compilation 2017-09-23 02:25:52 +02:00
c1f240687b UI-Coordinates: elaborate and simplify DSL draft (WIP) 2017-09-23 01:21:06 +02:00
ff1b22a889 UI-Coordinates: DSL draft (WIP) 2017-09-15 01:38:11 +02:00
afda9e0a69 UI-coordinates: also need to define a topological addressing scheme (#1106) 2017-09-10 00:32:31 +02:00
fef0a812c1 DockAccess: start implementation draft for the DSL 2017-09-09 23:30:44 +02:00
a9797e4a4f DockAccess: analysis continued...
exploring the idea of a configuration DSL.
As a first step, this could be a simple internal DSL,
implemented as a bunch of static functor objects, which are internally bound
and thus implemented by the ViewLocator within InteractionDirector
2017-09-08 03:53:52 +02:00
e46d23bd62 GCC-5 compatibility: need 1/3 more inline buffer space
GCC-5 requires more storage for some basic data types
Most notably std::string is now way larger than void*
2017-08-17 13:24:34 +02:00
ae2a9f0953 GCC-5 compatibility: fix some simple output matches in testsuite
GCC-5 produces slightly different output formatting
2017-08-17 12:50:25 +02:00
937ad64596 DiffMessage: now uniformly plays the role of MutationMessage (closes #1066) 2017-08-13 07:25:32 +02:00
5ea80f39cb DiffMessage: successfully finish extended integration test
now we're able to inject flocks of Borg into the alpha quadrant by diff message
2017-08-13 07:25:32 +02:00
3b547ce3d0 DiffMessage: basically got the integration test to work
...still with lots of diagnostic messages,
and need to fine tune the balance between generator and consumer,
in order to produce more interesting patterns.
Also need to verfiy the results automatically

Problems while building the test fixture: several, most notably again
the dangers when combining lambdas and multithreading. The most glorious
mistake was to capture the notifyGUI function, which led to locking
a corrupted uiDispatcher queue, causing deadlock.

Problems in the actual test subject: seemingly none.
Message passing and diff application works like a charm!
2017-08-13 07:25:32 +02:00
f7402ef89d Library: allow to consume an iterator while taking the snapshot 2017-08-13 07:25:32 +02:00
7e9bb1fb5d DiffMessage: elaborate integration test... 2017-08-12 23:02:00 +02:00
fb81751b91 DiffMessage: draft multithreaded integration test of diff application (#1066)
...because it seems adequate really to cover the whole invocation pattern
in a laboratory setup, including the twist to pass thread boundraries.
2017-08-12 19:32:57 +02:00
b45ffe5cbe DiffMessage: fix insidious initialisation bug (related to #963)
basically DiffMessage has a "take everything" ctor, which happens
to match on type DiffMessage itslef, since the latter is obviously
a Lumiera Forward Operator. Unfortunately the compiler now considers
this "take everyting" ctor as copy constructor. Worse even, such a
template generated ctor qualifies as "best match".

The result was, when just returing a DiffMessage by value form a
function, this erroneous "copy" operation was invoked, thus wrapping
the existing implementation into a WrappedLumieraIterator.

The only tangible symptom of this unwanted storage bloat was the fact
that our already materialised diagnostics where seemingly "gone". Indee
they weren't gone for real, just covered up under yet another layer of
DiffMessage wrapping another Lumiera Forward Iterator
2017-08-12 18:16:06 +02:00
5fbc4b84bf DiffMessage: switch to moving DiffMessage over the bus
basically the opaque-buffer based MutationMessage implementation is obsoleted now
2017-08-12 17:59:02 +02:00
b9acb3f50f DiffMessage: complete test coverage 2017-08-12 14:48:35 +02:00
06ff5c4e71 DiffMessage: complete test of diagnostic output 2017-08-12 14:33:26 +02:00
efc27fd07b DiffMessage: draft content diagnostics wrapper 2017-08-12 05:55:31 +02:00
a731b3caf4 metaprogramming: get rid of the remaining boost::enable_if usages
...low hanging fruit
2017-08-11 20:23:46 +02:00
6ee8737a17 WIP: dream up a conveninence interface 2017-08-11 19:28:16 +02:00
a0040fe6ab DiffMessage: basic test case PASS 2017-08-11 19:11:14 +02:00
9ad0dd9918 DiffMessage: start with drafting the most simple test case
damn it!
why the hell is the C++ language so tedious to write....
even after years of practice you need hours to get the most basic stuff to fly
2017-08-11 18:34:23 +02:00
88b2260496 DiffMessage: draft test steps to drive refactoring 2017-08-11 15:48:28 +02:00
f6baef16c5 DiffMessage: consider to unite the handling of mutation messages (#1066) 2017-08-11 15:23:33 +02:00
fd0a011ea4 DiffMessage: bold attempt towards a way to produce diffs (#1066)
actually I do not know much regarding the actual situation when,
within the Builder run, we're able to detect a change and generate
a diff description. However, as a first step, I'll pick IterSrouce
as a base interface and use a "generation context", which is to be
passed by shared-ptr
2017-08-11 00:59:10 +02:00
c324d2e594 Proc-Commands: remove a function we likely won't need ever (closes #291) 2017-08-10 21:52:51 +02:00
46fc900980 UI-Dispatch: get the multithreded test to work (#1098)
the (trivial) implementation turned out to be correct as written,
but it was (again) damn challenging to get the mulithreaded chaotic
test fixture and especially the lambda captures to work correct.
2017-08-07 05:19:58 +02:00
70e1a5b922 convert ScopedCollection to rely on C++11
- variadic templates
- type traits
- use uniqe_ptr to manage storage (instead of boost::scoped_array)
2017-08-06 18:21:25 +02:00
0b621e71c5 Library: fix a suptle misconception in the design of IterAdapter
again surprising how such fundamental bugs can hide for years...

Here the reason is that IterAdapter leaves the representation of "NIL" to
its instantiation / users; some users (here in for example the ScopedCollection)
can choose to allow for different representations of "NIL", but the comparison
provided by IterAdapter just compares the embedded pos by face value.
2017-08-06 16:58:22 +02:00
908d1a8faa test need to be linked against liblumierabackend
...while tests in the library subdirectory are linked only against
liblumierasupport, which does not provide the multithreading support

In this special case here the actual facility to be tested does not rely
on thread support, only on locking. But the stress test obviously needs
to create several threads. Simple workaround is to move the test into
a test collection linked against all of the application core...
2017-08-06 15:30:01 +02:00
4095cd8cf3 Ui-Dispatch: draft multithreaded stress test for call dispatcher queue
for the simplistic implementation we're using right now this effort might look
exaggerated, but we should consider using a lock-free implementation at some
point in the future, at which point it is good to have a stress test in place
2017-08-06 15:21:31 +02:00
87dc04f324 UI-Dispatch: verify consistency of argument data handling 2017-08-05 18:44:25 +02:00
3dea3c0fa0 UI-Dispatch: draft basic interface of a queue helper (#1098) 2017-08-05 17:36:32 +02:00
9b285a95c0 UI-Integration: plan the next steps to drive this topic ahead (#1099, #1098)
- concept for a first preliminary implementation of dispatch into the UI thread
 - define an integration effort to build a complete working communication chain
2017-08-05 17:36:32 +02:00
37cdfaba54 GCC-5 compatibility: remove the last remaining auto_ptrs 2017-05-01 21:43:10 +02:00
6a80053395 CmdAccess: reworked draft for context-bound commands and resolver expressions 2017-04-17 21:20:51 +02:00
10c2e4b9a9 CmdAccess: rename the front-end to CmdContext to clarify the purpose 2017-04-17 20:00:07 +02:00
82d66cef73 CmdAccess: discard the InvocationTrail concept
after extended analysis, it turned out to be a "placeholder concept"
and introduces an indirection, which can be removed altogether

- simple command invocation happens at gui::model::Tangible
- it is based on the command (definition) ID
- instance management happens automatically and transparently
- the extended case of context-bound commands will be treated later,
  and is entirely self-contained
2017-04-17 18:21:52 +02:00
8c7ac997de CmdAccess: replace existing usages of InvocationTrail 2017-04-17 16:57:09 +02:00
876c1dd1fd Commands: change implementation frame to include the command-ID
while the initial design treated the commands in a strictly top-down manner,
where the ID is known solely to the CommandRegistry, this change and information
duplication became necessary now, since by default we now always enqueue and
dispatch anonymous clone copies from the original command definition (prototype).

This implementation uses the trick to tag this command-ID when a command-hanlde
is activated, which is also the moment when it is tracked in the registry.
2017-04-17 03:09:12 +02:00
471fa5b9c4 CommandInstanceManager: fix error check accidentally killing the local instance
due to the refactorings, the instance was moved out prior to checking for
bound arguments. This is ammended now, albeit at the price of passing an
additional flagn and some tricky boolean conditions
2017-04-17 01:51:27 +02:00
3922bb58e1 Commands: fix and adapt instance management test 2017-04-17 01:51:27 +02:00
cfe192f8c6 Commands: some unit test coverage for unbinding arguments
...just to make sure it is properly integrated with the state predicates
2017-04-16 19:38:56 +02:00
410c36d2c3 Commands: change semantics of command instance management (#1089)
in accordance to the design changes concluded yesterday.
 - in the standard cases we now check the global registry first
 - automatically create anonymous clone copy from global commands
 - reorganise code internally to use common tail implementation
2017-04-16 18:27:05 +02:00
079ad715b0 Commands: change API to allow moving commands into the dispatcher queue 2017-04-16 16:16:26 +02:00
67e1032f7d Commands: draft the changes to be done with command instance management
...as consequence to be drawn from the design critique
2017-04-16 02:51:38 +02:00
5f6854621e Command-Cycle: remove the separate 'bang!' message
as it turns out, we can always trigger commands right away,
the moment all arguments are known. Thus it is sufficient to
send a single argument binding message, which allows us to
get rid of a lot or ugly complexities (payload visitor).
2017-04-14 23:45:35 +02:00
35a4e7705b CmdAccess: expand on the DSL draft 2017-04-14 03:22:08 +02:00
aecef2a8f4 Commands: refactor integration into SessionCommandService (#1089)
It seems more adequate to push the somewhat intricate mechanics
for the "fall back" onto generic commands down into the implementation
level of CommandInstanceManager. The point is, we know the standard
usage situation is to rely on the instance manager, and thus we want
to avoid redundant table lookups, only to support the rare case of
fallback to global commands. The latter is currently used only from
unit-tests, but might in future also be used by scripts.

Due to thread safety considerations, I have refrained from handing
out a direct reference to the command token sitting in the registry,
even while not doing so incurs a small runtime penalty (accessing
the shared ref-count for creating a copy of the smart-handle).
This is the typical situation where you'd be tempted to sacrifice
sanity for the sake of an imaginary performance benefit, which
in fact is dwarfed by all the machinery of UI-Bus and argument
passing via GenNode.
2017-04-09 19:11:40 +02:00
a53032cfc5 Analysis regarding the next step, integration of InstanceManagement into SessionCommand facade 2017-04-09 01:34:18 +02:00
22c1a1d189 Commands: rename some of the planned components for command access
...to make the names more handy
2017-04-08 16:24:36 +02:00
f495a069aa Symbol: also document usage as (tree)map key
especially note the absence of an comparison operator,
which causes std::map to fall back on pointer comparison.
2017-04-08 03:50:29 +02:00
dd0656e812 Symbol: add more test coverage for comparisons 2017-04-08 03:30:12 +02:00
3f17e6558e Symbol: clean-up of some occasional usages
hereby overlooking the elephant in the room: EntryID could switch to Symbol now
2017-04-08 00:40:04 +02:00
2204066a94 Symbol: test coverage for empty and bool
oh yeah
yet another opportunity for mistakes
2017-04-07 20:06:19 +02:00
4df59678a3 Symbol: rework initialisation and introduce a "bottom" Symbol
Up to now, we tolerated null pointers in Literal instances.
But we can not tolerate passing a null cString to Symbol initialisation.
Rather, hereby we introduce a dedicated "bottom" Symbol, a valid "null object"
2017-04-07 19:25:21 +02:00
29b8b2b8bc Symbol: switch to using the symbol-table as backing implementation (#158)
...which means, from now on identical input strings
will produce the same Symbol object (embedded pointer).

TODO: does not handle null pointers passed in as c-String properly
2017-04-07 06:34:41 +02:00
f9c3b8b61c Commands: get second testcase to PASS 2017-04-07 04:19:10 +02:00
f7d4a3c83e Commands: draft test case to cover lifecycle sanity checks 2017-04-06 20:40:18 +02:00
228f7d441f Commands: draft further test case to cover handling of duplicates
The instance manager opens (creates) a new instance by cloning
from the prototype. Unless this instance is dispatched, it does not
allow to open a further instance (for the same instanceID). But of course
it allows to open a different instance from the same prototype
2017-04-06 20:12:31 +02:00
b2dc6a0cb4 Commands: draft test case to clarify command instance identity 2017-04-06 19:58:45 +02:00
afe07bdb16 decommission the safe-bool-idiom (closes #477)
obsoleted by C++11

 * in most cases, it can be replaced by an explicit conversion operator
 * especially for the Lumiera Forward Iterators, we need an implicit conversion
2017-04-02 06:42:23 +02:00
9c21164ae6 Doxygen Fixes (#1062)
This changeset fixes a huge pile of problems, as indicated in the
error log of the Doxygen run after merging all the recent Doxygen improvements

unfortunately, auto-linking does still not work at various places.
There is no clear indication what might be the problem.
Possibly the rather unstable Sqlite support in this Doxygen version
is the cause. Anyway, needs to be investigated further.
2017-04-02 04:22:51 +02:00
26651a0a86 Fix notorious warning
...especially nasty on full rebuild
2017-04-01 23:59:37 +02:00
05aaa74422 MERGE Doxygen clean-up done during the last months 2017-04-01 23:59:00 +02:00
32f995f1ce Commands: simple instance management unit test PASS (#1089) 2017-04-01 18:39:53 +02:00
16737eb74c Commands: adjustments due to the change to anonymous instances
this is indeed a change of concept.
A 'command instance' can not be found through the official
Command front-end anymore, since we do not create a registration.
This allows us to avoid decorating command IDs with running counters
2017-04-01 02:56:49 +02:00
3dcd84232c Symbol-Table hack: the disease starts to spread (#158)
we need a real symbol table implementation, so we can assemble symbols
and then intern them. This was the whole purpose of inventing the class Symbol
2017-04-01 02:33:15 +02:00
97d7a6804e Commands: implement test fixture
...which acts here as a mocked "ProcDispatcher"
2017-04-01 02:33:15 +02:00
99d23570cd Commands: test driven stubbing.... 2017-04-01 02:33:15 +02:00
a13270a6b8 Commands: static registration for the existing test dummy commands
Up to now, these dummy functions where used by various unit tests
directly, by creating command definitions within the test fixture.

But since it is foreseeable that we'll need dummy commands for various
further unit tests, it seems adequate to setup a global static registration
with the newly created system of command registrations for these dummies.
2017-04-01 02:33:15 +02:00
a91d03b60a Commands: draft usage of CommandInstanceManager (#1089) 2017-04-01 02:33:15 +02:00
95af930a71 Commands: finish CommandSetup helper (#1088)
this is a prerequisite for command instance management:
We have now an (almost) complete framework for writing actual
command definitions in practice, which will be registered automatically.

This could be complemented (future work) by a script in the build process
to regenerate proc/cmd.hpp based on the IDs of those automatic definitions.
2017-03-31 18:30:29 +02:00
e7d24febee Commands: add automatic registration ON_GLOBAL_INIT
...which makes the unit test PASS
2017-03-31 04:36:26 +02:00
49102ff18f Commands: define typical standard usage of CommandSetup 2017-03-31 04:14:45 +02:00
b303bcebc0 Commands: complete the test case
verify the commands where indeed defined as given by the lambda
2017-03-31 03:27:26 +02:00
de7b9f87ed Commands: ensure the commands where actually defined by the closures
...next step in the CommandSetup_test
2017-03-19 06:03:17 +01:00
09b91197d3 Commands: now able to define commands by lambda!
...just pipe all passed functor-like objects
through the reworked function signature trait
2017-03-19 04:09:25 +01:00
017c72e74c Function-Tools: unit test for signature trait PASS 2017-03-19 04:09:25 +01:00
58898997d8 Function-Tools: get rid of the old-style FunctionSignature template
...it is now completely redundant, even superseded by the new _Fun
signature trait (which additionally also handles lambdas)
2017-03-19 04:09:24 +01:00
9a0b72e8ca Function-Tools: include the investigation code as unit test
...since there is not any test coverage for this trait, which
turned out to be quite deeply rooted in the system by now and
handles several rather subtle special cases
2017-03-19 02:29:39 +01:00
afadc35eab WIP: draft command binding by lambda...
as it stands, this does not work, since lambdas are passed by-value,
while function references can only be passed by explicit reference,
otherwise they'll degrade to a function pointer. And std::function
requires a plain function signature as type argument, not the type
of a function pointer (which doesn't mean you can't construct a
std::function from a FP, indeed there is an explicit overload for
that).
2017-03-18 19:02:41 +01:00
e9948084fc Commands: integrate inline command definition by lambda
...this was the problematic part of the whole design attempted here,
and seemingly it works like a charm!
2017-03-18 17:56:41 +01:00
180b1224e7 Commands: implement invocation of enqueued command definitions 2017-03-18 05:28:56 +01:00
d044abe3c7 Commands: implement the registration queue for command definitions 2017-03-18 04:40:16 +01:00
29ce5b9c69 Commands: define interface for installing a command definition
The idea is to assign a lambda, which will be enqueued by side-effect.
implementation is just stubbed.
2017-03-18 03:52:18 +01:00
833193342f Commands: define basic properties of unbound CommandSetup 2017-03-18 03:20:05 +01:00
4648703952 Commands: new test for shaping the CommandSetup helper 2017-03-18 02:27:11 +01:00
b865acf758 Commands: decide about the basic concept how commands are to be defined (#215)
The point in question is how to manage these definitions in practice,
since we're about to create a huge lot of them eventually. The solution
attempted here is heavily inspired by the boost-test framework
2017-03-18 01:55:45 +01:00
b4e0f6bf40 Doxygen: fill in the last missing file level comments for plain-C tests
now each and every source file should be marked with a @file doxygen comment
2017-02-22 03:46:23 +01:00
155bf95ce5 Doxygen: magically insert a reference to the test class
this bit of Sed magic relies on the fact that we happen to write
the almost correct class name of a test into the header comment.

HOWTO:
for F in $(find tests -type f \( -name '*.cpp' \)  -exec egrep -q '§§TODO§§' {} \; -print);
  do sed -r -i -e'
    2          {h;x;s/\s+(.+)\(Test\).*$/\\ref \1_test/;x};
    /§§TODO§§/ {s/§§TODO§§//;G;s/\n//}'
    $F;
done
2017-02-22 03:17:18 +01:00
42d97f6cf6 Doxygen: supply missing file level comments for test support helpers 2017-02-22 01:58:49 +01:00
24b3bec4be Doxygen: prepare all unit tests for inclusion in the documentation
Doxygen will only process files with a @file documentation comment.
Up to now, none of our test code has such a comment, preventing the
cross-links to unit tests from working.

This is unfortunate, since unit tests, and even the code comments there,
can be considered as the most useful form of technical documentation.
Thus I'll start an initiative to fill in those missing comments automatically
2017-02-22 01:54:20 +01:00
60adaa5639 UI-top-level: simplify name and namespace
the (Presentation)StateManager interface and implementation
seems to fit in more into the ctrl package
2017-02-19 04:27:09 +01:00
2045132d3e SessionCommand: multithreaded stress test PASS (closes #1046)
Writing and debugging such tests is always an interesting challenge...

Fortunately this exercise didn't unveil any problem in the newly written
code, only some insidious problems in the test fixture itself. Which
again highlights the necessity, that each *command instance* needs
to be an independent clone from the original *command prototype*,
since argument binding messages and trigger messages can appear
in arbitrary order.
2017-01-14 08:37:46 +01:00
1bebb0ef8d SessionCommand: draft a massive multithreaded stress test 2017-01-14 04:19:58 +01:00
3395d002bd Library: helper to produce threadsafe member-IDs for a family of objects
This is a little bit of functionality needed again and again;
first I thought to use the TypedCounter, but this would be overkill,
since we do not actually need different instances, and we do not need
to select by type when incrementing the counter. In fact, we do not
even need anything beyond just allocating a number.

So I made a new class, which can be used RAII style
2017-01-14 03:07:48 +01:00
0b0575050d SessionCommand: second function test PASS 2017-01-13 09:01:05 +01:00
b52ab62caf SessionCommand: define function test for message based invocation
the intention is to cover more of the full invocation path,
without running all of the application infrastructure. So this
second test cases simulates how messages are handled in CoreService,
where the CommandHandler (visitor) actually invokes the SessionCommand
facade
2017-01-13 08:26:41 +01:00
2d5ef968a8 CommandFramework: fill in a simplified function(integration) test
Start the ProcDispatcher and schedule a command into the session loop thread
2017-01-13 06:13:22 +01:00
edcf503da1 Command-Framework: enable the use of immutable types as state memento 2017-01-13 01:10:05 +01:00
c799c7644c Library: finish adapter to snapshot non-assignable values
this was a spin-off activity from writing the SessionCommand
function(integration) test, where I noted that we can't just
capture "a time value" as command memento
2017-01-12 23:41:20 +01:00
963524254b better provide a dedicated equality operator
basically this is not necessary, since the compiler figures out
to use the conversion to target type when attempting to resolve
an equality comparison. But it helps to avoid ambiguities in cases
where several conversion paths do exist, e.g. when comparing string
with C-string
2017-01-12 20:09:09 +01:00
625787fbba combine instance management with both code paths
for assignable / not assignable types
2017-01-12 08:41:58 +01:00
b6e0497f8b verify instance management
..including the singleton instance in NullValue<Tracker>
2017-01-12 08:02:55 +01:00
f4cd96428c verify a case with indeed non-assignable entities (lumiera Time)
explicitly observed with the debugger that the call path is sane;
the code looks innocuous, but it is quite magic how the compiler
picks precisely the right ctors and inserts conversions apropriately
2017-01-12 07:30:33 +01:00
e60abf66c0 get this wrapper basically to compile
the simple case of an embedded pointer actualy works already
2017-01-12 06:27:31 +01:00
9ba2618844 Library: draft a wrapper to snapshot a non assignable value 2017-01-12 05:21:29 +01:00
3a5790e422 add preliminary magic to dispatch test commands without much ado
command processing against the session is not yet implemented,
so to allow for unit testing, we magically recognise all commands
starting with "test." and invoke them directly within the Dispatcher.

With this addition, the basic functionality of the dispatcher works now
2017-01-11 06:09:34 +01:00
bfebb08015 define test for simple direct dispatching of the command 2017-01-11 05:26:53 +01:00
8a0f26c787 start and stop the Dispatcher for running the function(integration) test
need also to start and stop the interface registry,
since by policy we do not run the application framework itself
for execution of the test suite; thus if some test actually needs
an application service, it must be started/stopped manually
2017-01-11 05:01:47 +01:00
3cc3f69471 SessionCommand: draft the idea of a function(integration) test 2017-01-11 04:19:43 +01:00
2535e1b554 DispatcherLoop: no timeout turnaround necessary in idle state
...since the session loop will be notified on any change via the
interface, adding a command will activate the loop, and the builder
timeout is handled separately via the dirty state. So there is no
need to spin around the loop in idle state.

As a aside, timeout waiting on a condition variable can be intentional
and should thus not be logged as an error automatically. It is up to the
calling context to decide if a timeout constitutes an exceptional situation.

It is always a trade-off performance vs. readability.
Sometimes a single-threaded implementation of self-contained logic
is preferable to a slightly more performant yet obscure implementation
based on our threadpool and scheduler.
2017-01-07 02:46:34 +01:00
dd041ff80c Library: thread self recognition implemented and tested (closes #1054) 2017-01-07 01:01:39 +01:00
d74f1447f3 Library: thread self recognition feature defined (#1054) 2017-01-06 23:26:33 +01:00
3915e3230e DispatcherLoop: add wake-up notification on state change 2017-01-05 21:40:37 +01:00
567b00aa21 DOC: follow-up of removing boost::scoped_ptr 2017-01-05 01:20:34 +01:00
cd8844b409 clean-up: kill Boost scoped_ptr
std::unique_ptr is a drop-in replacement
2017-01-05 00:56:46 +01:00
77303ad007 Session-Subsystem(#318): investigation of locking sanity (ongoing...)
Found an inconsistency and a deadlock!
See proc-dispatcher.cpp, the lambda embedded into the start() operation!
2017-01-04 01:44:35 +01:00
282829956b ProcDispatcher: integrate queue and finish preliminary implementation draft
TODO: the wakeup / notification on changes still needs to be done consistently
2016-12-25 22:26:16 +01:00
3010c87008 CommandQueue: basic queue behaviour implemented and tested 2016-12-25 21:52:52 +01:00
b58427e49f Command-Framework: mark anonymous commands
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_")
2016-12-25 21:46:58 +01:00
3501732839 CommandQueue: simple interface 2016-12-25 19:30:59 +01:00
b5590fb22c CommandQueue: prepare for an unit test 2016-12-25 18:49:57 +01:00
b3f0605b9b SessionCommand-facade: consider how to expose command invocation
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.
2016-12-23 07:26:00 +01:00
386c15f039 obviously a better name
...since it became customary to have make_tuple, make_shared, make_unique
2016-12-23 04:24:22 +01:00
1a4b6545a0 maximum munch
...feels like X-mas
2016-12-23 04:23:03 +01:00
0d436deb9e clean-up and comments for the implementation finished thus far 2016-12-22 04:04:41 +01:00
99b9af0a74 Looper: loop control logic unit test PASS 2016-12-22 03:28:41 +01:00
96def6b1ba Looper: elaborate implementation
looks doable indeed...
2016-12-22 03:12:14 +01:00
196696a8d0 Looper: draft possible implementation
seemingly a quite simple "trap door" mechanism is sufficient
2016-12-21 03:56:56 +01:00
ef6ecf3dd0 Looper: rework the spec for the builder triggereing behaviour
...still don't know how to implement it, but now it is at least
specified more correct, with respect to the implementation of the loop
2016-12-21 03:15:36 +01:00
6073df3554 Looper: other (better?) idea how to handle "builder dirty" automatically
...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....?
2016-12-20 03:53:48 +01:00
14e0d65468 Looper: idea how to determine "builder dirty"
...just by offloading that task onto the CommandQueue,
which happens to know when a new command is being scheduled
2016-12-20 03:18:03 +01:00
746866f5fc Looper: draft requirements on logic for triggering the builder 2016-12-16 23:56:53 +01:00
b873f7025b ProcDispatcher: mark some next tasks to care for 2016-12-16 23:26:56 +01:00
8ee08905b3 Looper: extend test coverage 2016-12-16 20:38:00 +01:00
30254da95f Looper: implement core operation control logic 2016-12-16 19:21:06 +01:00
9c9e75ee01 Looper: define testcase regarding activity control 2016-12-16 18:40:29 +01:00
af92ed505b Looper: implementation 2016-12-16 18:34:04 +01:00
be97473779 Looper: define first basic testcase 2016-12-16 18:23:46 +01:00
5fd65d6613 Looper: test setup 2016-12-16 18:09:51 +01:00
00077d0431 ProcDispatcher: decide on requirements and implementation structure (#1049) 2016-12-15 20:48:35 +01:00
4fc1126a28 clean-up: mark subsystem implementations with noexcept and override
throw() is deprecated
noexcept behaves similar, but allows for optimisations and will be
promoted to a part of the signature type in C++17
2016-12-12 01:18:19 +01:00
a54990de7c define the plan for some scaffolding to drive the UI-Session connection (#1042)
...following a similar idea as employed when developing the Player-Engine connection
2016-12-10 01:21:08 +01:00
bd42793db7 DOC: a gentle introduction to diff binding
...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.
2016-12-03 23:37:17 +01:00
f995dd51e2 define creation and control structure of TimelineWidget 2016-12-03 05:42:34 +01:00
dbc75fac7d Doxygen: we missed the plain C code 2016-11-03 18:26:43 +01:00
48e9b7594a Doxygen: identify all files lacking a @file comment
reason is, only files with a @file comment will be processed
with further documentation commands. For this reason, our Doxygen
documentation is lacking a lot of entries.

HOWTO:
find src -type f \( -name '*.cpp' -or -name '*.hpp' \) -not -exec egrep -q '\*.+@file' {} \; -print -exec sed -i -r -e'\_\*/_,$ { 1,+0 a\
\
\
/** @file §§§\
 ** TODO §§§\
 */
}' {} \;
2016-11-03 18:20:10 +01:00
2d8a595038 Finish AbstractTangible_test and the basic UI-Element protocol
closes #975 and #992
2016-10-04 03:50:44 +02:00
22f06dca23 Bugfix: must init TreeMutator explicitly now
as consequence of previous fix.
Also, when building the preconfigured TreeMutator for GenNode,
the init hook must be called explicitly now.
2016-10-04 03:24:44 +02:00
1725a31df1 Bugfix: insidious dangling pointer caused by move after construction
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.
2016-10-03 23:54:09 +02:00
bada8ecffd TreeMutator binding: fix collection binding to support move-only types
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()
2016-10-03 20:08:54 +02:00
ffcfa7afd4 WIP: draft a concrete TreeMutator binding for MockElm
...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"
2016-10-03 01:59:47 +02:00
c8ad698ac4 MutationMessage: limit to treating of gui::model::Tangible
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
2016-10-02 23:51:45 +02:00
76fc444437 MutationMessage: implementation draft 2016-10-02 22:21:17 +02:00
c9a8b82dff WIP: draft a test to cover mutation via UI-Bus 2016-10-02 02:57:27 +02:00
d2e4f826ed UI-Bus/mutation: expand on draft for mutation message 2016-10-01 23:09:08 +02:00
27ba8d5896 UI-Bus/mutation: draft idea for mutation message on UI-Bus 2016-09-30 22:23:55 +02:00
e6223a80b9 UI-Bus/mutation: re-read documentation and code
seems I've mostly forgotten what is built and ready to use
2016-09-08 18:49:27 +02:00
2a26cef010 remove leftovers of first diff-applicator implementation
...obsoleted by new generic implementation
2016-09-08 18:30:27 +02:00
4267d3d1d7 application via TreeMutator is now the default
remove the intermediary header
2016-09-05 04:36:07 +02:00
7a29e260e9 tree-diff-language: remove the magic _THIS_ and _CHILD_ construct
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!
2016-09-05 04:04:02 +02:00
5c0baba2eb finish implementation of GenNode - TreeMutator binding
some minor code clean-up and comments;
the solution dafted yesterday is the way to go.
2016-09-04 20:55:21 +02:00
17f8922775 solution (draft) for the type field problem
unit test PASS

but the resulting code is hard to understand
should refactor it to use a binding class
similar to the other binding cases
2016-09-03 22:34:36 +02:00
8530d50b7c complete unit test definition
...but this uncovers problem with handling of the type field
2016-09-03 21:41:12 +02:00
e5f25d8453 third part of unit-test: value assignment 2016-09-03 20:17:46 +02:00
f8e98919fe second part of unit-test for GenNode TreeMutator-binding PASS
...out of the box!
2016-09-03 19:54:54 +02:00
5fed637909 investigate size of the generated TreeMutator (#1007) 2016-09-03 18:15:19 +02:00
a73e5ffffe TreeMutator binding: change handling of AFTER(Ref::ATTRIBS)
this is a subtle change in the semantics of the diff language,
actually IMHO a change towards the better. It was prompted by the
desire to integrate diff application onto GenNode-trees into the
implementation framework based on TreeMutator, and do away with
the dedicated implementation.

Now it is a matter of the *selector* to decide if a given layer
is responsible for "attributes". If so, then *all* elements within
this layer count as "attribute" and an after(Ref::ATTRIBS) verb
will fast forward behind *the end of this layer*

Note that the meta token Ref::ATTRIBS is a named GenNode,
and thus trivially responds to isNamed() == true
2016-09-02 18:40:16 +02:00
05768e4ac5 first part of unit-test for GenNode TreeMutator-binding PASS
needed to use a forward function declaration within the
lambda for recursive scope mutator building, since otherwise
everything is inline and thus the compilation fails when it
comes to deducing the auto return type of the builder.

Other than that, the whole mechanics seem to work out of the box!
2016-09-02 03:10:27 +02:00
f907ff05d6 WIP: define binding behaviour for diff->GenNode
...need still to solve a problem with circular definition dependencies
2016-09-01 22:58:08 +02:00
b3e7af90dc complete two more long standing test definitions 2016-08-29 23:04:44 +02:00
ffd40d86e7 finish integration test and TreeMutator binding (#992)
This implementation draft is now roughly complete
2016-08-29 19:39:19 +02:00
2814276387 a better name for the complex integration test 2016-08-29 17:52:35 +02:00
22281d7323 deal with a mismatch between diff language and impl situation
- for sake of consistency, diff language requires INS
- but typically, that implementation will be NOP
2016-08-26 02:56:48 +02:00
fe4b46ad7c implement mutation of nested scopes 2016-08-26 02:42:19 +02:00
cc91e5bba6 implement rest of the list diff verbs plus accept-until construct
basically just assembling the ready made building blocks now...
2016-08-25 17:48:40 +02:00
66022d623d reorder test definition accordingly: mutateAttribute()
similar reordering for the third part.
This time most operations are either passed down anyway,
or are NOP, since attribute binding has no notion of 'order'
2016-08-13 19:03:42 +02:00
4ea5b0d308 reorder test definition accordingly: mutateCollection()
similar reordering for the second part of the test...
2016-08-13 18:34:52 +02:00
4b5f562a3c reorder test definition accordingly: mutateDummy()
as said, I try to use the same underlying sequence of diff verbs both
for the high-level and the low-level test. Thus, since the high-level test
requires an adjustment to the test definition, we'll have to re-order
all of the low-level tests likewise. This is part-1 of this re-ordering
2016-08-13 18:05:15 +02:00
33534065a6 reshape test diff to be more in line with the newly written implementation
...during implementation of the binding, I decided to be more strict
with the interpretation of "reshaping" of attributes: since my onion-layer
for attribute binding works without the notion of any 'position' or 'ordering',
I made up my mind that it's best outright to reject any diff verbs attempting
to re-order or delete attributes. The rationale is that otherwise the same diff
might lead to substantially different results when applied to a Rec<GenNode>
as when applied to a target data structure bound via TreeMutator.

Consequently, the previously established test diff sequence would raise an error::Logic
in the second segment, since it attempts to re-order attributes. Instead of this,
I've now introduced a after(Ref::ATTRIBS) verb and I'm re-ordering children
rather than attributes.

Unfortunately this also prompts me to re-adjust all of the TreeMutatorBinding_tests,
since these detail tests are intended to play the same sequence on low level.
This is not a fundamental problem, though, just laborious.          CHECK (target.showContent() == "α = 1, γ = 3.45, γ = 3.45, β = 2, Rec(), 78:56:34.012, b");
2016-08-13 17:50:40 +02:00
0782dd4922 investigate and confirm the logic underlying the matchSrc, skipSrc and acceptSrc primitives
In Theory, acceptSrc and skipSrc are to operate symmetrically,
with the sole difference that skipSrc does not move anything
into the new content.

BUT, since skipSrc is also used to implement the `skip` verb,
which serves to discard garbage left back by a preceeding `find`,
we cannot touch the data found in the src position without risk
of SEGFAULT. For this reason, there is a dedicated matchSrc operation,
which shall be used to generate the verification step to properly
implement the `del` verb.

I've spent quite some time to verify the logic of predicate evaluation.
It seems to be OK: whenever the SELECTOR applies, then we'll perform
the local match, and then also we'll perform the skipSrc. Otherwise,
we'll delegate both operations likewise to the next lower layer,
without touching anything here.
2016-08-09 23:42:42 +02:00
43f3560b15 get the first diff verb to work
surprise surprise, no catastrophe thus far....
2016-08-08 14:20:54 +02:00
6e829e3f22 guard applicability by selector predicate
OMG ... this can't possibly work???!
2016-08-07 01:58:26 +02:00
18c9f95cbe integrate the first diff verb 'ins'
--> now it becomes obvious that we've mostly
missed to integrate the Selector predicate properly
in most bindings defined thus far. Which now causes
the sub-object binding to kick in, while actually
the sub-value collection should have handled
the nested values CHILD_B and CHILD_T
2016-07-31 00:33:26 +02:00
cbdc53e2d8 define a TreeMutator binding for our test::Opaque type
OMG, this is intricate stuff....
Questionable if anyone (other than myself) will be able
to get those bindings right???

Probably we'll need yet another abstraction layer to handle
the most common binding situations automatically, so that people
can use the diff framework without intricate knowledge of
TreeMutator construction.
2016-07-31 00:33:26 +02:00
2b424be57c deprecate planned Option monad
...since C++17 will likely ship an option type with the standard library
2016-07-31 00:33:26 +02:00
78c9b0835e solution draft for integration of the whole tree diff application machinery
This is the first skeleton to combine all the building blocks,
and it passes compilation, while of course most of the binding
implementation still needs to be filled in...
2016-07-31 00:33:25 +02:00
ed18e1161c WIP: code organisation - double layered architecture 2016-07-31 00:33:19 +02:00
4a2340ca5e solution for access to "tree mutator building closure"
- default recommendation is to implement DiffMutable interface
- ability to pick up similar non-virtual method on target
- for anything else client shall provide free function mutatorBinding(subject)


PERSONAL NOTE: this is the first commit after an extended leave,
where I was in hospital to get an abdominal cancer removed.
Right now it looks like surgery was successful.
2016-07-21 19:29:16 +02:00
5744244f73 considerations how to access the "tree mutator building closure"
this is at the core of the integration problem: how do we expose
the ability of some opaque data structure to create a TreeMutator?

The idea is
 - to use a marker/capability interface
 - to use template specialisation to fabricate an instance of that interface
   based on the given access point to the opaque data structure
2016-06-14 02:33:28 +02:00
61627b26a0 WIP: first attempt to use a TreeMutator based binding
but unfortunately this runs straight into a tough problem,
which I tried to avoid and circumvent all the time:
At some point, we're bound to reveal the concrete type
of the Mutator -- at least to such an extent that we're
able to determine the size of an allocator buffer.

Moreover, by the design chosen thus far, the active
TreeMutator instance (subclass) is assumed to live within
the top-level of a Stack, which means that we need to
place-construct it into that location. Thus, either
we know the type, or we need to move it into place.
2016-06-11 19:40:53 +02:00
37f4caf7be draft data structure for the integration test to work on
the idea is to demonstrate the typical situation
of some implementation class, which offers to create
a binding for diff messages. This alone is sufficient
to allow mapping onto our "External Tree Description"
2016-06-10 04:30:02 +02:00
41f5ddb029 use the same underlying diff sequence in both tests
this is done to help with understanding these quite technical matters:
in the integration test, we use a specific diff sequence and
apply it against an opaque data structure, which is bound using
the TreeMutator::Builder

On the other hand, the TreeMutatorBinding_test covers the
elementary building blocks available to construct such a TreeMutator;
here again we assume the precisely same sequence of diff verbs
in all test cases, but actually we're issuing here those interface
actions on the TreeMutator API, which *would* be issued to
consume this diff sequence. Of course, there need to be
slight variations, since not any kind of binding can
handle all operations, but in principle the result
on the target data structure should be semantically
equivalent in all cases
2016-06-10 03:19:33 +02:00
57b105bbc5 fix a re-entrance problem
initially, even the diff applicator was meant to be a
"throwaway" object. But then, on writing some tests,
it seemed natural to allow re-using a single applicator,
after having attached it to some target.

With that change, I failed to care for the garbage
left back in the "old" sequence after applying one diff;
since in the typical usage sequence, the first use builds
content from scratch, this problem starts to show up only
with the third usage, where the garbage left from the input
of the second usage appears at the begin of the "new sequence"

Solution is to throw away that garbage explicitly on re-entrance
2016-06-10 02:48:22 +02:00
15246ef323 investigate surprising behaviour 2016-06-10 02:42:08 +02:00
115f03b092 draft idea for the next (integration) test
the plan is to put together an integration test
of diff application to opaque data through the TreeMutator,
using the now roughly finished binding primitives.

moreover, the idea is to apply precisely the same diff sequence,
as was used in the detail test (TreeMutatorBinding_test).


NOTE: right now, the existing placehoder code applies this sequence
onto a Rec<GenNode>. This should work already -- and it does,
BUT the result of the third step is wrong. Really have to
investigate this accidental finding, because this highlights
a conceptual mismatch in the handling of mixed scopes.
2016-06-09 02:15:50 +02:00
37cfdbb7e1 better name for nested handle type 2016-06-09 01:18:21 +02:00
ef27c09fa2 round-up and document the attribute binding and test 2016-06-09 01:10:52 +02:00
b5ab5df929 supply implementation, basically working already
so this test case is more or less finished,
just needs some more polishing and documentation
2016-06-05 17:26:48 +02:00
20c6116732 draft remainder of this test case 2016-06-05 16:52:37 +02:00
6eff16f21c supply missing implementation
standard case of attribute binding, i.e.
the setter invocation is fully functional now.
2016-06-05 16:31:29 +02:00
771295db6d draft next segment of the test 2016-06-05 16:14:18 +02:00
1ae3c1991d second round of this test implemented
...which mostly just is either ignoring the
operations or indicating failure on attempt to
'reorder' attributes (which don't have any notion of 'ordering')
2016-06-04 15:08:10 +02:00
e5bbcb27d8 identify attributes through an EntryID (including type hash)
this also supersedes and removes the initial implementation
draft for attribute binding with the 'setAttribute' API
The elementary part of diff application incl. setting
new attribute values works by now.
2016-05-28 03:41:03 +02:00
5dbe877318 Library: add option to bypass the sanitising in EntryID
While in general it is fine to clean-up any entity IDs
to be US-ASCII alphanumerics (plus some allowed interpunction),
the GenNodes and also keys in object-bindings for diff are
considerd internal interfaces, assuming that any passed
ID symbol is already sanitised and checked. So the
sanitise operation can be skipped. This changeset
adds the same option directly to lib::EntryID,
allowing to create an EntryID that matches
a similar GenNode's (hash) ID.
2016-05-28 03:21:04 +02:00
201b6542f2 API change to allow to detect missing attribute binding
The way we build this attribute binding, there is no single
entity to handle all attribute bindings. Thus the only way
to detect a missing binding is when none of the binding layers
was able to handle a given INS verb
2016-05-28 01:17:45 +02:00
6382cac830 fix test
obvious mistake, we need a match on the GenNode ID,
so the key of the attribute binding must use the same symbol

...now the test fails at when hitting unimplemented stuff,
i.e. here the missing failure check
2016-05-27 03:39:22 +02:00
b4c91fd968 start next tree mutator test case: settle outline of the implementation
the idea is again to perform the same sequence of primitives,
this time with a binding to some local variables within the test function
here to enact the role of "object fields"

together with drafting the first segment of the test code,
I've settled down onto an implementation approach
2016-05-26 04:05:37 +02:00
06102b74ad rename test (no change) 2016-05-26 02:16:34 +02:00
dcad50ef1b test diff: codify and document the diff sequence
the plan is to use this specific diff sequence
both in the individual binding tests, and in a
more high level integration test. Hopefully this
helps to make these quite technical tests more readable
2016-05-26 01:56:13 +02:00
4571d3fb0f introduce new mutation primitive as pointed out by preceding analysis
to summarise, it turned out that it is impossible to
provide an airtight 'emptySrc' implementation when binding
to object fields -- so we distinguish into positive and
negative tests, allowing to loosen the sanity check
only for the latter ones when binding to object fields.
2016-05-24 23:43:55 +02:00
b47b4c3f94 flip logic of emptySrc -> hasSrc
..as concluded from the preceding analysis.
NOTE this entails a semantical change, since this
predicate is now only meant to be indicative, not conclusive

remarks: the actual implementation of the diff application process
as bound via the TreeMutator remains yet to be written...
2016-05-24 21:34:08 +02:00
d3869d2280 Design/Analysis: Attribute TreeMutator binding
how can ordinary object fields be treated as "Attributes"
and thus tied into the Diff framework defined thus far.
This turns out to be really tricky, even questionable
2016-04-30 00:26:19 +02:00
7467e6da2a extend test to cover nested mutation of another disjoint sub-scope
which also verifies the object ownership and lifecycle handling
of the opaque buffer used to place the nested mutator.
2016-04-18 01:41:41 +02:00
7bbfb4bc68 implement nested mutation of sub structures
...basically this worked right away and was easy to put together.
However, when considering how many components, indirections and
nested lambdas are working together here, I feel a bit dizzy...

:-/
2016-04-17 04:51:19 +02:00
8167fbff77 implement fast-forward and assignment to value
...all of this implementation boils down to slightly adjusting
the code written for the test-mutation-target. Insofar it pays off now
having implemented this diagnostic and demonstration first.

Moreover I'm implementing this basic scheme of "diff application"
roughly the fourth time, thus things kindof fall into place now.
What's really hard is all those layers of abstraction in between.

Lesson learned (after being off for three weeks, due to LAC and
other obligations): I really need to document the meaning of the
closures, and I need to document the "abstract operational semantics"
of diff application, otherwise no one will be able to provide
the correct closures.
2016-04-17 01:07:07 +02:00
7f42b9b7e7 draft third round of mutation operations to be implemented
...now about opening a sub mutator within a nested scope
2016-04-16 02:20:23 +02:00
54fb335a9c allow to "peek" into an embedded Record's type field
while I still keep my stance not to allow reflection and
switch-on-type, access to the internal / semantic type of
an embedded record seems a valid compromise to allow
to deal with collections of object-like children
of mixed kind.

Indirectly (and quite intentional) this also opens a loophole
to detect if a given GenNode might constitute a nested scope,
but with the for the actual nested element indeed to cary
a type symbol. Effectively this limits the use of this shortcut
to situations where the handling context does have some pre-established
knowledge about what types *might* be expected. This is precisely
the kind of constraint I intend to uphold: I do not want the
false notion of "total flexibility", as is conveyed by introspection.
2016-04-16 00:48:15 +02:00
f9f2a225c3 implement content reordering mutation primitives
and cover result in test.
This also demonstrates that it is possible to install
a specific lambda on each usage
2016-03-26 01:22:40 +01:00
c49dd04b44 address an insidious dangling reference
I still feel somewhat queasy with this whole situation!
We need to return the product of the DSL/Builder by value,
but we also want to swap away the current contents before
starting the mutation, and we do not want a stateful lifecycle
for the mutator implementation. Which means, we need to swap
right at construction, and then we copy -- TADAAA!

Thus I'm going for the solution to disallow copying of the
mutator, yet to allow moving, and to change the builder
to move its product into place. Probably should even push
this policy up into the base class (TreeMutator) to set
everyone straight.

Looks like this didn't show up with the test dummy implementation
just because in this case the src buffer also lived within th
TestMutationTarget, which is assumed to sit where it is, so
effectively we moved around only pointers.
2016-03-26 00:48:38 +01:00
adf01b0fbf WIP: define what will be the next steps to implement
basically we're duplicating the existing test case literally
2016-03-25 23:45:32 +01:00
d98fde5b0e better verification in test
...actually iterate the populated collection
and verify each element in order. Also verify
and document the mutator's storage requirements
2016-03-25 23:12:54 +01:00
e84844142f implement inserting of new elements 2016-03-25 22:43:11 +01:00
91bf75d54a spelling in comments 2016-03-25 21:40:30 +01:00
77bbe98275 draft first round of operation in test to be implemented.... 2016-03-25 03:12:02 +01:00
e698a3800b verify signatures of binding lambdas
the collection binding can be configured with various
lambdas to supply the basic building blocks of the generated binding.

Since we allow picking up basically anything (functors,
function pointers, function objects, lamdas), and since
we speculate on inlining optimisation of lambdas, we can not
enforce a specific signature in the builder functions.

But at least we can static_assert on the effective signature
at the point where we're generating the actual binding configuration
2016-03-25 02:51:56 +01:00
cb2a95627d WIP: specify first example binding...
...but does not compile, since all of the fallback functions
will be instantiated, even while in fact we're overriding them
right away with something that *can* be compiled.

this prompts me to reconsider and question the basic approach
with closures for binding, while in fact what I am doing here
is to implement an ABC.
2016-03-24 17:32:30 +01:00
df8ca071a8 first outline of test and aggregate initialisation problem
- the test will use some really private data types,
  valid only within the scope of the test function.

- invoking the builder for real got me into problems
  with the aggregate initialisation I'd used.
  Maybe it's the function pointers? Anyway, working
  around that by definint a telescope ctor
2016-03-19 16:47:40 +01:00
a106a0e090 spelling fixes 2016-03-19 01:42:27 +01:00
9ef32e0d62 complete dummy/proof-of-concept implementation of TreeMutator primitives
the first part of the unit test (now passing)
is able to demonstrate the full set of diff operations
just by binding to a TestMutationTarget.

Now, after verifying the design of those primmitive operations,
we can now proceed with bindings to "real" data structures
2016-03-11 21:30:25 +01:00
b0c6ba0777 switch implementation of TestMutationTarget to storing full GenNodes
when implementing the assignment and mutation primitives
it became clear that the original approach of just storing
a log or string rendered elements does not work: for
assignment, we need to locate an element by ID
2016-03-11 17:39:25 +01:00
75a6b4c05d specify and stub the test thus far to complete API design
now the full API for the "mutation primitives" is shaped.
Of course the actual implementation is missing, but that
should be low hanging fuit by now.

What still requires some thinking though is how to implement
the selector, so we'll actually get a onion shaped decorator
2016-03-06 03:55:31 +01:00
7b73aa6950 add some further checks and coverage to the test
...basically we've now the list mutation primitives working,
albeit in a test/dummy implementation only. Next steps will
be to integrate the assignment and sub scope primitives,
and then to re-do the same implementation respectively
for the case of mutating a standard collection of arbitrary type
2016-03-04 23:56:53 +01:00
75de98fe4d get the unit test to pass again
what's problematic is that we leave back waste in the
internal buffer holding the source. Thus it doesn't make
sense to check if this buffer is empty. Rather the
Mutator must offer an predicate emptySrc().

This will be relevant for other implementations as well
2016-03-04 23:18:25 +01:00
6cf97f2478 forward operations to test/dummy onion layer
...first round of implementation happens here
2016-03-04 21:26:25 +01:00
b0ee330737 stub and decide about further part of the API 2016-03-04 21:13:49 +01:00
7d63167276 WIP: define usage of the reordering part of the mutation primitives
...this kind of settles the problem with the "opaque" position
2016-03-04 20:55:52 +01:00
9875c93ca7 add iteration and some diagnostics to the test 2016-03-04 19:23:21 +01:00
af50e84737 first partial implementation unit test PASS
that is, the dummy/diagnostic-implementation
of the first "mutation primitive", namely injectNew(elm)
2016-03-04 00:25:36 +01:00
d8fe9bce94 baseline of test-dummy implementation or a mutation target binding
- we're using the source / target buffer paradigm to implement the mutation
 - we're using Record<string> to account for "the current content"
2016-03-03 23:11:36 +01:00
3f8946c157 better naming of Record::Mutator content moving operation
while the original name, 'replace', conveys the intention,
this more standard name 'swap' reveals what is done
and thus opens a wider array of possible usage
2016-03-03 22:58:33 +01:00
48f519e785 align naming of mutation primitives
...convinced myself to retain an uniform naming scheme,
even while the implementation spans several onion-like layers
2016-03-03 22:02:01 +01:00
8bcd37df0a stub first round of mutation primitives to pass compiler again
now this feels like making progress again,
even when just writing stubs ;-)

Moreover, it became clear that the "typing" of typed child collections
will always be ad hoc, and thus needs to be ensured on a case by case
base. As a consequence, all mutation primitives must carry the
necessary information for the internal selector to decide if this
primitive is applicable to a given decorator layer. Because
otherwise it is not possible to uphold the concept of a single,
abstracted "source position", where in fact each typed sub-collection
of children (and thus each "onion layer" in the decorator chain)
maintains its own private position
2016-02-27 01:47:33 +01:00
5d230aa7ac WIP: start defining the inner API systematically
...trying to get ahead step by step
2016-02-27 00:18:06 +01:00
bdf48e1b7b WIP: desperate attempt to get out of the design deadlock
Arrrrgh.
I go round in circles since hours now.
Whatever I attempt, it again relies on
yet further unsecured suppositions
2016-02-26 22:57:49 +01:00
dd1afef970 WIP: consider what kind of changes to support and how
especially the nagging question is:
- do we need to support children of mixed type
- and how can we support those, wihtout massively indirected calls
2016-02-20 00:19:01 +01:00
afbba968b5 WIP: decide how to target the task of mutating "unspecific" data structures 2016-02-19 20:25:30 +01:00
d22cc18c13 introduce a value assignment verb into the tree-diff-language
after sleeping one night over the problem, this seems to be
the most natural solution, since the possibility of assignment
naturally arises from the fact that, for tree diff, we have
to distinguish between the *identity* of an element node and
its payload (which could be recursive). Thus, IFF the payoad
is an assignable value, why not allow to assign it. Doing so
elegnatly solves the problem with assignment of attributes

Signed-off-by: Ichthyostega <prg@ichthyostega.de>
2016-02-19 17:22:41 +01:00
d7d90bf491 Element protocol: broadcast of state reset messages unit test PASS
This basically finishes definition of the fundamental
UI-Element and Bus protocol -- with one notable exception:
how to mutate elements by diff.

This will be the next topic to address
2016-02-14 05:03:08 +01:00
5bbf08adcb implement deleting of individual property state data 2016-02-14 04:29:40 +01:00
18b6a388a0 implement state reset handlers / mock handlers 2016-02-14 03:42:10 +01:00
afeedfc288 draft state reset behaviour (test)
indeed building on the new broadcast functionality now.
Probably this implies we'll get some broadcast-with-filter eventually
2016-02-14 02:42:14 +01:00
44bb044eee message broadcast implementation unit test PASS
...was indeed dead easy to implement
2016-02-14 02:20:51 +01:00
b5b62f101f WIP: draft a message broadcasting function
not really sure about its usefullness, but it seems
low hanging fruit for me right now (while I am still
aware of all details how the UI-Bus works).

This might possibly be helpful to broadcast "reset" messages....
2016-02-14 01:47:21 +01:00
1b9e4a7310 test to cover call sequence of message dispatch in UI-Bus 2016-02-14 01:34:58 +01:00
cbd69ea4fb cover additional message/error diagnostics in MockElm
NOTE: we don't have any "real" UI-Element implementation yet.
Such would have to define its own, private error and message handling.
It is likely that we'll end up with some kind of base implementation
within model::Element and model::Controller.

Anyhow, this is future work
2016-02-14 00:23:24 +01:00
1059458e11 MockElm: add the ability to store/query received errors and messages
this is just a draft and in expectation of what we'll likely
add to the real model::Element and model::Controller entities
2016-02-14 00:16:10 +01:00
0be12aaa79 PresentationStateManager unit test PASS
basic state capturing, storage and replay now works as intended
More elaborate state management will be implemented later,
when we know more about perspectives and work sites!
2016-02-13 23:53:09 +01:00
4da75dd4d3 bus protocol change: special handling for reset state marks
- suppres sending redundant stat mark messages from MockElm
- emit a "reset" state mark when an actual reset happens
- let the PresentationStateManager discard recorded special state
  when receiving a "reset" mark for a given element
2016-02-13 23:48:34 +01:00
d57af50ad6 state manager storage implemented and covered by unit test
sigh.
If you want to feel slick and cool,
never dare to write any unit test....
2016-02-13 22:55:59 +01:00
f80982b52b gen-node: fix insidious data conssitency problem
I assumed that, since GenNode is composed of copyable and
assignable types, the standard implementation will do.
But I overlooked the run time type check on the opaque
payload type within lib::Variant. When a type mismatch
is detected, the default implementation has already
assigned and thus altered the IDs.

So we need to roll our own implementation, and to add
insult to injury, we can't use the copy-and-swap idiom either.
2016-02-13 22:55:59 +01:00
121cd41408 ouch: GCC-4.9 doesn't yet support the C++14 transparent comparators
This is actually a STL library feature, and was added precisely
for the reason encountered here: if we want logarithmic search,
we'll have to construct a new GenNode object, just to have something
for the set to invoke the comparison operator.

C++14 introduced the convention that the Comparator of the set
may define a marker type `is_transparent` alongside with a generic
comparison operator. But, as is obvious from the source code of
our GNU Standard library implementation, our std::set has no such
overload to make use of that feature

http://en.cppreference.com/w/cpp/container/set/find
http://stackoverflow.com/questions/20317413/what-are-transparent-comparators

The only good thing is that, just 10 minutes ago, I felt like
a complete moron because I'm writing a unit test for such a simple
storage class. ;-)
2016-02-13 22:55:59 +01:00
94576af4df finialise simple state manager implementation
...and rearrange storage interface to suit
2016-02-13 22:55:59 +01:00
071f49027f change presentation state manager API
...based on elementIDs rather, to avoid any
tangling and trickery with reconstructing IDs
2016-02-13 22:55:58 +01:00
c54dfd6a94 factor out generic map based state manager implementation 2016-02-13 22:55:58 +01:00
15c1343fae class name rochade
it occured to me that my "mock implementation" actually
is entirely generic, so it could as well be "the" implementation
2016-02-13 22:55:58 +01:00
49a42b4d50 add outline of corresponding storage implementation 2016-02-13 22:55:58 +01:00