Commit graph

94 commits

Author SHA1 Message Date
1705c40dc2 Invocation: rearrange SeveralBuilder policy
redefine the policy for `lib::SeveralBuilder` to be a template-template parameter.
In fact it should have been this way from start, yet defining this kind of
very elaborate code bottom-up lets you sometime miss the wood for the trees

So to restate: `lib::SeveralBuilder` takes a ''policy template,''
which then in turn will be instantiated with the same types `I` (interface)
and `E` (element type) used on `SeveralBuilder` itself. Obviously, there can be
further types involved and thus additional type parameters may be necessary,
notably the ''Allocator'' — yet these are better injected when ''defining''
the policy template itself.

The default binding for this policy template is defined as `allo::HeapOwn`,
which causes the builder to allocate the storage extents through the standard
heap allocator, and for the created `lib::Several` to take full ownership of
embedded objects, invoking their destructors when falling out of scope.
2024-07-17 01:43:17 +02:00
2fd3629d80 Invocation: difficulties with defining a suitable DataBuilder
As a direct consequence of the insights regarding Dependency-Injection,
a ''Builder Toolkit'' is required, which can be used to adapt various
kinds of ''Weaving Patterns'' — since obviously it is not possible to
settle down on a single Pattern, and thus several ''families of builders''
will emerge, one for each ''line of construction'' for ''Weaving Patterns''.

To stress this point, what I am coding here is a prototype, aimed at
being used as part of a **Test Domain Ontology** — and other Domain Ontologies
(e.g. für FFmpeg) will certainly require other construction schemes
for their Weaving Patterns. So this is an open field, and can not be
settled once and for all.

This immediately leads to another, rather technical problem:
If we're about to work with ''delegate Builders,'' then also
a way to pass-down the allocator configuration is required.

We had settled on a preliminary solution with the helper `DataBuilder`,
yet this solution looks like it defines how `lib::SeveralBuilder`
should be used in most of the cases. So there is now a conflict
between the existing definition scheme for `lib::SeveralBuilder`,
which was achieved in a bottom-up way, and a slightly different
definition scheme ''as it should be''

Starting to attack this latter detail problem, as a first step,
the definition of `DataBuilder` can be simplified by collapsing
it with the `lib::allo::SetupSeveral`
2024-07-17 02:35:05 +02:00
fc9ff9252a Invocation: clarify role of Buffer-Descriptor and Dependency-Injection
It became clear that a secondary system of connections must be added,
running top-down from a global model context, and thus contrary to the
regular orientation of the node network, which connects upwards from
predecessor to successor, in accordance with the pull principle.

If we accept this wiring as part of the primary structure, it can be
established immediately while building the nodes, thus adding a preconfigured
''pattern of Buffer Descriptors'' to each node, since there is no further
''moving part'' — beyond the wiring to the `BufferProvider`, which thus
becomes part of a global `ModelContext`

As an immediate consequence, the storage for this configuraion should
also be switched to `lib::Several` and handled similar to the primary
node wiring in the Builder...
2024-07-15 18:52:59 +02:00
968bfb8fab Invocation: look for ways how to build the Turnout
It seems we need a `WeavingPattern`-Builder, which obviously
must be rather flexible, since those patterns are to be composed
from several layers, which should be extensible within a given ''Domain Ontology''

So this seems to lead to a builder-DSL which creates »**onion layers**«
of builders, with the ability to extend and specialise the type on each layer.

''As it will be quite challenging to get this into usable shape,
it seems best to approach this step by step through prototyping...''
2024-07-15 02:26:53 +02:00
95046489d2 Invocation: release buffer after completed calculation
Not entirely sure how to use the `emit()` call properly,
assuming that it means that data is complete in buffer,
but can still be read after that point
2024-07-15 00:36:20 +02:00
133dd9e8ce Invocation: now able to implement connecting of buffers
* at least for a simple, prototypical setup
 * and actually shifting the onerous into the Level-1 builder \\
   ''(which is precisely the intention here)''
2024-07-12 03:06:11 +02:00
1955d28087 Invocation: use introspection to setup an example
The deeper problem is that we must not engage into any premature decisions
regarding the structure or layout of the actual processing function invocation.

Thus attempting to create a kind of »firewall« of sorts, by connecting
the building blocks strictly through template parameter and preferably
figuring out any detailed knowledge locally, through ''compile-time introspection...''
2024-07-11 18:35:17 +02:00
e7b68427d3 Invocation: look for ways to build an example InvocationAdapter
...even the initial effort to stub its operation turns into a
challenge, since honestly there is near nothing we can assume safely,
without sliding into uncovered provisions regarding the ''Domain Ontology''
2024-07-11 16:31:11 +02:00
0d7d4b5afa Invocation: consider how to arrange the InvocationAdapter
- it is clear that this adaptor will be a ''Concept''
- yet it must in some way access the `FeedManifold` and also control additional storage
- a rather obvious solution is to layer it ''on top'' of the manifold
2024-07-11 02:41:33 +02:00
ec65e2b7b9 Invocation: continue draft of a simple 1:1 WeavingPattern
...which brings about various (preliminary) decisions regarding
Metadata storage in the `Turnout`-object, which acts as a guidance
and specification for the actual invocation for this specific node.

As starting point, I choose the ''KISS'' solution of embedding some
blocks of `UninitialisedStorage` directly into the `Turnout`; obviously
these blocks must be oversized, since we can not effort emitting a
dedicated template instance for each different count of input / output
feeds. Moreover, these data buffers are assumed to be filled with
valid objects by the builder ''(this is a lurking danger)''
2024-07-10 03:35:51 +02:00
0b938320ea Invocation: draft a simplified prototype for an invocation
...attempt to somehow get my foot into the door...
2024-07-09 21:06:38 +02:00
3d6515acca Invocation: further analysis of invocation structure
...turns out that the intended structure is still too fine grained
and explicit and many operational steps can be collapsed into a single
virtual scope, wherein they can be deemed implementation detail...
2024-07-09 18:03:13 +02:00
d09b061434 Invocation: add nested builder to configure a port
...which brings us right into the middle of the task of building a Turnout...
2024-07-08 19:24:03 +02:00
d3344e7dd3 Invocation: improve notation by using a wrapper
...so the solution is to build up the working data as `lib::SeveralBuilder`;
however, a more concise notation can be achieved with a suitably configured
wrapping subclass; together with the cross-builder trick, this allows
to write the allocation configuration in a clearly libelled way,
while the field definition and the builder constructor hides the
complexities of picking up the extension point and passing on the
wiring to the allocator instance.
2024-07-08 05:41:31 +02:00
d291853174 Invocation: add cross-builder to inject a specific (node) allocator
...using the same pattern here as was successful also for the underlying lib::SeveralBuilder;
even if it may seem logically backwards, it just reads much better and
is more understandable, and has the added benefit of providing a dedicated
definition scope, which can be kept separate from the constructor definition
of the actual builder

{{{
  prepareNode()
    .withAllocator<XYZ>()
    .addLead(predecessor)
    .build()
}}}
2024-07-08 04:45:16 +02:00
cedb1830dc Invocation: work out solution for builder initialisation
...turns out to be surprisingly tricky, since the nested
lib::SeveralBuilder instances require parametrisation by a
''policy template,'' which in turn relies on the actual allocator.
And we want to provide the allocator as a constructor parameter,
including the ability to pick up a custom specialisation for
some specific allocator (notably AllocationCluster requires
to hook into this kind of extension point, to be able to
employ its dedicated API for dynamic allocation adjustment)
2024-07-08 03:56:38 +02:00
58a955a879 Invocation: first draft of the node builder invocation 2024-07-06 21:31:03 +02:00
7c554caf08 Invocation: clarify further requirements for the Level-2 builder
...especially what is necessary to represent at this level and what information
is implicit; notably there will be an implicit default wiring, but we allow
for case-by-case deviations
2024-07-06 04:37:36 +02:00
1f7ddbe5ec Invocation: draft possible syntactic structure based on these conjectures
The Builder will have to perform several passes, gradually refining
the model into the low-level Render Node network. Right now, some
guesses regarding the last steps of this process are possible,
thus defining the lowest level of a model builder structure
 * Level-3 : mapping data flow paths
 * Level-2 : detailed configuration of data buffer passing
 * Level-1 : build the actual parameter structures for invocation

In the current »Vertical Slice« we're able to fully define Level-1
and maybe Level-2
2024-07-06 01:28:18 +02:00
ce9bf7f143 Invocation: conjectures pertaining an implementation of Node-Graph generation
To escape a possible deadlock in analysis, I resort to developing
some kind of free-wheeling presupposition how the **Builder** could
be implemented — a centrepiece of the Lumiera architecture envisioned
thus far — which ''unfortunately'' can only be planned and developed
in a more solid way ''after'' the current »Vertical Slice« is completed.

Thus I find myself in the uncomfortable situation of having to work towards
a core piece, which can not yet be built, since it relies heavily on
the very structures to be built...
2024-07-06 01:13:23 +02:00
604c4b580b Invocation: painstaking analysis of calculation requirements
...the complexity of details is a nightmare
...still fighting to grasp a generic structure allowing to ''fold down''
   the details into the specific ''domain ontologies'' for the media libraries
2024-07-03 04:34:04 +02:00
8c536fc637 Invocation: consider what is required to setup a FeedManifold
...and this line of analysis brings us deep into the ''Buffer Provider''
concept developed in 2012 — which appears to be very well to the point
and stands the test of time.

Adding some ''variadic arguments'' at the right place surprisingly leads
to an ''extension point'' — which in turn directly taps into the
still quite uncharted territory interfacing to a **Domain Ontology**;
the latter is assumed to define how to deal with entities and relationships
defined by some media handling library like e.g. FFmpeg.
So what we're set to do here is actually ''ontology mapping....''
2024-06-29 04:22:23 +02:00
717af81986 Invocation: Identify parts relevant for a node builder
The immediate next step is to build some render nodes directly
in a test setting, without using any kind of ''node factory.''
Getting ahead with this task requires to identify the constituents
to be represented on the first code layer for the reworked code
(here ''first layer'' means any part that are ''not'' supplied
by generic, templated building blocks).

Notably we need to build a descriptor for the `FeedManifold` —
which in turn implies we have to decide on some fundamental aspects
of handling buffers in the render process.

To allow rework of the `ProcNode` connectivity, a lot of presumably obsoleted
draft code from 2011 has to be detached, to be able to keep it in-tree
for further reference (until the rework and refactoring is settled).
2024-06-25 04:54:39 +02:00
9f233f1e90 Invocation: Detail-planning of node invocation
* consider which operations to provide where
 * collect components to be built for a basic node wiring
 * define an entrance point for node invocation
2024-06-23 19:40:43 +02:00
17dcb7495f Invocation: establish a concept for the rework
As outlined in #1367, the integration effort requires some rework
of existing code, which will be driven ahead by the `NodeLinkage_test`
 * redefine Node Connectivity
 * build simple `ProcNode` directly in scope
 * create an `TurnoutSystem` instance
 * perform a ''dummy Node-Invocation''
2024-06-21 16:22:58 +02:00
c0d5341b15 Invocation: capture idea for sharpened invocation structure
- the starting point is the idea to build a dedicated ''turnout system''
- `StateAdapter`, `BuffTable` ⟶ `FeedManifold` and _Invocation_ will be fused
- actually, the `TurnoutSystem` will be ''pulled'' and orchestrate the invocation
- the structure is assumed to be recursive

The essence of the Node-Invocation, as developed 2009 / 2011 remains intact,
yet it will be organised along a clearer structure
2024-05-12 17:27:07 +02:00
bd9527716a Invocation: segregate first and second buffer feed implementation
Within the existing body of code, there are two unfinished attempts
towards building a node invocation and management of data buffers.

The first attempt was entirely driven from the angle of invoking a
processing function, while the second one draws from a wider scope
and can be considered the solution to build upon regarding data buffers
in general. However, the results of the first approach are well suited
for their specific purpose, so both solutions will be combined.

Thus the arrangement of data feeds going in and out of the render node
shall be renamed into `BuffTable` -> `FeedManifold`
2024-05-11 17:06:12 +02:00
9a435a667e Invocation: start with some rename-refactorings
... to plot a clearer understanding of the intended usage
2024-05-11 16:39:58 +02:00
bb3d565436 Invocation: Reassessment of existing code
...which seems to be basically fine thus far
...beyond some renaming and rearranging

''it turns out that the final, crucial links,
necessary to tie all together, are yet to be developed''
2024-05-05 15:12:23 +02:00
47e26e2a65 Invocation: initial considerations...
Looks like some code archaeology is required
to sort apart the various effort to get this topic started....
2024-04-21 02:58:30 +02:00
a90b9e5f16 Library: uniform definition scheme for error-IDs
In the Lumiera code base, we use C-String constants as unique error-IDs.
Basically this allows to create new unique error IDs anywhere in the code.

However, definition of such IDs in arbitrary namespaces tends to create
slight confusion and ambiguities, while maintaining the proper use statements
requires some manual work.

Thus I introduce a new **standard scheme**
 * Error-IDs for widespread use shall be defined _exclusively_ into `namespace lumiera::error`
 * The shorthand-Macro `LERR_()` can now be used to simplify inclusion and referral
 * (for local or single-usage errors, a local or even hidden definition is OK)
2024-03-21 19:57:34 +01:00
c5679b0fd0 Library: Uninitialised-Storage array (see #1204)
Introduced as remedy for a long standing sloppiness:
Using a `char[]` together with `reinterpret_cast` in storage management helpers
bears danger of placing objects with wrong alignment; moreover, there are increasing
risks that modern code optimisers miss the ''backdoor access'' and might apply too
aggressive rewritings.

With C++17, there is a standard conformant way to express such a usage scheme.
 * `lib::UninitialisedStorage` can now be used in a situation (e.g. as in `ExtentFamily`)
   where a complete block of storage is allocated once and then subsequently used
   to plant objects one by one
 * moreover, I went over the code base and adapted the most relevant usages of
   ''placement-new into buffer'' to also include the `std::launder()` marker
2023-12-02 23:56:46 +01:00
cb15b43489 Library/Application: keep DummyPlayer compilable (see #1342)
code must still be kept around as point of reference for integrating the Player
2023-10-05 03:21:51 +02:00
ab7f506f4b Activity-Lang: failure will certainly not be signalled to the Job
doing so would contradict the fundamental architecture,
all kinds of failures and timeouts need to be handled within
Scheduler-Layer-2 rather.

Jobs are never aborted, nor do they need to know if and when they are invoked
2023-08-15 17:18:30 +02:00
3169ba88ad Scheduler: devise the arrangement of basic components
- define organisation of vault-layer namespaces
- define the ground plan of the scheduler implementation
2023-06-24 03:14:17 +02:00
130bc095d9 the new design takes the old name
The second design from 2017, based on a pipeline builder,
is now renamed `TreeExplorer` ⟼ `IterExplorer` and uses
the memorable entrance point `lib::explore(<seq>)`

✔
2023-06-22 20:23:55 +02:00
d109f5e1fb bye bye Monad (closes #1276)
after completing the recent clean-up and refactoring work,
the monad based framework for recursive tree expansion
can be abandoned and retracted.

This approach from functional programming leads to code,
which is ''cool to write'' yet ''hard to understand.''

A second design attempt was based on the pipeline and decorator pattern
and integrates the monadic expansion as a special case, used here to
discover the prerequisites for a render job. This turned out to be
more effective and prolific and became standard for several exploring
and backtracking algorithms in Lumiera.
2023-06-22 20:23:55 +02:00
8c78e50730 Job-Planning: extended deadline integration test
- allow to configure the expected job runtime in the test spec
- remove link to EngineConfig and hard-wire the engine latency for now

... extended integration testing reveals two further bugs ;-)
... document deadline calculation
2023-06-21 04:04:11 +02:00
1f840730a0 Job-Planning: build and verify complete pipeline
- strip the builder
- add a terminal / front-end with convenience functions
- verify integration, incl multi-step prerequisites and deadlines
2023-06-20 01:46:44 +02:00
848bb6fb86 Job-Planning: implement handling of deadlines for prerequisites
...simple implementation
...decide *not* to cache the deadlines for now (possibly quadratic!)
...Test GREEN
2023-06-19 18:28:01 +02:00
dc1bbfc918 Job-Planning: rework pipeline to enable dependency planning
This finishes the last series of refactorings; the basic concept
remains the same, but in the initial version we arranged the expander
function in the pipeline to maintain a Tuple (parent, child) for the
JobTickets. Unfortunately this turned out to be insufficient, since
JobTicket is effectively const and responsible for a complete Sement,
so there is no room to memorise a Deadline for the parent dependency.

This leads to the better idea to link the JobPlanning aggregators
themselves by parent-child references, which is possible since the
whole dependency chain actually sits in the stack embedded into the
Expander (in the pipeline)
2023-06-19 03:56:11 +02:00
9ef3d98de7 Job-Planning: replace FrameCoord by direct references
...in the hope that the Optimiser is able to elide those references entirely,
when (as is here the case) they point into another field of a larger object compound
2023-06-19 01:51:48 +02:00
a1c1456849 Job-Planning: dispose of FrameCoord in pipeline and Dispatcher interface
...as a preparation for solving a logical problem with the Planning-Pipeline;
it can not quite work as intended just by passing down the pair of
current ticket and dependent ticket, since we have to calculate a chained
calculation of job deadlines, leading up to the root ticket for a frame.

My solution idea is to create the JobPlanning earlier in the pipeline,
already *before* the expansion of prerequisites, and rather to integrate
the representation of the dependency relation direcly into JobPlanning
2023-06-18 03:50:48 +02:00
661d768fad Job-Planning: frame number now additionally required in FrameCoord
...which was the reason why the test failed;
the calculation works as expected


PS: rename JobPlanningSetup_test to JobPlanningPipeline_test
2023-06-17 03:10:57 +02:00
6228c623b4 Job-Planning: implement braindead deadline calculation
...using hard coded values instead of observation of actual runtimes,
but at least the calculation scheme (now relocated from TimeAnchor to JobPlanning)
should be a reasonable starting point.

TODO: test fails...
2023-06-16 04:09:38 +02:00
73a9e4495a Job-Planning: code up simplest use case 2023-06-16 01:50:11 +02:00
b9f8356afc Job-Planning: investigate input data
- collect list of entities to be picked up from the dispatcher-pipeline
- as it turns out: there is no sensible use for the realTimeDeadline in
  in the FrameCoord record ==> remove it
2023-06-15 18:24:25 +02:00
a551314e80 Job-Planning: start rework of the planning data aggregation
The initial implementation effort for Player and Job-Planning
has been reviewed and largely reworked, and some parts are now
obsoleted by the reworked alternative and can be disabled.

The basic idea will be retained though: JobPlanning is a
data aggregator and performs the final step of creating a Job
2023-06-15 03:51:07 +02:00
08dfe1007c Dispatcher-Pipeline: verify the expansion of prerequisites
- fix a bug in the MockDispatcher, when duplicating the ExitNodes.
  A vector-ctor with curly braces will be interpreted as std::initializer_list

- add visualisation of the contents appearing at the end of the pipeline

*** something still broken here, increments don't happen as expected
2023-06-14 04:20:50 +02:00
542017aa65 Dispatcher-Pipeline: mocked Dispatcher implementation complete (closes: #1294)
`steam/engine/mock-dispatcher.hpp |cpp` now integrates this
''complete mock setup for render jobs and frame dispatching.''
The exising `DummyJob` has been slightly adapted and renamed
to `MockJob` and is tightly integrated with the other mocks.

The implementation of a `MockDispatcher` necessitated to change
the use of `MockJobTicket`. The initial attempts used a complete
mock implementation, but this approach turned out not to be viable.
Instead — based on the ideas developed for the mock setup —
now the prospective real implementation of `JobTicket` is available
and will be used by the mock setup too. Instead of a synthetic spec,
now a setup of recursively connected `ExitNode`(s) is used; the latter
seems to develop into some kind of Facade for the render node network.

Based on this mock setup, we can now demonstrate the (mostly) complete
Job-Planning pipeline, starting from a segmentation up to render jobs,
and verify proper connectivity and job invocation.
✔
2023-06-13 20:23:33 +02:00