Commit graph

1182 commits

Author SHA1 Message Date
c2c25f8134 NotificationDisplay: define and include the unique error-Log ID 2018-09-14 21:06:12 +02:00
53c47a6fcc Assets: verify creation of ErrorLog meta-Asset 2018-09-14 21:06:12 +02:00
928b4372e0 Assets: investigating the unclear distinction between asset::Struct and asset::Meta (#1156)
including a kind-of Bugfix: the ctor of TimeGrid erroneously categorised it as asset::Kind STRUCT
2018-09-14 21:06:12 +02:00
1d69bb9050 NotificationDisplay: define a new ErrorLog asset
...for now to serve as placeholder type, used as anchor for the corresponding UI display widget
2018-09-14 21:06:12 +02:00
5475839a49 NotificationDisplay: the question where to define the entity-ID 2018-09-14 21:06:12 +02:00
12244afc90 NotificationDisplay: fill in some default implementation for the controller 2018-09-14 21:06:12 +02:00
0c8151cb2f NotificationDisplay: decide upon the architecture for handling notification messages (#1102)
* have a dedicated "information hub" controller, which acts a receiver of "error log messages" on the UI-Bus
 * let that controller in turn allocate an apropriate view on demand
2018-09-14 21:06:12 +02:00
06b3c382f3 DemoGuiRoundtrip: expand on that idea (#1099) and start analysis how to create that UI component
The goal is to build a (in itself completely meaningless) ping-pong interaction
between the UI and Proc-Layer, for the purpose of driving the integration ahead.

The immediate challenge is how to create and place an apropriate "GuiComponentView",
i.e. a Tangible, which is connected to the UI-Bus with an predictable EntryID.
And the problem is to get that settled right now, without building the envisioned
generic framework for View allocation in the UI. When this is achieved,
it should be a rather small step to actually send those notifications over
the UI-Bus, which is basically implemented and ready by now.
2018-09-14 21:06:12 +02:00
3a100972d7 UI-Lifecycle: send up a dummy notification message to indicate start of content population
right now this will just end up in the log, since not even the
notification display is implemented beyond the GuiNotification-facade.

Anyway, we get some kind of communication now for real, in the actual application
2018-08-04 19:07:21 +02:00
4e77a28112 UI-Lifecycle: use dummy-mechanism to get the new command executed
...because due of #211, we usually don't execute commands yet.
For now there is only the backdoor to prefix the command-ID with "test"

With this change, the TODO message appears now immediately after GUI start!
2018-08-04 18:45:58 +02:00
d58890e2d5 UI-Lifecycle: define a new Proc-Command to implement the population trigger (#1150) 2018-08-04 17:10:04 +02:00
eca06a8309 UI-Lifecycle: build trigger point for content population into InteractionDirector (closes #1151)
In the end, I decided against building a generic service here,
since it pretty much looks like a one-time problem.

Preferrably UI content will be pushed or pulled on demand,
rather than actively coding content from within the UI-Layer
2018-08-04 16:02:00 +02:00
4306e47930 (DOC) GTK start-up internals and design of Lumiera's UI-Layer 2018-08-03 22:33:06 +02:00
7db8bf4c0c UI-Lifecycle: research regarding GTK's activation signal. Document the findings
- activation signal is a facility offered and used solely by Gtk::Application
- we do not need nor want an Gtk::Application, we deal with our own application
  concerns as we see fit.
2018-08-03 19:28:12 +02:00
f33573daec UI-Lifecycle: note down reference point for this task in Gtk::Application
Gio::Application holds a signal_activation(), which seems to be used for
precisely that task we need here: to do something right after the UI is operative
2018-08-03 01:48:08 +02:00
d3daed9a18 UI-Lifecycle: invstigate where to issue the trigger (#1151) 2018-08-02 19:59:26 +02:00
9a39781667 UI-Lifecycle: draft a plan how to trigger content population
...and while doing so, also re-check the state of the GTK toolkit initialisation.
Looks like we're still future-proof, while cunningly avoiding all this
Gnome-style "Application" blurb
2018-07-28 19:01:23 +02:00
0c5a0fed6a UI-Lifecycle: verify and rectify start-up sequence (#1147)
...still not entirely decided yet where to plant the mechanism for
UI content retrieval (#1150)
2018-07-14 19:39:00 +02:00
c24778132e After a long break (LAC.2018 Berlin) -- start planning the next steps
I will abandon work on the ViewSpec DSL in current shape (everything fine with that)
and instead work on a general UI start-up and content population sequence.
From there, my intention is to return to the docks, the placement of views
and then finally to the TimelineView
2018-07-12 21:32:41 +02:00
5cac40654f DockAccess: draft code reorganisation (#1144) 2018-06-17 15:09:52 +02:00
8097485dbf ViewSpec: integrate the simple View access case (Unit test PASS)
This finishes the first round of design drafts in this area.
Right now it seems difficult to get any further, since most of
the actual view creation and management in the UI is not yet coded.
2018-06-15 18:02:08 +02:00
800fc5915a ViewSpec: recast the ElementAccess API to work around the design problem
...it is not really solved, rather postponed.
But who knows. Maybe it's already good enough...
2018-06-15 16:42:51 +02:00
2e8bc9227a ViewSpec: analysis of design alternatives
looks like I'm trapped with the choice between a convoluted API design
and an braindead and inefficient implementation. I am leaning towards the latter
2018-06-15 01:51:10 +02:00
f55a8f606b ...one month later: pick up after the LAC.18 Berlin
...happened to be completely absorbed by the preparations
for my workshop about Yoshimi and musical presets
2018-06-14 17:02:34 +02:00
64b45a41c9 ViewSpec: some more musing...
the damn thing is: now we get three consecutive accesses for each invocation.
This starts looking really dumb
2018-06-14 15:15:08 +02:00
363d24ba91 ViewSpec: unsuccessful atempt to implement the allocator token
looks like we're hitting a design mismatch here....

...and unfortunately I have to abandon this task now and concentrate
on preparation of my talk at LAC.2018 in June
2018-06-14 15:13:06 +02:00
852a3521db Static-Init: switch lib::Depend to embed the factory as Meyer's Singleton (#1142)
this is a (hopefully just temporary) workaround to deal with static initialisation
ordering problems. The original solution was cleaner from a code readability viewpoint,
however, when lib::Depend was used from static initialisation code, it could
be observed that the factory constructor was invoked after first use.

And while this did not interfer with the instance lifecycle management itself,
because the zero-initialisation of the instance (atomic) pointer did happen
beforehand, it would discard any special factory functions installed from such
a context (and this counts as bug for my taste).
2018-05-01 18:49:20 +02:00
d0538a55ff ViewSpec: implement the generic access function in ViewLocator
still missing: internal wiring from the allocation token(s) of the DSL
into the ElementAccess service designed last week.
2018-04-15 03:07:54 +02:00
ba3d9e57b5 ViewSpec: draft a way to code an integration test for ViewLocator (#1129)
The original goal for #1129 (ViewSpecDSL_test) is impossible to accomplish,
at least within our existing test framework. Thus I'll limit myself to coding
a clean-room integration test with purely synthetic DSL definitions and mock widgets
2018-04-15 01:39:46 +02:00
86b1aac721 ElementAccess: somewhat improve the mock implementation to cover the standard case
...still quite braindead, but well....
2018-04-14 03:58:02 +02:00
4071a58454 ElementAccess: fix first unit test case
ouch, the typedef Base /is/ already a pointer...
2018-04-14 01:59:41 +02:00
4c273d902c ElementAccess: add very simplistic mock implementation 2018-04-14 01:37:56 +02:00
35ea547fd1 ElementAccess: (WIP) another unsuccessful attempt
Problem is, we can not even compile the conversion in the "other branch".
Thus we need to find some way to pick the suitable branch at compile time.

Quite similar to the solution found for binding Rec<GenNode> onto a typed Tuple
2018-04-09 02:19:54 +02:00
91b83f5ede ElementAccess: (WIP) unsuccessful attempt to solve the typing problem
the intention was to return disparate result types, just depending on the
actual position in the UI-Coordinates. The client knows what to expect
2018-04-09 01:14:12 +02:00
c245098d45 ElementAccess: (WIP) first draft for internal accessor function
...but can not work this way.
Since void* has not RTTI, no secure access with downcast is possible
2018-04-09 00:51:24 +02:00
e99ad7a3e6 ElementAccess: draft simple lookup interface 2018-04-08 18:43:27 +02:00
09359cf92a ElementAccess: initial brainstorming about the interface mechanics 2018-04-07 02:28:29 +02:00
dc97ab5546 ElementAccess: consider helper to encapsulte access to actual GTK structures (#1134) 2018-04-07 01:00:25 +02:00
2f899a921c ViewSpec: draft next steps to address
...should implement the generic invocation in ViewLocator,
without actually implementing the backing UI element allocation logic
2018-04-05 19:43:10 +02:00
18a552002d ViewSpec: use mocked LocationSolver to verify operation of the DSL 2018-04-05 01:09:13 +02:00
64d5f868ea ViewSpec: and finally solve the daunting problem of service access
this is f***ng unbelievable.
Its just two lines of code now
VICTORY!
2018-04-04 04:37:13 +02:00
cb6155c85e ViewSpec: now turn the UILocationSolver into yet another global service
feels a bit uncanny after all
can't be *that* easy
2018-04-04 03:59:11 +02:00
71bb2b48b6 ViewSpec: pick up with dependency-injection into the DSL tokens (#1126)
Attempt to find my way back to the point
where the digression regarding dependency-injection started.

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


FIRST STEP is to expose the Navigator as generic "LocationQuery" service
through lib::Depend<LocationQuery>
2018-04-04 03:29:26 +02:00
fb8a5333fc DOC: reduce DependencyFactory page in the TiddlyWiki
...since it has been published almost 1:1 on the Lumiera website.
Retain only some technical reference information here
2018-04-04 01:43:24 +02:00
b3c5142c2f DOC: publish the microbenchmark results in the technical documentation section (closes #1086) 2018-04-03 09:08:40 +02:00
6f2ed76d83 Improve the code for proxy generation
more of a layout improvement, to avoid any code duplication.
The mechanics remain the same
 - write an explicit specialisation
 - trigger template intantiation within a dedicated translation unit
2018-04-03 07:45:13 +02:00
db7172df29 DOC: update technical (doxygen) documentation to reflect the integration with lib::Depend 2018-04-03 06:37:36 +02:00
18d0970a86 Rework Interface-Proxy definition to fit with the new scheme
everything works now after the switch.
BUT this solution is ugly, we need to trigger template instantiation explicitly
2018-04-03 05:15:26 +02:00
f24c548443 Reorganise translation units for interface proxies
from now on, we'll have dedicated individual translation units (*cpp)
for each distinct interface proxy. All of these will include the
interfaceproxy.hpp, which now holds the boilerplate part of the code
and *must not be included* in anything else than interfac proxy
translation units. The reason is, we now *definie* (with external linkage)
implementations of the facade::Link ctor and dtor for each distinct
type of interface proxy. This allows to decouple the proxy definition code
from the service implementation code (which is crucial for plug-ins
like the GUI)
2018-04-03 03:14:55 +02:00
1101e1f1db Dismantle the woefully complex interfaceproxy Accessor in favour of lib::Depend
The recently rewritten lib::Depend front-end for service dependencies,
together with the configuration as lib::DependInject::ServiceInstance
provides all the necessary features and is even threadsafe.

Beyond that, the expectation is that also the instantiation of the
interface proxies can be simplified. The proxies themselves however
need to be hand-written as before
2018-04-03 02:44:12 +02:00
4e0d99e928 Demote the Play-Facade to a in-language (C++) Interface to get rid of InterfaceFacadeLink
I am fully aware this change has some far reaching ramifications.
Effectively I am hereby abandoning the goal of a highly modularised Lumiera,
where every major component is mapped over the Interface-System. This was
always a goal I accepted only reluctantly, and my now years of experience
confirm my reservation: it will cost us lots of efforts just for the
sake of being "sexy".
2018-04-03 02:14:45 +02:00
9f3c127240 (WIP) Draft to replace the Interface-Proxy-Binding by lib::Depend
in theory this should be possible and obsolete a lot of dedicated code,
since lib::Depend provides all the intance management and error checking
2018-04-02 08:20:56 +02:00
29ee5131f4 Switch first Layer-Separation-Interface to expose the service implementation via lib::Depend
Actually this is on the implementation side only.
Since Layer-Separation-Interfaces route each call through a binding layer,
we get two Service-"Instances" to manage
- on the client side we have to route into the Lumiera Interface system
- on the implementation side the C-Language calls from the Interface system
  need to get to the actual service implementation. The latter is now
  managed and exposed via DependInject::ServiceInstance
2018-04-02 04:19:17 +02:00
be789bea59 Fix funny problem with C header stdbool.h
...which is so kind as to redefine bool, true and false as macros. Yessss!
2018-04-02 03:27:07 +02:00
6460ff8344 Switch basic Application initialisation to the rewritten DependencyFactory
this is the classic case of a singleton object
2018-04-02 02:56:08 +02:00
4669260cd1 Fix setup of the ConfigManager implementation
...still using the FAKE implementation, not a real rules engine.
However, with the new Dependency-Injection framework we need to define
the actual class from the service-provider, not from some service-client.
This is more orthogonal, but we're forced to install a Lifecycle-Hook now,
in order to get this configuration into the system prior to any use
2018-04-02 02:20:54 +02:00
d6167c1845 DependencyFactory: reorder destructor to allow for re-entrance
This is borderline yet acceptable;
A service might indeed depend on itself circularly
The concrete example is the Advice-System, which needs to push
the clean-up of AdviceProvicions into a static context. From there
the deleters need to call back into the AdviceSystem, since they have
no wey to find out, if this is an individual Advice being retracted,
or a mass-cleanup due to system shutdown.

Thus the DependencyFactory now invokes the actual deleter
prior to setting the instance-Ptr to NULL.
This sidesteps the whole issue with the ClassLock, which actually
must be already destroyed at that point, according to the C++ standard.
(since it was created on-demand, on first actual usage, *after* the
DependencyFactory was statically initialised). A workaround would be
to have the ctor of DependencyFactory actively pull and allocate the
Monitor for the ClassLock; however this seems a bit overingeneered
to deal with such a borderline issue
2018-04-01 07:06:58 +02:00
21fdce0dfc a better solution to reject out-of-order static access after shutdown
Static initialisation and shutdown can be intricate; but in fact they
work quite precise and deterministic, once you understand the rules
of the game.

In the actual case at hand the ClassLock was already destroyed, and
it must be destroyed at that point, according to the standard. Simply
because it is created on-demand, *after* the initialisation of the
static DependencyFactory, which uses this lock, and so its destructor
must be called befor the dtor of DependencyFactory -- which is precisely
what happens.

So there is no need to establish a special secure "base runtime system",
and this whole idea is ill-guided. I'll thus close ticket #1133 as wontfix

Conflicts:
	src/lib/dependable-base.hpp
2018-04-01 04:52:50 +02:00
f0eeafddaa Identified some problems regarding static destruction
When some dependency or singleton violates Lumiera's policy regarding destructors and shutdown,
we are unable to detect this violation reliably and produce a Fatal Error message.
This is due to lib::Depend's de-initialisating being itself tied to template generated
static variables, which unfortunately have a visibility scope beyond the translation unit
responsible for construction and clean-up.
2018-03-31 17:27:13 +02:00
80207ea224 DI: (WIP) switch to totally rewritten new implementation of lib::Depend (#1086)
- state-of-the-art implementation of access with Double Checked Locking + Atomics
- improved design for configuration of dependencies. Now at the provider, not the consumer
- support for exposing services with a lifecycle through the lib::Depend<SRV> front-end
2018-03-31 01:06:06 +02:00
562c14e15d DI: safer to make DependencyFactor noncopyable
...and to use a dedicated function for transferring the definition
2018-03-30 07:57:08 +02:00
cc46c5b04b DI: solve problem with leftover deleter in testmock. Unit test PASS 2018-03-30 07:42:53 +02:00
5d0c2b6d2c DI: special solution for singletons with private default ctor
...which declare DependencyFactory as friend.
Yes, we want to encourrage that usage pattern.

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

A minor twist was spotted though (nice to have more unit tests indeed!):
Sometimes we want to pass a custom constructor *not* as modern-style lambda,
but rather as direct function reference, function pointer or even member
function pointer. However, we can not store those types into the closure
for later lazy invocation. This is basically the same twist I run into
yesterday, when modernising the thread-wrapper. And the solution is
similar. Our traits class _Fun<FUN> has a new typedef Functor
with a suitable functor type to be instantiated and copied. In case of
the Lambda this is the (anonymous) lamda class itself, but in case of
a function reference or pointer it is a std::function.
2018-03-26 07:54:16 +02:00
4d783770d0 Bugfix: CallQueue_test initialisation was not threadsafe (see also #1131)
...which showed up under high system load.
The initialisation of the member variables for the check sum
could be delayed while the corresponding thread was already running
2018-03-26 04:40:54 +02:00
942bad5d0a DI: document the reworked Singleton / Dependency-Factory
- polish the text in the TiddlyWiki
 - integrate some new pages in the published documentation
   Still mostly placeholder text with some indications
 - fill in the relevant sections in the overview document
 - adjust, expand and update the Doxygen comments

TODO: could convert the TiddlyWiki page to Asciidoc and
      publish it mostly as-is. Especially the nice benchmarks
      from yesterday :-D
2018-03-25 09:33:57 +02:00
7a250ca9e5 DI: benchmark atomic locking 2018-03-24 11:02:44 +01:00
d78211a9a1 DI: implement C++11 solution of Double-Checked-Locking with std::atomic + Mutex
This solution is considered correct by the experts.

Regarding the dependency-configuration part, we do not care too much about performance
and use the somewhat slower default memory ordering constraint
2018-03-24 11:02:44 +01:00
f05ec78e08 DI: benchmark Double-Checked-Locking with Mutex
This is essentially the solution we used since start of the Lumiera project.
This solution is not entirely correct in theory, because the assignment to the
instance pointer can be visible prior to releasing the Mutex -- so another thread
might see a partially initialised object
2018-03-24 11:02:44 +01:00
ff256d9e57 DI: benchmark naive lock protected access
...which gives us the dramatic numbers we'd expect.
Especially the multithreaded variant contends drastically
2018-03-24 11:02:43 +01:00
d2dababf5c DI: benchmark dependency-factory with unprotected lazy init
NOT threadsafe.
Indeed, crashed several times during the multithreaded benchmark runs
2018-03-24 08:29:39 +01:00
69f21d96af DI: prepare benchmark of reference cases
_not_ using the dependency factory, rather direct access

 - to a shared object in the enclosing stack frame
 - to a heap allocated existing object accessed through uniqe_ptr
2018-03-24 07:48:59 +01:00
3104016cf2 DI: set up framework for investigation of performance impact
We are about to switch to Double Checked Locking with C++11 atomics,
and we want some rough numbers regarding the Impact
2018-03-23 23:42:10 +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
f66d452c56 DI: refurbish internal access for the configuration handles
explicit friendship seems adequate here
DependInject<SRV> becomes more or less a hidden part of Depend<SRV>,
but I prefer to bundle all those quite technical details in a separate
header, and close to the usage
2018-03-19 01:14:52 +01:00
b776ce568f DI: fix inspiring Segfault
a bloody closure that bangs itself away....
2018-03-19 00:44:26 +01:00
f0c8928301 DI: draft implementation for testmock support 2018-03-19 00:05:02 +01:00
786f051132 DI: problem of misconfiguration for service access
This is a tricky problem an an immediate consequence of the dynamic configuration
favoured by this design. We avoid a centralised configuration and thus there
are no automatic rules to enforce consistency. It would thus be possible
to start using a dependency in singleton style, but to switch to service
style later, after the fact.

An attempt was made to prevent such a mismatch by static initialisiation;
basically the presence of any Depend<SRV>::ServiceInstance<X> would disable
any usage of Depend<SRV> in singleton style. However, such a mechanism
was found to be fragile at best. It seems more apropriate just to fail
when establishing a ServiceInstance on a dependency already actively in
use (and to lock usage after destroying the ServiceInstance).

This issue is considered rather an architectural one, which can not be
solved by any mechanism at implementation level ever
2018-03-18 17:19:30 +01:00
5516700523 DI: draft configuration for using a service implementation created elsewhere 2018-03-18 02:11:46 +01:00
9f93154f62 DI: draft configuration for using a subclass Singleton 2018-03-18 01:30:51 +01:00
e1ca9f447b DI: draft syntax for special dependency injection configuration 2018-03-18 00:57:25 +01:00
eebe31aa7e DI: change to heap allocation for singletons
up to now we used placement into a static buffer.
While this approach is somewhat cool, I can't see much practical benefit anymore,
given that we use an elaborate framework which rules out the use of Meyers Singleton.
And given that with C++11 we're able just to use std::unique_ptr to do all work.

Moreover, the intended configurability will become much simpler by relying
on a _closure_ to produce a heap-allocated instance for all cases likewise.

The only possible problem I can see is that critical infrastructure might
rely on failsafe creation of some singleton. Up to now this scenario
remains theoretical however
2018-03-17 23:41:56 +01:00
e393d44e92 DI: replace Meyers Singleton by an explicitly managed buffer
Meyers Singleton is elegant and fast and considered the default solution
However...

 - we want an "instance" pointer that can be rebound and reset,
   and thus we are forced to use an explicit Mutex and an atomic variable.
   And the situation is such that the optimiser can not detect/verify this usage
   and thus generates a spurious additional lock for Meyers Singleton

 - we want the option to destroy our singletons explicitly
 - we need to create an abstracted closure for the ctor invocation
 - we need a compiletime-branch to exclude code generation for invoking
   the ctor of an abstract baseclass or interface

All those points would be somehow manageable, but would counterfeit the
simplicity of Meyers Singleton
2018-03-17 17:30:28 +01:00
261049e04d DI: minimalistic design for service access
Problems:
 - using Meyers Singleton plus a ClassLock;
   This is wasteful, since the compiler will emit additional synchronisation
   and will likely not be able to detect the presence of our explicit locking guard

 - what happens if the Meyers Singleton can not even be instantiated, e.g. for
   an abstract baseclass? We are required to install an explicit subclass configuration
   in that case, but the compiler is not able to see this will happen, when just
   compiling the lib::Depend
2018-03-17 03:36:58 +01:00
28176c58ed DI: drafts towards a new dependency factory design 2018-03-16 03:57:02 +01:00
2bc6b398ea DI: thoughts regarding the design of the dependency configuration 2018-03-15 04:24:03 +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
9ca9b1b89a ViewSpec: clarify how the inline DSL spec is transformed into a rule set
several nested repackaging ctor calls here.
In the end, it's an UICoord array, which is moved into heap storage within the rules set
2018-03-05 00:56:43 +01:00
69f87e994c ViewSpec: decide how to cast the types for building the DSL
we'll use a typedef to represent the default case
and provide the level within the UI-Tree as template parameter for the generic case

This avoids wrapping each definition into a builder function, which will be
the same function for 99% of the cases, and it looks rather compact and natural
for the default case, while still retaining genericity.

Another alternative would have been to inject the Tree-level at the invocation;
but doing so feels more like magic for me.
2018-02-24 04:25:41 +01:00
41b8d12b66 ViewSpec: reconsider how to build and structure the DSL (#1126)
...in the light of all the foundation components and frameworks created meanwhile
2018-02-23 05:07:39 +01:00
b6360b2e9c LocationSolver: automatically inject persp(UIC_ELIDED) (closes #1128)
decided to add a very specific preprocessing here, to make the DSL notation more natural.
My guess is that most people won't spot the presence of this tiny bit of magic,
and it would be way more surprising to have rules like

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

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

What *could* be done though is to inject that UIC_ELIDED marker
on missing perspective specs in create clauses automatically...
2018-02-16 07:34:48 +01:00