Commit graph

2599 commits

Author SHA1 Message Date
75cda5ebc6 BufferProvider: consolidate information passed to BufferStore
This change largely resolves the problems with the storage API,
so that the implementation can now be split in two disjoint segments.
One operation, `mark_emitted()`, is still misplaced on that API, yet
must be retained until the refactoring on the metadata side is complete
(this latter refactoring can not be started sensibly, before the old
»tracking« implementation is cleaned up to care for allocation solely).

With this change, the existing implementation, which combines the
tracking functionality and the allocation, has been squeezed down
into the heap-memory implementation class, yet the tracking functionality
is already detached. The remaining code down there is a huge pile of mess,
that can hopefully be dismantled soon. But at least all of this code
passes the compiler again, and so it should be possible now to focus
on getting the `DiagnosticBufferProvider` up and running, thereby
providing a new clean re-implementation of the diagnostic functions.
2026-02-13 03:12:08 +01:00
925ee0f27e BufferProvider: expand BuffStore API to provide buffer size info
This is an important step to prepare a split of the existing implementation APIs
into a type-management part and a memory-allocation part; generally speaking,
a memory allocator needs to know the allocation size, preferably also for
releasing memory. Up to now, this information could be retrieved locally,
with a metadata lookup through the hash-ID; now we ensure that the
size is always passed alongside through the implementation API.

Incidentally, it looks like we might be able to form a common allocation-descriptor,
to represent this internal API in a more concise way. Note further that
all these changes are considered not relevant for the performance,
since work buffers are large and media computation dominates.
2026-02-12 23:26:16 +01:00
cd415c05aa BufferProvider: implement first strike of diagnostics accessors
...just enough to be able to write the assertions in the first test case
(..and the test case fails still, due to the pending work on sorting out
   the implementation APIs between `BufferStage` und `BufferStore`)
2026-02-12 20:22:11 +01:00
e10aa751bb BufferProvider: design a new diagnostics API
To push ahead with the refactoring,
I will build the test/diagnostics API completely anew,
and attach it solely to an instance of `DiagnosticBufferProvider`.

Unfortunately this ''leads us into chainsaw surgery...''
 * it uncovers a host of conceptual contradictions
 * actually, the `HeapMemProvider` was more an implementation
   of diagnostic tracking, than it was an actual `BufferProvider`
   implementation (hence the old name: `TrackingHeapBlockProivder`)
 * and this lured me into using these tracking functions directly,
   while the `DiagnosticBufferProvider` remained in unfinished state.

So basically I have now **disabled** all verification from the Unit-tests.
I'll have to rebuild them from scratch, thereby reproducing the logic/intention
2026-02-12 05:29:03 +01:00
ace20660aa BufferProvider: analyse the existing API
- write some documentation
 - identify some add-on API that must be retracted
 - consider further how to disentangle ''diagnostics'' and ''implementation''
2026-02-12 05:06:13 +01:00
9c5eb11b0c BufferProvider: switch to the new implementation structure
More or less forcibly squeeze all the existing implementation
into the new basic structure with two separate »pillars«

**Breakages**
 - existing code expected the `BufferStore` to transition to ''locked'' state
 - existing code expected `provideLockedBuffer(typeID)` to tail-call the
   `buildHandle()` function of the enclosing `BufferProvider` base implementation
 - various diagnostic usages bypassed the official APIs and called directly
   into the implementation. This is no longer possible; rather, `DiagnosticBufferProvider`
   needs to provide additional diagnostic API to suit those purposes
2026-02-11 02:13:43 +01:00
a9bdad2c66 BufferProvider: draft a new layout for the implementation
As a consequence of preceding experiments..
 * I'll stick to the structure of the BufferProvider front-end interface
 * also the »code behind« will remain there; a purely abstract API has no merit here
 * however, the ''setup'' of the actual implementation will move into a derived class
 * this derived scope class, `BufferProviderSetup` will house two implementation classes
 * these two, now named `Stage` and `Store` provide the base implementation
   for the two "pillars" of the implementation

Admitted, this structure is now much more elaborate, but it's the only path forward
I'm currently able to come up in order to disentangle the existing implementation mess...
2026-02-10 21:11:02 +01:00
c21ddc1844 BufferProvider: looking for ways to disentangle the implementation (see #1410)
The outward interface has stood the test of time quite well.
But the back-side towards the implementation is a tangled mess,
presumably due to being developed from prototyping code: the
actual implementation is completely overgrown by diagnostics
and test instrumentation, since running in unit test setup
was the only actual usage of this code ever since.

My first attempt with decomposing into a decorator-chain failed.
Thus the new line of attack is to introduce two implementation
pillars right from top-level
- `BufferStage` : the state and metadata handling
- `BufferStore` : the storage backend
These are defined as nested interfaces, and the further refactoring
starts with subclassing everything, nested as it is.
2026-02-10 00:41:41 +01:00
bb6401aaf3 BufferProvider: reshape diagnostics into a decorator
The intention is to build the tracking functionality from scratch,
while wrapping the old implementation as delegate. Hopefully this allows
to reduce the complexity of the existing implementation step by step,
until I'm ''able to grasp what this implementation does''.

This old implementation works, but is highly problematic code.
The Git history shows that I had already problems to understand this code
while building the DiagnosticOutputSlot, one year later.

To my defense, in both cases (2011 and 2012), I had no clear idea yet
how the processing within the engine would work, and thus I considered
that Buffer Type registry a mere implementation detail, that can be
lumped into the »code behind«.
2026-02-09 03:29:06 +01:00
1ebefbe36e BufferProvider: identify usages of the default BufferProvider
The prototype implementations of BuferProvider and OutputSlot are confusing;
in-depth analysis shows that this is related to intermingling use
of test instrumentation and features of a prototypical default.

To get anywhere with the existing code, it seems we'd need to split off
the test instrumentation (i.e. `DiagnosticBufferProvider`) altogether,
even if this causes duplication of implementation code. Many years ago,
when first implementing this prototype, I had no clear idea what the usage
in the Render Engine entails, yet I noticed that some basic buffer »tracking«
could be used as implementation primitive to simplify the prototyping work.
This might be one of the reasons, why the "code behind" in the protocol
implementations both in `BufferProvider` and `OutputSlot` became so strongly
tangled, so that I way unable to make both protocols orthogonally composable.
2026-02-09 00:59:35 +01:00
0f12b19148 BufferProvider: devise a better structure for Engine-context access
`EngineCtx` is considered merely an access front-end now;
After some analysis of existing code, it seems the RenderEnvironment
is the most appropriate framework to configure the global engine services
and thus to ''boot the Render Engine''.

The access to the `EngineCtx` is tricky, because of the requirements
 * it will be dependency-injected into the internals of the Render Nodes
 * excessive indirection should be avioded; preferrably the actual
   code in the render pipeline sees a pointer (coded as language reference)
   which directly refers to the buffer and cache manager.
 * but on the other hand, we want configurability; simple tests shall
   access "the buffer manager" without much ado, while the actual
   render engine obviously has a life cycle and needs an administrative
   access to the various global implementation facilities
 * this both together implies some kind of ''virtual constructor''
 * and since such a pattern can not be implemented in C++ with simple
   inheritance (because the base constructor does not "see" the actual
   implementation type at the time when it's invoked), the solution
   is to rely on a second indirection through our dependency-injection
   framework: thus the setup of the actual implementation is what
   can be configured flexibly, and overridden by mock implementation
   for some test cases
2026-02-08 01:22:35 +01:00
d00992ff70 BufferProvider: start with some requirement analysis
It seems evident that the the problems with the existing BufferProvider implementation
are rooted in a lack of understanding of the actual usage situation at that time(2011).
This caused a »hexagonal design«, i.e. something entirely driven by uint testing
for the sake of unit testing.

So to identify the unsuitable decisions, some degree of deductive work is necessary,
based on our much better understanding of the Render Engine.

A crucial challenge is that buffer management must perform well
within a massively concurrent environment, and do so without excessive latency.
2026-01-25 02:19:30 +01:00
3fe6d5f54c BufferProvider: define standard usage as test case
This picks up the work for [ticket:1395 resolve integration of BufferProvider with DataSink (#1395)]:
Almost a year ago, before the long hiatus due to important general clean-up
and maintenance work, and the research regarding Video output —
a discrepancy was discovered between the »Buffer Provider Protocol«
and the »Output Slot Protocol«. This mismatch prevents us from building
a simple preliminary `BufferProvider` to be used for the engine integration
as part of the [ticket:1228 »Playback Vertical Slice«].

After re-establisihing the work context, I have read through the new
Render Node code built last year, and distilled the sequence of
buffer management operations that actually happen during a recursive
`pull()` call. With this kowledge, I am now able to fill in the
''standard case for rendering'' — which I was unable to formulate
during the first attempt of building the Render Engine in 2011.

__Next Steps__: Redesign of the standard implementation base of the
`BufferProvider` to prepare for a massively concurrent usage.
2026-01-24 15:13:16 +01:00
1986850fa3 Infrastructure: Webserver upgrade and maintenance completed
...some notes to my personal mindmap.

- Webserver OS upgrade
- Clean-up of services and cronjobs
- Apache configuration updated and fine-tuned
- deployed Anubis to protect against overload by AI-scraper bots
2026-01-23 03:45:52 +01:00
b22ffdacb6 Infrastructure: evaluate Anubis -- document setup 2026-01-13 02:34:27 +01:00
1f0b8085e3 Infrastructure: document simple webserver load monitoring 2026-01-11 02:30:17 +01:00
9df85992ee Infrastructure: upgrade and document the Lumiera Trac 2026-01-08 23:16:29 +01:00
5289e43066 Some notes regarding the next topic: buffer management 2025-12-17 21:49:53 +01:00
bd48b17f70 Status: Release published -- now again in Development Phase
Hereby I introduce a ''Development Status'' page, where the
current phase of the release cycle can be marked and similar
status information is published. This page also includes
the Changelog (from the file NEWS). Since updates must
be checked into Git and then pushed to our website,
such status marks are documented in the history.

Some notes regarding the phases of the Release cycle
were also added to the Release checklist.

+ some additional links resources and documentation tweaks
2025-12-11 05:11:55 +01:00
d0f7b3787c Merge branch 'rel/0.pre.04' into integration 2025-12-03 14:44:55 +01:00
651cf144a5 Release: general washdown
- comb through the Website, starting at the frontpage
- add a **news** entry to confirm this major upgrade step (C++23)
- improve the wording in various overview pages
- adapt the ''release checklist'' to align it with **git-flow**
- reorganise the image folder(s) on the website
- the animated beating heart is back ;-)
2025-11-30 21:22:23 +01:00
797174ef19 Release: extensive makeover of Build and Debian documentation
On the Website, there is a set of interconnected pages related
to compiling from source, the Debian package and our DEB depot.

Although these pages have always been superficially kept up-to-date,
the overall presentation feels dated and generally not well organized.
During the last weeks, I have almost entirely rewritten all those pages,
added information about the (now reworked) DEB package, explained the
alternate ways to build from a Debian source package (notably the
`mk-build-deps` for handling the build dependencies, which effectively
the only method which always worked during the last years, since our
DEB package was totally outdated)

Furthermore, I have tested most of the build steps with the current
source trees, repositories and package definition, and finally I
have also updated and polished the front-page of our DEB-Depot
(-> see commit on the depot-Branch)

Wheew ... quite some work done!
2025-11-29 18:04:30 +01:00
eb4c49e1b2 Build: upgrade, tighten and document the prerequisites
Many versions enforced with this changeset are chosen such
as to support Ubuntu/Noble (24.04) and otherwise use versions
reasonably close to Debian-Trixie (≙reference-platform)

Since we now require a fairly modern compiler for C++23,
I have added now an explicit version check, which however
is performed only if the defined compiler is named `g++*`

Furthermore, I combed through all of our build tutorials and documentation pages
and updated a lot of information regarding dependencies and build practices...
2025-11-28 04:24:52 +01:00
d24e025de2 Build: chase down and solve spurious SVG icon rebuilds
Many years ago, I integrated the IconSvgRenderer (written by Joel Holdsworth)
directly into the SCons build by means of a custom builder with an ''emitter function''.

The build as such works fine and automatically determines which icons can be
generated from a given SVG source. However, those SVG icons tend to be rebuilt
very frequently, even while none of the SVG sources has changed.

Basically this was more of an annoyance, since we have now about 15 icons
and the rendering is really fast ... it is just ugly, especially on
incremental builds (and it could become a problem once we have a
massive amount of graphics to process.

So I took the opportunity to take close look now, since I am doing
uninspiring clean-up work since several weeks now. But that problem
turned out to be quite insidious and hard to spot.

First, AI set me off into a completely wrong angle, since it is ''not''
caused by a missing string representation of the custom Action class.
However, from there I went to watching the target checks with the debugger,
and this eventually got me to realise, that SCons mistakenly detects
a change in the Executor / the Action class.

The root cause is, that we invoke Python code from an external Module,
IconSvgRenderer.py, and this is »materialised« by SCons automatically
into a string representation, which includes memory addresses of functions
in that module. And that yields a signature, that is, quite obviously,
not stable, even while you end up sometimes with loading the code to
the same memory location.

As a solution / workaround, we now subclass the standard implementation
from SCons and override the signature function; instead of fingerprinting
the binary code, we just compute a MD5 over the python source file,
which can be easily achieved with the help of the File-Node from SCons.

Essential resources:
https://scons.org/doc/4.8.0/HTML/scons-user.html#chap-builders-writing

...and the Reference / Manpage of SCons
https://scons.org/doc/4.8.0/HTML/scons-man.html#action_objects

SCons/Action.py
SCons/Node/__init__.py
2025-11-27 18:15:49 +01:00
8b2a329898 Build: some further code clean-up and documentation
* Simplify some constructs from the Python-3 migration
 * update copyright, since I did maintain the SCons build continuosly
 * remove unused method from Buildhelper

Furthermore, the documentation page for our build system
https://lumiera.org/documentation/technical/build/SCons.html
has been reworked, to add a synopsis, some further background
information about the internal structure of SCons and about
the specific conventions and definitions used for Lumiera
2025-11-27 18:21:22 +01:00
88ae398e67 Build: remove old workaround for transitive shared object lookup (closes: #965)
Lumiera is built such that it can be invoked from a ''bundle directory''
without the need to install it into the system; this requires to perform
a relative lookup of shared modules loaded as dependencies.

Since Lumiera has a layered architecture, and each layer is built into a shared object,
we get transitive dependencies and thus transitive relative lookup.

There was a bug in binutils 2.23, which caused that transitive relative lookup to fail.

 * as of 2025, Debian/Trixie is defined as ''Reference Platform''
 * in Trixie the binutils version is v2.44-3
 * after removing the workaround, Lumiera and all tests can be launched
 * thus ''considering this workaround as obsolete now''
2025-11-24 23:12:39 +01:00
3812c801fb Build: ensure that installed shared libs are not executable
This is a Debian policy, which collides with the default behaviour
of GCC rsp. the plattform linker. The latter creates all ELF files as
executable, possibly because some platforms require that, and also
because some libraries provide a main() function for diagnostics.

The argument by the Debian people is that most libraries don't provide
such a main() and that this is an esoteric feature which should not be
supported by default.

We can fix that in our SCons build, since we use a specialised Builder
to also define the install targets systematically; it suffices to add
a post-action to these install targets for shared objects.

Note: currently Debian/Trixie provides SCons 4.8, but v4.10 will provide
a shorthand notation with the env.Chmod Action factory.
2025-11-24 22:03:11 +01:00
ceceaf4ece Release: compile authorship information
Some recherche regarding the requirements and conditions of the GPL
made it clear that we are obliged to have at least an summary statement
of all authors and the years of their contributions embedded somewhere
in the source itself. The Git history alone is not sufficient to fulfil
this requirement, since a code base could be packaged as Tarball
and passed-on outside of any Git repository.

Thus I propose the following policy
- add yourself to the copyright header whenever you made
  some ''significant'' contribution to a code file
- maintain a list of relevant authors at top-level,
  indicating a time range of their contribution
- use the same information also in the debian/copyright (DEB package)
- clarify in the LICENSE that authorship can be extracted from Git

__Remark__: Anton Yakovlev made a single code contribution in 2009 (87e528bd),
which was never used anywhere and removed as part of a general clean-up in 2023.
Thus I do not list him as a code author, but he is mentioned in credits.txt
2025-11-24 00:52:47 +01:00
524dc61771 Release: check and update licensing information
- use a current copy of the GPL2 text, downloaded from fsf.org
- reformat the AUTHORS and get rid of the table formatting
- Stackoverflow has upgraded its Subscriber Content license to CC-By-SA 4.0
2025-11-26 00:57:25 +01:00
8601202be5 Release: rework and update the changelog
A handwritten changelog is considered important and
helps to single out the overall relevant achievements.
Following a proposal from the Debian policy, this summary
of development steps will now be maintained in the NEWS file.

It will be marked with the version number of Lumiera.
2025-11-22 23:51:21 +01:00
6c3f0edf10 Release: update README
...and split-out the description of preview-releases,
since that rather belongs into some kind of changelog (NEWS).

Furthermore, check the links to the build dependencies
2025-11-22 01:40:43 +01:00
4d373c929e Release: check legal statements / Authors
See corresponding commit in the website repository.
- Verified all authors via Git
- simplify the list and group by core/contributors
- list only significant contributors here

__Note__: the page "project/contributors" on the website
contains a much more extensive list with all helpers,
casual contributors and concept discussion participants
2025-11-21 18:36:27 +01:00
b3d8abcb2c Build: provide and install a lumiera.desktop file
The XDG Desktop spec is accepted universally, and thus
the old Debian-specific 'menu' system is deprecated and
no longer engaged automatically.

See: https://lists.debian.org/debian-devel-announce/2015/09/msg00000.html

Thus we'll now provide a Desktop file and install that already from out
SCons build system, together with a suitable variation of the Lumiera icon.

TODO: not sure if everything was done the correct way
 * do we need to ''register'' the new file in some way (preinst script?)
 * the menu entry shows up, but not the icon
 * but if we put an absolute path for the lumiera.svg into the desktop file, it shows up

Remark: in later experiments with package building,
the menu entry and the icon showed up in the menu.
Not sure if this requires a reboot or some similar
trigger (like restart of the destkop)
2025-11-21 01:12:49 +01:00
5a5168b145 Build: fix problem that prevented installation into absolute path
...funny enough I never noticed this obvious mistake,
since I never install software directly into my system,
while the DEB-build does not use absolute paths...

Solution:
 * SCons has this speical convention that a path prefixed with '#'
   is resolved relative to the root of the build (where the SConstruct resides)
 * now we apply this automatically to the two relevant settings
   ** INSTALLDIR
   ** TARGDIR
 * but only (conditionally) if the configured path is relative, not absolute

As a consequence, most other hard-coded usages of the '#'-prefix can then be dropped
2025-11-19 22:40:08 +01:00
c8196ce234 Build: configuring via environment is bad practice
Yes, I know...
Programmers absolutely LOVE to sneak-in various nifty toggles via environment.

Yet this is an anti-pattern!
And, by extension of that verdict, a "build interface" which relies
on the implicit convention that some magical variables are set,
is **not a proper interface** but a hack.

Thus we abandon that bad practice and handle the build in a clean and explicit way.

 * the DEB-Build in `debian/rules` now invokes SCons explicitly, passing arguments
 * the Lumiera Build-System is FSH aware and knows the proper installation locations
 * the setup of the application uses a setup configuration, shipped with the package
 * there is no need to ''compile-in any configuration''
   ** `LUMIERA_PLUGIN_PATH` is obsolete and unused since several years now
   ** `LUMIERA_CONFIG_PATH` was never used at all
   ** consequently, we also do not need `PKGLIBDIR` and `PKGDATADIR`
2025-11-16 02:09:24 +01:00
aac9ee2934 Bugfix: uninitialised stack-memory used in test
...this bug was spotted as the test failed reproducibly
when built with `-fstack-protector-strong` — which adds
additional "canary" markers to some kinds of problematic
stack storage; this seemed to have the effect that now
the second test uses exactly the same location as the
preceding test, and thus finds valid data in the newly
created work buffers.

There is no reason for using uninitialised storage in this
test (I can recall that I wanted to build a generic helper
and intended to use that as ''virtual overlay'' over existing
memory — but that usage never took place, and the `struct Buffer`
is not a general-purpose tool now, but only made for this
specific test. Thus memory can be easily zero-initialised.
2025-11-15 02:00:11 +01:00
a34b1f6ddd Bugfix: setVersion.py -- ability to handle suffixes
Turns out that in practice there will be (at least temporarily)
some version-tags including a suffix: the RC-versions!

Now there is the special twist, that Git does not allow '~' in Tag names,
and thus `git-buildpackage` introduced an additional layer of translation.
So we are forced to revert that translation, which is possible,
since the basic Debian version syntax disallows '_' in version numbers
(because '_' is used to separate the package name from the version number).

It seems prudent to implement that as an preprocessing step
and thus keep it out of the regular version number syntax.

Furthermore we need the ability to handle existing suffixes,
which (as we know now) can be picked up from the Git history.
 * my decision is to allow both pass-through and suppressing them
 * use `--suffix=False` to suppress / remove any existing suffix
 * the latter now allows us also to automate the setting of
   the final Release version
2025-11-13 22:06:06 +01:00
2ca07bfe6b Bugfix-failed: attempt to fix XVideo widget drawing problems
Based on the additional insight gained through the FrOSCon talk,
an attempt was made to investigate and fix the garbled display of the
docking panel header directly above our VideoDisplayWidget.

However, that turned out to be a problem with insufficeint support
of the XVideo standard with my (very old, 2011) NVidia graphic card.
Indeed, the hardware+software stack needs to support this Auto-Keying
extension of XVideo, so that the video display can be integrated
seamlessly into the rest of the UI. In my case, the driver seemingly
just fills the complete XWindow with the key-marker and thus the
decorations of the docking panel, which happens to use the same XWindow,
will just not be flushed to the display.

This unsuccessful research indicates that upholding support for XVideo
could become problematic...
2025-11-20 21:36:47 +01:00
11efb6e9de Git-flow: Illustrations
Vectorgraphic drawings to show the Git-flow branching scheme
explained in the accompanying text
2025-11-10 19:20:15 +01:00
1c234d5a0b clean-up: some Doxygen improvements
- reorganise the navigation tab structure
- place all further index lists into a common "Index" tab
- include a list of concepts
- remove the various "member" sub-tabs, these are not helpful
- the "modules" tab is now called "topics" (since C++ has now Modules!)
- generally re-sync DoxygenLayout.xml with a current pristine template
- comb though the Doxygen Warnings and fix a lot of small problems
2025-11-05 02:55:45 +01:00
19497f8a7b clean-up: update content of the introductory overview pages
The »Outer Space« and »Inner Core« documents present a comprehensive
overview of the vision, architecture and essential parts of the implementation.

In the light of changes to policy, design and implementation approaches,
some updates were necessary to align these crucial texts with the current
state of planning and implementation. Notably I have added a recent Screenshot
of the UI, showing a nested track structure pushed up by Diff from the core.

Over the last weeks, I conducted an extended analysis of the inception time
of the Lumiera project, which gave me a sharpened understanding of the goals,
going forward. I have also written an in-depth essay "Complexity and Flexibility".
See the corresponding commits in the Website repository.
2025-10-28 02:23:42 +01:00
8bff48fd2f Design: ramifications for the Event-Log
Expand on this problem with the consequences of rule changes.
Need to consider how recording this information is related
to the data structures of the Event-Log...

__Remark__: this topic belongs into the ''next planned'' Vertical Slice »LoadClip«
2025-10-12 22:54:09 +02:00
38ea195555 Design: Idea how to reconcile rules with controlled change
Allowing to change rules and facts seems to be in direct contradiction
to using an Event-Log for deterministic and reproducible behaviour.

Notably, the facts can be a representation of the environment,
like e.g. the sound setup in a Studio vs. working on a Laptop.

Since a long time, I used the formula to separate decisions
from the processing logic in the code. An analysis of the kinds
of decisions relevant for the situation with editing a media arrangement
reveals that a dangerous conflict might ensue when the foundation
of a past rule application changes, possibly by undo or replay
of the Event-Log.

A solution could be not only to apply rules, but also capture
and materialise the fact that a rule has been applied and
especially to record a connection between the setting and
the rule it was based on. This amounts to documenting
the reasoning why some decision came about. If done correct,
such a data model would allow to re-evaluate past decisions
quickly in case the facts or the rules are changed.
2025-10-10 00:43:08 +02:00
c0082593b4 Design: consider what makes decision logic problematic...
While I am currently deeply entrenched in the history of Lumiera
and related general questions of dealing with complexity, some
ramifications became clear for the next topics to address,
notably related to ''Event Sourcing''
2025-10-09 19:35:17 +02:00
051cb31e28 clean-up: re-classify essential RfCs
The RfC documents were written to complement discussions of the Lumiera developers;
yet since the time where ''Ichthyo'' is working basically alone on the project,
this kind of discussions have ceased. During the following years, some ideas
promoted by the existing RfC documents became rather detached from the
actual state of development in the code base.

Many of the existing RfC documents require some commentary to place them
into context, and some of the decisions taken in the early stage of the
project should be **re-assessed**. This includes the decision to reject
some proposals, which initially might have seemed desirable, yet could not
be reconciled with the understanding of the matter and topic in question,
as was gained through the ongoing analysis and development.
2025-10-08 00:48:13 +02:00
b556d2b770 clean-up: comb through the historical pages to fix markup errors
Some sections of the Lumiera website document meeting minutes,
discussion protocols and design proposals from the early days
of the project; these pages were initially authored in the
»Moin Moin Wiki« operated by Cehteh on pipapo.org at that time;
this wiki backed the first publications of the »Cinelerra-3«
initiative, which turned into the Lumiera project eventually.

Some years later, those pages were transliterated into Asciidoc
semi-automatically, resulting in a lot of broken markup and links.
This is a long standing maintenance problem problem plaguing the
Lumiera website, since those breakages cause a lot of warnings
and flood the logs of any linkchecker run.
2025-09-21 05:40:15 +02:00
0c3cd9027c DOC: clarify UI / discussion
- indicate clearly that a ''past discussion'' is documented here
- point out what is the primary focus for UI design ''currently''
- arrange some links better
- use cross-links / Linkfarm; especially cross-link to
  the discussion regarding Wouter's Workflow proposals (2025)
2025-09-19 19:51:28 +02:00
217ec447c0 DOC: reorganise time handling pages (use Linkfarm)
Create a new subcategory "design/architecture/time"
and rearrange several pages related to time handling and time codes.

NOTE: starting with this changeset, a ''Link-Farm'' is required for cross-links;
since we don't have an automatic solution for this task yet, I have created
the necessary forwarding pages manually in the website repository.
2025-09-19 19:34:27 +02:00
643779c4a2 Review: integrate Christian's improvements to the website build
Christian started a series of reworks in 2018;
the result was considered experimental and was parked on website-staging ever since.

As part of the current release- and clean-up activities I now reviewed
and integrated those changes into the current website as far as applicable.
2025-09-02 02:20:39 +02:00
9225d868bb DOC: Notes regarding the ongoing workflow-discussion 2025-08-31 01:02:49 +02:00
592622d750 Workflow-publish: adapt additions to Asciidoc 2025-08-23 18:50:13 +02:00
4dba1c816d DOC: FrOSCon meeting -- integrate improvements from Benny 2025-08-23 04:29:08 +02:00
7bbb21a8ad DOC: minutes of FrOSCon meeting
Topic: proposals for Lumiera Workflow
Present:
- Wouter Verweijlen
- Benny Lyons
- Hermann Voßeler

Note: This commit creates a new subsection
      for the discussion related to Wouter's »Lumiera Workflow Proposals«....
2025-08-19 15:15:36 +02:00
7e8a8a5b76 Recherche / preparation for FrOSCon talk
The topic of this talk was ''Video output from a Linux desktop application''
after extended research we built a demo application in four flavours
(XVideo, SDL, OpenGL legacy / modern).

This research project was set off by our immediate needs for a setup
to show computed video pixel data in a viewer window in the GUI; the
investigated technologies should work at present and in the near term
future (yet leaving out Vulkan and Wayland)
2025-08-21 00:39:51 +02:00
17ee3ac1cb Release: Introduce the Git-flow branching model
Starting with the upcoming ''preview release'', branches, branch names and tags
will be rearranged to follow the Git-flow pattern instead of the existing
ad-hoc organisation with a release branch.

The documentation provided here defines the actual naming conventions
and some fine points regarding the version number upgrades
and placement of release tags.


Furthermore, two helper-scripts are provided to automate version number updates
- `buildVersion.py` : extract current version from git tag and allow to bump version
- `setVersion` : manipulate all relevant files with `sed` to update the version info
2025-07-21 02:46:28 +02:00
20f3252892 Upgrade: down with typename!!
Yet another chainsaw massacre.

One of the most obnoxious annoyances with C++ metaprogramming
is the need to insert `typename` and `template` qualifiers into
most definitions, to help the compiler to cope with the syntax,
which is not context-free.

The recent standards adds several clarifications, so that most
of these qualifiers are redundant now, at least at places where
it is unambiguously clear that only a type can be given.

GCC already supports most of these relaxing rules
(Clang unfortunately lags way behind with support of newer language features...)
2025-07-06 01:19:08 +02:00
2cd3e95228 Upgrade: simplify Either-type
`lib::Result` can invoke, capture the result and thereby
represent ''either'' a result or a failure.

The old implementation required a delegate, due to the complexities
of integrating the `void` case. With C++23, `invoke_r` from the Stdlib
handles those issues, allowing a cleaner formulation, with directly
capturing the result into `lib::ItemWrapper`
2025-07-04 21:27:50 +02:00
b6a39fa831 Upgrade: simplify comparisons
Now able to remove most complicated comparison operators and most usages of boost::operators...
In most cases it is sufficient just to define one ''spaceship operator'',
and often even that one can be synthesised.

However — we still use boost::operators for arithmetic types,
notably the `lib::time::TimeValue`, which is addable and mutipliable
2025-07-04 03:37:54 +02:00
bad4827b34 Upgrade: Literal can be constexpr
Only minor rearrangements necessary to make that possible with C++20
And while at this change (which requires a full rebuild of Lumiera)

- simplify the defined comparison operators, as C++20 can infer most variations
- also mark various usages of `const char*` either as Literal or CStr

Remark: regarding copyright, up to now this is entirely my work,
        with two major creation steps in 2008 (conception) and
        in 2017 (introduction of a symbol table)
2025-07-02 22:18:39 +02:00
170b68ac5c Upgrade: further extend usage of the tuple_like concept + generic apply
This changeset removes various heuristics and marker-traits
by a constraint to tuple_like types. Furthermore, several usages
of `apply` can thereby be generalised to work on any tuple_like.

This generalisation is essential for the passing generic data blocks
via `FeedManifold` into the node invocation
2025-07-02 01:16:08 +02:00
3a1f64ec41 Upgrade: now able to reformulate the tuple_like concept
Now this draft seems ready to be put into actual use in the code base.
Furthermore, a generic ''get adapter'' is introduced to level the difference
between both tolerated forms of element access, also working correctly
for const and RValue references
2025-06-24 01:03:57 +02:00
49e7b31511 Upgrade: develop better formulation for ''and-all-generic''
...need to do this in a test context first,
since `variadic-helper` is in widespread use
2025-06-23 04:24:00 +02:00
7d461adabc Upgrade: explore construction of a ''tuple-like'' concept
Motivated by the difficulties encountered with `std::apply` —
which basically forced us to define our own alternative with
conceptually more adequate limitations....

...so these are the first attempts towards building a C++20 concept.
2025-06-22 19:42:03 +02:00
de066348af Upgrade: workaround for compiler-bug
Compilation failure with GCC-14.2 with the following code

class Base
  {
  protected:
    Base() = default;
  };

struct Feed
  : Base
  { };

int
main (int, char**)
  {
    Feed f1;
//  Feed f2{};       /// does not compile with GCC 14.2
    return 0;
  }

In the actual code base this can be triggered when instantiating
classes with the `NonCopyable`-mix-in; seemingly the compiler attempts
to invoke the base class ctor directly, while it should invoke a
(synthesised) default ctor for the derived class.

The problem could not be reproduced with other compiler versions at Godbolt.org
2025-06-20 18:29:51 +02:00
afa7ca2e4d Upgrade: switch to C++23 (see #1245)
The Lumiera »Reference Platform« is now upgraded to Debian/Buster, which provides GCC-14 and Clang-20.
Thus the compiler support for C++20 language features seems solid enough, and C++23,
while still in ''experimental stage'' can be seen as a complement and addendum.

This changeset
 * upgrades the compile switches for the build system
 * provides all the necessary adjustments to keep the code base compilable

Notable changes:
 * λ-capture by value now requires explicit qualification how to handle `this`
 * comparison operators are now handled transparently by the core language,
   largely obsoleting boost::operators. This change incurs several changes
   to implicit handling rules and causes lots of ambiguities — which typically
   pinpoint some long standing design issues, especially related to MObjects
   and the ''time entities''. Most tweaks done here can be ''considered preliminary''
 * unfortunately the upgraded standard ''fails'' to handle **tuple-like** entities
   in a satisfactory way — rather an ''exposition-only'' concept is introduced,
   which applies solely to some containers from the STL, thereby breaking some
   very crucial code in the render entities, which was built upon the notion of
   ''tuple-like'' entities and the ''tuple protocol''. The solution is to
   abandon the STL in this respect and **provide an alternative implementation**
   of the `apply` function and related elements.
2025-06-19 01:52:55 +02:00
20392eee1c clean-up: successfully replaced the old fixed type sequence (closes: #987)
This resolves an intricate problem related to metaprogramming with
variadic templates and function signatures. Due to exceptional complexity,
a direct solution was blocked for several years, and required a better
organisation of the support code involved; several workarounds were
developed, gradually leading to a transition path, which could now
be completed in an focused clean-up effort over the last week.

Metaprogramming with sequences of types is organised into three layers:
- simple tasks can be solved with the standard facilities of the language,
  using pattern match with variadic template specialisations
- the ''type-sequence'' construct `Types<T...>` takes the centre stage
  for the explicit definition of collections of types; it can be re-bound
  to other variadic templates and supports simple direct manipulation
- for more elaborate and advanced processing tasks, a ''Loki-style type list''
  can be obtained from a type-sequence, allowing to perform recursive
  list processing task with a technique similar to LISP.
2025-06-07 18:04:59 +02:00
acc77654d1 clean-up: can now switch remaining downstream usages
after all the relevant library components do support both kinds of
type sequences transparently, any usages in core code can now be
switched over to the new, variadic type sequences.
2025-06-07 01:07:36 +02:00
95a9ceac35 clean-up: simplify function-closure -- avoiding std::function
A very performance relevant shortcoming of the existing implementation
of partial function closure is that the result is always wrapped into a
std::function, which typically causes a heap allocation when more than
a single pre-bound argument must be stored — which is annoying,
since the underlying Binder provides inline storage and thus
could be handled directly as a value object.

However, returning the Binder directly is also problematic, since
this object is outfitted with several overloaded function call operators,
which defeats most techniques to detect a function signature. Notably,
relevant down-stream metaprogramming code, like the tuple-closure used
in the `NodeBuilder` would break when being confronted directly with
a binder object.

An investigation shows that there is no direct remedy, short of
wrapping the binder into another functor. This can be accomplished
with a helper template, that generates a wrapper; however, this
wrapper builder must be supplied with explicit type information
regarding the function arguments (precisely because this type
signature can not be picked up from the Binder object itself)
2025-06-06 19:44:24 +02:00
10daa06ba2 clean-up: simplify function-closure -- enable forwarding and remove workarounds
This is a rather intricate and technical change, but allows in the end
to switch back all usages to a main implementation patch, which is now
based on `func::BindToArgument` — so this could become the final
implementation core and replace the old `PApply` template eventually...

Largely, these changes are related to allow for ''perfect forwarding''
of the functor and the argument values to be closed; these will be
copied into the ''Binder object'' created by `std::bind`.

Notably the `TupleConstructor` was changed to perfect-forward its »source«
into the specialised `ElmMapper`; this is possible since the latter
already receives a `SRC` template parameter, which can be supplied
with whatever base type the `std::forward` invocation will expose.
In the specialisation relevant here, template `PartiallyInitTuple`,
now an ''universal reference'' is stored and passed to `std::get`,
so that (depending on the input used), either a LValue or an
RValue reference is used for the extracted data elements.

After these changes, all existing usages of `applyFirst()` or `applyLast()`
can be replaced by this modernised implementation back-end, thus obsoleting
the various hard-coded workaround added during the last years.
2025-06-06 03:23:34 +02:00
f6f8220fbe clean-up: simplify function-closure -- can now remove obsoleted impl
A lot of repetitive, pre C++11 metaprogramming code can now be removed,
and several helper constructs, which were needed to handle generic
function application and passing a tuple of values to create a binder.

Note however, the highly complex and technical core of this header
still remains intact; which is to create a ''partial closure'' over
some arguments of a function, while keeping the remaining arguments
open as parameters for invocation.

TODO: Even in the remaining code there is a lot of redundancy
and helper construct which are no longer necessary
2025-06-05 19:11:46 +02:00
738d9e5b67 clean-up: simplify function-closure -- investigate BindToArgument
...because swapping in the new standards-based implementation
leads to compile failures on tests to cover out-of-bounds cases.

Under the (wrong) assumption, that some mistake must be hidden in
the Splice-metafunction, I first provided a complete test coverage;
while the actual problem was right below my nose, and quite obvious...

The old implementation, being based on a case distinction over the argument count,
simply was not able even to notice excess arguments; other the new implementation,
based on variadics and `std::apply`, which is fully generic and thus
passes excess arguments to `std::bind` when a position beyond the actual
argument list is specified to be closed.

The old behaviour was to silently ignore such an out-of-bounds spec,
and this can be reinstated by explicitly capping the prepared tuple
of binders and actual arguments passed to `std::bind`

Another question of course is, if being tolerant here is a good idea.


And beyond that, function-closure.hpp is still terrifyingly complex,
unorganised and use-case driven, to start with....
2025-06-05 18:00:05 +02:00
415e4746a6 clean-up: simplify function-closure -- rebuild the 'bind' case
...can now be formulated in a single function,
based on the apply-to-λ technique invented by David Vandervoorde.

WARNING: the rewritten version of BindToArgument<...>::reduced()
does not compile in the out-of-bounds case, revealing a possibly
long standing defect in the typelist-metafunction Splice
2025-06-05 03:19:03 +02:00
400d0eb92e clean-up: simplify function-closure -- eliminate the 'apply' case
This library header was developed at a time, where C++ had no built-in support
for so called "invokables"; `std::invoke` and `std::apply` were added much later;
So in that early version that was a significant technical hurdle to overcome.

seems like it might be possible to get rid of the TupleApplicator alltogether?
2025-06-05 01:18:59 +02:00
1a2c2ededa clean-up: switch the tricky function-closure
This is one of the most problematic headers, because it is highly complex
and comprises tightly interwoven definitions (in functional programming style),
which in turn are used deep within other features.

What concerns me is that this header is very much tangled
and pushes me (as the author) to my mental limits.

And on top of this comes that this code has to deal with intricate aspects
like perfect forwarding, and proper handling of binder instances and
function argument copying (which basically should be left to `std::bind`)

Fortunately, the changes ''for this specific topic'' are transparent:
Type sequences are not used on the API for function closure and composition,
but only as an internal tool to assemble argument tuples used for either
binding or invocation of the resulting (partially closed) function.
2025-06-04 01:49:07 +02:00
429a7e2339 clean-up: define variadic type-sequences independently
To bootstrap this tricky refactoring, initially a bridge definition
was used, with a variadic argument pack, but delegating to the old
non-variadic type sequence and from there further into LISP style
list processing of types and meta definitions, as pioneered by the
Loki libarary. Luimiera uses this technique since a long time to
perform the complex tasks sometimes required for code generation
and generic function and type adaptation.

with this changeset, a direct variadics based entrance into
type list processing is provided, so that the old definition
is now completely separate and can be removed eventually.
2025-06-04 03:21:18 +02:00
412abbace2 clean-up: validate use of variadic seq with tuples and generators
Most of the type-list and type-sequence related eccosystem can be
just switched over, after having added the conversion variants for
the new-style variadic type sequences

Again this was used as opportunity to improve readability of related tests
2025-06-03 16:14:13 +02:00
47b57da646 clean-up: validate the typelist manipulations
As expected, these work on the new-style variadic type sequences
equally well than on the old ones (tail-filled with `Nil` markers).

On that occasion, a complete makeover of the huge test case was carried out,
now relying on `ExpectString` instead of printing to STDOUT. This has the
benefit of showing the expectation immediately next to the code to be tested,
and thus makes it much easier to ''actually see'' how these meta-functions
operate on their parameters (which in fact are types in a type list)
2025-06-02 23:55:08 +02:00
c8187bdf88 clean-up: complement and modernise basic type-lists
- provide complete conversion paths old-style ⟷ new-style
- switch the basic tests to the new variadic sequences
- modernise the code; replace typedefs by `using`
- change some struct-style ''meta-functions'' into
  constexpr or compile-time constants
2025-06-02 19:07:05 +02:00
7aa1698a95 clean-up: prepare for variadic Type-Sequences (see #987)
Attempting to reduce the remaining pre-C++11 workarounds before upgrade to C++20...

As a first step: rename the old type-sequence implementation into `TyOLD`
to make it clearly distinguishable; a new variadic implementation `TySeq`
was already introduced as partial workaround, and the next steps
will be to switch over essential parts of the type-sequence library.
2025-06-02 03:24:44 +02:00
1da5d57098 clean-up: RefArray is gone (closes: #473)
After the leftovers of the first Render-Engine implementation attempt were removed,
only one further usage of `RefArray` remains to be sorted out: the ''Session Element Tracker''.

Luckily, this one did not actually make any use of the abstraction abilities
of the `RefArray` — rather it basically stated that ''the interface is a data structure...''
After considering ''what kind of data'' can be expected to live in this structure,
it became clear that ''this will be a symbolic representation''

And thus the container can be simply switched to a `std::vector`.
This change allows to retain the existing placeholder-implementation unaffected,
while it would be possible to maintain algebraic terms here, in future.

__As an asside__: in order to decide about a suitable replacement in the Session,
                  I had to consier a first draft regarding the intended usage
                  and the prospective way of content representation
2025-06-01 02:44:40 +02:00
08bdb912a5 clean-up: some further bits never actually used
design sketches, prototype, textbook-implementation,
this-might-be-a-good-idea stuff
2025-06-01 00:53:35 +02:00
bec55a89e0 clean-up: ScopedHolder now obsoleted (closes: #958)
Investigated this topic again...
 * these were initially created before C++11
 * at that time, ''non-copyable'' objects were not common place
 * but we embraced that concept already, and thus had quite some pain
   when attempting to use such objects in STL containers
 * with C++11 and ''move semantics'' these problems basically evaporated
 * most usages were already upgraded and resolved
 * another use case is to handle a state variable, which is based on
   an immutable entity (like Time entities); `ItemWrapper` can be used
   as a remedy in such a situation
2025-05-31 19:43:43 +02:00
2bec3ccd4e clean-up: make ScopedPtrVect move-assignable to use it in STL containers
This was a pre-C++11 implementation, and at that time,
I developed the ScopedHolder to allow handling non-copyable objects in STL containers

Meanwhile we have move semantics to achieve the same goal;
and since `ScopedPtrVect` shall be retained, it should be upgraded,
using the copy-and-swap approach
2025-05-31 19:10:19 +02:00
071ab82a7a clean-up: review and validate ScopedPtrVect
This is a plausible concept, and without obvious replacement
(letting aside `boost::ptr_vector`). It has a small number
of usages, and provides a dedicated API to show the
semantics when used as implementation of an ''Object Manager''

The original implementation used private inheritance from `std::vector`,
which is not really justified here, since we neither use the ''template method''
pattern, nor want to gain access to protected internals.
So this can be replaced with a private member.
2025-05-31 19:02:43 +02:00
8960aed7ba clean-up: ItemWrapper now stands on its own
...initially, this header was a collection of small helpers made on occasion;
one of them, the `ItemWrapper` used in transforming pipelines came
into widespread use and was much augmented and improved over the years.

many other tiny helpers could be replaced by standard library facilities...
2025-05-31 01:21:57 +02:00
bc6a219543 clean-up: trash ReplacableItem (closes: #1059)
Now looking into largely obsolete library facilities...
Starting from `ScopedHolder`, I found a surprising problem with ''perfect forwarding....''

...which however turned out to be the result of ''sloppy programming'' on my side.
At that time, in 2017, seemingly I was under pressure to define a Session-Command,
which captures a Time-entity as »State Memento«. Which turned out to be impossible,
since the Time entities were conceived as being immutable -- a questionable design
decision (see #1261), which already generated quite some additional complexities.


In the course of this »exercise«, I could again clarify that the implementation
of perfect forwarding works as expected on modern compilers — confusion may arrise
sometimes due to ''copy elision'' (which the compiler is required to perform
since C++17, even when the elided constructor has observable side effects).
And it can be derailed when (as was the case here) a »grab everything« constructor
accidentally ends up generating a copy- or move-constructor for the container class
itself. This is an instance of the problem documented with #963 ...

.... and the best solution is to abide by the rule-of-five (and a half)
and to put that `ReplacableItem` to where it belongs...
2025-05-30 19:12:01 +02:00
11322ad955 clean-up: finally discard remainders form the first Render Engine draft
During the early stage of the Project, at some point I attempted
to »attack« the topic of Engine and Render Nodes following a ''top down path.''

This effort went into a dead end eventually — due to the total lack
of tangible reference points to relate to. However, the implementation
at that time prompted the development of several supporting facilities,
which remain relevant until today. And it resulted in a ''free wheeling''
compound of implementation structures, which could even be operated
through some highly convoluted unit test.

This piece of implementation code was valuable as starting point for th
»Playback Vertical Slice« in 2024 — resulting in a new design which was
''re-oriented'' towards a new degree of freedom (the »Domain Ontology«)
while handling the configuration and connectivity of Render Nodes in
a rather fixed and finite way. This new approach seems to be much more
successful, as we're now able to build, connect and invoke Render Nodes,
thereby mapping the processing through a functor binding into some
arbitrary, external processing function (which will later be supplied
by a media processing library — and thus be part of some »Domain Ontology«)
2025-05-30 01:47:27 +02:00
a317593822 clean-up: dismantle the low-level time handling library (see #1259)
Initially we assumed that »handling time« is largely a matter of computation.
''Time is just a value'' and can be treated with integral arithmetic, some
modulus computations and pre-defined constants.

This turned out to be a mistake. Anything related to time is intricate,
and it is essential to distinguish different meanings of "times"
 - time values related to an internal computation framework have
   implementation-defined meaning and should be ''marked as opaque''
 - temporal data can be ''mapped to a grid scale'' — an essential step
   for media processing, which however incurs information loss
 - externally relevant time specifications are represented symbolically,
   by translation into a ''Time Code''

Drawing from these insights, a framework for time handling has been established;
building in part on the low-level function style base implementation.
Exposing this base implementation as a C-library however is considered
dangerous, as it may lure into ''ad hoc'' computations, which are a major
source of inconsistencies and notorious defects in many media applications.
2025-05-29 02:04:36 +02:00
27089550d2 clean-up: relocate frame quantisation operations
The `FixedFrameQuantiser` relied on three functions from the raw-time handling library.
Since this (and NTSC drop-frame) are the only usages, these functions
can be relocated into the implemntation translation unit `lib/time/quantiser.cpp`

On closer inspection, this reveals some room for improvements:
Instead of relying on raw-computation functions written in C,
we could rather revert the dependency and express these computations
in terms of our Time-entities, which are written in C++, are much more
systematic and provide consistency checks and protection against numeric
overflow, all integrated with linear arithmetic and concise notation.

After performing these rearrangements,
most of the functions can be collapsed into ''almost nothing''.

This was taken as opportunity to re-check and improve the remaining
implementation core of the `FixedFrameQuantiser` -- the handling of
extreme corner cases can be much improved, now representing the
"grid-local time" as `Offset`, which doubles the possible value range.

The reworked unit test shows that, with this change, now the limitation
happens prior to quantisation, meaning that we always get a grid-aligned
result, even in the most extreme corner cases.
2025-05-28 23:49:01 +02:00
255fc82a1b clean-up: relocate NTSC drop-frame conversion functions
...extract these functions and the associated test
from the low-level C time handling library and
document them with a dedicated C++ header and test.

''This is unfinished work'' —
the extracted functions provide only the low level computations;
actually, a specialised time quantisation or time code would be required.

------------
Note though,
after extracting these functions, the rest of the plain-C test
can be removed, since equivalent functionality is covered in
much more detail by the tests of the C++ time handling framework.

Notably this allows to get rid of the direct component accessor functions.

------------
__Remark__: the base implementation of many time conversion functions
            and especially NTSC drop-frame was provided by Stefan Kangas

See:
6a44134833
2025-05-27 23:39:36 +02:00
55b39ae592 clean-up: retract usages of »time component access«
While these function may seem superficially plausible,
I more and more come to the conclusion that offering such
function as ''basic building blocks'' is in itself an
ill-guided approach to handling of time entities.

Time is neither „just a number“ — nor does it „contain“ hours, minutes and seconds.
It is possible to ''represent'' it through a **time-code**, which incurs
a quantisation step and implies a reference grid.

Thus Lumiera ''should not offer'' a »basic time handling library«.
Doing so would be just an invitation to bypass proper time handling
and avoid the use of more demanding but also more adequate mental concepts.

So the next step will be to remove functions not deemed adequate, and
better directly inline the respective modulus based computations.
Other functions can be integrated into the respective implementation
translation units for time quantisation and timecode representation.
2025-05-27 20:43:52 +02:00
d31d4295a4 clean-up: remove gavl_time_t as external dependency
Indeed — this change set is kind of sad.
Because I still admire the design of the GAVL library,
and would love to use it for processing of raw video.
However, up to now, we never got to the point of actually
doing so. For the future, I am not sure if there remains
room to rely on lib-GAVL, since FFmpeg roughly covers
a similar ground (and a lot beyond that). And providing
a plug-in for FFmpeg is unavoidable, practically speaking.

So I still retain the nominal dependency on lib-GAVL
in the Build system (since it is still packaged in Debian).

But it is pointless to rely on this library just for an
external type-def `gavl_time_t`. We owe much to this
inspiration, but it can be expected that we'll wrap
these raw time-values into a dedicated marker type
soon, and we certainly won't be exposing any C-style
interface for time calculations in future, since
we do not want anyone to side-step the Lumiera
time handling framework in favour of working
„just with plain numbers“


NOTE: lib-GAVL hompage has moved to Github:
      https://github.com/bplaum/gavl
2025-05-17 23:12:47 +02:00
ee6e720d00 Clean-up: sort out further leftovers from the GTK-2 UI
After the Dummy-Player (interface and prototype implementation)
is removed, some further bits of debris can be sorted out.
The first version of the Timeline was mostly rewritten and
the obsolete parts were removed in 2023, yet a small number
of files was kept around as reference for later.

Some of these are no longer considered of any information value,
other ones were moved into the widget package (and further problematic
parts were annotated, but can be still used with GTK-3)
2025-05-15 23:41:54 +02:00
017ba5f160 Clean-up: remove dummy-player services and interfaces (see #1342)
For the [ticket:1221 »Playback Vertical Slice«] one of the next steps
will be to define a way to pass buffers from the core to the UI.

The `DisplayService` and the `DummyPlayerService` where parts of an
early architecture study to see how such a flexible connection between
components in different layers can be accomplished.

The findings from this prototyping work helped to shape the design
of the actual `PlayService`...
2025-05-14 01:32:21 +02:00
8abeb02397 XV-Display: prototype for flexible control of ouput pixel format
As an example, the `PixbufDisplayer` needs packed RGB888 data,
while the `XvDisplayer` expects YUV (MPEG-style) pixels.

The research setup is not well equipped to handle any kind of content
or format negotiation; yet for the experimentation, the connections can
be wired as !SigC-Signals. After the preceding refactorings,
`DummyImageGenerator` can be configured to perform the conversion to YUV
only when necessary, and to use the working buffer flexibly.

When supplied with packed RGB pixel data, the display in the Gtk::Image
is now correct, and also handles layout and scaling appropriately.
2025-05-12 03:43:09 +02:00
b42143f425 XV-Display: refine the formulation of the image-generator
- since we now use 32bit int arithmetic (which is faster),
   we can also use the exact value of the MPEG / Rec.601 coefficients

 - and also the generation of the NTSC colour bar pattern
   can be written much simpler and cleare with C++
2025-05-11 16:06:20 +02:00
8fe50e37a4 XV-Display: reorganise image-generator code
This is a first step towards the ability to produce several different output formats...

Refactor the code to separate
 - the double buffering
 - the actual image generation, which works in RGB
 - the conversion routine

Furthermore, replace unsigned char by std::byte
and introduce std::array and structured binding
to avoid many usages of pointers; hopefully this
makes the intention of the code clearer.

Verified and cross-checked the actual converion logic;
in fact this is a conversion to "YUV" as used by MPEG,
which in more precise terms is Y'CrCb with Rec.601 colour space
and a scan range limitation (16...235) on the Luma component.
2025-05-11 01:18:19 +02:00
42ce53aa09 XV-Display: investigate and fix some problems with this XV code
Generally speaking, this experiment shows that we need some additional know-how
regarding the XVideo standard. And we should re-think the means of integration.

From some further debugging end experimenting with this code,
the following conlusions can be drawn:

- the code retrieves the GDK-Window, to which the widget was mapped
- it uses this to access an underlying X-Window
- seemingly the docking panel uses a separate X-Window, which also
  hosts the header area of the panel
- this whole underlying X-Window is treated with some compositing method,
  presumably (just guessing from the code) we use keying with a
  marker-colour. This explains why the whole area of the panel
  is no longer updated regularly
- furthermore, we need to take into account that the actual display widget
  area uses some part of this window, which can be found out from
  the VideoWidget's ''Allocation''
- when correcting the origin of the video display by using this
  allocation's origin, at least the display of the video is precisely
  at the right location and size

Furthermore, the code takes quite some shortcut and basically
looks for one specific display format, and uses the corresponding
configuration for the "port" it got.

This Format has the Abbreviation "YUY2" (packed)
2025-05-09 04:28:17 +02:00
5d3710fca8 XV-Display: the old XVideo display code indeed still works
''it basically works...''
TODO
 - the image is updated only when moving the mouse over the widget
 - calculation of window decoration is not correct
 - a strange transparent zone appears in the UI directly above the widget
2025-05-08 17:31:27 +02:00
7fd3e71936 XV-Display: partial success with the fallback / pixbuf display
The new solution is to (still) use a Gdk::Pixbuf,
because in GTK-3 the more modern alternatives are not yet provided.
But we can pass this Pixbuf directly to Gtk::Image, instead of trying
to do low-level drawing on the X-Window.

Other than that, I more or less transformed the old C-style code
into the corresponding calls in Gdkmm.

__SUCCESS__: we get **some display**
__TODO__ : the displayed image is Garbage, which means that the pixel layout is not correct
2025-05-07 18:39:11 +02:00
93a62af39e XV-Display: re-implement fallback video display technique
In cases where none of the preferred, library based approaches works,
we can attempt to provide a ''poor man's video display'' by placing the
image data into a bitmap, which can be rendered by the UI toolkit.

The existing solution for such bitmap content is the GDK Pixmap.
But note, this approach is ''deprecated with GTK-4'', since,
generally speaking, GTK moves away from the notion of an
''underlying windowing system'' and relies on the concept
of ''graphic surfaces, textures and paintables'' rather...
2025-05-06 19:41:51 +02:00
02ac4a169b XV-Display: establish wiring for the controller and verify logic
Here we face the problem that the buttons in the play control panel
need to be connected to the controller, which sits in the viewer panel.

Obviously a direct connection is not correct, since there could be
several panels, and furthermore the controller should be a service and
addressed by commands via UI-Bus.

But this is an experiment, and we'll have to figure out anyway
how the playback-display-connection works, as one of the next tasks
for the »Playback Vertical Slice«

Thus we'll use the PanelManager to fetch the first viewer panel,
and then forward to the controller calls. With this setup,
the controller logic can be verified by printing to STDOUT.

TODO: we are not yet invoking any XVideo code....
2025-05-06 03:54:03 +02:00
b0e8fa2ff6 XV-Display: introduce a new kind of docking panel for the play-control
While this is not strictly necessary for this experiment,
this is something we should try to establish early:

A »play control« should be handled as an independent UI element,
without tying it logically with some viewer (or timeline); the reason is
that such a play control needs a set of very well designed keyboard bindings,
and thus we will attempt use a focus concept to link to some active viewer
instead of creating one primary viewer, which gets the benefit of the
well accessible keybindings.

Basically we want to create an explicit association between
 - a timeline
 - some viewer
 - a play-control

Introducing a new kind of panel shows again that the `PanelManager`
needs a rework; everything there is way too much ''hard wired''

And the new panel with the play control needs an **Icon** — which is
a challenge in itself; my proposal here is to build on the film metaphor,
and combine the symbol of "Play / Pause" with an stylised film or tape player
(with the secondary idea that this icon also somewhat looks like a owl face)
2025-05-05 23:48:22 +02:00
ac5a2f371d XV-Display: build new GTK-3 widget framework and controller
- place a `DemoController` instance as direct member into the `ViewerPanel`
 - create a direct wiring, so that the `DemoController` can push to the `VideoDisplayWidget`
 - make the `DemoController` directly instantiate a `TickService` and `DummyImageGenerator`
 - reimplement play control functions by direct invocation
 - add a new class to the Lumiera CSS stylesheet
2025-05-03 23:33:44 +02:00
0ae96294e8 XV-Display: start a research project to port the existing code (see #1403)
- initial assessment shows that the Design of the **Displayer** framework is adequate
 - for context: this code originates from the »Kino« video editor 20 years ago
 - notably the `XvDisplayer` contains almost no GTK(2)-code
 - so it seems feasible to attempt a port to GTK-3

This is a limited research project, and the setup shall be based mostly on existing code.
In the early stage of the Lumiera application, we did some architecture studies
regarding ongoing video generation and display, resulting in a `DemoVideoPlayer`.

This code was broken by the GTK-3 transition, but kept in-tree for later referral.
For this research project, we can mostly short-circuit all of the layer separation
and service communication stuff and build a minimal invocation directly hooked-up
behind the GUI widget. In preparation for such a setup, the existing
demo player code is partially forked by this changeset, pushing aside
the (defunct) !DummyPlayer pseudo-subsystem.
2025-05-02 23:19:55 +02:00
998e225490 Clean-up: reimplement the SeachPathSplitter
...to be more compliant to the »Lumiera Forward Iterator« concept.
This can be easily achieved by inheriting from util::RegexSearchIter,
similar to the example in CSV.hpp

Regarding #896, I changed the string rendering to use fs::path::generic_string
where appropriate, which means that we're using the normalised path rendering
2025-04-28 19:14:27 +02:00
c5292dd0dd Clean-up: get rid of boost::filesystem
Since C++17 we can use the std::filesystem instead (and we ''do use it'' indeed)
- relocate the `/lib/file.hpp` header
- adapt the self-discovery of the executable to using std::filesystem

Furthermore, some recherche regarding XVideo and Video Output
2025-04-27 23:54:21 +02:00
555af315b3 Upgrade: improve Doxygen parameters and treat some warnings
- remove obsolete configuration settings
- walk through all settings according to the documentation
  https://www.doxygen.nl/manual/config.html
- now try to use the new feature to rely on Clang for C++ parsing
- walk through the doxygen-warnings.txt and fix some obvious misspellings
  and structural problems in the documentation comments.

With Debian-Trixie, we are now using Doxygen 1.9.8 —
which produces massively better results in various fine points.

However, there are still problems with automatic cross links,
especially from implementation to the corresponding test classes.
2025-04-27 05:00:14 +02:00
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
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
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
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
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
f6a2a641df Invocation: tricky pipeline to unfold the repetition-abbreviation
This is a nice little goodie: allow to write repeated arguments with the
shorthand notation known from lisp and logic programming. For multi-channel media,
structurally similar wirings for each channel will be quite common....
2025-02-02 03:49:13 +01:00
5c2b6b69f6 Invocation: can now ''just parse'' the argument spec
can you imagine?
spell out that convoluted syntax, and it just works!!!
2025-02-01 02:21:34 +01:00
bd70c5faec Invocation: pick up work on the render node spec
...at the point where I identified the need to parse nested terms.
The goals are still the same
 * write tests to ''verify connectivity'' of nodes generated by the new `NodeBuilder`
 * allow for ''extended custom attributes'' in the ProcID
 * provide the ability to mark specific parametrisations
 * build a Hash-Key to identify a given processing step

__Note Library__: this is the first time `lib::Several` was used to hold a ''const object''.
Some small adjustments in type detection were necessary to make that work.
Access to stored data happens through the `lib::Several` front-end and thus always includes
the const modifier; so casting any const-ness out of the way in the low-level memory management
is not a concern...
2025-01-31 19:29:04 +01:00
0a0369a4a5 Library: complete test and documentaton of parsing support
This finishes an ''exercise'' in tool design,
which was set off by the requirement to parse the spec-ID of a render node.
While generally within the confines of a helper utility for simple use cases,
the solution became quite succinct and generic, as it allows to handle arbitrary
LL(n) grammars, possibly with recursion.
2025-01-29 23:51:13 +01:00
cdbdf620ca Library: explore how to build a nested-spec parser
...which is the reason for this whole excursion into parser business;
we want to accept specification terms with elements from C++ type expressions,
which especially requires to accept complete comma separated lists within
angle brackets or parenthesis, while separating by comma at top level.

The idea is to model ''not as an expression'' but rather as an ''extended quote'',
and to use inverted regular expressions for non-quote-characters as terminal
2025-01-29 00:16:19 +01:00
f8d0c1cf0b Library: demonstrate »the« textbook example
...evaluating the recursive syntax of a numerical expression!
 * so this light-weight parsing support framework indeed allows
   to build fully capable LL(x) parsers, when the user knows how
   handle syntax clauses and bind the result models
 * furthermore, a notation is demonstrated how to arrange the
   binding functions so to keep the syntax definition legible
 * this involves a shortcut for homogeneous alternatives
2025-01-28 20:23:28 +01:00