Commit graph

3602 commits

Author SHA1 Message Date
de7e47fa21 UI-top-level: solve several of the previously tricky wiring problems
...this solution feels good thus far
2017-02-14 03:43:41 +01:00
e94b294121 UI-top-level: wiring in accordance to the new global context
this pretty much resolves most of the uncertainities:
we now get a set of mutually dependent services, each of which
is aware of each other member's capabilities, but accesses those
only through this partner's API
2017-02-14 03:42:03 +01:00
f8eb640dd7 UI-top-level: decision to form a cohesive top-level context (#1067) 2017-02-14 03:01:19 +01:00
4f302eb81b pondering over the top-level UI structure.... 2017-02-13 01:19:33 +01:00
dcd19ed2bd fix definition of raw string
the parens need to be innermost
2017-02-12 00:39:22 +01:00
c84f5e00e6 add a similar function to find the window with keyboard focus
...added for sake of completeness, since it is low hanging fruit
2017-02-11 23:51:47 +01:00
ca49a949c0 supply a function to find the currently active workspace window
Idea is to use the window list, which should hold any workspace window
ever created, and pick the first one marked as 'active' by GTK
(whatever that means)
2017-02-11 23:45:50 +01:00
fa7fbb3554 remove top-level default include 2017-02-11 23:40:26 +01:00
8a912926ec UI-top-level: integrate and wire the new InteractionDirector 2017-02-11 00:09:20 +01:00
27c8e78cf5 UI-top-level: invent a new backbone entity to link between model and interaction state
After quite some pondering, it occured to me that we both
- need some top-level model::Tangible to correspond to the RootMO in the session
- need some Controller to handle globally relevant actions
- need a way to link action invocation to transient interaction state (like focus)

This leads to the introduction of a new top-level controller, which is better
suited to fill that role than the depreacted model-controller or the demoted window-manager


looks like we're in management business here  ;-)
we chop off heads, slaughter the holy cows and then install -- a new manager
2017-02-10 23:10:17 +01:00
eb42db537f implement opening the initial top level window 2017-02-08 04:08:55 +01:00
8a10862372 write the global menu definition as C++11 raw string 2017-02-08 04:08:15 +01:00
02ba010d2c UI-top-level: define the menu bindings by lambda
...allows us to get rid of a lot of sigc boilerplate syntax.
The downside is that the resulting functors are not sigc::trackable.
This seems adequate here, since the whole top-level UI backbone is
maintained by GtkLumiera, and thus ensured to exist as long as the
main GTK event loop is running.

WARNING: beware of creating "wild" background thrads in the UI, without
proper scheduling of any communication via the event loop!
2017-02-02 21:52:22 +01:00
0f2fa24a01 UI-top-level: turn Actions helper into header-only definition
no need for a further translation unit,
rather, definition of global menu now becomes part of the
ui-manager.cpp translation unit, which allows for some additional
inlining and simplifications by the compiler
2017-02-02 21:28:11 +01:00
52d2bad6db UI-top-level: turn Actions into a PImpl
it turns out to be essentially an implementation detail,
it is a builder class and it acts as closure for the bound
menu actions, but it is not accessed after initialisation.

This allows to reduce the header inclusion load significantly
2017-02-02 20:59:54 +01:00
f913f30499 UI-top-level: reshape Actions
start with drilling down unnecessary includes
2017-02-02 20:51:03 +01:00
fb8923036d reduce unnecessary header includes 2017-02-02 19:57:01 +01:00
04cb0790e8 fix missing initialisation 2017-02-02 19:41:58 +01:00
0f5280a4f0 UI-top-level: draft a concept how to attach actions to the current window (#1069)
This is a very pervasive change and basically turns the whole top-level
of the GTK-UI bottom-up. If this change turns out right, it would likely
solve #1048

WARNING: in parts not implemented, breaks UI
2017-02-01 03:55:20 +01:00
865ee11621 UI-top-level: push down Config access to actual usage site (#1067)
...allows us to get rid of the access key constants and the
accessor functions in GtkLumiera
2017-02-01 03:46:30 +01:00
4e1641f192 sketchy workaround for access to the PlayController (#1072)
...which itself is obsolete and needs to be redesigned from scratch.
For now we create a local instance of this obsolete PlaybackController
in each viewer panel and we use a static accessor function to just some
instance. Which would break if we start playback with multiple viewer
panels. But we can't anyway, since the Player itself is also a broken
leftover from an obsoleted design study from the early days.

so why care...
2017-01-28 01:11:04 +01:00
6aec1adb38 resolve ambiguity with std::ref vs boost::ref
unfortunately boost/program-options make the boost reference-wrapper visible
And it doesn't help to alias to std::ref at the definition site of the
problematic function (in TimeControl), because this itself is picked up
via ADL

So this is not really a solution, rather a workaround, in the hope
that boost will clean-up this ambiguity eventually
2017-01-28 01:09:16 +01:00
c09eb3e1ed remove the obsolete Project and Controler from ctor arguments
...this (finally) allows us to get rid of these elements within GtkLumiera.
Our Model will be represented in a quite different way (via UI-Bus).
2017-01-27 23:30:38 +01:00
0bdc4e1bb4 QA: mark all wildcard includes in the GUI code (#1071)
as a rule, one should not rely on "using namespace xyz",
since this makes organisation of minimal header includes near impossible.
You end up with mass includes in some "top level" headers, resulting
in painfully slow compilation turnaround times.

In exceptional cases, using namespace foo might be adequate though
2017-01-27 22:47:01 +01:00
d49983d4cb identify items which force GtkLumiera to be a singleton
- WindowList (ex WindowManager)
- Project & Controller

the latter ones are defunct and can be replicated down into each
of the old timeline pannel instances. They just serve the purpose
to keep this old code barely functional, so it can be used as reference
for building the new timeline
2017-01-27 22:17:58 +01:00
86d6e11505 demote the WindowManager to be a petty window list (#1964)
the only adequate thing you can do with managers is to demote them.
2017-01-27 20:48:01 +01:00
a6fb10b9e0 clean-up the WindowManager source (#1064)
in one of the preceding refactorings, I've extracted most of the
functionality from WindowManager, to make it more focussed
2017-01-27 20:22:52 +01:00
1cb2567557 Ui-top-level: use a sincle UiManager instance
instead of letting each window create its own "private interface"
2017-01-26 22:02:45 +01:00
43bd5c3f57 further decisions regarting the UI top-level 2017-01-26 20:51:43 +01:00
7a51a0bd18 split functionality according to concerns (#1067)
window handling -> WindowManager
styles, icons, themes  -> UiManager
2017-01-23 01:13:38 +01:00
735563ebc5 Rectify UI top-level -- introduce a global UiManager (#1067)
There seems to be a mismatch in the arrangement of the top-level entities
 * we support multiple windows, yet from reading the code, you'd ge the impression we aren't really aware we have multiple top-level windows
 * the `WindowManager` is the core UI manager, which feels like a mix-up in concerns
 * the `WorkspaceWindow::createUI()` does the global UI initialisation. Again, we have multiple workspace windows.
 * `GtkLumiera::main()` creates a `Model` and a `Controller` in local function scope, but stores the `WindowManager` in an object field.
 * it seems, for that very reason, `GtlLumiera` needed to be a singleton, to allow by-name access to "the" `WindowManager`
 * needless to say, this causes a host of problems when shutting down the UI.

The idea is to introduce a dedicated UiManager, to deal with the central
framework induced concerns solely, and to demote the WindowManager and the
WorkspaceWindows to care only for their local concerns
2017-01-23 00:40:17 +01:00
6baff38beb GuiNotification: actually pass the calls through the interface system 2017-01-20 04:23:00 +01:00
ffd2b079df GuiNotification: use placeholder for the yet unsolved diff passing problem
see Ticket #1066
2017-01-20 03:46:48 +01:00
0d5ca55019 GuiNotification: define outline of this service interface 2017-01-20 03:27:32 +01:00
8105be399e GuiNotification: demote this service to be just a BusTerm
in fact it just does not fulfil any of the behavioural properties
of a full-fledged UI-Element. All it needs is an uplink bus connection,
so let's just keep it as that

Sidenote: I've realised today that such a "free standing" BusTerm
without registration in Nexus is a good idea and acceptable solution.
2017-01-20 02:40:38 +01:00
8f2023dea3 Nexus/CoreService: verify shutdown cycle
yes, it's a cycle and indeed quite tricky.
Just verified it (again) with the debugger and saw all
dtor calls happening in the expected order. Also the number
of Nexus registration is sane
2017-01-20 02:23:24 +01:00
06a61773fa Nexus/CoreService: consider handling of bus connections.
Now I've realised that there are two degrees of connectedness.
It is very much possible to have a "free standing" BusTerm, which
only allows to send uplink messages. In fact, this is how CoreService
is implemented, and probably it should also the way how to connect
the GuiNotification service...
2017-01-20 01:54:49 +01:00
cb31b145c3 GuiStart: further streamlined the invocation code
due to investigating that Heisenbug, I understand the storage layout
more clearly. It occured to me that there is no reason to copy the
terminationHandler (functor) into an instance variable, since it is
easily possible to keep all of the invocation and error handling
confined within the scope of the run function, i.e. on stack.

So the effective memory layout does not change, but the legibility
of the code is improved, since we're able to remove the dtor and
simplyfy the ctor and avoid most of the member fields.
2017-01-19 23:52:30 +01:00
2354c53a50 GuiStart / Shutdown: nailed the Heisenbug
Reason was some insideous detail regarding Lambdas:
When a Lambda captures context, a *closure* is created.
And while the Lambda itself is generated code, pretty much
like an anonymous function, the closure depends on the context
that was captured. In our case here, the Lambda used to start
the thread was the problem: it captured the termCallback functor
from the argument of the enclosing function. In fact it did not
help or change anything if we successively package that lambda
into a function objet and store this by value, because the
lambda still refers to the transient function context present
on stack at the moment it was captured.

The solution is to revert back to a bind expression, since this
creates a dedicated storage for the bound function arguments
managed within the bind-functor. This makes us independent
from the call context
2017-01-19 23:41:32 +01:00
22be990631 GuiStart / shutdown: chasing a Heisenbug 2017-01-19 23:08:09 +01:00
4ba8032a60 Nexus/CoreService: fix sanity check on shutdown
...because some Bus connections stem from elements which are
member of CoreService, thus the'll still be connected when the
sanity check in the dtor runs

But even with this fix, we still get a SEGFAULT
2017-01-19 23:08:09 +01:00
aec700f1b1 GuiNotification: connect to UI-Bus by inheriting from Controller
TODO
 - is this actually a sensible idea, from a design viewpoint?
 - in which way to bind GuiNotification for receiving diff messages?
 - Problem with disconnnecting from Nexus on shutdown
2017-01-19 23:08:09 +01:00
1bd3eabe7d GUI-start: replace the chained termination functors with a lambda
This is the solution I found out when implementing the ProcDispatcher;
looks way more readable to me
2017-01-19 23:08:08 +01:00
df84de2e81 Library: remove the dispatchSequenced helper
...such can be done way more succinctly with Lambdas now
2017-01-19 23:08:08 +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
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
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
3cc3f69471 SessionCommand: draft the idea of a function(integration) test 2017-01-11 04:19:43 +01:00
104b71e8aa Timehandling: allow default initialisation for Offset values
From a purely logical viewpoint, it looked sensible to require an actual
value for an offset, especially since our time values are immutable.
But this has the unfortunate consequence that we'd be unable to use
an offset value as parameter for any command, since we store the arguments
as tuple and the tuple type has a default constructor. We might be able
to get around that problem, but such looks brittle to me; it is just
plain surprising for anyone not familiar with the internals of the
command system.

For that reason, I've now added a default ctor to the Offset type
2017-01-11 04:09:32 +01:00
2e9bd78791 consider to extend the command handling protocol on UI-Bus (#1058) 2017-01-09 03:24:17 +01:00
38b908d510 CoreService: simple (and obvious) implementation of command handling (#1046)
disregarding all doubts due to the massive indirection
and deferring the question where command-IDs are actually to be allocated....
2017-01-09 02:32:56 +01:00
cfbbb750f8 considerations regarding the integration of commmand invocations (#1046)
not quite sure how to get the design straight.
Also a bit concerned because we'll get this much indirections;
the approach to send invocations via the UI-Bus needs to prove its viability
2017-01-09 01:22:43 +01:00
c2c6262be6 mark where command handling needs to be integrated (#1046) 2017-01-07 03:18:39 +01:00
c0337abcaf Application: from now on start the »session subsystem« (closes #699) 2017-01-07 02:48:51 +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
458fda4058 DispatcherLoop implementation complete (closes #1049)
Did a full review of state and locking logic, seems airtight now.
- command processing itself is unimplemented, we log a TODO message for now
- likewise, builder is not implemented
- need to add the deadlock safeguard #1054
2017-01-05 23:36:42 +01:00
b0b662f200 DispatcherLoop: fix race on initialisation 2017-01-05 22:35:33 +01:00
3915e3230e DispatcherLoop: add wake-up notification on state change 2017-01-05 21:40:37 +01:00
f26ef5230c CommandQueue: finish integration into ProcDispatcher
...leaving out the *actual operations* of
- command dispatch
- builder run
2017-01-05 20:43:53 +01:00
1b970cd943 Session-Subsytem(#318): finish review of locking and lifecycle sanity
This subsystem as such can be considered as implemented now,
while several details still wait to be filled in.
2017-01-05 03:38:46 +01:00
3809240312 ProcDispatcher(#318): forgo joining the loop thread to avoid deadlock
Due to object scoping we can conclude reliably that the only one
ever to delete the DispacherLoop object will be the the loop thread
from within this object itself, when invoking the termination callback.

Btw, the lock on the inner object was insufficient and will be
replaced by taking the outer lock
2017-01-05 02:00:35 +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
34686713d4 Proc-Layer: Builder is not a subsystem (anymore)
We found out that it's best to run it single threaded
within the session loop thread. This does not mean the Builder
itself is necessarily single threaded, but the Builder's top level
will block any other session operation, and this is a good thing.
For this reason it makes more sense to have the Builder integrated
as a component into the session subsystem.
2017-01-03 21:10:27 +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
387a553e98 Lib: fix warning regarding subobject-linkage
And yes, this warning is for real, while the compiler has no way
to decide if there is actual danger lurking. A type with internal
linkage (e.g. defined in an anonymous namespace) will be treated
by the linker as a separate entity on each encounter (i.e. in
each distinct compilation unit). When multiple translation units
start collaborating on such a type, they *might* be referring
to different memory locations, while semantically the intention
is to refer to the same location.

And since we're dealing with a library facility here, *we* have
likewise now power to ensure proper usage, so we better be cautious.
2016-12-25 20:09:24 +01:00
b5590fb22c CommandQueue: prepare for an unit test 2016-12-25 18:49:57 +01:00
b6d5cd1c76 SessionCommandService implemented by delegating to the ProcDispatcher 2016-12-23 23:42:27 +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
39060297ee ProcDispatcher: solve the sync waiting for a "checkpoint"
...based on the logic of the whole loop
2016-12-22 21:36:03 +01:00
8bbc0fb97f more clean-up and comments 2016-12-22 19:35:42 +01:00
ad6a2ef090 ProcDispatcher: fix possible race at startup 2016-12-22 18:42:12 +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
bae3d4b96f mark a solution how to create a safeguard against deadlock on session shutdown
....if by some weird coincidence, a command dispatched into the session
happens to trigger session shutdown or re-loading, this will cause a deadlock,
since decommissioning of session data structures must wait for the
ProcDispatcher to disable command processing -- and this will obviously
never happen when in a callstack below some command execution!
2016-12-20 02:35:45 +01:00
b873f7025b ProcDispatcher: mark some next tasks to care for 2016-12-16 23:26:56 +01:00
53ed0e9aa3 ProcDispatcher: consider and document the fine points of operational semantics
there are some pitfalls related to timing and state,
especially since some state changes are triggered, but not immediately reached
2016-12-16 23:11:19 +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
af92ed505b Looper: implementation 2016-12-16 18:34:04 +01:00
7b860947b1 ProcDispatcher: skeleton of the processing loop
including a draft of the Looper control component and the
invocation of the object monitor for waiting on condition var
2016-12-15 22:15:20 +01:00
00077d0431 ProcDispatcher: decide on requirements and implementation structure (#1049) 2016-12-15 20:48:35 +01:00
7e65dda771 draft request to halt the dispatcher loop 2016-12-15 06:21:59 +01:00
86f446c197 better control of the shutdown sequence
holding the SessionCommandService in a unique_ptr allows us to
close the Interface reliably *before* the Loop is halted.
2016-12-15 05:54:48 +01:00
a3c22b8aff SessionCommandService to be operated by the DispatcherLoop 2016-12-15 05:38:12 +01:00
715d3d2890 fix indentation 2016-12-15 05:31:56 +01:00
4d45dfd4be introduce CommandDispatch interface
this allows to let the DispatcherLoop actually serve
as implementation facility for the SessionCommandService
2016-12-15 05:21:03 +01:00
1ec883787a DOC: decision about where to home the SessionCommandService
After some consideration, it became clear that this service implementation
is closely tied to the DispatcherLoop -- which will consequently be
responsible to run and expose this service implementation
2016-12-15 05:07:40 +01:00
479f4170c2 implement activated state
need to keep state variables on both levels,
since the session manager (lifecycle) "opens" the session
for external access by starting the dispatcher; it may well happen
thus that the session starts up, while the *session subsystem*
is not(yet) started
2016-12-14 04:57:08 +01:00
a853851447 add complete locking to the ProcDispatcher
on both levels
- the front-end needs locking to ensure consistent state (memory barrier)
- the back-end nees locking to coordinate command processing
2016-12-14 04:18:58 +01:00
4c30c349aa change the way command dispatching is controlled by the session
"command dispatching" == the public session interface
so we'll better implement this important causal link directly,
instead of some obscure trickery with lifecycle events.
2016-12-14 03:59:13 +01:00
8b354ab721 consider and rectify session lifecycle
turns out that I've created a race and consistency problem
just by a silly idiotic fixation on performance. Never ever
leave out a lock to "improve" performance, mind me.
2016-12-14 03:48:30 +01:00
8da9858056 draft skeleton of the dispatcher loop thread 2016-12-13 04:45:00 +01:00
1a8408afb5 rework ProcDispatcher to run dispatcher thread as PImpl
note the idea is to have a joinable thread, where deleting
the enclosing object blocks until the thread is finished
2016-12-13 04:34:28 +01:00
08e426047b define session subsystem lifefycle (#318)
...by forwarding over the static interface to the ProcDispatcher
2016-12-13 04:32:37 +01:00
014a828c63 next task: implement minimal "Session subsystem" (#318)
mark TODOs in code to make that happen.
Actually, it is not hard to do so, it just requires to combine
all the existing building blocks. When this is done, we can define
the "Session" subsystem as prerequisite for "GUI" in main.cpp

Unless I've made some (copy-n-paste) mistake with defining the facades,
this should be sufficient to pull up "the Session" and automatically
let the Gui-Plugin connect against the SessionCommandService
2016-12-12 03:45:21 +01:00
c144d15e65 add two placeholder functions for now
...soon to be replaced by the actual stuff, but right now
I am only concerned with getting all the boilerplate straight
2016-12-12 03:16:29 +01:00
4975712b5e copy-n-paste-programming to define SessionCommand interface / service
...the sheer amount of mechanical replacements scattered all over these
files might be a vivid indication, that the design of the interface system
is subobptimal ;-)
2016-12-12 03:09:08 +01:00
64e303999e WIP: start definition of SessionCommand interface 2016-12-12 02:55:32 +01:00
a51c9b9a63 clean-up: rename header to reflect interface name 2016-12-12 02:10:52 +01:00
b6e7caf737 Guistart(#1045): relocate opening of GuiNotification into the CoreServices
up to now this happened from the GuiRunner, which was a rather bad idea
- it can throw and thus interfer with the startup process
- the GuiNotification can not sensibly be *implemented* just backed
  by the GuiRunner. While CoreService offers access to the necessary
  implementation facilities to do so
2016-12-12 01:49:11 +01:00
5e9b3be985 better name for the interface function actually to launch the UI 2016-12-12 01:46:03 +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
79800bb6eb workaround for shutdown problems due to circular UI-Bus topology
so the true reason is an inner contradiction in the design
- I want it to be completely self similar
- but the connection to CoreService does not conform
- and I do not want to hard code CoreService into the Nexus classdefinition

So we treat CoreService as uplink für Nexus and Nexus as uplink for CoreService,
with the obvious consequences that we're f**ed at init and shutdown.

And since I want to retain the overall design, I resort to implement
a short circuit detector, which suppresses circular deregistration calls
2016-12-11 01:34:32 +01:00
e75152b29d install and activate UI-Bus in the actual GUI (#1043)
Decision was made to use the CoreService as PImpl to organise
all those technical aspects of running the backbone. Thus,
the Nexus (UI-Bus hub) becomes part of CoreService
2016-12-10 04:01:06 +01:00
562b47166d identify problems with existing UI lifecycle (#1048) 2016-12-10 03:10:34 +01:00
4322c90367 set up dummy-session-connection to implement this scaffolding
...and as first step towards an UI-Session connection:
actually include the Nexus and the CoreService in to ui-bus.cpp
2016-12-10 01:58:58 +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
1627edd96f define (preliminary) diff bindings for a MarkerWidget
...problem is, I actually don't know much about what kinds of markers
we'll get, and how we handle them. Thus introducing a marker kind
is just a wild guess, in order to get *any* tangible attribute
2016-12-04 00:29:50 +01:00
6eeb23df9e define the diff bindings for the ClipPresenter 2016-12-04 00:23:32 +01:00
803a71cc31 define the diff bindings for the TrackPresenter
Phew, convoluted.
And I was doubtful that we need to support multiple typed child collection
Well, we get three such collections already in the first real world example...
2016-12-04 00:03:24 +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
81febc27e1 define the diff bindings for TimelineController
- set the name field
- manage a nested collection of markers

All based on boilerplate code copied from my diff binding tests
2016-12-03 22:59:03 +01:00
c5eff7f4c5 markers can appear at various scopes
need to add them at the respective levels into the structural model
2016-12-03 22:37:41 +01:00
5d077ae5b4 add the necessary widgets to be maintained by the Presenters 2016-12-03 22:01:44 +01:00
9b8fae1a9b (re)consider the problem how to deal with mandatory/optional object fields
this is a tricky problem and a tough decision.
After quite some pondering I choose to enforce mandatory fields
through the ctor, and not to allow myself cheating my way around it
2016-12-03 19:37:52 +01:00
8666daca94 flesh out the buildup of the control hierarchy
TODO
 - define the actual diff bindings
 - find out how to inject the views
2016-12-03 06:22:21 +01:00
f995dd51e2 define creation and control structure of TimelineWidget 2016-12-03 05:42:34 +01:00
14588dbc19 clarify the principles of UI - Core collaboration
it occurred to me that effectively we abandoned the use of
a business facade and proxy model in the UI. The connection
becomes entirely message based now.

To put that into context, the originally intended architecture
never came to life. The UI development stalled before this could
happen; possibly it was also hampered by the "impedance mismatch"
between our intentions in the core and such a classical, model centric
architecture. Joel several times complained that he felt blocked; but
I did not really understand this issue. Only recently, when I came to
adapting the timeline display to GTK-3, I realised the model centric
approach can not possibly work with such an open model as intended
in our case. It would lead to endless cascades of introspection.
2016-12-02 20:07:31 +01:00
3ffd511a76 consider lifecycle and instance management of the timeline 2016-12-02 19:34:38 +01:00
b946884228 fix compilation
...shows again why its not adwisable to use wildcard namespace include.
Well, the old timeline code is going away soon, and for the rewritten new one,
we'll learn from such structural problems
2016-12-02 04:36:42 +01:00
0b1bc6a579 define and document the building blocks of the new timeline UI
these are just empty class files, but writing a basic description
for each made me flesh out a lot of organisational aspects of what
I am about to build now
2016-12-02 01:53:00 +01:00
67beeab25a start with actual rework of the timeline display
draft a concept for timeline layout management
2016-12-01 21:01:45 +01:00
df46c3f901 Doxygen: fill in missing file level headlines for Proc-Layer (Player) 2016-11-09 23:40:46 +01:00
fb15c258ea Doxygen: fill in missing file level headlines for Proc-Layer (top-level) 2016-11-09 23:17:02 +01:00
bfccd99623 Doxygen: fill in missing file level headlines for Proc-Layer (Session) 2016-11-09 22:22:55 +01:00
6577a392e3 Doxygen: fill in missing file level headlines for Proc-Layer (Builder) 2016-11-09 20:43:45 +01:00
bb139a5c73 Doxygen: fill in missing file level headlines for some supplemental code 2016-11-09 20:09:19 +01:00
846e9af174 Doxygen: fill in missing file level headlines for Proc-Layer (Engine II) 2016-11-09 19:50:16 +01:00
9676d17366 Doxygen: fill in missing file level headlines for Proc-Layer (Engine I) 2016-11-09 19:13:52 +01:00
a5c9951012 Doxygen: fill in missing file level headlines for Proc-Layer (Controller) 2016-11-08 14:34:39 +01:00
88405c3f2a Doxygen: fill in missing file level headlines for Proc-Layer (Assets) 2016-11-08 14:18:28 +01:00
faa9cfca14 Doxygen: fill in missing file level headlines for Proc-Layer 2016-11-08 13:33:17 +01:00
8e6936d0ad Doxygen: fill in missing file level headlines for the Library 2016-11-08 13:18:05 +01:00
545a07db33 Doxygen: fill in missing file level headlines for the Library (timecode handling) 2016-11-07 16:22:04 +01:00
933cd81c18 Doxygen: fill in missing file level headlines for the Library (test helpers) 2016-11-07 15:51:41 +01:00
a3a245ec19 Doxygen: fill in missing file level headlines for the Library (metaprogramming) 2016-11-07 15:39:13 +01:00
311ed218cb Doxygen: fill in missing file level headlines for the GUI (2) 2016-11-06 14:38:12 +01:00
b258bc9275 Doxygen: fill in missing file level headlines for the GUI 2016-11-06 14:19:14 +01:00
f694f9aa2d Doxygen: fill in file level headlines for further application core services 2016-11-04 22:29:24 +01:00
aa335b5605 Doxygen: fill in missing file level headlines for config and query frameworks
Added warning tags to several headers of the first config system draft from 2008
since this effort is stalled and likely to be implemented differently
2016-11-04 21:26:56 +01:00
ddc915db41 Doxygen: fill in missing file level headlines for the Backend 2016-11-03 19:37:38 +01:00
dbc75fac7d Doxygen: we missed the plain C code 2016-11-03 18:26:43 +01:00
6339a288dd Doxygen: insert actual filename into those automatically added file comments
HOWTO
for F in $(find src -type f \( -name '*.cpp' -or -name '*.hpp' \)  -exec egrep -q '§§§' {} \; -print);
    do D=$(basename $F);
       sed -r -e"s/§§§/$D/" $F ;
done
2016-11-03 18:22:31 +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
1e642dc805 Inv(#1020): remove debugging output
...done thus far!
2016-11-01 23:44:42 +01:00
1fbade3a67 Inv(#1020): find a reliable way to determine extension of the canvas
bottom line
- seems we need to do that manually
- must wait until in the on_draw() callback
- use Container::foreach() to visit all child widgets
- Layout::set_size()
2016-11-01 23:20:43 +01:00
6fd0045a65 Inv(#1020): adjust curtom drawing for scrolled viewport
this makes the custom drawing stiched to the absolute canvas,
allowing to move around with the help of the scrollbars...
2016-10-30 17:08:41 +01:00
90cc17b733 Inv(#1020): learn how to draw a simple line
here we draw a red diagnoal line behind the embedded widgets.
2016-10-30 02:55:38 +01:00
1255a4fc04 Inv(#1020): framework for custom drawing 2016-10-30 02:15:01 +01:00
ae07329ada Inv(#1020): expand some widgets by text change 2016-10-29 18:17:58 +02:00
f8d8a89220 Inv(#1020): reorganise tooltips and accelerators 2016-10-29 18:09:03 +02:00
1b9a45930b Inv(#1020): control extension of the scrollable area
this uncovers some possible problem in GTK (#1037)
2016-10-29 17:53:52 +02:00
9397f064c7 Inv(#1020): add some tooltips
...to describe the implemented experiments
2016-10-29 16:22:06 +02:00
e4bf84657c Inv(#1020): erase arbitrary child widgets 2016-10-29 16:05:37 +02:00
8348696a56 Inv(#1020): add function to align all widgets in a single row
...which allows us to verify consistency of z-order
2016-10-29 15:40:23 +02:00
03a9611608 Inv(#1020): iteration and moving of children 2016-10-29 03:26:07 +02:00
94a0adcb5b Inv(#1020): place widgets irregularily
- partially overlapping
- beyond the scrollable area
2016-10-29 00:51:28 +02:00
e7d284783b Inv(#1020): place widgets on canvas
- randomly
- partially overlapping
- event dispatch works as expected
2016-10-28 17:32:43 +02:00
5897d1ffad clean-up: unnecessary includes
they'll hamper the investigation by causing extended compilation round-trip
2016-10-28 16:54:03 +02:00
f3e791d1ac Ticket #1034 : leave note at dlclose() call 2016-10-28 16:54:02 +02:00
12f1165765 Inv(#1020): add code to monitor clean-up by GTK
I am still suspicious the cleanup mechanism for child widgets works as expected...
But right now, we can't verify that, since on shutdown we get an assertion failure
from ld.so "dl-close.c: 762: _dl_close: Assertion `map->l_init_called' failed!"
Seems we're loading the GUI plugin not properly
2016-10-27 23:36:20 +02:00
dd9f34e93a Inv(#1020): prepare Investigation
- define tasks to be addressed during investigation
- read documentation, identify problematic aspects
- prepare a child widget class to be placed on the canvas
2016-10-27 22:57:46 +02:00
2350998fdb setup layout for experiments (closes #1021) 2016-10-27 04:15:20 +02:00
0888e0afe7 new empty dock for research and experiments (#1020)
My intention is to use this space for experiments first,
and then as a construction site for a rewrite of the
custom timeline widget.

We really need a rewrite here, in order to be properly
aligned to the standard way of writing such a custom widget,
and also to build our first connection to the UI-Bus and then
remove the old placeholder UI model
2016-10-27 02:57:23 +02:00
3bb76f2f2c move asside old code to make room for investigation
...goal is to have a new dockable panel,
where we'll build the new timeline widget eventually.

Signed-off-by: Ichthyostega <prg@ichthyostega.de>
2016-10-26 18:44:27 +02:00
c8b6e7a699 mark some code smells (#1026) 2016-10-26 18:44:27 +02: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
d58f8c853a TreeMutator binding: extend collection binding to support std::map
actually this is a pragmatic extension for some special use cases,
and in general rather discurraged, since it contradicts the
established diff semantics. Yet with some precaution, it should
be possible to transport information via an intermediary ETD

Map -> ETD -> Map
2016-10-03 19:31:59 +02:00
15ac0d6310 clean-up: remove one leftover of Ref::THIS (#996)
for the record: while it is indeed sweet-and-simple to support Ref::THIS
here, it is near impossible to represent it in general, in a setup with
multiple "onion-layers". The reason is, we'd have to incorporate such
special treatment into the /selector predicate/, which in turn undermines
the ability to pick the right onion layer to handle a given diff verb,
since "Ref::THIS" is a generic marker and we have no other data to base
the decision in the selector on.
2016-10-03 17:33:30 +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
b251b9a022 MutationMessage: generic implementation based on the DiffMutable interface 2016-10-02 23:34:07 +02:00
76fc444437 MutationMessage: implementation draft 2016-10-02 22:21:17 +02:00
f0de986399 Library: allow to immediately emplace a subclass type into InPlaceBuffer
Up to now, InPlaceBuffer used to default construct an instance of the
Interface class, and then you'd need to invoke the `create()` function
to actually create the desired subclass. This is not only inefficient,
but rules out the use of abstract interfaces / base classes.

Unfortunately, there is no way in C++ to specify an explicit template argument list
on ctor calls, so we resort to the trick of passing an additional dummy marker argument
2016-10-02 22:15:55 +02:00
d2e4f826ed UI-Bus/mutation: expand on draft for mutation message 2016-10-01 23:09:08 +02:00
d87111f703 DOC: MutationMessage 2016-10-01 22:36:52 +02:00
27ba8d5896 UI-Bus/mutation: draft idea for mutation message on UI-Bus 2016-09-30 22:23:55 +02:00
6c3024adcd UI-Bus/mutation: search for ways how to integrate Diff processing 2016-09-30 18:13:04 +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
a066650eb7 remove the now obsolete, dedicated first diff implementation
yay! this piece of code has served its purpose:
it was the blueprint to build a way better design and implementation,
which can now cover this "generic tree" case as a special case as well
2016-09-05 04:05:31 +02:00
840d9e4397 make Rec::Mutator as such diff mutable
this adds kind of an extension point to diff::Record<GenNode>::Mutator,
which is then actually defined (implemented) within the diff framework.

This allows the TreeDiffTraits automatically to use this function
to get a TreeMutator for a given Rec::Mutator. Which in turn allows
the generic version of DiffApplicator automatically to attach and
bind to a Record<GenNode>

together this allows us to ditch the explicit specialisation
and dedicated, hand-written implementation of DiffApplication
to GenNode in favour of using the TreeMutator and friends.
2016-09-05 02:25:07 +02:00
ebb3ccb589 clean-up: move PlantingHandle over to the OpaqueHolder facility
...where it belongs; it is entirely generic
and we'd expect more usage on APIs for callbacks
2016-09-04 23:21:15 +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
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
e00d6c2a4c reorganise inclusion of TreeMutator-DSL builders
previously they where included in the middle of tree-mutator.hpp
This was straight forward, since the builder relies on the classes
defined in the detail headers.

However, the GenNode-binding needs to use a specifically configured
collection binding, and this in turn requires writing a recursive
lambda to deal with nested scopes. This gets us into trouble with
circular definition dependencies.

As a workaround we now only *declare* the DSL builder functions
in the tree-mutator-builder object, and additionally use auto on
all return types. This allows us to spell out the complete builder
definition, without mentioning any of the implementation classes.
Obviously, the detail headers have then to be included *after*
the builder definition, at bottom of tree-mutator.hpp
This also allows us to turn these implementation headers into
completely normal headers, with namespaces and transitive #includes

In the end, the whole setup looks much more "innocent" now.

But beware: the #include of the implementation headers at bottom
of tree-mutator.hpp needs to be given in reverse dependency order,
due to the circular inclusion (back to tree-mutator.hpp) in
conjunction with the inclusion guards!
2016-09-02 01:29:32 +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
c791763890 implement builder setup for Rec<GenNode>
this compiles just fine.
But we still need to define the concrete closures
to make it work with the actual contents of GenNode
2016-08-31 18:40:09 +02:00
a01435f367 WIP: outline of a new GenNode binding
...instead of using a hand written implementation,
the idea is to rely on the now implemented building blocks,
with just some custom closures to make it work.
2016-08-31 17:09:32 +02:00
3774960dcc finish and document some loose ends
...with the exception of a GenNode binding, the whole
diff application and binding framework is now built and ready for use
2016-08-29 22:14:03 +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
77ada853a2 verify and clean-up implementation diff application through TreeMutator
- esp. verify the proper inclusion of the Selector closure in all Operations
- straighten the implementation of Attribute binding
- clean-up the error checking helpers
2016-08-26 16:29:50 +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
1b6a87324d implement value assignment through TreeMutator 2016-08-25 18:42:51 +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
e1687c1c18 supply missing implementation for after(Ref::ATTRIBS) to TestMutationTarget
yay! unit testing rocks.
Actually I changed the test definition for another reason, just to discover
that I've missed to implement that operation in this onion layer
2016-08-13 17:34:57 +02:00
c027ce4638 implement list diff verbs pick, del, find and skip.
now failing due to a contradiction in test fixture:
it is nonsensical to re-order attributes; rather, we should
cover re-ordering of children, to verify that the mutator binding
properly surpasses the attribute layers and forwards operations
to the lower layers responsible for handling child scopes...
2016-08-10 03:29:32 +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
cbe29fead3 Library: allow for pretty-printing of smart-ptr values
- an extension to our custom toString and typeString helpers.
- currently just for shared_ptr and unique_ptr
- might add further overloads for other smart-ptr types
2016-07-31 00:33:26 +02:00
52918b069f metaprogramming: trait to detect smart-pointers 2016-07-31 00:33:26 +02:00
020940545c integrate the complete initialisation sequence
when about to consume the next diff sequence, the
scopeStack will be reset and a new root scope TreeMutator
will be placed into this top buffer
2016-07-31 00:33:26 +02:00
17c78f369c ScopeManager stack based implementation
integrated into the generic DiffApplicationStrategy.
The dedicated, explicit specialisation for DiffMutable is
no longer needed, since the generic template will degrade or
fall back to precisely this functionality, when the target
implements the DiffMutable interface
2016-07-31 00:33:26 +02:00
a7b5a88c60 integrate size traits and ScopeManager implementation 2016-07-31 00:33:25 +02:00
d1bbf01029 solution to integrate heap based storage for nested scopes 2016-07-31 00:33:25 +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
40b032c9c2 WIP: code organisation - declaration and definition 2016-07-25 15:21:30 +02:00
0d2335c9ed WIP: code organisation - create dedicated implementation unit
It occurred to me, that 90% of this template specialisation
are entirely generic and not dependant on the actual target type.
While the compiler/linker is able to sort such a situation out,
this might lead to template bloat and possibly subtle errors.

So it seems more adequate to emit the generic part of the code
right away from within a dedicated translation unit within the
library module; so the vtable is already in place and only
the flexible part of the code needs to be re-emitted on
each usage site.
2016-07-24 15:16:06 +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
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
6fa54411b3 improved log msg
..because actually we don't know if the intention is
to drop those waste elements -- and for sure this
discarding of waste does not happen through the
invocation logged here; rather it happens by
abandoning the scope
2016-06-09 01:21:06 +02:00
37cfdbb7e1 better name for nested handle type 2016-06-09 01:18:21 +02:00