Commit graph

6975 commits

Author SHA1 Message Date
a68f145640 Upgrade: fix test-failures(3)
The Boost-Libraries changed their internal implementation
of the formula to chain hash values.

Fortunately, we had already extracted the existing implementation
from Boost 1.67 and incorporated it in-tree, in the Lumiera support libary.
After switching to that `lib:#️⃣:combine()` function, all the graph
computations related to the Scheduler-test-load can be shown to be identical.

So at the moment, the impact is still limited, but this incident highlights
the importance of a controlled, stable (and ideally also portable) hash implementation.
2025-04-25 19:54:28 +02:00
4ce936529e Upgrade: fix test-failures(2)
seems that I've played too much with »undefined behaviour« in this test;
basically we can not assume ''any'' specific placement of local variables
in a stack frame....

In this test, what I wanted to demonstrate is that the overflow-block can reside
just »anywhere«, and that HeteraoData is just a light-weight front-End and accessor.

However, I can just demonstrate that without totally ''undefined behaviour;''
placement-new can be used to force the storage at a specific location (in the UninitialiesdStorage);
continue to access and use that data after leaving the nested scope is still
kind-of borderline, yet demonstrates that the data itself is just residing in a storage block...
2025-04-25 19:02:04 +02:00
1d3cb6b23b Upgrade: fix test-failures (1)
- with Debian 12/13, the top-level `/bin`, `/sbin` and `/lib`
  are collapsed into `/usr`. Seemingly this has prompted changes
  to the way the shell prints some error messages. This broke
  the expectation of some test of the test-framework itself.

- SCons always had the policy to ''sanitise'' the invocation environment,
  to prevent unintended impact of environment settings to the test subject.
  Seemingly this now also leads to `$HOME` not being defined.
  Our file handling framework however expects to be able to expand "~"

- An old-style cast in the constructor lib::diff::Record(Mutator const&)
  is now translated into a static_cast (≙conversion); and since the appropriate
  conversion operator is missing on Mutator, the constructor attempts to
  create a temporary, by re-invoking the same constructor ⟹ Stackoverflow ↯
2025-04-24 23:39:58 +02:00
96c654f66c Upgrade: address further warnings
- conversion from pointer to bool now counts as ''narrowing conversion''
 - constructor names must not include template arguments (enforced with C++20)
 - better use std::array for some dummy test code

Several further warnings are due to known obsoleted or questionable constructs
and were left as-is (e.g. for ScopedHolder) or just commented for later referral
2025-04-15 23:40:14 +02:00
47f5390b18 Upgrade: address warnings -- shaddowing overloaded-virtual
This is an advanced diagnostics added (presumably) with GCC-13
and attempts to protect against an insidious side-effect of ''overload resolution''

Basically C++ (like its ancestor C) is oriented towards direct linkage and adds
the OO-style dynamic dispatch (through virtual functions and a VTable)
only as an extension, which must be requested explicitly.

Thus the resolution of ''overloads'' (as opposed to ''overridden'' virtual functions)
always takes precedence and happens within the directly visible scope,
which can cause the compiler to perform an implicit conversion instead of
invoking a different virtual function, which is defined in a base class.

However, this diagnostics seems to be implemented in an overly zealous way:
The compiler warns at the time of the type instantiation, and even in cases
where it is effectively impossible to encounter this dangerous shadowing situation.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740

This leads to several ill-guided warnings in the Lumiera code base, which unfortunately
can only be addressed by disabling this diagnostics for all usages of some header.
The reason is, we often generate chains of template instantiations driven by type lists,
and in such usage pattern, it is not even possible to bring all the other inherited overloads
into scope (with a using `BASE::func` clause), because such a specification would be ambiguous
and result in a real compile error, because even the interface is generated from a chain of mix-in templates
2025-04-15 22:42:34 +02:00
bf6532a69d Upgrade: address warnings -- deprecated implicit copy
Future C++ versions will no longer generate default copy operations
once any single one was defined explicitly. So the goal is to kind-of
''enforce the rule of five'' (if you define one, define them all).

However, sometimes one of these special operators must be defined for a different reason,
e.g. because it is defined as protected, yet should not be exposed on the public API.
In such cases, any other copy operation which still is valid in the default form
must be declared explicitly ''as defaulted''

Overall this seems to be quite an improvement --
and it highlights (again) some known instances of questionable design,
which are mostly obsoleted and require clean-up anyway, or (as in the case of the
Placements) indicate »placeholder code« where the actual solution still needs to be worked out
2025-04-15 18:32:52 +02:00
2ff28236f6 Upgrade: address warnings -- pessimizing-move
Oh this is an interesting one...
GCC now highlights situations with `-Wpessimizing-move`,
where an overly zealous developer attempts to optimise by `std::move`,
which however prevents the compiler from applying the ''Return Value Optimisation''

The latter is mandatory since C++17, and essentially means that a value object
created within a function and then returned (by value) will actually be created
directly in the target location, possibly eliding a whole chain of
delegating value returns.

Thus: if we write `std::move(value)`, we change the returned type into an RValue reference,
and thereby ''force the compiler'' to invoke a move-ctor....
2025-04-15 16:46:00 +02:00
6c627d83dc Upgrade: address warnings -- obsoleted features
Some pre C++11 features are marked deprecated and will be rejected with C++20

Notably the old marker inferfaces for unary (and binary) functions are no longer needed, since function-like objects can be detected by traits or concepts nowadays

Moreover we can get rid of some boost(bind) usages and use a λ
2025-04-15 14:09:32 +02:00
92c99e5b7d Upgrade: re-enable Doxygen generation
The new version indeed works as expected,
and current Doxygen produces much better cross links
:-)
2025-04-08 05:07:58 +02:00
425f7b3f21 Upgrade: Scons Doxygen Builder from 2022
A long time ago, we grabbed this plug-in from the Scons Wiki.
The latest version from 2022-07-31 was upgraded to Python-3

Note: this merge retains our reformatted copyright header
      and the addition of a ",doxylog" file in the target dir
2025-04-08 04:17:57 +02:00
7b7821c0ee MERGE: bring in the latest Scons Doxygen Builder
Actually, the Lumiera project picked an early version of this tool in August 2008.
See the commits:
6d5cf0e642
9643f46cc8

This subtree add/merge commit brings in a consolidated history of the Scons Doxygen code
from the scons-contrib repository, combined with the old Mercurial history.

We need a current version of this tool which has been ported to Python-3
2025-04-08 04:04:42 +02:00
37a56bd564 Anchor: Directory for Scons tools 2025-04-08 04:10:02 +02:00
8fe2deed95 Upgrade: allow for build on »Trixie« with GCC-14
* need to upgrade our custom packages to current standards
 * switch those packages from CDBS to dh
 * re-build on Trixie and upgrade the Lumiera DEB-Depot

After these (in detail quite expensive) preparations,
build with Scons and GCC-14 can be started.

Fix some further (basically trivial) compile problems,
uncovered by the improved type checking of modern compilers.

Note: a tremendous amount of warnings (and depreciations) is
also indicated, which will be addressed later....
2025-04-06 18:18:52 +02:00
67fb61298a Upgrade: compile fixes for GCC-12 2025-03-16 16:52:26 +01:00
4131602593 Upgrade: disable doxygen builder (WIP)
BuilderDoxygen and BuilderGCH are external plug-ins,
not developed in this project and probably unmaintained.

TODO: decide how to fix or replace them...
2025-03-16 16:48:14 +01:00
0376fd7376 Upgrade: Fix TypeError in list concatenation
Here is the exact error message for this type of error:
TypeError: can only concatenate list (not "dict_values") to list:
2025-03-16 16:46:44 +01:00
0e8fc5889f Upgrade: comment-out code not supported in Python3
ListType not supported in types.py in Python3
 Why do we require ListType?

To do something like
   if type(item) is ListType:
       ....

But types.py does not have ListType anymore
A solution could be

   if isinstance(item, list):

TODO: WIP-remove these comments and fix the code or replace BuilderGCH
2025-03-16 16:42:37 +01:00
406275abbe Upgrade: adapt to use Scons 4.x which uses Python 3
The build system Scons switched from using Python 2.7 to using
Python 3.x, so the build breaks on, for example, Debian Bullseye.

As a first step use `ato3` to convert Python scripts from 2 to 3.
2025-03-16 16:38:07 +01:00
cc9a1e410a MERGE: prepare for upgrade and release
With the ability to invoke a Render Node graph,
the development on branch `play` reached some kind of milestone
regarding the »Playback Vertical Slice«.

This is a good opportunity to update the reference platform
and upgrade the preview releases and packaging setup accordingly.
This will include adjustments to compile on recent compilers and
upgrade the build system to support Python-3.
2025-03-16 05:09:53 +01:00
efcb456e25 Invocation: ++ Milestone ++ invoke complex render graph
Based on the building blocks developed thus far,
it was possible to assemble a typical media processing chain
 * two source nodes
 * one of these passes data through a filter
 * a mixer node on top to combine both chains
 * time-based automation for processing parameters
As actual computation, hash-chaining on blocks of
reproducible random data was used, allowing to verify
for every data word that expected computations were
carried out, in the expected order.
2025-02-19 23:27:52 +01:00
93812d5a6d Invocation: build a complex Render Node network for integration test
Using basically the same topology as in the preceding test, which focused on connectivity. However, in this case we retrieve actual processing functions from the »Test-Rand« ontology in order to perform hash-chaining computations on full data blocks. And, in addition, a »Param Agent Node« is used.
2025-02-19 19:37:55 +01:00
6c2761b337 Invocation: complement NodeBase_test with simple example
While initially intended as introductory test, it meanwhile
focuses on intricate technical details on the level of
basic building blocks, notably the `FeedManifold`

Now I have added a simple end-to-end demonstration example
how a Render Node is built from scratch, leaving out all
technical details and all convenience front-ends like
the `NodeBuilder` — just one dummy port invoked directly.
2025-02-19 01:30:54 +01:00
8a4060861f Invocation: complete simple test case regarding TurnoutSystem
NodeBase_test demonstrates the building blocks of a Render Node,
and verifies low-level mechanics of those building blocks, which
can be quite technical. At the top of this test however are some
very basic interactions, which serve as an introduction.

__Remark__: renamed the low-level technical dispatch-access
for the parameter-accessors in `TurnoutSystem` to be more obvious,
and added comment (I was confused myself how to use them properly)
2025-02-18 23:55:58 +01:00
b7fc2df478 Invocation: NodeBuilder now handles all cases of partial-closure
This is a crucial feature, discovered only late, while building
an overall integration test: it is quite common for processing functionality
to require both a technical, and an artistic parametrisation. Obviously,
both are configured from quite different sources, and thus we need a way
to pre-configure ''some parameter values,'' while addressing other ones
later by an automation function. Probably there will be further similar
requirements, regarding the combination of automation and fixed
user-provided settings (but I'll leave that for later to settle).

On a technical level, wiring such independent sources of information
can be quite a challenging organisational problem — which however can be
decomposed using ''partial function closure'' (as building a value tuple
can be packaged into a builder function). Thus in the end I was able to
delegate a highly technical problem to an existing generic library function.
2025-02-18 20:42:25 +01:00
e014d88b2c Invocation: complete closure-helper and tests
* now able to demonstrate close-front, close-back and close-argument
 * can also apply the same cases to `std::array`, with input and
   output type seamlessly adapted to `std::array`
2025-02-18 00:24:55 +01:00
89f839854c Invocation / Library: analyse perfect-forwarding in function-closure
__Summary__:
 * the first part to prepare a binding involves creating a mapped tuple,
   with re-ordered elements and some elements replaced by placehoder-markers.
   This part **must not use RValue-References** (doing so would be possible
   only under very controlled conditions)
 * the second part, which transports these mapped-tuple elements into the binder
   ''could be converted to perfect-forwarding.'' This would require to replace
   the `Apply<N>' by a variadic template, delegating to `std::apply` and `std::bind`

With this changeset, I have modernised a lot of typedefs to make them more legible,
and I have introduced perfect-forwarding in the entrance path, up to the point
where the values are passed to `TupleConstructor`.
2025-02-17 23:34:06 +01:00
a5a3d46b6a Invocation: generalise partial-closure cases
With these additions, all conceivable cases are basically addressed.

Take this as opportunity to investigate how the existing implementation
transports values into the Binder, where they will be stored as data fields.
Notably the mechanism of the `TupleConstructor` / `ElmMapper` indeed
''essentially requires'' to pass the initialisers ''by-reference'',
because otherwise there would be limitations on possible mappings.

This implies that not much can be done for ''perfect forwarding'' of initialisers,
but at least the `BindToArgument` can be simplified to take the value directly.
2025-02-17 21:18:37 +01:00
0cad2dacc0 Invocation: build a solution to adapt std::array
...which should ''basically work,'' since `std::array` is ''»tuple-like«'' —
BUT unfortunately it has a quite distinct template signature which does not fit
into the generic scheme of a product type.

Obviously we'd need a partial specialisation, but even re-implementing this
turns out to be damn hard, because there is no way to generate a builder method
with a suitable explicit type signature directly, because such a builder would
need to accept precisely N arguments of same type. This leads to a different
solution approach: we can introduce an ''adapter type'', which will be layered
on top of `std::array` and just expose the proper type signature so that the
existing Implementation can handle the array, relying on the tuple-protocol.


__Note__: this changeset adds a convenient pretty-printer for `std::array`,
based on the same forward-declaration trick employed recently for `lib::Several`.
You need to include 'lib/format-util.hpp' to actually use it.
2025-02-17 18:36:23 +01:00
8bb332cc5e Invocation: reorganise and add test 2025-02-16 23:40:43 +01:00
769060b9dd Invocation: extract partial closure functionality
What emerges here, seems to be a generic helper to handle
partial closure of ''tuple-like'' data records. In any case,
this is highly technical meta-programming code and mandates
extraction into a separate header — simplifying `NodeBuilder`
2025-02-16 23:16:46 +01:00
fbf7a792a8 Library: a step towards variadic type sequences (see #987)
Likely the most widely used facility, which enters into meta-programming
with type sequences, is our function-signature-detector `_Fun<X>`,
which returns a argument type-sequence.

After adding some bridges for cross-compatibility,
function-arguments are now extracted as a new-style,
''variadic sequence'' without trailing `NullType`.

Doing so required to augment some of the most widely used
sequence-processing helpers to work seamlessly also with the
new-style variadic sequences with a definition variant based
on variadics, which typically will later-on obsolete the original
solution, which at that time needed to be tediously coded as a
series of explicit specialisations for N arguments.
2025-02-16 21:10:06 +01:00
3611bc94ee Invocation: investigate ways to provide partial application
...on top of the parameter-decorating functionality developed thus far.
The idea is to allow in the `NodeBuilder` to supply ''some parameters''
directly, while the remaining parameters will be drawn from automation.

Several years ago, I developed some helpers for partial function closure.
Unfortunately these utils are somewhat limited, and rely on some pre-C++11
constructs, yet seem to be usable for the task at hand, since parameters
are always expected as value objects by definition.

This changeset shows a working proof-of concept for left-closing a
parameter tuple with 5 elements; this turns out to surprisingly difficult
due to the full genericity of the acceptable parameter-aggregates...
2025-02-15 23:47:21 +01:00
79b45601c0 Invocation: rearrange for clearer definitions
seemingly the definition can not be much simplified,
since there is no way around handling several definition flavours
of the processing-functor distinctly.

However, the definitions can be rearranged to be clearer,
the resulting type of the `FeedPrototype` can be deduced from the
builder function, and more stringent assertions can be added
2025-02-13 16:27:50 +01:00
0e5ffe7780 Invocation: draft a way to decorate the processing-functor
...the idea is to limit the scope of possible changes
and rather directly accept a functor to transform the parameters.
We need then to account for the possible flexibility in processing-functor
arguments, while in fact only two cases must be actually handled.

''This proof-of-concept works in test setup''
2025-02-11 17:15:32 +01:00
61c685fa9f Invocation: draft missing feature for integration test
It seemed that the integration test will end up as a dull repetition
of already coded stuff, just with more ports and thus more boilerplate;
and so I reconsidered what an actually relevant integration test might encompass
- getting parameters from the invocation
- translating and wiring parameters
- which entails to adapt / partially close a processing function!

Thus — surprise — there is a new feature not yet supported by the `NodeBuilder`,
which would be very likely to be used in many real-world use cases: which is
to adapt the parameter tuple expected by the binding from the library.
Obviously we want this, since many »raw« processing functions will expose a mix
of technical and artistic parameters; and we'd like to ''close'' the technical ones.

Such a feature ''should be implementable,'' based on the already developed
technique with the »cross builder«, which implies to switch the template arguments
from within a builder expression. We already do this very thing for adapting
parameter functor, and thus the main difficulty would be to compose an
adaptor functor to the correct argument of the processing functor...

Which is... (well, it is nasty and technical, yet feasible).
2025-02-11 01:10:25 +01:00
8694d9ebc1 Invocation: also provide a mixer node backed by ''Test Rand'' 2025-02-10 22:48:31 +01:00
72d7a6c5b8 Invocation: ''Test Rand'' filter node test pass 2025-02-10 03:41:05 +01:00
ccb10f3c65 Invocation: chase down insidious use-after-free problem
Just wanted to use a helper function to build a source-data node.
However, the resulting node had a corrupted Node-ID spec.
Investigation with the debugger showed that the ID was still valid
while in construction and shows up corrupted after returning from the
helper function.

As it turned out, the reason is related to the de-duplication of ProcID data.
While the de-duplicated strings themselves are ''not'' affected, the corruption
happened by an intermediate instance of ProcID, which was inadvertently created
and bound by-value to the builder-λ. The created Port then picks up a reference
to this temporary, leading to the use-after-free of the string_view obejcts.

Obviously, `ProcID` must not be instantiated other than through the static
front-end `ProcID::describe`. Due to the private constructor, I can not make this
object non-copyable (because then the hash-set would not be allowed to emplace it).
But making it at least move-only will provoke a compiler error whenever binding
to a lambda capture by value, which hopefully helps to pinpoint this
insidious problem in the future...
2025-02-10 03:15:28 +01:00
5121bce156 Invocation: cover definition of a »Test-Rand« filter-node
The scheme to provide preconfigured nodes with random `TestFrame` data
seems to be suitable and easy to extend to further cases; should however
always document the setup through a dedicated case in `NodeDevel_test`
2025-02-09 23:05:41 +01:00
b9b80ce923 Invocation: draft setup for a Test-Node for data-manipulation
Seems to be straight forward now, based on the implementation
of `TestFrame` manipulation provided by the »Test Rand Ontology«


__Remark__: the next goal is to reproduce the complex Node tree
with operations on TestFrame and then to invoke these and verify results.
2025-02-09 18:04:39 +01:00
f767cce77b Invocation: also invoke all these nodes
...while this is not the main objective of this test case,
and another test will focus on invocation with full-fledged
`TestFrame` buffers and hash computation...

...it is still a nice achievement to see that these simple
algebraic operations used for demonstration can actually be
invoked in the whole connected network :-)
2025-02-09 01:44:45 +01:00
d54dbc93df Invocation: verify connectivity on complex network 2025-02-08 22:42:13 +01:00
dbbdac02c4 Invocation: now able to code verifications for the demo-network
Using a Node network with
 * two source nodes
 * one of them chained up linearly with a filter node
 * then on top a mix node to combine both chains

Can now verify the generated port specs and verify proper connections
at node level and at port level
2025-02-08 19:39:00 +01:00
72d7986b5e Invocation: build a DSL to verify connectivity (see #1377)
This was a lot of intricate technical work,
and is now verified in-depth, covering all possible cases.

__We can now__
 * build Nodes
 * verify in detail correct connectivity
 * read Node-IDs and processing specifications
 * maintain a symbolic spec for the arguments of a Port

(and beyond that, we can also **invoke nodes**, which remains to be formally verified)
2025-02-05 00:25:02 +01:00
d5a47bf3e4 Invocation: consider how to verify connectivity
An essential goal still to reach is a verification of the `NodeBuilder`'s products
Relying on the low-level diagnostic facilities pioneered last days,
it should now be possible to define simple and readable connectivity-clauses,
allowing to build some connected nodes and then verify the connections explicitly.
2025-02-04 20:25:33 +01:00
fa720ae975 Invocation: for now only set flags by builder
Handling of extended attributes in conjunction with the hash
turns out to be a rather complicated topic, with some tricky fine details.
And, most important, at the moment I am lacking the proper perspective
to address it and find adequate solutions. Luckily, the cache-key is
not required at the moment, ''and so this topic will be postponed''

As a minimum to complete the diagnostics functions, it is sufficient to set
the appropriate flags in the `ProcID` directly -- and to add some convenience wrappers.
2025-02-04 00:22:55 +01:00
72543a8b34 Invocation: investigate kind of data to be represented in ProcID
...especially the extended attributes remain somewhat nebulous,
since non of the prospective usages are close to being implemented right now.

It seems, we'll get two distinct sources at construction time of the Node
 * additional qualifiers from the Library plug-in
 * internal flags or qualifiers provided by the `NodeBuilder`

Another related concern seems to be generation of cache-keys,
which however will ''consume'' the proc-hash generated by the ProcID,
but not change the ID itself; cache-key generation is a tricky subject
and was somewhat overlooked regarding the connection to the `BufferProvider`.

Opened a new ticket #1292 as reminder for this issue.
2025-02-03 22:10:10 +01:00
583b73bc62 Invocation: now able to access predecessor-ports
...exploiting the ''backdoor access'' bypassing the VTable,
as made possible by a common congruent storage layout.

This is a first proof-of-concept, but also shows that the demo nodes
in NodeMeta_test are wired as expected. What is needed now is to make
this diagnostic access easier to invoke and more bullet-proof, by setting
the proper Attribute bits directly in the `NodeBuilder`
2025-02-03 03:54:21 +01:00
bcdcb36615 Invocation: rearrange MediaWeavingPattern storage layout
...to create an ''access path for diagnostics'' and further evaluations
while ''bypassing the VTable.''

It is a well-known downside of specifically typed, highly optimisable
template-based code to create a dangerous leverage for generating spurious,
mostly identical virtual function instances added for secondary concerns.

Thus it is a consequence of this design choice, either to forego some diagnostic
and analytical possibilities, or to exploit ''other means'' for retrieving
internal data, which is needed for tangential purposes only. The solution
pursued hereby exploits similar layout of various ''weaving pattern''
template instances to create an ''access backdoor'' for use cases
beyond the primary performance-critical path.
2025-02-03 03:27:06 +01:00
ead494e465 Invocation: Argument-spec evaluation sufficiently complete for now
Some additional tests to challenge the parser, which seems to work well.
Without extended analysis into the usage of those node specifications,
it is pointless to expand further on its capabilities. For now, it is
sufficient to have a foundation for hash-computation in place.

__Note__: found a nifty way to give lib::Several an easy toString rendering,
without cranking up the header inclusion load.
2025-02-02 17:22:16 +01:00