Commit graph

997 commits

Author SHA1 Message Date
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
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
c65c5f812b Library: put the new type rebinding trait into general use
Obsoletes and replaces the ad-hoc written type rebindings from
iter-adapter and friends. The new scheme is more consistent and does
less magic, which necessitates an additional remove_pointer<IT> within
the iterator adaptors. Rationale is, "pointer" is treated now just as
a primitive type without additional magic or unwrapping, since it is
impossible to tell generically if the pointer or the pointee was
meant to be the "value"
2017-12-02 02:51:51 +01:00
847593f18b Investigation: resolve the mystery and fix the problem
Oh well.
This kept me busy a whole day long -- and someone less stubborn like myself
would probably supect a "compiler bug" or put the blame on the language C++

So to stress this point: the compiler behaved CORRECT

Just SFINAE is dangerous stuff: the metafunction I concieved yesterday requires
a complete type, yet, under rather specific circumstances, when instantiating
mutually dependent templates (in our case lib::diff::Record<GenNode> is a
recursive type), the distinction between "complete" and "incomplete"
becomes blurry, and depends on the processing order. Which gave the
misleading impression as if there was a side-effect where the presence
of one definition changes the meaning of another one used in the same
program. What happened in fact was just that the evaluation order was
changed, causing the metafunction to fail silently, thus picking
another specialisation.
2017-12-02 02:51:51 +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
9e96ea8323 TreeExplorer: documentation of technicalities 2017-11-25 03:56:44 +01:00
76a11b3730 TreeExplorer: rename and refactor for readability
...while this implementation works now, it is still very complex and intricate.
I am still doubtful this is a good approach, but well, we need to try that route....
2017-11-25 03:54:41 +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
8bdd9e7d66 Research: build "anything function-like" trait
...with the sole exception that such a trait can not detect
a templated or overloaded function call operator
2017-11-24 23:48:56 +01:00
2533565f83 Research: probing a generic lambda is not possible
...since all those metaprogramming techniques rely on SFINAE,
but *instantiating* a template means to compile it, which is more
than just substituate a type into the signature

If forming the signature fails -> SFINAE, try next one
If instantiating a template fails -> compile error, abort
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
c5311a116a TreeExplorer: concept how to generalise the expansion functor
Basically we want to support two distinct cases, just by slightly adapting
the invocation of the expansion functor:

Case-1: classical monadic flatMap:
        the Functor accepts a value yielded by the source iterator
        and builds a new "expaneded" iterator

Case-2: manipulation of opaque implementation state
        the Functor knows internal details of the source iterator
        and thus takes the source iterator as such as argument,
        performs some manipulation and then builds a new sub-iterator

A soulution to reconcile those two distinct cases can be built
with the help of a generic lambda
2017-11-23 03:06:02 +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
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
ca35891c41 Navigator: implement the mutation operations defined thus far
...so the only thing not yet implemented is the actual path resolution algorithm
2017-10-30 03:10:51 +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
4b6b4ad708 LocationQuery: now able to handle perspective info properly
...which was deliberately represented in an asymmetric way, to verify the
design's ability to cope with such implementation intricacies. So basically
we have to kick in at LEVEL == 1 and access the implementation differently.

This exercise just shows again, that treating tree structures recursively
is the way to go, and we should do similar when coding up the query-API
for the real GTK toolkit based window elements...
2017-10-29 16:00:08 +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
800407637a LocationQuery: compensate for the special representation of perspective info
this assymetry in representation was introduced deliberately,
to test the design's ability to cope with such complications
2017-10-28 01:12:06 +02: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
16abe82cde LocationQuery: fix a segfault due to ill guided conversion path 2017-10-27 05:12:28 +02:00
240459c550 LocationQuery: implement simple resolution of explicit anchoring by window-ID 2017-10-23 02:16:57 +02:00
2c96fcd164 LocationQuery: draft unit test to cover the query API 2017-10-22 00:44:30 +02:00
fd3777de54 Navigator: draft the trivial resolution case
...based on the abstract LocationQuery interface
2017-10-21 23:47:27 +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
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
2b1c9370b8 Navigator: analysis continued.... 2017-10-15 00:55:06 +02:00
cbd58662ba Navigator: start investigation of requirements (#1107, #1108, #1109) 2017-10-14 02:15:39 +02:00
322467159f DOC: Considerations and Definitions regarding »Interaction Control«
..this collection of ideas, terms and conclusions has been shaped
since some time within the TiddlyWiki. Since I've now started even
some supporting implementation regarding these concepts, its time
to publish them in the design documentation section of the Website
2017-10-09 04:00:07 +02:00
ed76151d14 UI-Coordinates: value representation finished and unit test PASS (#1106) 2017-10-03 00:57:23 +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
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
5097637f0d UI-Coordinates: basic unit test PASS 2017-10-01 21:54:35 +02:00
ac38f0f963 UI-Coordinates: implement string representation 2017-10-01 21:10:18 +02:00
6322f1bc3c UI-Coordinates: define next steps to cover 2017-10-01 20:04:12 +02:00
9378badf6b UI-Coordinates: integrate the initialisation split
...as developed in during the metaprogramming investigation
2017-09-30 00:46:52 +02:00
e5dc7ba2bc Investigation: dissect argument packs
start investigation on generic techniques to dissect an variadic argument pack
2017-09-26 19:23:03 +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
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
8a36327604 DockAccess: elaborate design of the DSL 2017-09-09 15:21:40 +02:00
b27681ec4f DockAccess: design a configuration DSL 2017-09-08 18:50:39 +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
eb04552c88 DockAccess: some analysis regarding Configuration/Strategy for access to views
...we have to face the problem that we need some generic strategy
for access to component views, which possibly will become customisable.
And the allowed patterns of access are quite different for the various
kind of view we know....
2017-09-04 01:21:53 +02:00
753c895035 DockAccess: consider a generic ID addessing scheme for the UI (#1005)
...based on a selection of Model types and an access strategy
2017-09-03 01:04:00 +02:00
0ad387f5c9 DockAccess: create a ViewLocator service
responsible for access and allocation of component views.
Internally wired to the PanelLocator within the global WindowLocator

This setup settles those nasty qeustions of crosswise top-level access
2017-09-02 19:28:57 +02:00
4f77075d9c DockAccess: integrate a PanelLocator intermediary
...into the WindowLocator
This is to become a low-level query and acess front-end
and will be implemented just by traversing the windowList_
2017-09-02 19:03:00 +02:00
0614ca36ca DockAccess: consider how to access view components. Rename WindowList (#1104)
this starts work on a new UI global topic (#1004)

- coin a new term: "view component"
- distinction between veiw component and Panel
- consider how to locate view components
- WindowList becomes WindowLocator
2017-09-02 18:36:58 +02:00
5b445a2361 InfoBox: extract into dedicated widget 2017-09-02 00:51:06 +02:00
ee67e4914c InfoBox: scroll to the last inserted line reliably
need to use a text mark; we can simplify this task somewhat
by exploiting the fact that the text cursor is a default defined text mark
2017-09-01 01:02:48 +02:00
2d2a549341 InfoBox: add a simple text display widget 2017-09-01 00:28:43 +02:00
a91b444ade InfoBox: draft the next preliminary implementation steps (#1002)
...I need a quick-n-dirty temporary solution,
just to have a place to display some messages in the UI asynchronously
2017-08-31 20:32:49 +02:00
45b3a990f2 DemoGuiRoundtrip: add new dock for UI experiments (#1099)
...after investigating problems related to the management of docking pane contents
2017-08-31 20:15:52 +02:00
526fd3ca16 UI-Dispatch: add generic catch-all error handler
...to ensure no exception can escape at top level of the actions
dispatched asynchronously into the UI event thread
2017-08-25 17:38:51 +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
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
4a2384e242 DiffMessage: add further convenience ctor for varargs
hey... all my dream constructors became true
2017-08-12 03:00:38 +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
f498f3be1b mark next steps to address
- error handling
 - settle MutationMessage
2017-08-11 02:37:29 +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
2344d5b03f UI-top-level: implement external UI-Shutdown-Trigger 2017-08-10 20:58:00 +02:00
805e6047ba UI-Dispatch: document some implementation intricacies 2017-08-10 20:57:59 +02:00
768a07f181 UI-Dispatch: draft the dispatcher invocation 2017-08-10 17:14:44 +02:00
07c9ed15e8 UI-Dispatch: how to integrate into the NotificationService
WIP setup of an empty framework
2017-08-10 16:24:36 +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
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
1e81b8d61a Settle proper activation of the external UI interfaces (#1098)
This change was caused by investigation of UI event loop dispatch;
since the GTK UI is designed to run single threaded, any invocation
from other threads need to be diepatched explicitly.

A possible way to achieve this is to use Glib::Dispatcher, which
in turn requires that the current thread (which is in this case the UI thread)
already holds a Glib::MainContext

This prompted me to create a tight link between the external facade interfaces
of the UI and the event loop itself. What remains to be settled is how
to hand over arguments to the action in the main loop
2017-08-05 17:36:32 +02:00
9cf868c9cd after a long break: find my way back into what has to be done.... 2017-08-03 20:34:42 +02:00
c96845ab65 GTK evolution: abandon Gtk::Main and start event loop directly (closes #1032)
After investigation of current GTK and GIO code, I came to the conclusion
that we do *not* want to rely on the shiny new Gtk::Application, which
provides a lot of additional "convenience" functionality we do neither
need nor want. Most notably, we do not want extended desktop integration
like automatically connecting to D-Bus or exposing application actions
as desktop events.

After stripping away all those optional functions and extensions, it turns
out the basic code to operate the GTK main event loop is quite simple.
This changeset extracts this code from the (deprecated) Gtk::Main and
integrates it directly in Lumiera's UI framework object (UiManager).
2017-05-19 23:42:55 +02:00
f089a34934 UI-Lifecycle: tie UI-Bus and UI-Manager directly to GtkLumiera
this is just a tiny change to make things more othogonal.
Now the unwinding and calls to any GTK / Widget dtors happen *after*
emitting the term signal from UI shutdown. Which means, the other subsystems
are shutting down (in their dedicated threads) as well, thus lowering
the probability of some action still using the UI and triggering an exception
2017-05-19 18:12:58 +02:00
5e172ff6a0 UI-top-level: reactivate the updateActionState function as NOP
as it turned out, the former functionality was deactivated in 2009
with changeset 6151415

The whole concept seems to be unfinished, and needs to be reworked
and integrated with "Views and Perspectives" (whatever that is...)

See also #1097
2017-05-19 17:00:41 +02:00
e59e8d0ab5 UI-top-level: consider how to rework the UI main object (#1067)
Gtk::Main is deprecated, but the new solution, instantiating a
Gtk::Application object does not match our use case, since we handle
all application concerns already and just need a Gtk main loop to run.

Anyway, it became clear that the "main object" will be the new UiManager.
As a first step, I've now moved the (deprecated) Gtk::Main object
down there. Next step (planned) will be to inherit from Gio::Application
and clone some functionality from Gtk::Application
2017-05-03 02:37:48 +02:00
5cb5ad3507 Menu-Actions: just log unimplemented actions for now (closes #1085)
this topic is basically settled by now.
Mostly by delegating to other entites not-yet-implemented :-D
2017-04-23 18:46:58 +02:00
1ccf54fa41 CmdAccess: draft some further command invocations
...which opens more questions than it solves at the moment.
Especially note #1096, the question how to refer to object-IDs
Maybe we need to enable sending EntryIDs via GenNode?

Anyway, the magic spell is broken now: we have a way how to
establish commands and how to issue them from the UI, with full integration
of UI-Bus, layer separation facade, instance management and ProcDispatcher

Looks like a stepping stone
2017-04-17 23:16:57 +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