Commit graph

1659 commits

Author SHA1 Message Date
8cb67fd9fa Library: inline the thread operation when possible
The Lumiera thread-wrapper accepts the operation to be performed
within the new thread as a function object, function reference or lambda.
Some of these types can be directly instantiated in the threadMain
function, and thus possibly inlined altogether. This is especially
relevant for Lambdas. OTOH, we can not instantiate function references
or bound member functions; in those cases we fall back to using a
std::function object, possibly incurring heap allocations.
2018-03-24 02:19:49 +01:00
31539f00c8 Library: a function for performing multithreaded microbenchmarks 2018-03-24 01:58:34 +01:00
364dcd5291 DI: verify and improve static sanity checks
esp. for subclass instance creation from within a lambda
2018-03-22 21:43:19 +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
e74576f6b0 DI: pass-through arbitrary arguments for initialisation of a ServiceInstance
...this part is a no-brainer.
However, it is not clear yet if we can (and want to) do something similar for deferred (lazy) instance creation
2018-03-22 04:19:33 +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
83476b3ef1 DI: Reworked dependency-factory implementation draft complete -- move into library headers
This is a complete makeover of our lib::Depend and lib::DependencyFactory templates.
While retaining the basic idea, the configuration has been completely rewritten
to favour configuration at the point where a service is provided rather,
than at the point where a dependency is used.

Note: we use differently named headers, so the entire Lumiera
code base still uses the old implementation. Next step will be
to switch the tests (which should be drop-in)
2018-03-19 03:46:49 +01:00
533ed45d8b DI: expand the concept of our dependency factory to handle service instances (#1086)
Most dependencies within Lumiera are singletons and this approach remains adequate.
Singletons are not "EVIL" per se. But in some cases, there is an explicit
lifecycle, managed by some subsystem. E.g. some GUI services are only available
while the GTK event loop is running.

This special case can be integrated transparently into our lib::Depend<TY> front-end,
which defaults to creating a singleton otherwise.
2018-03-11 03:20:21 +01:00
e1dd88970c Library: enable the STL algorithms to work with "Lumiera Forward Iterators"
especially std::find is relevant here.
I consider this only a preliminary solution and need to think it over
more in detail. But, judging from the description given in

http://en.cppreference.com/w/cpp/iterator

and

http://en.cppreference.com/w/cpp/concept/InputIterator

...the standard concept of "input iterator" seems to be closest to our
own concept, albeit it requires things like post increment, and a
reference_type convertible to value_type -- requirements we do not
necessarily support with our more limited "Lumiera Forward Iterator"
2018-02-16 06:48:52 +01:00
136e78d023 DockAccess: decide on next steps towards integration (#1126) 2018-02-01 23:08:43 +01:00
b6961e8f03 DockAccess: better pass functor as const& into partial application
seems to be the most orthogonal way to strip adornments from the SIG type
Moreover, we want to move the functor into the closure, where it will be stored anyay.
From there on, we can pass as const& into the binder (for creating the partially closed functor)
2018-01-13 00:58:08 +01:00
5dea8eea1f DockAccess: draft how the partial application-builder for the DSL might work
...but not yet able to get it to compile.
Problem seems to be the generic lambda, which is itself a template.
Thus we need a way to instantiate that template with the correct arguments
prior to binding it into a std::function

been there, seen that recently (-> TreeExplorer, the Expander had a similar problem)
2018-01-12 05:50:01 +01:00
ef74527f6b DOC: eliminate spurious mentions of tr1:: 2018-01-12 03:03:25 +01:00
7434212ecf UI-Coordinates: allow for noexcept move construction 2018-01-06 03:38:52 +01:00
9d0186a8d6 Navigator: implement core of the matching algo 2018-01-02 14:03:04 +01:00
3598e07c59 Navigator: draft skeletton of the patch matching algo 2018-01-02 00:57:41 +01:00
416d6c7b01 TreeExplorer: delayed expansion implemented and unit test PASS 2018-01-01 18:23:04 +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
1a6cac9d66 UI-Coordinates: fix potential segfault
...when truncating to a position within the inline part, yet behind the actual end
2017-12-27 01:57:15 +01:00
33ea1ebb79 Navigator: work around the clumsy design of IterExplorer (#1125)
yet some more trickery to get around this design problem.
I just do not want to rework IterSource right now, since this will be
a major change and require more careful consideration.

Thus introduce a workaround and mark it as future work

Using this implementation, "child expansion" should now be possible.
But we do not cover this directly in Unit test yet
2017-12-26 04:49:59 +01:00
30a90166fb X-mas: switch demo-Child-Iterator to the new framework
...passes all the existing unit tests!
2017-12-24 23:30:22 +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
9f171682ce Navigator: resolve problem with including anonymous namespace
...yet I do not want to move all of the traits over into the
publicly visible lib::iter_explorer namespace -- I'm quite happy
with these traits being clearly marked as local internal details
2017-12-23 00:42:18 +01:00
08489b5900 Library: avoid spurious copy in string-join
surprise: the standard for-Loop causes a copy of the iterator.
From a logical POV this is correct, since the iterator is named,
it can not just be moved into the loop construct and be consumed.

Thus: write a plain old-fashioned for loop and consume the damn thing.
So the top-level call into util::join(&&) decides, if we copy or consume
2017-12-17 03:15:18 +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
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
d56c2295ae TreeExplorer: fix remaining problem and get the test to pass
...but for now the price is that we need to punch a hole into IterAdapter.
And obviously, this is all way to tangled and complex on implementation level.
2017-12-09 04:30:17 +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
160a5e5465 TreeExplorer: cover further flavours of predicate definition 2017-12-07 02:19:19 +01:00
e9e7004a2e TreeExplorer: simple implementation based on eager pulling and an Invariant
lazy pulling would require us to store an additional bool
(the way the FilterIterator from itertools does)
2017-12-07 02:19:14 +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
9e9c6c3ec6 TreeExplorer: solve refresh-problem when expanding children
We need a way for higher layers to discard their caching and re-evaluate,
once some expansion layer was invoked to replace the current element with
its (functionally defined) "children" -- otherwise the first child will
remain obscured by what was there beforehand.

Solution is to pass such manipulation calls through the full chain of
decorators, allowing them to refresh themselves when necessary. To achieve
that technially, we add a base layer to absorb any such call passed down
through the whole decorator chain -- since we can not assume that the
parent, the original source core implements those manipualation calls
like expandChildren()
2017-12-06 00:43:43 +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
ca270028a9 TreeExplorer: transform-operation implemented and covered in test 2017-12-04 04:34:27 +01:00