Compare commits

..

No commits in common. "integration" and "prg@ichthyostega.de/integration_signature" have entirely different histories.

734 changed files with 11705 additions and 67088 deletions

4
README
View file

@ -61,8 +61,8 @@ For building Lumiera, you'll need:
* https://gtkmm.gnome.org/en/[gtkmm]
* https://cgit.freedesktop.org/xorg/lib/libXv[libXv]
* https://wiki.gnome.org/Projects/LibRsvg[lib rSVG]
* https://git.lumiera.org/gitweb?p=debian/gdl;a=summary[lib GDL]
* https://git.lumiera.org/gitweb?p=debian/gdlmm;a=summary[GDL-mm bindings]
* https://git.lumiera.org/?p=debian/gdl;a=summary[lib GDL]
* https://git.lumiera.org/?p=debian/gdlmm;a=summary[GDL-mm bindings]
Further information:

View file

@ -97,8 +97,6 @@ def configure(env):
problems.append('We need boost::lexical_cast')
if not conf.CheckCXXHeader('boost/format.hpp'):
problems.append('We need boost::format (header).')
if not conf.CheckCXXHeader('boost/lockfree/queue.hpp'):
problems.append('We need boost::lockfree (header).')
if not conf.CheckLibWithHeader('boost_program_options','boost/program_options.hpp','C++'):
problems.append('We need boost::program_options (including binary lib for linking).')

View file

@ -1,47 +1,42 @@
Application : Start-up and Subsystems
=====================================
The Application : Start-up and Subsystems
=========================================
:Date: 2009
:Author: Ichthyo
//MENU: label Start-up
.the purpose of »Application-main«
Lumiera is envisaged as a heavyweight yet coherent »**Application**« -- which implies
it is not so much seen as ``a platform'', framework or operating system. And, in line
with this understanding, we place no emphasis on possible configuration changes and state
transitions within the running application _as a whole._ The ability to react ``life'' to
some global setting changes can be limited to relevant special cases. And, while it is
indeed possible to close and load a new Session from a running application instance, in
most parts of the code base we assume the application just to be ``up and running'' -- all
required services are assumed to be available and interfaces to be accessible. If some of
these assumptions break, an exception is raised and the application unwinds.
Without doubt, these decisions represent a forcible simplification, and might be limiting
at times, yet serve us well to cut down complexity in large parts of the code base --
however, there needs to be _one dedicated realm_ to deal with all these specific concerns
related to configuration, interdependency and lifecyle.
Lumiera is envisioned as a heavyweight yet coherent »**Application**« -- not so much
as platform, framework or operating system. And, in accordance with this focus, we
place no emphasis on possible configuration changes and state transitions within
the running application _as a whole._ And, while in fact it is possible to close
and load a new Session, most of the time we assume the application just to be
``up and running'' -- all required services to be available and interfaces to
be accessible. Without doubt, these are simplifications, but serve us well
to cut down complexity -- yet still there needs to be one dedicated realm
to deal with these specific concerns of configuration, dependency and lifecyle.
The Vessel
----------
So we treat all these concerns within a focused and self contained structure, called
the »**Vessel**«, and clearly set apart from all the other layers, services and subsystems.
This dedicated _Application Realm_ is organised around the ``Application main object''.footnote:[
This is the singleton `vessel::Voyage`, which is triggered by the `main` function
of the Lumiera Application. The sourcecode is kept in a separate folder 'src/vessel'
and linked into the shared library 'liblumieravessel.so']
Its purpose is to bootstrap and tear-down the application in a controlled way,
which includes to provide the backbone services, evaluate the start-up parameters
and to connect and start the necessary core components. The beginning and end of
this vessel's voyage therefore marks the *Lifecycle* of the application, as a
succession of ``lifecycle phases'' -- where almost any activity happens within
the _operational phase,_ when everything is considered ``up and running''.
The Application Realm
---------------------
So we treat all these concerns within a small and self contained structure, clearly
set apart from all the other layers, services and subsystems. This dedicated
_Application Realm_ is organised around the ``Application main object''.footnote:[
This is the singleton `lumiera::AppState`, which is triggered by the `main` function
of the Lumiera Application. The sourcecode is kept in a separate folder 'src/common'
and linked into the shared library 'liblumieracommon.so']
It serves the purpose of pulling up and tearing down the application in a controlled
fashion. And additionally, it provides the Interface and Config core services.
The act of building or tearing down this core realm and main object is what creates
the *Lifecycle* of the application. This is a succession of ``lifecycle phases'' --
and almost all activities happen within the _operational phase,_ when everything
is ``up and running'' or ``just available''.
Subsystems
~~~~~~~~~~
However, before becoming operational, the application must be bootstrapped, and at the end,
all parts need to be unwound cleanly. To organise this process, we identify a limited number
of *Subsystems* within the Application, which are self-sufficient and operate independently,
at least to some degree.
However, initially the application needs to be brought up, and at the end, all
parts need to be unwound cleanly. To organise this process, we identify a limited
number of *Subsystems* within the Application, which are more or less independent.
Each link:{ldoc}/design/architecture/Subsystems.html[Subsystem] is self contained
and groups some other parts and services, which typically work together and may
be mutually dependent. These subsystems represent a grouping, applied for the purpose
@ -66,7 +61,7 @@ the startup phase. It is the responsibility of the _Application main object_ to
pull up required functionality, which in turn might result in pulling up
further subsystems as dependencies.
Subsystems are defined by implementing the interface `vessel::Subsys`, which acts
Subsystems are defined by implementing the interface `lumiera::Subsys`, which acts
as façade to conduct the lifecycle, find out about dependencies and shut down
the subsystem in the end. So this interface, together with the _Subsystem Runner,_
define a lifecycle protocol; each subsystem is free to implement this as it
@ -102,21 +97,20 @@ within the engine independently, relying on worker jobs and a thread pool.
Initialisation and Lifecycle
----------------------------
After some discussion,footnote:[
See the link:{rfc}/GlobalInitialization.html[GlobalInitialisation] RfC
from spring 2008. In the beginning, we all agreed to ``keep matters simple''
and build an `init()` function within one central piece of code everyone knows
and hooks into. However, while the outline of the application emerged, there
was a tension between the concern about _over-engineering_ versus the concern
about _tangled and unmanageable complexity._ At some point, an alternative
implementation based on lifecycle callbacks was elaborated, which then turned
into the solution described here. At that point, Lumiera ceased to be the
typical UI based application started-up by GTK-main, and the existing GTK
code was retrofitted to be launched from within a plug-in.
]
After some discussion,footnote:[See the
link:{rfc}/GlobalInitialization.html[GlobalInitialisation] RfC
from spring 2008. In the beginning, we all agreed to ``keep matters simple''
and build an `init()` function within one central piece of code everyone knows
and hooks into. However, while the outline of the application emerged, there
was a tension between the concern about _over-engineering_ versus the concern
about _tangled and unmanageable complexity._ At some point, an alternative
implementation based on lifecycle callbacks was elaborated, which then turned
into the solution described here. Lumiera then ceased to be the typical UI
application started by GTK, and the existing GTK code was retrofitted to
launch from within a plug-in.]
the design leaned toward loosely coupled parts and a formal lifecycle; which
saves us from investigating and coding up the various interdependencies
explicitly. Rather, all parts of the application have to comply to
explicitly. Rather, the parts of the application have to comply to
link:{ldoc}/design/architecture/Subsystems.html#lifecycle[Lifecycle Phases],
and each part has to care for its own state transitions, invoked through
_lifecycle callbacks._ We can distinguish two distinct models how to deal
@ -134,9 +128,9 @@ Application Start
~~~~~~~~~~~~~~~~~
* some fundamental language-level facilities will be prepared during
_static initialisation._ At some point, execution enters `main(argc,arvv)`.
* `Voyage::init()` brings up the plugin loader and opens the config-interface.
* `AppState::init()` brings up the plugin loader and opens the config-interface.
* ...followed by triggering *ON_GLOBAL_INIT*
* the main thread then pulls up the subsystems (`Voyage::maybeStart(subsystem)`),
* the main thread then pulls up the subsystems (`AppState::maybeStart(subsystem)`),
according to the command line options.
* within each subsystem, façade interfaces will be opened through the
interface/plug-in system.
@ -148,7 +142,7 @@ Application Start
the main window.
* there is an *ON_GLOBAL_SHUTDOWN* event, which can be used for normal cleanup;
In case of an emergency exit, the *ON_EMERGENCY_EXIT* event is triggered alternatively.
* the Voyage destructor tears down the core systems (config-interface and pluginloader).
* the AppState destructor tears down the core systems (config-interface and pluginloader).
* we establish a policy to _prohibit any non-local and non-trivial activities_ during the
tear-down phase after leaving the `main()` function.

View file

@ -1,71 +1,15 @@
Application and Session Configuration
=====================================
Lumiera Design: Application and Session Configuration
=====================================================
.After initial discussion, this topic was postponed.
[CAUTION]
In its current form, as of 2026, the Lumiera application is headed towards a first
integration of the parts developed thus far. A simple configuration file, 'setup.ini'
is used to supply some minimal parameters for bootstrap of the application; all further
settings are defined as local constants in the source code.
*TODO* : 'write design document'
**Configuration and Parametrisation** of software describe a state of setting, that lies
between the fixed structure embodied into the code and the transient work state of the
application. It encompasses all settings and options that determine how a software system
behaves in a specific environment, without changing its underlying source code.
The Lumiera application uses two quite different sources for configuration
The purpose of configuration
----------------------------
For a video editing application, the scope of ``configuration'' can be far reaching.
Not only are there numerous parameters in the engine, that must be fine-tuned for optimal
performance, but also several patterns of behaviour are available that can not be decided by
first principle alone and must thus be left open for the user to configure to their preference.
Some of these are linked to the actual user, some to the setup in the system, and some to the
current project.
Furthermore, many of these ``settings'' turn out, upon closer inspection, to be a form of
rule-based knowledge. In a project with the scale of a movie, it is essential for a fluid
and intuitive working style to handle some default setup and configuration of connections
and conversions automatically, while the user can have very valid reasons to prohibit
some other specific class of automatic conversions to be applied without explicit confirmation.
- individual __settings values__ can be loaded from an application- and user configuration in the conventional way
- various facilities, especially in the Steam-Layer, base the actual behavour on __queries__, which are
to be resolve employing a rules based system '(planned)'. Configuration rules will be provided by the
application (defaults), a session template and rules stored in the actual session.
After some initial, prototyping for a ``config loader'', it was deemed too risky to engage
into any kind of preliminary design without knowing the possible ramifications. +
-> link:/x/rfc/ConfigLoaderDraft2008.html[Config Loader brainstorming from 2008]
-> see also the link:rfc/ConfigLoaderDraft2008.html[Config Loader brainstorming from 2008] (implementation details)
The following preliminary measures have now been established for the ongoing development:
- whenever a _tweaking parameter_ is discovered, it will be extracted and marked
with a **language constant** in the setup or integration header of the software component.
- whenever a _decision point_ is encountered, that can not be related to technical dependencies,
it is marked as a **query call** -- with a corresponding, hard-wired _faked configuration rule_.
The integration of some kind of configuration rule language is considered part of the primary agenda.
Requirements
------------
To track any insights gained regarding the requirements for configuration,
https://issues.lumiera.org/ticket/1224[Ticket #1224 (»Layered Configuration«)]
was added to the list of medium-term
https://issues.lumiera.org/report/17[»Focus Topics«]
The following requirements have been identified to date (2026)
- It is pointless to build one huge flat global "configuration file";
rather, groups of configuration settings are scoped and closely related to a _local context_
- the degree of _consistency checking_ must be tied to such a local context, where the
situation is reasonably clear: the consumer of specific configuration usually has
clear-cut requirements to demand some configuration to be mandatory, while other
configuration is optional. Misspelled or misplaced configuration that does not
fit in such a category must be flagged as error.
- such a locally defined set of expected and optional configuration might become
subject to versioning (forward- / backward compatibility)
- Configuration must be assembled from several configuration sources,
with clearly defined precedence and shadowing. Notably we have default configuration,
system-wide configuration, user specific configuration and project related configuration.
- a _preferences UI_ must be able to alter configuration settings, thereby intelligently
routing the changes into the appropriate configuration source or create a suitable overlay
- when configuration causes a decision from a rule to flip, this fact must be recorded
permanently in the session; the reason for this mechanism is that configuration might
change later, and the application must be able then to point out all places
affected by the change.
- Any detected configuration change must be captured and logged as Event and thus
be un-doable cleanly, with all possible ripple effects.

View file

@ -1,48 +1,10 @@
The Application Realm
=====================
Design Documents: Application Framework
=======================================
// Menu : prepend child ApplicationStart
Shaping the outside world through software requires a variety of effective mechanisms
that capture, represent, and transform elements of reality. A well-designed part is
focused on a single aspect, is coherent and cohesive in itself, with links to other
parts based on concepts and abstraction rather then on shared technology. Yet this
structural perspective must be complemented by a meaningful overall arrangement that
supports the desired workflow and can be adapted to circumstances.
* link:Config.html[Configuration]
* link:plugin_loader.html[Plugin Loader]
* link:ApplicationStart.html[Application Subsystems and Lifecycle]
In software systems, such coherency does not emerge spontaneously. It must be supported
by definition work to establish suitable terms and interfaces, components must be
interconnected and configured, and the overall state needs coordination.
An application is therefore more than just a collection of software components.
In the Lumiera Architecture, this application realm is embodied into a structure
called the »**Vessel**«:
- it is built as a library with only basic linkage to the support library
- it can be invoked from a `main()` function, with an argument parser
- at source code level, it provides all the types and definitions
required to express the _binding_ between components
- _conceptually,_ all layers are encased in the _application vessel_
- and while the Vessel can not just ``control'' the configuration of parts
on upper layers, it has to bootstrap their ability to adapt to circumstances.
--
 
--
Dependencies::
While the code base is organised into _three layers,_ the actual implementation
structures are arranged into **Subsystems** that _depend_ on each other and
can be _started and shut down_
+
-> link:ApplicationStart.html[Subsystems and Lifecycle]
Configuration::
As a means to adapt to the environment and enable flexibility,
this topic is surprisingly intricate and development has barely scratched
the surface: while the effective configuration is assembled from several
layered sources, the meaning (and documentation) of individual settings
is scoped, and users can expect the ability to override some settings
from within the application.
+
-> link:Config.html[Configuration]

View file

@ -0,0 +1,5 @@
Lumiera Design: Plugin system
=============================
Eventually, this will have design documentation for the Plugin system.

View file

@ -237,7 +237,7 @@ Lifecycle Events
The Application as a whole conducts a well defined lifecycle; whenever transitioning to the next phase,
a _Lifecycle Event_ is issued. Components may register a notification hook with the central _Lifecycle Manager_
(see 'include/lifecycle.h') to be invoked whenever a specific event is emitted. The process of registration
can be simplified by planting a static variable of type `vessel::LifecycleHook`.
can be simplified by planting a static variable of type `lumiera::LifecycleHook`.
WARNING: A callback enrolled this way needs to be callable at the respective point in the lifecycle,
otherwise the application will crash.
@ -246,7 +246,7 @@ WARNING: A callback enrolled this way needs to be callable at the respective poi
Invoked as early as possible, somewhere in the static initialisation phase prior to entering `main()`.
In order to install a callback hook for this event, the client must plant a static variable somewhere.
`Voyage`::
`AppState`::
This is the Lumiera »Application Object«. It is a singleton, and should be used by `main()` solely.
While not a lifecycle event in itself, it serves to bring up some very fundamental application services:
+
@ -255,7 +255,7 @@ WARNING: A callback enrolled this way needs to be callable at the respective poi
- the application configuration
--
+
After starting those services within the `Voyage::init()` function,
After starting those services within the `AppState::init()` function,
the event `ON_GLOBAL_INIT` is emitted.
`ON_GLOBAL_INIT`::

View file

@ -1,19 +0,0 @@
Extending the Application
=========================
During the inception phase, the link:/x/rfc/AllPluginInterfacesAreC.html[idea was commended]
to bootstrap the application as a multi-lingual compound of plug-ins, for maximum flexibility
and ease of contribution. Although this approach garnered much support initially, the ensuing
discussions questioned its viability, with well-known plugin-based systems and frameworks
cited as cautionary example.
A prototype implementation
(-> link:PluginBrainstorm.html[draft for the plugin interface])
was nevertheless developed, but it proved problematic in practical use.
The goal of a flexibly expandable application is still maintained,
but the path to achieving it should be based on actual requirements.
Development of an https://issues.lumiera.org/ticket/1212[Extension Concept #1212]
was thus placed on the list of medium-term
https://issues.lumiera.org/report/17[»Focus Topics«]

View file

@ -7,23 +7,22 @@ Lumiera Design Documents
// Menu : prepend child design/gui
// Menu : prepend child architecture
// Menu : append child extension
// Menu : append child plugins
// Menu : append child workflow
// Menu : append child governance
Lumiera aspires to be a professional tool for video editing on
Lumiera is to be a professional tool for video editing on
GNU/Linux systems. The vision of the development team defines a modern design
for the core of a Non-Linear Editing software. A key aspect of Lumiera
is the strong separation between the user interface and the processing core.
We are developing Lumiera with a general purpose GTK UI -- which is loaded as
an optional component, so that the core can also be invoked from scripts to
use the editing and processing capabilities of the engine.
We are developing Lumiera with a GTK GUI but that will in no way be exclusive;
other GUIs can be written, as well as scripts to drive the core.
This becomes possible by an ongoing effort to decrease coupling. Each major
component in the application strives to be open to extensions, but closed
against external modification. The presentation, the model and the ``performing''
of the model are separate and self-contained parts of the application.
Lumiera as a processing core will be able to perform any conceivable task
on video and audio, maybe even tasks entirely unrelated to video editing.
of the model are separate and self-contained parts of the application. Lumiera
as a processing core will be able to perform any conceivable
task on video and audio, maybe even tasks entirely unrelated to video editing.
.Workflow
*****************
@ -53,8 +52,7 @@ specialised GUIs. The interface is the component that is closest to the user. I
provides purely visual interaction with the user. Within this work environment, the user
manipulates, organizes, loads, configures all sorts of data, especially MObjects (media
objects) and Assets. These elements are contained within a structure called the Session. +
-> link:gui/index.html[GUI/Stage-Layer design documents] +
-> link:{ldoc}/technical/stage/index.html[GUI technical documentation]
-> link:gui/index.html[GUI/Stage-Layer design documents]
Steam: the Transformation Layer
@ -89,23 +87,24 @@ the screen or to external output. +
Extra Components
----------------
The Vessel
~~~~~~~~~~
A structure that is anchored below all layers, yet contains everything, conceptually.
Definitions for building common interfaces are located here, as is the mechanism for initialisation
and shutdown of the application, the loading of bootstrap configuration and optional components.
It encloses and coordinates all parts to work together as a coherent whole.
This -> link:application/index.html[Application framework] is complemented by
a link:{ldoc}/technical/library/index.html[Support-Lbrary] with commonly used components,
algorithms and data structures.
The Application
~~~~~~~~~~~~~~~
The application controls the initialization and shutdown procedures as well as
loading external elements such as plug-ins, which are widely used throughout
Lumiera. It acts as the framework which supports core component operations. This
framework is complemented by a library of commonly used components, algorithms and data structures. +
-> link:application/index.html[Application framework]
link:plugins/index.html[Plugins]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Plug-ins play an important role within Lumiera since the application relies
heavily on current FLOSS implementations and external libraries. Moreover, the
application will be configurable and can be extended in various
ways; whenever some extension isn't permanent or will be used only on demand, it
is packaged as a separate module into a plug-in. For example, the GUI of Lumiera
is a plugin. +
-> design documents regarding the link:plugins/index.html[Plugins]
Extensions
~~~~~~~~~~
Lumiera uses proven and field-tested implementations for the actual media processing,
which are available as FLOSS or open-source libraries. To avoid extensive external dependencies
on the main application however, such libraries need to be loaded through _adaptor plug-ins._
Furthermore, the application will be configurable and it is conceivable that external
extensions will be created. Designing and building a future-proof framework for configuration
and extension is an important medium-term goal for further development.

View file

@ -1,30 +1,14 @@
Low-level Services
==================
Design Documents: Vault
=======================
Towards the _upper side_ of the Lumiera core, in »Steam Layer«,
several components and subsystems work together to provide functionality
that is close to the requirements of the _problem domain_ -- editing and
rendering of media. The implementation of these features however requires
a foundation of generic, technical services: Memory needs to be allocated,
working buffers must be provided and managed, work tasks coordinated.
It is hard to associate these responsibilities directly to
some specific domain, other than just _data processing._
What follows is a summary of Lumiera's *Data Handling Backend*
A common trait of all those special aspects of processing is that they
require special care and attention to achieve the necessary level of
performance, while they are _technical_ in nature and do not directly
reflect and model structures of the real world.
Data Handling
-------------
The task of editing video and processing media requires to read and write
a significant amount of data, while using the capabilities of the hardware
to the best degree possible. Lumiera thus needs a foundation layer for
high volume data access; two kinds of data handling can be distinguished:
This is the foundation layer responsible for any high performance or high volume
data access. Within Lumiera, there are two main kinds of data handling:
* The Session and the object models manipulated through the GUI are kept in memory.
They will be backed by a _storage backend,_ which provides database-like storage
and especially logging, and controlled execution of _mutating actions._
They are backed by a _storage backend,_ which provides database-like storage and
especially logging, replaying and ``Undo'' of all ongoing modifications..
* Media data is handled _frame wise_ -- prefetching data asynchronously.
The goal is to optimize CPU utilization; large scale data IO will be performed

View file

@ -0,0 +1,4 @@
Design Documents: Plug-In
=========================
* link:PluginBrainstorm.html[early draft for the plugin interface]

View file

@ -1,15 +1,16 @@
Lumiera Workflow Proposals
==========================
:Author: Wouter Verwijlen
:Date: 16 March 2026
:Date: 19 August 2025
:TOC:
I would like to share a collection of workflow ideas for Lumiera. These ideas come from
having cut hundreds (or possibly thousands) of videos over the past 20 years as a professional
editor, working in Avid Media Composer, Adobe Premiere, Lightworks and DaVinci Resolve.
I would like to share a first version of a collection of workflow ideas for Lumiera. These ideas come
from having cut hundreds (or possibly thousands) of videos over the past 20 years as a professional
editor, working in Avid Media Composer, Adobe Premiere Pro (from before it was called "Pro"),
Lightworks and DaVinci Resolve.
This document focuses on analysing the behaviour of Non-linear Editors (NLE's): software
in which a user can edit films and videos, in order to discuss possible solutions for the
This document focuses on analysing the behaviour of Non-linear Editors (NLE's), in other words
software in which a user can edit films and videos, in order to discuss possible solutions for the
design of Lumiera.
The main ideas behind these proposals are:
@ -177,354 +178,14 @@ specific project in order to select the parts needed for the final edit. I will
which different NLE's handle this and will propose possible directions for Lumiera to support
certain workflows.
Project creation
~~~~~~~~~~~~~~~~
When starting a new project, a user often needs to set the project resolution and framerate. Adobe
Premiere (optionally) shows an import panel immediately after this. The first time you drop a clip
on a timeline, Resolve and Premiere will ask if you want to change your project settings to match
the clip settings, when these are different.
.Premiere's import panel
image::{imgg}/wouter/v4-01-importPanel.jpg[width="100%", alt="Premiere's import panel"]
Projects themselves exist within an application's database (Resolve), or as a file/folder on local or
shared storage (Avid, Premiere, Lightworks, FCP).
One of the first things that needs to be setup is the organisational structure of the project, in other
words: the structure that's going to house all of the project's contents. Most applications use bins for
this, a bin being simply a container for items like video clips. In a sense they are similar to folders
on a computer's storage, except bins usually only exist within the project in your NLE. Avid's bins
also exist as folders on local or shared storage, but this is an exception.
For top level organisation, bins can either be placed in other bins (Premiere, Resolve) or in
groups/folders (Avid, Lightworks).
As we'll see throughout this document, Final Cut Pro is usually the only application that takes a
different approach. Projects are called ``libraries'' and FCP sorts footage based on events (top level
containers of timelines, footage and keyword collections), keywords (tags) and collections, instead
of bins (timelines are confusingly called ``projects''). Footage, when imported, is placed in an event
and from there all emphasis is on the metadata, in how you rate and tag (parts of) the footage. This
also serves as a replacement of the subclips feature found in other NLE's.
.Final Cut Pro's Keywords dialog. +
image::{imgg}/wouter/v4-02-keywords.jpg[width="100%", alt="Final Cut Pro's Keywords dialog"]
^↑``Travel part 1'' and ``Travel part 2'' on the left are events.^
In any case, when working in a professional environment, you will probably want to start with a
template that defines your top level structure, instead of having to recreate your entire bin setup
for every project. Surprisingly, at the time of writing only Adobe Premiere has introduced a project
template feature (in version 2024). In other apps you will need to manually create your own template project
and duplicate that, or even literally copy and paste bins from a template project in a file browser (Avid).
Importing footage
~~~~~~~~~~~~~~~~~
Every application works with clips: virtual representations of (parts of) the video files that exist on
your preferred type of storage. Getting footage into your project (``ingest'') will create these clips in
your project. Most apps will offer several options to do this:
. Creating links to the original video files, wherever these may reside (on your computer,
external storage, network storage or in the cloud).
. Copying your files to a dedicated folder managed by the application (this could again be on
local or network storage). Importing to a dedicated application folder is very useful for
feature film editing and TV production, but is less common elsewhere in the media industry.
Its strong point is that when your media is managed by the application, you won't have to
re-link files when moving to a different editing station.
. Optionally, files can be transcoded during import. New media files will be created in either
the app's dedicated folder or to a user specified location. The transcoded files will be much
more optimised for editing, resulting in better playback performance.
The latter is part of what is known as the *offline-online* workflow, in which you work with
optimised files, and once an edit is finished (``picture lock''), the clips on the timeline
will be exchanged with clips that link to the original camera files. Often, after colour grading
in an external application, all colour graded shots are rendered with their colour corrections
and placed back onto the timeline in the NLE.
A specific type of offline-online workflow is the *proxy workflow*, that allows switching
on-the-fly between the proxy files and the original camera files and will ensure that exports
of your video will use these original camera files when rendering. When using a proxy workflow,
you can either create optimised files inside the application itself (or in Premiere's case, via
Adobe Media Encoder) or attach existing proxy files that were created by a third party application
or by the camera during recording.
After importing media and possibly creating/attaching proxies, clip attributes might need altering.
You might need to change incorrectly determined frame rates or, more commonly, change the audio
channel mapping of your clips (e.g. setup clips with two audio channels as dual mono instead of
stereo).
Clip types
^^^^^^^^^^
We usually find the following types of clips in NLE's:
Source clips:: they represent media files (containing video and/or audio streams) to its full
extent, and for other types of media (most notably still images) -- these usually get a default
duration upon import.
Subclips:: they represent a portion of a video or audio file.
Timeline clips:: duplicates of source clips that only exist within a timeline. Properties of
these clips can often be altered without altering the same properties of the source clip.
Compound clips/nested sequences:: these are in fact (sub)timelines that can contain any
number of tracks and clips.
Multicam clips:: (group clips in Avid), these are compound clips, in which multiple clips are
synchronised and combined into one. This compound contains clips with different camera angles
(for video) or audio recordings for the same event.
Filler (Avid), FX clips (Lightworks) or Adjustment Clips (Premiere, Resolve):: these special clips
can hold effects that are applied to all clips on lower tracks of a timeline, directly underneath.
Bin types
^^^^^^^^^
Often there are two types of bins in which these clips sit
. ``Normal'' bins.
. Search bins (Premiere) / filters (Lightworks) / smart bins (Resolve) / smart collections
(FCP): for these you setup certain rules based on clip names or metadata. All clips to which
these rules apply are automatically added to these bins. This means that the same clip can
simultaneously exist in a regular bin and a search bin, in contrast to normal bins, where each
clip will only exist in a single bin and you'd have to duplicate this clip for it to be also
placed in another bin (Lightworks being the exception here).
.Filter options in Lightworks
image::{imgg}/wouter/v4-03-filterOptions.jpg[alt="Filter options in Lightworks"]
Resolve adds a third kind of bins, known as ``Power bins'': these are bins that are accessible by all projects.
Bin views
^^^^^^^^^
Bins offer several views to see its contents. These include:
* List View / Text View: all items in the bin are listed vertically. Multiple columns will show
different kinds of metadata -- the user can choose which fields are displayed and can
rearrange their order.
* Icon View (Premiere) / Frame View (Avid) / Thumbnail View (Resolve) / Tile View
(Lightworks): this will show a small frame from each clip in a raster. In general you're able
to change which frame is displayed if you wish to see another.
* Freeform View (Premiere): same as Icon View, but you can freely position the clips
wherever you want. Note that Avid and Lightworks allow you to do this within Icon/Frame
View itself.
* Script View (Avid): similar to Text View, but with a frame being displayed for each clip and
a large field for entering comments. In Script View, the vertical order of clips can be
rearranged, in contrast to Text View, which only supports automatic sorting.
* Metadata View (Resolve): similar to Avid's Script View, except you can't reorder clips.
* Filmstrip View (Final Cut Pro): similar to Icon View, but [red]#TODO: missing text??#
Avid is famous for allowing you to save your Text or Script View configuration as a preset that can
be quickly recalled. Premiere allows this through its Metadata Display window, Final Cut Pro by
Control+left clicking any column header and Lightworks via the Columns > Presets menu, but these
methods are less straightforward than Avid's. Another neat feature that Avid has is a bin map: an
overview of bin contents that can be toggled when in Frame View.
.Creating a custom view preset in Avid Media Composer, which can be selected from the drop-down menu in the top bar.
image::{imgg}/wouter/v4-04-customView.jpg[width="120%", alt="Creating a custom view preset"]
Note that all apps offer a search/filter box (or button) on top of each bin view. Final Cut Pro and
Resolve allow skimming clips from the bin view, simply by hovering the mouse on top of the
thumbnail and moving it from left to right.
Organising footage
~~~~~~~~~~~~~~~~~~
Once your footage is represented by clips in bins, organisation can begin. Wildly different methods
exist for this. In the simplest version you will just drop your footage in one or several bins and be
done with it. In professional environments there are often strict bin structures and naming
conventions, and additional methods for organising are being used:
* First and foremost: with multi-camera shoots and/or when audio has been recorded
separately, now is the time to synchronise these. Create multicam clips and/or synchronise
sound, either in the NLE itself, or in an external application. I personally create source reels
first (see further down this list), export these to another application for syncing, import the
synced reel back, and in case of a multicam shoot, split this reel into multiple reels and
convert each to a multicam clip (Premiere and Resolve both support this).
* Metadata. This is a very powerful way to search for or filter specific types of content and it
could be a chapter on its own. Metadata is often created by the camera during recording,
added during offloading by a DIT (digital imaging technician) or applied after ingest by
assistant editors. Nowadays metadata is also added by AI/machine learning algorithms to
help identify the contents of a clip, create transcriptions from audio, etc. Avid provides the
option to (automatically or manually) connect clips to lines in a script (ScriptSync).
* The aforementioned subclips are often used to extract sections out of a longer clip.
* Sequence/timeline markers to mark points in time, or sections (so-called ranged or spanned
markers; terminology is different per app).
+
.Plenty of marker options in Adobe Premiere
image::{imgg}/wouter/v4-05-markerOptions.png[width="70%", alt="Marker options in Premiere"]
+
* Timeline clip notes (Avid): these can be added to a timeline clip, and will stay connected to
this clip. You can't trim them off and they will automatically move whenever a clip moves.
They can be burned into a render upon export. Premiere and Resolve offer clip markers
instead -- these are similar to sequence markers, but are attached to clips.
* Tagging or rating (parts of) clips (FCP and to a lesser extent Resolve). FCP's rating only
goes as far as letting you mark clips or sections as ``favourite'' or reject clips entirely,
but its keyword system (as described later in this chapter) is much more elaborate and useful.
Resolve has an option to add keywords, but its workflow is quite clunky when trying to
apply this to a section within a clip.
* Clip colours. Often there exist multiple levels at which a clip can get a colour. Colours can be
applied based on source clip (usually different colours for different media types), timeline
clip, timeline track, offline footage, different framerates, and more. Avid has the most
options in this field and lets you choose exactly which types of colours to display on the
timeline. Manually set clip colours are a very useful organisational tool, e.g. to differentiate
between several cameras, interviewed persons in a documentary or different locations.
+
.Avid has many options for choosing how clips are coloured in the timeline
image::{imgg}/wouter/v4-06-clipColor.png[width="50%", alt="Coosing clip colours in Avid"]
+
* Flags (Resolve). Similar to markers, but these apply to entire (source) clips, while markers
apply to a single point in time or a time range within a clip. Multiple flags can be added to
each source clip.
* Reels: source footage is divided over one or multiple timelines to be able to quickly navigate
many clips without having to load individual clips in the source viewer. These are called
``source reels''. A special kind of source reel is a ``sync map'', which contains all footage
of a day of shooting from multiple cameras synced and laid out chronologically.
FCP doesn't quite support source reels and instead offers continuous playback from the
browser window. Resolve has a ``source tape'' option that works in a similar way.
.Simple example of a source reel (top), converted to a sync map (bottom)
image::{imgg}/wouter/v4-07-syncMap.png[width="100%", alt="Example of a sync map", link="{imgg}/wouter/v4-07-syncMap.png"]
Viewing footage
^^^^^^^^^^^^^^^
Once basic organisation is in place, the editor can start watching and adding further notes/comments
to narrow down large amounts of footage and seek out options of useful content for the edit. Most
apps offer two types of monitors for video playback: source and record/program monitors. FCP has
only a single monitor that switches between these two functions. Some others (Avid, Resolve) give
users the choice between single or multi viewer modes. Lightworks and Avid support an unlimited
amount of floating viewers.
.You can open (and position) as many viewers as you like in Lightworks
image::{imgg}/wouter/v4-08-multiViewer.jpg[width="120%", alt="Multiple viewers in Lightworks", link="{imgg}/wouter/v4-08-multiViewer.jpg"]
Viewers are usually coupled with timecode display and have a ton of settings.
I won't go into details about these.
In most applications you can also watch your source footage from the bin when in Frame/Icon
View. You'll be able to use JKL shortcuts for playback, mark in and out points and add it to the
timeline, similar as to when the clip is loaded in the source viewer. Final Cut Pro lets you click and
drag in-out regions in the thumbnail.
Selects
^^^^^^^
Time to create a selection of material to consider for the rough cut. One way to do this, as
previously described, is by creating subclips or by tagging. Drop the subclips in a bin in
Icon / Frame View and you have a good visual overview of selected shots. This is great for selecting
B-roll material, or for projects that require a very visual approach, f.e. trailers, music videos
or aftermovies (not hoping to ever cut one of those again though, but that's a different story 😉).
Another way to select footage is to cut selections from source clips or source reels to one or more
selects reels: these are timelines that hold your selections and are only used for that purpose. Selects
reels can then be loaded again as if they were a source clip, in order for an another selection to be
made. This is called *reel-to-reel editing*. Many apps allow seeing the source timeline, either in their
own panel (Premiere) or window (Lightworks), or by switching the timeline panel between a source
and record mode (Avid, Resolve). A method known as _pancake timeline editing_ works when an
application supports viewing multiple timelines simultaneously. By stacking timelines above each
other you can easily drag selections from one timeline to another. This is possible in Premiere,
Lightworks and Resolve.
.Pancake timeline editing in Lightworks
image::{imgg}/wouter/v4-09-pancake.png[width="110%", alt="Example of a sync map", link="{imgg}/wouter/v4-09-pancake.png"]
Reels can be further managed by using markers to describe certain points in time or sections, and
these markers can be viewed as a list in their own panel. When selecting a marker in this panel, the
playhead of the corresponding monitor will jump to the (start) frame of this marker. Markers can
have multiple input fields and a colour. They are one of the most important tools to be able to make
notes and navigate large amounts of footage over extended periods of time. As an aside: Lightworks
has an option to turn ranged markers into subclips, quite useful, as it allows you to use markers
to make your selection.
Some NLE's have a ``ripple markers'' option for timeline markers. This means markers will move
when clips in the timeline are shortened or extended.
FCP has ``todo markers'' that can be checked. And when tagging clips with keywords in FCP,
keyword collections are automatically created in which all sections of clips with the same keyword
can be found. It's also possible to manually create keyword collections and drag and drop clips or
tagged sections (``content ranges'') there.
Back to the reels: one advantage of reel-to-reel editing is that it's very useful to see the audio
waveforms of your source clips on an actual timeline: this way you can freely zoom and scroll.
Final Cut Pro will only display a clip's waveform at the bottom of the clip preview in the browser,
but when an interview is an hour or longer, this waveform will be squeezed in a way that's of little
use.
Another advantage of reel-to-reel editing is a sense of space: you get an idea of where certain
footage can be found (more to the left, in the middle, or at the end of a reel). Combined with
markers, clip colours and gaps between sections, this makes it easier to find things back later. A third
advantage is that it's easy to filter in rounds: you can narrow down your footage in multiple reel-to-reel
selection passes.
I personally often use a variation of reel-to-reel editing, in which I lift sections in my source reel.
I then duplicate this reel, remove the first video and audio track(s) and keep the lifted parts to create
my selects reel. The advantage here is that I can rate sections as _not useful_ (V1), _possibly useful_
(V2), _quite useful_ (V3) or _highly useful_ (V4) by lifting the video clip one, two or three tracks up --
see it as a 4-star rating system. I have seen other editors use this method for selecting footage,
although in all fairness I'm not sure how widespread this technique is.
.Lifting selections; also note the use of clip colours, gaps and markers for organising the selects reel.
image::{imgg}/wouter/v4-10-selectsReel.png[width="100%", alt="Example of a sync map", link="{imgg}/wouter/v4-10-selectsReel.png"]
In FCP you can create your own rating system by using keywords (as shown in the screenshot at the
start of this chapter) and then having everything filtered through keyword collections, as described
in this https://blog.frame.io/2016/10/18/make-fcp-x-log-better-1/[blog post at Frame.io].
Quite handy as well!
Proposals
~~~~~~~~~
* Which system(s) of organising a project and selecting footage should Lumiera support? I
would say: most. They don't interfere with each other, so let the user choose. Definitely
support source timelines and let people rate, tag and mark all they want. Subclips might not
be necessary when a tagging/keyword system is present, as Final Cut has proven.
* Metadata-based organising, searching and filtering of content are _must-haves_.
* I would include a native rating system (1 to 5 stars should suffice) that works both on clip
sections and entire clips, rather than FCP's favourite/reject system, as it's more granular.
* As for bins-in-bins vs bins-in-folders: the first one is more flexible (bins can contain both
media files and other bins, while folders can only contain bins) and more closely resembles
how folders work on a PC, so my preference would be to go that route, although there's also
something to be said for the strict division of function that folders+bins have.
* I would like to propose an option to automatically create source reels based on rules you can
set, for example: one source reel for every day of shooting. These automatic source reels
could have a filter function to select which clips are being displayed on the timeline. This
way it becomes easy to say something like ``show me all clips from the second day of the
shoot from camera A''.
* A versioning system for timelines is something that only Resolve has recently picked up
with its Create (and Restore) Timeline Backup feature, and honestly I've been amazed by
how this hasn't been a core feature in NLE's for decades now, as it makes so much sense to
have. Let users make snapshots and perhaps make one automatically every day, without the
need to manually duplicate and rename timelines and putting them in some sort of archive
bin.
* Importing: auto-import based on watch folders could be very useful during certain stages of
an edit. Setup which folders to watch and whenever a new file is dropped in that folder it
will be imported into a bin of choice. Especially handy when working with sound effects.
However, we might not want to be scanning folders all the time.
* About sound effects: there's a free application called Metadigger that let's you quickly filter
your sound collection by metadata and then copy sound files to your project folder with a
keyboard shortcut. Something like this, built-in, would be quite handy for those of us with
local sound effect libraries.
* A small one: I'd like each project to remember the last location you imported from. I often
switch between projects and each time I want to import something in current NLE's, the file
dialog points to the last used directory, which is often the wrong one.
Not a big deal, but not ideal either.
[red]#To be written:#
- Asset organisation: bins vs metadata-based structures (+ search bins/filters)
- Viewing footage: single clips vs source reels; continuous playback from browser
- Source monitor + program monitor vs a single monitor
- Creating selects: selects reels, subclips and keyword collections
- On markers and notes
- From selects to editing in the timeline: Timelines in the source viewer: reel to reel editing
Chapter 2: the timeline
-----------------------
@ -622,7 +283,7 @@ Editors often proudly share screenshots of their timelines on social media, and
impressive, but these are in fact pretty fragile structures.
.One of my own timelines, which is relatively simple by comparison to those of many Hollywood movies
image::{imgg}/wouter/v3-01-timeline.jpg[width="110%", alt="Screenshot of a timeline", link="{imgg}/wouter/v3-01-timeline.jpg"]
image::{imgg}/wouter/01-timeline.jpg[width="110%", alt="Screenshot of a timeline", link="{imgg}/wouter/01-timeline.jpg"]
So naturally, a question would be: what will happen if we would let go of the track paradigm? This
is what Final Cut Pro has done, starting from the rewrite of Final Cut Pro X. At the time, a
@ -639,10 +300,10 @@ primary storyline, and all connected clips automatically move with it. With a mo
ignore clip connections, so that you can also easily move a primary clip elsewhere without its
connected siblings coming along.
image::{imgg}/wouter/v3-02-trim-magnetic-1.jpg[width="100%", alt="(before trim)"]
image::{imgg}/wouter/02-trim-magnetic-1.jpg[width="100%", alt="(before trim)"]
.Extending one clip will automatically move all connected clips in order to keep sync
image::{imgg}/wouter/v3-02-trim-magnetic-2.jpg[width="100%", alt="(after trim)"]
image::{imgg}/wouter/02-trim-magnetic-2.jpg[width="100%", alt="(after trim)"]
_Sounds good._ Why not just copy this? One reason is that FCP assumes that all clips that are not on
the primary storyline should be connected to this primary storyline. This might work well for fiction
@ -657,7 +318,7 @@ How else could we group clips together that ought to be connected? +
We could create groups that are directly editable, like so:
.Compound clips
image::{imgg}/wouter/v3-03-grouped-1.png[width="100%", alt="Timeline with compound clips"]
image::{imgg}/wouter/03-grouped-1.png[width="100%", alt="Timeline with compound clips"]
However, there are a few problems with this: we expect rendering to happen from top to bottom, in
which case the b-roll would cover the subtitles. On top of that, it's hard to see at which points video
@ -666,7 +327,7 @@ clips overlap. Last but not least: it looks rather unorganised.
Can we restructure this? Perhaps like this:
.Overlapping compound clips
image::{imgg}/wouter/v3-03-grouped-2.png[width="100%", alt="Timeline with stacked overlapping compound clips"]
image::{imgg}/wouter/03-grouped-2.png[width="100%", alt="Timeline with stacked overlapping compound clips"]
But how exactly would a user interact with a timeline like this? I will leave the answer to that
question for an actual design document, as for now I just wanted to show the concept of grouping so
@ -693,7 +354,7 @@ FCP's precision editor. It doesn't change the working of keyboard shortcuts or t
alters the timeline via animations in a very fluid way.
.Final Cut Pro's precision editor
image::{imgg}/wouter/v3-04-fcp-precision-editor.jpg[precision editor]
image::{imgg}/wouter/04-fcp-precision-editor.jpg[precision editor]
Another example is the Trim View in DaVinci Resolve: whenever you perform a trimming
operation, the program monitor displays a trim view (showing the frames left and right of the cut
@ -725,7 +386,7 @@ the use of a _contextual bar_ that appears over the bottom part of the timeline
mode is active.
.Contextual bar with options for the mode/tool
image::{imgg}/wouter/v3-05-contextual-bar.png[width="100%", alt="contextual bar"]
image::{imgg}/wouter/05-contextual-bar.png[width="100%", alt="contextual bar"]
Currently I'm thinking of using this bar on two or three occasions:
@ -806,10 +467,10 @@ One last thing I would like to address is the destruction that an insert operati
this can be prevented by proper track management, but you can wonder why you would ever want
an insert action to cause the following:
image::{imgg}/wouter/v3-06-sync-insert-1.png[height=110, alt="sync insert"]
image::{imgg}/wouter/06-sync-insert-1.png[height=110, alt="sync insert"]
.Inserting a clip with sync locks enabled for V2 might split a clip in Avid Media Composer.
image::{imgg}/wouter/v3-06-sync-insert-2.png[height=110, alt="sync insert"]
image::{imgg}/wouter/06-sync-insert-2.png[height=110, alt="sync insert"]
In this case, if you'd like the clips on V2 to stay in sync, the overlapping clip will be split in two.
If you don't want this to happen you would have to move the overlapping clip to another track
@ -961,7 +622,7 @@ will move both the viewport and playhead. Clicking the left mouse button will ac
position and close the widget.
+
.Skim widget
image::{imgg}/wouter/v3-07-1-skim.png[width="100%", alt="A skim widget rendered as overlay"]
image::{imgg}/wouter/07-1-skim.png[width="100%", alt="A skim widget rendered as overlay"]
Autoscroll widget:: when the user moves the mouse cursor slightly left or right, it will enter zones
@ -970,14 +631,14 @@ When the user moves the mouse farther away from the initial starting point, the
increase. This will also work vertically. The playhead will move along as well.
+
.Autoscroll widget
image::{imgg}/wouter/v3-07-2-autoscroll.png[width="100%", alt="A widget for auto-scrolling"]
image::{imgg}/wouter/07-2-autoscroll.png[width="100%", alt="A widget for auto-scrolling"]
Zoom widget:: moving the mouse left or right from the centre will zoom horizontally, up and
down will zoom vertically.
+
.Zoom widget
image::{imgg}/wouter/v3-07-3-zoom.png[width="100%", alt="An overlay widget to control zooming"]
image::{imgg}/wouter/07-3-zoom.png[width="100%", alt="An overlay widget to control zooming"]
Mouse-only navigation:
@ -987,7 +648,7 @@ mouse button. When released, it will commit to the new location/view. If a user
immediately releases the button, a regular context menu will appear.
+
.Combined skim, zoom and scroll widget
image::{imgg}/wouter/v3-07-4-combined.png[width="100%", alt="Overlay widget to combin skim, zoom and autoscrol function"]
image::{imgg}/wouter/07-4-combined.png[width="100%", alt="Overlay widget to combin skim, zoom and autoscrol function"]
Why popup widgets?
@ -1047,7 +708,7 @@ what any other NLE does at the moment, but enabling multi-clip selection by keyb
good reason to go in this direction.
.Selection mockup: selected clips are highlighted in yellow, the cursor is a white dot.
image::{imgg}/wouter/v3-08-selection.png[width="100%", alt="selecting clips"]
image::{imgg}/wouter/08-selection.png[width="100%", alt="selecting clips"]
For selecting, we can introduce an ``add to selection'' key which adds the highlighted clip to the
current selection (apart from the convention of using Ctrl+mouse click). We could also think of
@ -1062,10 +723,10 @@ Most NLE's have functions for selecting many clips at once, called ``select forw
backward''. In Adobe Premiere these are tools: click and you select all clips to either the left or right
of the mouse cursor, and using Shift will toggle between selecting all clips on a single track or on
all tracks (it doesn't respect track activation status though, which it should). Other NLE's (Resolve,
Avid, Lightworks) have keyboard shortcuts for these functions (in Avid you can place a button in the
GUI as well), which do affect activated tracks only. This is a bit faster: in Premiere you need to
switch to the Select Forward/Backward Tool, make your selection, then switch back to your previous
tool. With a keyboard shortcut you only have to press a single key (if your track selection is correct).
Avid, Lightworks) only have keyboard shortcuts for these functions, which do only affect activated
tracks. This is a bit faster: in Premiere you need to switch to the Select Forward/Backward Tool,
make your selection, then switch back to your previous tool. With a keyboard shortcut you only
have to press a single key (if your track selection is correct).
Arranging clips
~~~~~~~~~~~~~~~
@ -1128,7 +789,7 @@ entering trim mode.
* Lightworks has a trim mode that defaults to ripple trimming, unless you specifically use the
“drag to black” feature by Control-clicking trim edges when entering trim mode. When
using the keyboard, one needs to mark a section and use the Remove command (similar to
Avid's ``lift'') to create a gap.
Avid''s ``lift'') to create a gap.
Next to ripple/non-ripple trimming there are three other edit operations closely related to trimming
that need to be mentioned:
@ -1155,10 +816,10 @@ tracks automatically stay in sync. This means (manually) enabling or disabling t
track. Once set, trimming a single clip can be enough to have all tracks move along, although you
might still need to manually select trim sides for overlapping clips to get the desired result.
image::{imgg}/wouter/v3-09-sync-trim-1.png[height=140, alt="trimming with sync-lock(before)"]
image::{imgg}/wouter/09-sync-trim-1.png[height=140, alt="trimming with sync-lock(before)"]
.Avid's sync locks will split longer clips by default, in order to keep sync. Such destructive behaviour should be avoided in Lumiera.
image::{imgg}/wouter/v3-09-sync-trim-2.png[height=140, alt="trimming with sync-lock(after)"]
image::{imgg}/wouter/09-sync-trim-2.png[height=140, alt="trimming with sync-lock(after)"]
Without sync locks you will have to select trim sides on every track that needs to stay in sync,
although, as we'll see, even that can be accomplished by a single keystroke. FCP is the exception
@ -1189,7 +850,7 @@ These commands can be combined: when pressing multiple keys, new trim sides are
selection. This allows for quickly selecting many trim sides on many tracks.
.One keystroke led to the selection of these four trim sides in Lightworks
image::{imgg}/wouter/v3-10-trim-side.png["select trim side"]
image::{imgg}/wouter/10-trim-side.png["select trim side"]
Another feature that was already mentioned in a previous chapter, is FCP's precision editor, which
can be triggered by double clicking a cut or by keyboard shortcut. This shows how much footage
@ -1276,7 +937,7 @@ exited automatically whenever the user clicks in an empty spot of the timeline o
mode key (T). This key can also be used to return to the last-used trim configuration.
.Mockup of the trim mode. The striped area marks the pre- and post-roll that will be previewed.
image::{imgg}/wouter/v3-11-trim-mode.png[width="100%", alt="using trim mode"]
image::{imgg}/wouter/11-trim-mode.png[width="100%", alt="using trim mode"]
Splitting and merging clips
@ -1312,7 +973,7 @@ I would like to propose the ability to divide a timeline into multiple sections.
will have a header in the ruler that can be edited, to give each section a name (similar to how
duration markers in Premiere are displayed).
image::{imgg}/wouter/v3-12-sections.png[width="100%", alt="Timeline with sections"]
image::{imgg}/wouter/12-sections.png[width="100%", alt="Timeline with sections"]
The benefits of sections:
@ -1369,7 +1030,7 @@ transition from a clip's start or end to the position of the playhead.
* Avid has a configuration panel for adding transitions:
image::{imgg}/wouter/v3-13-transition.png[align="center", alt="transition properties"]
image::{imgg}/wouter/13-transition.png[align="center", alt="transition properties"]
* Some apps allow adding transitions to every cut in the in-out range (Avid, Lightworks). Avid
gives you the option to skip cuts that already have a transition. Very useful for adding short
@ -1439,12 +1100,6 @@ Chapter 3: finishing
--------------------
[red]#To be written.#
- Nodes vs Layers
- Audio mixing
- Color grading
- Visual effects compositing
- Titling
Chapter 4: a broader GUI concept
--------------------------------
[red]#To be written.#

View file

@ -51,7 +51,7 @@ Current Release
[red]#Lumiera is not usable yet#.
- A »Preview Release« was
https://git.lumiera.org/gitweb?p=LUMIERA;a=tag;h=refs/tags/v0.pre.04[published at Dec 2, 2025]
https://git.lumiera.org/?p=LUMIERA;a=tag;h=refs/tags/v0.pre.04[published at Dec 2, 2025]
- link:/debian[DEB packages]
were built for »Trixie« and »Noble«

View file

@ -214,7 +214,7 @@ Interface Definition Language
-----------------------------
In his work on the plugin loader, _Cehteh_ created a first draft how to export an interface, and calls for review.
An example can be found in
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=tests/backend/test-interfaces.c;h=09fa25afa3cb57b79a2717d0bf3a8253afeba000;hb=ebcc5c7fd2d8700f3375e3309b724ac2517a0f40[tests/backend/test-interfaces.c]
https://git.lumiera.org/?p=LUMIERA;a=blob;f=tests/backend/test-interfaces.c;h=09fa25afa3cb57b79a2717d0bf3a8253afeba000;hb=ebcc5c7fd2d8700f3375e3309b724ac2517a0f40[tests/backend/test-interfaces.c]
An interface is a list of »slots« mapping functions. The interface descriptor is itself realised as interface,
and thus can be versioned, extended and specialised.

View file

@ -95,7 +95,7 @@ For now the focus is on getting a single frame into the gui and there will be ti
The devs agreed to meet up on Saturday to get the latest version up and running.
NOTE: Demonstration in https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=src/common/guifacade.cpp;h=60a16d0f67bd95b43e44662daa9c0525235e14f5;hb=5f10e65852de2c51364c2e2a5a1cf29cae81c6b2#l64[guifacade.cpp]
NOTE: Demonstration in https://git.lumiera.org/?p=LUMIERA;a=blob;f=src/common/guifacade.cpp;h=60a16d0f67bd95b43e44662daa9c0525235e14f5;hb=5f10e65852de2c51364c2e2a5a1cf29cae81c6b2#l64[guifacade.cpp]
(The thread shall be forked from within the GUI code not from the facade)
This was discussed and ichthyo has already pushed a new cleaned up state and resolved most of the dependency problems with the liblumiera. It raised the question: do we prefer a UI facade to a GUI facade or do we want an extra script facade someday?

View file

@ -191,7 +191,7 @@ don't think we get much program options, maybe something to set a GUI skin.
Moreover, I've written last year a thin wrapper around the commandline and
integrated it with the boost options parser such that user code can receive the
remaining options as a vector of `std::string`s. Please have a look at
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=tests/common/mainsuite.cpp;h=455bfd98effd0b7dbe6597f712a1bdfa35232308;hb=80e1e382f42512ebf2e10a802f77e50327b8fb73[the test class runner main]
https://git.lumiera.org/?p=LUMIERA;a=blob;f=tests/common/mainsuite.cpp;h=455bfd98effd0b7dbe6597f712a1bdfa35232308;hb=80e1e382f42512ebf2e10a802f77e50327b8fb73[the test class runner main]
for an usage example. I really want our Lumiera main to be clean and expressive
in the way showed there. Probably the most important part of the startup is
pulling up the session core; because of that I think most of the startup

View file

@ -15,8 +15,8 @@ This proposal intends to capture envisioned Architecture of the Application.
image:{ldoc}/devel/draw/rendered/Lumi.Architecture-1.png[Overview of Lumiera Architecture]
^The SVG source of this drawing is
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-1.svg;hb=HEAD[maintained in GIT(2008)]·
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=HEAD[(current: 2022)]^
https://git.lumiera.org/?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-1.svg;hb=HEAD[maintained in GIT(2008)]·
https://git.lumiera.org/?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=HEAD[(current: 2022)]^
Description
@ -75,7 +75,7 @@ Conclusion
----------
Accepted. The drawing was moved into the GIT tree. +
It was upgraded and reworked
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=0b9f2e2c3139cad542013caac593cb5972a2e3f6[in 2022]
https://git.lumiera.org/?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=0b9f2e2c3139cad542013caac593cb5972a2e3f6[in 2022]
Back to link:/x/DesignProcess.html[Lumiera Design Process overview]

View file

@ -106,7 +106,7 @@ details of carrying out the operations are much more involved.
Please see the
link/wiki/renderengine.html#Rendering[Development internal doc (TiddlyWiki)]
and the
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=src/proc/engine/procnode.hpp;h=9cf3a2ea8c33091d0ee992ec0fc8f37bb5874d34;hb=f9452f654cf39a4abbbeecfd81bef51aa347b321[Draft: ProcNode (src)]
https://git.lumiera.org/?p=LUMIERA;a=blob;f=src/proc/engine/procnode.hpp;h=9cf3a2ea8c33091d0ee992ec0fc8f37bb5874d34;hb=f9452f654cf39a4abbbeecfd81bef51aa347b321[Draft: ProcNode (src)]
for details
(and/or contact Ichthyo for in-depth discussion of those technical details)

View file

@ -149,7 +149,7 @@ We soon settled upon the following toolchain, which is used up to today:
history is consolidated eventually into the
link:{rfc}/MasterRepositorySetup.html#historical_remark[»official Lumiera repository«],
which is made accessible at
https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[`git://git.lumiera.org/LUMIERA`]
https://git.lumiera.org/?p=LUMIERA;a=summary[`git://git.lumiera.org/LUMIERA`]
- We never used link:{rfc}/GitSubmoduleTransistion.html#_comments[Git submodules]...
- https://www.scons.org/[SCons] became the primary buildsystem soon,
with Autotools discontinued in 2011
@ -158,14 +158,14 @@ We soon settled upon the following toolchain, which is used up to today:
- Website and documentation pages are generated by
https://asciidoc-py.github.io/[Asciidoc], with source files for
documentation maintained
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=doc/index.txt;h=9bc0f11e6fb67588388e7616320b695841571278;hb=20f3252892d5b53a05ecd8aeb571122806baba17[in-tree],
https://git.lumiera.org/?p=LUMIERA;a=blob;f=doc/index.txt;h=9bc0f11e6fb67588388e7616320b695841571278;hb=20f3252892d5b53a05ecd8aeb571122806baba17[in-tree],
published
https://git.lumiera.org/gitweb?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[automatically on push].
https://git.lumiera.org/?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[automatically on push].
- A https://classic.tiddlywiki.com/[TiddlyWiki] is used for development notes
- for Unit-Tests, we use our own minimalist
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=src/lib/test/run.hpp;h=035633af9bde7a8053bcd304baffc21693dcf031;hb=20f3252892d5b53a05ecd8aeb571122806baba17[Test-runner].
https://git.lumiera.org/?p=LUMIERA;a=blob;f=src/lib/test/run.hpp;h=035633af9bde7a8053bcd304baffc21693dcf031;hb=20f3252892d5b53a05ecd8aeb571122806baba17[Test-runner].
and a
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=tests/test.sh;h=8c13810eb475bbacd97c528607e6750f47bb145e;hb=20f3252892d5b53a05ecd8aeb571122806baba17[shell script]
https://git.lumiera.org/?p=LUMIERA;a=blob;f=tests/test.sh;h=8c13810eb475bbacd97c528607e6750f47bb145e;hb=20f3252892d5b53a05ecd8aeb571122806baba17[shell script]
to support definition of test collections.
- A Debian package is maintained with
https://wiki.debian.org/PackagingWithGit[git-buildpackage] and published

View file

@ -68,9 +68,9 @@ rather -- a task no one was willing to take on.
Yet the Lumiera project succeeded in building a web presence based on
https://asciidoc-py.github.io/[Asciidoc] sources
https://git.lumiera.org/gitweb?p=website;a=summary[checked into Git],
https://git.lumiera.org/?p=website;a=summary[checked into Git],
with a lightweight
https://git.lumiera.org/gitweb?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[commit-hook script]
https://git.lumiera.org/?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[commit-hook script]
to automatically publish any changes on git-push -- a scheme
which comes close to the gist of this RfC.

View file

@ -16,7 +16,7 @@ This describes how the shared MASTER is set up and syncronized.
Description
~~~~~~~~~~~
We have now a shared master repository in
https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[/git/LUMIERA].
https://git.lumiera.org/?p=LUMIERA;a=summary[/git/LUMIERA].
- The public/anonymous git url is [yellow-background]#`git://git.lumiera.org/LUMIERA`#
- for people with ssh access it is pushable at [purple]#`UID@git.lumiera.org:/git/LUMIERA`#.
@ -71,10 +71,10 @@ That being said -- the shared master at [yellow-background]#`git://git.lumiera.o
still contains the _official_ state of the Lumiera codebase, while
actual development is published first in a repository per developer
(so effectively in
https://git.lumiera.org/gitweb?p=lumiera/ichthyo;a=summary[the Ichthyo repository]
https://git.lumiera.org/?p=lumiera/ichthyo;a=summary[the Ichthyo repository]
for the time being);
development is consolidated intermittently into the
https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[LUMIERA Git].
https://git.lumiera.org/?p=LUMIERA;a=summary[LUMIERA Git].
''''

View file

@ -18,7 +18,7 @@ Propose a documentation/planning about the setup.
Description
~~~~~~~~~~~
Take a look at my draft at:
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=doc/devel/nobug_flags.txt;h=325141acb52a7be7f75425359b6057c74ed30253;hb=a03e3c5e73a4c0be2264ac4e4e0f02eb8749837b[nobug_flags.txt]
https://git.lumiera.org/?p=LUMIERA;a=blob;f=doc/devel/nobug_flags.txt;h=325141acb52a7be7f75425359b6057c74ed30253;hb=a03e3c5e73a4c0be2264ac4e4e0f02eb8749837b[nobug_flags.txt]
I've added the things I planning for the backend, others might add their own
plans there too. So far this is an early draft, comments welcome.

View file

@ -210,7 +210,7 @@ during this effort leads to the following refinements:
- Workers manage their capacity through a statistical distribution of _sleep times._
In this form, the proposal can be considered as implemented. +
^(see -> https://git.lumiera.org/gitweb?p=LUMIERA;a=commit;h=d71eb37[d71eb37]
^(see -> https://git.lumiera.org/?p=LUMIERA;a=commit;h=d71eb37[d71eb37]
and https://issues.lumiera.org/ticket/1344[#1344])^
Ichthyostega:: '2024-04-20 01:55 CEST'

View file

@ -49,4 +49,6 @@ On occasion, we'll replace them by drawings from our current UML model.
128517: classdiagram 142725 "Time flavours"
133637: classdiagram 143877 "Player Entities"
133637: objectdiagram 144005 "Play Process Structure"
133637: sequencediagram 145157 "output data exchange"
133637: classdiagram 151685 "Player Output"
128773: classdiagram 158213 "UIBus"

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 256 KiB

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 83 KiB

BIN
doc/devel/uml/fig145157.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
doc/devel/uml/fig151685.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,7 +1,7 @@
Documentation
=============
This documentation section contains documentation for users and developers alike.
This documentation section contains documentation for both users and developers.
== User ==
@ -60,8 +60,8 @@ deeper documentation dungeons.
At the second layer, the reader must make the first major decision on which
router to pursue: documentation with a heavy code based leaning; or more descriptive
documentation on the design of Lumiera, which omits most technical details of the implementation.
Consequently, the documentation is divided into two main parts:
documentation on the design of Lumiera which avoids a code narrative. This
section has two main sections:
* link:design/index.html[Lumiera Developer Design Documents]
* link:technical/index.html[Lumiera Developer Technical Documents]
@ -75,14 +75,14 @@ Consequently, the documentation is divided into two main parts:
[width="90%",frame="topbot",options="header",cols="^,2<"]
|================================================================================================
|Section|Remarks
|Sub-System|Remarks
|link:design/architecture/[Architecture]|Structure of Lumiera
|link:design/gui/[GUI]|The Lumiera ⟷ user interaction layer
|link:design/model/[Model]|Low-level and high-level models
|link:design/engine/[Engine]|Renderer, output generation, ...
|link:design/lowlevel/[Low-level]|Low-level and system services
|link:design/application/[Application]|Application framework
|link:design/extension/[Extension]|Dynamically loaded Extensions
|link:design/plugins/[Plugins]|Dynamically loaded Extensions
|link:design/workflow/[Workflow]|Workflow and Interaction Design
|link:design/governance/[Governance]|Meta project concerns
|================================================================================================
@ -93,12 +93,12 @@ Consequently, the documentation is divided into two main parts:
[width="90%",frame="topbot",options="header",cols="^,2<"]
|================================================================================================
|Section|Remarks
|Sub-System|Remarks
|link:technical/build/[Build System]|Build, Packaging and CI
|link:technical/stage/[Stage]|GUI (technical aspects)
|link:technical/steam/[Steam]|Session and processing coordination
|link:technical/vault/[Vault]|Low-level operations
|link:technical/library/[Library]|Utilities and custom frameworks
|link:technical/library/[Support lib]|Interface and support libraries
|link:technical/code/[Code base]|Code management, organisation, ...
|link:technical/infra/[Infrastructure]|Website and developer tooling ...
|link:technical/howto/[Developer HowTos]|Instructions and guides for developers

View file

@ -40,7 +40,7 @@ Lumiera expects a ``standard'' desktop installation running a XServer.footnote:[
Wayland is ``just around the corner'' since 10 years now. Well, recently it
seems it is _really_ just around the corner. We are aware of the necessary
changes, which are not very complicated to implement (since we are using
GTK-3). However, as long as Wayland simply crashes or hangs in our
GTK-3). However, as long as Wayland simply crashes or hands in our
everyday work setup with XFCE, we will not consider this topic
a priority. In the meantime, please report any problems
you encounter with Lumiera running on XWayland.
@ -97,8 +97,7 @@ Languages and Tools
* BOOST (listed below are the Debian package names)
- libboost-dev (at least *1.83*)
- notably including `boost::lockfree`
- libboost-program-options-dev (link dependency)
- libboost-program-options-dev
* Script languages
- Python (*3.10*) required for building (->SCons)
@ -124,7 +123,7 @@ Build Tools
* pkg-config
* Doxygen (optional)
* Asciidoc (optional)
* Git -> https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[git://git.lumiera.org/LUMIERA]
* Git -> https://git.lumiera.org/?p=LUMIERA;a=summary[git://git.lumiera.org/LUMIERA]
footnote:[
_Ichthyo_ maintains a repo at https://github.com/Ichthyostega/Lumiera/[Github ^~Ichthyostega/Lumiera^]
]
@ -161,9 +160,9 @@ Libraries
which is possible, but would require some considerable effort. As of 2025, GDL is still usable,
but no longer available through the standard distribution channels. +
We provide a Git repository at our Website for
https://git.lumiera.org/gitweb?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
https://git.lumiera.org/?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
and the
https://git.lumiera.org/gitweb?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+]
https://git.lumiera.org/?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+]
and we maintain custom Debian packages for both in our
link:/debian/[Debian DEB depot].
]

View file

@ -79,8 +79,8 @@ How the Lumiera Debian package works
Since we maintain both the Debian package and our build system, we can always try to do
_the heavy lifting_ in our link:{ldoc}/technical/build/SCons.html[SCons build system],
as this helps to keep the Debian packaging as simple as possible. Please have a look at the
-> https://git.lumiera.org/gitweb?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/control[control file]
· https://git.lumiera.org/gitweb?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/rules[debian/rules]
-> https://git.lumiera.org/?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/control[control file]
· https://git.lumiera.org/?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/rules[debian/rules]
- we rely on the _Debhelper Sequencer_ "`dh_*`" in our 'debian/rules' +
-> https://manpages.debian.org/trixie/debhelper/dh.1.en.html[Manpage]
@ -106,7 +106,7 @@ into `master` and marked with a tag there.
For the actual packaging, we use these release tags as _upstream tag_ and perform a merge
from that tag into the **debian branch**.footnote:[
This _debian branch_ is called `deb` by convention. As mentioned above, it is published through
a separate https://git.lumiera.org/gitweb?p=debian/lumiera;a=summary[Git repository `git://git.lumiera.org/debian/lumiera`],
a separate https://git.lumiera.org/?p=debian/lumiera;a=summary[Git repository `git://git.lumiera.org/debian/lumiera`],
which is kept separate, since packaging is considered a ``downstream process''.
]
This branch carries only the additions and tweaks done for debian packaging. Yet still, this `deb`
@ -115,7 +115,7 @@ repository as the `master` branch. When the packaging process is complete, the p
DEB version is marked with a tag `debian/<full_debian_version_spec>`
Note however that there is another branch in the aforementioned `debian/lumiera` repository,
which is called https://git.lumiera.org/gitweb?p=debian/lumiera;a=shortlog;h=refs/heads/depot[depot]
which is called https://git.lumiera.org/?p=debian/lumiera;a=shortlog;h=refs/heads/depot[depot]
and is related to our link:/debian[DEB package depot] on Lumiera.org. This branch carries a completely
different directory structure, since it is used with the
https://wiki.debian.org/DebianRepository/SetupWithReprepro[»reprepro« tool from Debian]

View file

@ -352,6 +352,6 @@ shared object (dynamic library), which is then again a SCons target
and can be passed to other executable builders as library dependency
for compilation and linking. Look into 'src/SConscript' or 'test/SConscript'
to see examples of that technique -- which we also use to define that
global compound target variables like `core`, `vessel_lib`, `core_lib`,
global compound target variables like `core`, `app_lib`, `core_lib`,
`vault_lib`, and `support_lib`. These in turn are essential for
building the layered dependency hierarchy in our code.

View file

@ -322,8 +322,8 @@ actively step by step
modules of the application will be placed by default
. after the core application has been loaded and all direct dependencies are resolved,
but still before entering `main()`, the class `vessel::Voyage` will be initialised,
which in turn holds a member of type `vessel::BasicSetup`. The latter will figure out
but still before entering `main()`, the class `lumiera::AppState` will be initialised,
which in turn holds a member of type `lumiera::BasicSetup`. The latter will figure out
the location of the executable footnote:[this is a Linux-only trick, using `/proc/self/exe`]
and require a 'setup.ini' file in the same directory. This setup file is mandatory.

View file

@ -88,33 +88,6 @@ test with random numbers::
several threads; each thread should use its own generator then (yet this can be handled sloppy if
the _quality_ of the random number actually does not matter!)
special test setup::
It can be very helpful to use _policy based design_ for some complex evaluation or algorithm,
even in cases where it is clear that the actual usage will only ever involve one specific data type
and configuration. Not only does such a structured approach help with clarifying the design itself,
since the core of the evaluation logic can be abstracted from data representation -- yet also the
testing and verification of correctness is simplified, as the test can be written to use simple,
human-readable data (strings, symbols), and, furthermore, many kinds of instrumentation can be
included into the test data to gain detailed insight what is happening in the test subject.
verify behaviour sequence::
Use the `lib::EventLog`:
+
- within the test, notable points are marked into the log, possibly with arguments
- after the test, the Event Log can be verified with a search-sequence
- this way it is possible to ensure that some events did happen, and happened
in a very specific order, or that some event did _not_ happen after another event
- the `test::Tracker` defined in 'src/test/tracking-dummy.hpp' will mark all constructor,
destructor and copy events into an embedded Event Log instance. By inheriting or mix-in
from that type, the allocation and instance behaviour of some service can be scrutinised.
verify incidences and concurrency::
Aside from using some generic tracing utility, sometimes it is much easier to setup
a _specifically tailored instrumentation_. This can be achieved with 'incidence-count.hpp'
+
- for instrumentation, the `markEnter()` and `markLeave()` functions need to be invoked
- after the test run, various statistics can be computed and evaluated, including
cumulated time and concurrency for the "cases" marked with enter / leave.
Common Tasks
@ -136,12 +109,6 @@ structured data::
- also useful as output format, both for debugging and because it can be matched against
an expected structure, which is generated with the DSL notation.
- [yellow-background]#(planned)# will be able to map this from/to JSON easily.
scoped collection::
unique-ownership collection that holds a sequence of objects in a preallocated fixed
storage block. Notably even non-copyable objects can be managed (which is not possible
with a `std::vector`), and type-erased instances of subclasses can be mixed. Furthermore
there is a constructor variant that allows to populate a `ScopedCollection` in RAII-style.
This can e.g. be used to fire-off a set of Threads or open a set of wrapped connections.
Iterating
~~~~~~~~~
@ -167,26 +134,6 @@ IterSource::
even the production-state can be hooked up into the IterSource instance (with a smart-ptr).
This allows e.g. to send a Diff to the UI through the UI-Bus, while the actual generation
and application both happen demand-driven or _lazy..._
State Core::
When some algorithm involves a statefull evaluation, it might be helpful to package that into
a _State Core_ container. This is a class that is expected to expose three operations, which
allow to build an iteration on top. The header 'iter-adapter.hpp' provides several adapters
and wrappers, notable `lib::IterStateWrapper` wraps any _state core_ and provides a
Lumiera Iterator interface; likewise, `IterExplorer` heavily relies on that concept and
is able to accept and iterate any state core in a pipeline.
special iterators::
Some additional adaptors are provided as building block so that specific evaluations
can be made to conform with the »Lumiera Iterator« concept
+
- several given iterators can be combined into a iteration over tuples with 'lib/iter-zip.hpp'
- there is also a variation 'lib::izip' that adds a running index into the _zipping operation_
- IterExplorer provides a `flatten()` operation, that can be used to join an iterator-of-iterators
into a single seamless iteration lazily.
- when a STL container also supports _backwards iteration_, then a lumiera iterator can be
created that can _switch direction_ dynamically, with the help of 'iter-cursor.hpp'
- a STL »deque« container can be used both as a stack and a queue; the header 'iter-stack.hpp'
provides an iteration adapter for both usage schemes, so that either the stack or the queue
can be _"discharged"_ as a Lumiera Iterator (possibly with an IterExplorer pipeline)
Formatting
@ -208,25 +155,6 @@ Formatting
because there are way more capable solutions _out there_ ☺)
Setup and wiring
~~~~~~~~~~~~~~~~
Generally speaking, we prefer _constructor wiring_ whenever possible, to avoid creating
unnecessary statefulness (as would be the case when connecting dependencies through setters).
This design also favours decomposition into self-contained components with a single purpose,
and simplifies error handling with the help of the RAII pattern.
However, sometimes a piece of code depends on some remote and even global service; in these
cases, the `lib::Depend` framework can be used to access that service via type name. The
actual service can either be created on-demand as a singleton, or it can be installed
explicitly as a service instance. Furthermore, it is possible to "push aside" the
current service instance temporarily and replace it by a _test mock_.
One point to note is that `lib::Depend` is a _monostate_, and not a _singleton_.
The actual service should be written as a free-standing class, that can be instantiated
directly for the purpose of testing.
Language constructs
-------------------
Templates
@ -307,14 +235,4 @@ unpack iterator into tuple::
- see tuple-record-init-test.cpp
- used in 'command-simple-closure.hpp' to receive parameter values sent via UI-Bus and package them
into a tuple for invocation of a Steam-Layer command.
+
index and iterate over tuple elements::
This is another example of bridging the compile-time / runtime barrier, using a trampoline.
Obviously such a solution requires that it is somehow possible to define a generic functor / λ that
can accept any of the tuple elements. And, in order to build a runtime index access, we additionally
need to convert each of the tuple elements into a _common reconciled type_.
+
- If such a type exists, can be figured out with the help of the `meta::CommonReturn` _metafunction_
- `lib::meta::TupleIdxAdaptor` provides the necessary machinery to define a subscript `operator[]`
- see `TupleIdxAdaptor_test` for some usage examples, including a runtime iteration...

View file

@ -9,34 +9,34 @@ Technical Documentation
// Menu : prepend child overview
This documentation section contains technical documentation about Lumiera. +
To get an *overview* of all the internals and components, you might want to read
This documentation section contains technical documentation about Lumiera. To
get an *overview* of all the internals and components, you might want to read
link:overview.html[Lumiera the Inner Core]
== Three Layers
The technical documentation is divided into three main parts and some supplements,
corresponding to the code organisation in three layers. The information here can be
very detailed and technical at times, and the topics are organised by individual components.
The technical documentation is split in three parts, one for each of the three
main layers of Lumiera. You may want to read the
link:{ldoc}/design/index.html[Design Documents] first to get an overview of all the
components.
* link:stage/index.html[*Stage Layer*] : Documents related to the GTK based Lumiera GUI
* link:steam/index.html[*Steam Layer*] : Documents regarding Session, the models and the engine
* link:vault/index.html[*Vault Layer*] : Documents about the data and processing backend
* link:steam/index.html[*Steam Layer*] : Documents regarding Session, models and the engine structure
To better understand the underlying concepts, it might be helpful to also consult the
link:{ldoc}/design/index.html[Design Documents].
* link:vault/index.html[*Vault Layer*] : Documents about the data and processing backend
== Tools
.Development
* link:/doxy/[*Doxygen*] : API documentation of the Lumiera code.
* link:/doxy/[*Doxygen* generated documentation] : API documentation of the Lumiera code.
* organisation of the link:code/index.html[Code Base] in general
* link:/x/CodingGuidelines.html[Coding Style] and further guidelines
.Building
* link:build/index.html[Buildsystem] : Installation and compilation tools, dependencies and packaging.
* link:build/index.html[Buildsystem] : Installation & compilation tools, dependencies and packaging.
.HOWTO
* link:/x/DevHowto.html[Developer *HOWTOs*] : Collection of instructions, recipes, hints, misdeeds
and confessions and similar helpful resources for developers
* link:/x/DevHowto.html[Developer *HOWTOs*] : Collection of instructions, recipes, hints and similar
materials intended for developers

View file

@ -8,32 +8,30 @@ NOTE: This page holds content copied from the old "main" TiddlyWiki +
It needs to be reworked, formatted and generally brought into line
********************************************
.Lumiera employs test-driven development
.Lumiera relies on *test-driven development*
This page discusses the overall organisation
of test code, and the tools used for
running test cases
********************************************
Tests are the only known form of documentation that offers some resilience against
getting outdated. Tests help to focus on the usage, instead of engaging in spurious
Tests are the only form of documentation, known to provides some resilience against
becoming outdated. Tests help to focus on the usage, instead of engaging in spurious
implementation details. Developers are highly encouraged to write the tests _before_
the actual implementation, or at least alongside and interleaved with expanding the
feature set of the actual code.
There may be exceptions to this rule. Not every single bit needs to be covered by tests.
Some features are highly cross-cutting and exceptionally difficult to cover with tests.
Test code must not duplicate the logic of implementation code, it should represent an
abstracted, outside, logical view of the matter at hand. And sometimes it is the better
choice to simply write an abstract specification in understandable language.
And sometimes, just an abstract specification is a better choice.
As a rule of thumb, consider to write test code which is easy to read and understand,
_like a narration_ to show off the relevant properties of the test subject.
Test Structure
--------------
- a *test case* is an executable, expected to run without failure; test code not only invokes
a _subject under test_ -- the important part is to _verify_ its behaviour.
- a *test case* is an executable, expected to run without failure, and optionally producing
some verifiable output
- simple test cases may be written as stand-alone application, while the more tightly
integrated test cases can be written as classes within the Lumiera application framework.
- test cases should use the +CHECK+ macro of NoBug to verify test results, since the normal
assertions may be de-configured for optimised release builds.
- our test runner script 'test.sh' provides mechanisms to check for expected output
@ -43,13 +41,15 @@ several functions within the same test fixture. This allows to create a ``narrat
in the code: first do this, than do that, and now that, and now this should happen...
Generally speaking, it is up to the individual test to take care or isolate himself
from any _dependencies_. Test code and application code uses the same mechanisms
for accessing other components within the application.
for accessing other components within the application. Up to now (2014), there
was no need for any kind of _dependency injection_, nor did we face any
difficulties with tainted state.
Test classes are organised into a tree closely mirroring the main application source
code tree. Large sections of this test tree are linked together into *test libraries*.
Some of these are linked against a specific (sub)scope of the application, like e.g.
only against the support library, the application framework or the vault. Since we
use _strict dependencies_, this linking step will also spot code not placed at the
use _strict dependencies_, this linking step will spot code not being placed at the
correct scope within the whole system. As a final step, the build system creates a
*test runner* application (`target/test-suite`), which links dynamically against _all_
the test libraries and thus against all application dependencies.
@ -81,9 +81,9 @@ to help with automating the build and test execution, test code should adhere to
- test classes should be placed into a sub namespace +...::test+
- specific definitions for a single test case may rely on global variables,
but these should live within an anonymous namespace
- free standing test executables should be named according to the pattern `test-*`
- all test executables should be named according to the pattern +test-*+
- all test source code is within the 'tests' subtree
- immediately within the 'tests/' directory are the test collection definitions `*.tests`,
- immediately within the 'tests/' directory are the test collection definitions +*.tests+,
ordered by number prefixes
- below are the directories with test cases, to be grouped into the aforementioned test-executables.
- we distinguish two ways to write and link tests: _standalone_ and _suite_
@ -107,7 +107,7 @@ See the following
.hello-world-test example
[source,C]
----------------------------------------------------------------
#include "test/run.hpp"
#include "lib/test/run.hpp"
#include <iostream>
using std::cout;

View file

@ -18,25 +18,22 @@ The main Website.
- Data is in '/var/www'. The Website is a git repository.
- Configuration is at '/etc/apache2/sites-available/lumiera.conf'
- cehteh and ichthyo are responsible for the administration.
- cehteh cares for the administration.
- To proprose some changes clone the git repository and send a
notfication/merge-request to the mailinglist.
Some directories symlink to other directories (see below).
The »staging site«
~~~~~~~~~~~~~~~~~~
https://staging.lumiera.org
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Testing repository for the Website. It is configured in Apache
to be served from a separate virtual host, with an obvious DNS
name (which _must not_ be mentioned in published content!).
Web development is done and reviewed here before it gets
pushed to the main Website.
Testing repository for the Website. Web development is done and
reviewed here before it gets pushed to the main Website.
- Data is in '/var/www-staging'. The Website is a git repository.
- Configuration is at '/etc/apache2/sites-available/staging.conf'
- cehteh and ichthyo are responsible for the administration.
- cehteh cares for the administration.
- To proprose some changes clone the git repository and send a
notfication/merge-request to the mailinglist.
@ -111,113 +108,5 @@ Upload directory where people can rsync data.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Clone of the lumiera source repository to serve the documentation within.
/var/local/trac/
~~~~~~~~~~~~~~~~
This is the configuration root of our https://trac.edgewall.org/[Trac] installation
for the Lumiera issue tracker. This is actually a Git repository, since our setup
became gradually more elaborate over time. We even have some local tweaks to
the CSS styles and the Subtickets-Plugin (Python code).
- a copy of the Apache configuration is checked in as well
- note some scripts in the 'scripts' subdirectory
- an export of current Trac resources was dumped into 'static'
and is served directly by Apache from there
- the actual »Trac-environment« with config and SQLite-DB is in 'trac-env'
- all source trees of all essential plug-ins are checked into 'PluginBuild',
so that any plugin could be regenerated by `python3 setup.py bdist_egg`
- a dump of the TracDB is also checked into that Git
Setup and Configuration
-----------------------
- Apache is configured with the `worker'-MPM
- Trac runs under WSGI configured with a pool of _multithread daemon processes_
Load and Calibration
~~~~~~~~~~~~~~~~~~~~
As of 1/2026, we employ a simplistic load monitoring based on evaluating the
running processes and some server statistics. This is implemented as a bash script,
checked in as '/var/local/trac/scripts/collect-server-stats' and configured to run
every two minutes (via SystemD timer). The resulting data trail can be found in
'/var/log/apache2/loadwatch.csv', with the following columns:
- Timestamp: ISO UTC min
- Sum webserver...
* Processes
* Threads
* overall resident memory (KiB)
* factor of overall memory resident
- Apache
* workload factor
* Processes
* Threads
* resident memory
- WSGI-Trac
* workload factor
* Processes
* Threads
* resident memory
- Server-statistics
* ∅ requests per second
* ∅ request duration in ms
* currently active slots
* currently idle workers
* scoreboard of slot allocation
The parameters of the Apache MPM and the WSGI daemon are then tuned such
as to make good use of the available memory, while avoiding excess idle workers.
Anubis
~~~~~~
https://anubis.techaro.lol/[Anubis] is a service that was discussed controversially
in the community this year. It was created by a
https://github.com/Xe[Canadian Open-Source programmer] as an immediate stopgap
to help protect the _»small internet«_ from the endless storm of requests that
flood in from AI companies. It is configured as a gateway proxy, which classifies
incoming requests based on request properties and sends suspicious clients first
to a JavaScript proof-of-work challenge. After passing Anubis, the client gets
a Cookie to prevent further challenges for some limited time.
Anubis was reported to be very effective for keeping aggressive scraper bots away,
yet the bots have adapted already to some degree. So this remains a game of
cat and mouse. Our first evaluations however indicate very promising numbers,
by keeping out 92% of PageImpressions and UniqueUsers, thereby reducing
the traffic deliverey by the Lumiera issue tracker by more than 80%.
Introducing such an entrance gateway may be seen as an extreme measure;
the rationale is that we have reached such a level of threat that generic rate limits
would have to be so severe that they practically render those resources useless.
Without these protective measures, we would no longer be able to provide Lumiera.org
as a free resource to everyone.
[underline]#Legal stance#: I consider this usage covered by the provisions of GDPR.
Setting this cookie is justified by our legitimate interest of keeping the service operational;
we evaluate IP data patterns for the sole purpose of detecting abuse of our website,
and we state that fact clearly on our GDPR page.
Setup
^^^^^
Anubis runs as single-instance SystemD service unit `anubis@lumiera`, with transient
storage backend only. It is integrated into the Website as a _gateway_ (reverse proxy).
Anubis is configured by a set of rules in https://cel.dev/[Common Excpression Language].
The active rule set is configured in '/etc/anubis' and also checked into the
xref:_var_local_trac[Trac-Git]. Rules are evaluated according to the _commited-choice_
pattern, i.e. the first rule where the guard condition matches will terminate the
evaluation and yield a decision. Anubis was installed from a custom DEB package
and ships with
https://github.com/TecharoHQ/anubis/tree/main/data[a set of rule building blocks],
that can be imported from the `(data)` prefix -- which translates into the path
'/usr/share/doc/anubis/data'
TIP: https://anubis.techaro.lol/[Homepage]
· https://anubis.techaro.lol/docs/admin/native-install[Installation]
· https://anubis.techaro.lol/docs/admin/environments/apache[Apache-setup]
· https://github.com/TecharoHQ/anubis[Github]
As of 1/2026, Anubis protects our
https://issues.lumiera.org/timeline[Issue tracker],
the https://git.lumiera.org/[Git repository browser] and the
https://lumiera.org/doxy/[API-doc] -- which together constitute
the majority of pages accessible on the website.

View file

@ -109,7 +109,7 @@ Configuration
~~~~~~~~~~~~~
All the current configuration and the state of the Debian depot index files is tracked
in the aforementioned ``debian/lumiera'' Git repository, on a separate branch called
https://git.lumiera.org/gitweb?p=debian/lumiera;a=shortlog;h=refs/heads/depot[`depot']
https://git.lumiera.org/?p=debian/lumiera;a=shortlog;h=refs/heads/depot[`depot']
TIP: this is a slightly unconventional setup, insofar the `depot' branch carries
a directory tree that is completely separate from the main Lumiera source tree, which

View file

@ -1,70 +1,41 @@
Library documentation
=====================
//Menu: label Support Lib
Alongside with the core Lumiera Application, and as part of ongoing development work,
a lot of *Library code* is written. Many of this happens on occasion. Library solutions
are frequently ``discovered'', while in the middle of the implementation, driven by the
desire to re-use some code structure that was built just recently and in a similar way.
Support Library
---------------
Over time, a huge and growing number of generic building blocks has been collected.
Hoever, not all parts of this collection are equally well maintained and presentable.
It happened time and again that some pattern extracted into the library turned out
to be rather some kind or ephemeral habit -- maybe even a bad habit in hindsight --
and turned into a dead-end eventually. Furthermore, a lot of our library code has
been superseded by very similar features of newer language standards.footnote:[
It seems like developers working on similar problems tend to have similar ideas
to improve productivity. Unfortunately, the solutions resulting from this convergence
of ideas have a tendency not to ``converge'' so well in practical terms.
For example, Lumiera had a tuple type a long time before a mature tuple implementation
was available in the Boost libraries, yet in the end, we could retrofit most of our
tuple-handling library. However, other cases did not play out so well: we evolved
the idea of ``iterators'' to become a lazy processing pipeline, but unfortunately
our design leans more into the direction of functional programming and is much
more expressive and powerful as abbreviation than the »Range-TS« from C++20.
]
The entrance barrier for something to be added to our _Support Library_ is rather low:
- extracting it as a library function _must make the client code clearer_
- it must be possible to describe its purpose and its usage in _generic terms_ --
without referring to data types and definitions from our domain models.
- it must be _essentially stateless_ and self-contained
- it must be easy to document with an unit-test.
Over time, parts of the Support Library have evolved into some kind of a framework:
Notably the link:{ldoc}/design/architecture/time/index.html[time and timecode] handling,
our link:Dependencies.html[dependency and service handling],
the link:DiffFramework.html[»Diff framework«], together with the recursive property trees
used for link:{ldoc}/design/architecture/ETD.html[»External Tree Description«], the
link:iterator.html[iterator pipeline builders], the metaprogramming helpers for transforming
function signatures and generic sequences, and our collection of string conversion, parsing
and rendering functions. These all turned into distinguishing traits of the Lumiera code base.
The link:{ldoc}/technical/overview.html#_library[»Library« section of the »Overview« document]
contains a long list of short descriptions for relevant features of the Support Library.
.how to crack nuts...
[NOTE]
In the how-to section, there is a page with a loose collection of
link:{ldoc}/technical/howto/crackNuts.html[successful solution patterns],
many of which rely on unique features of our Support Lib.
Alongside with the core Lumiera Application, we're also creating several *Libraries*. +
This section holds pages with in-depth technical documentation regarding those. Please don't
expect a coherent or complete coverage for the time being -- library functionality is typically
``discovered'' while in the middle of the implementation, then factored out, reused and remoulded
over time.
Interface Library
-----------------
The Lumiera Application is designed deliberately in a way to be controllable by scripts. All of
the Session, the models and the vault are fully operational without the GUI. Any significant
functionality shall be usable through the primary Façade Interfaces alone. Yet in order to create
such an open and extensible application as envisioned, we also need to build up an _interface layer._
Eventually, this should evolve into a binding library for using Lumiera -- however, none of this
interface building work has been accomplished yet, as of 2026. We do not even have a complete
picture how _event sourcing_ meshes together with our UI commands and the configuration rules.
functionality can be addressed through the primary Façade Interfaces.
- we still need to identify those select core concepts which need to be exposed
But, in order to make such an open and extensible application a reality, we need to build up
an 'interface layer' -- provided as library for client code and script adapters to link against.
This library allows to access the primary external interfaces and exposes everything needed to
work with the specifics of the application.
[,yellow]#TODO as of 1/2012:# _this is just a nebulous plan for now._ Nothing of the work required
really to address facilities from the outside has been done. All we've managed to achieve is actually
to use clean interfaces and decouple the parts of the application appropriately.
- we still need to identify those core concepts which need to be exposed
- we need to refactor the corresponding data types to resolve cross dependencies to the implementation
- only then we could think about moving those data types into an _official Lumiera interface_
- then we could think about moving those data types into an _official Lumiera interface_
Support Library
---------------
There is a huge collection of generic building blocks, re-used more or less frequently.
The're written in a generic way, but in accordance to the rest of the source base, relying only
on the general error handling and logging framework used within Lumiera. (Some facilities may depend
on other parts of the Application; this can be qualified as a bug -- please complain when you've found
something of that sort).

View file

@ -1,7 +1,7 @@
Lumiera: The Inner Core
=======================
:Author: Lumiera_Core_Developers
:Date: 2012 / 2026
:Date: 2012 / 2025
:toc:
[abstract]
@ -30,7 +30,7 @@ This three Layers are:
The Steam Layer::
Keeps the Session, generates the rendering graphs for sequences,
prearranges elements and decides what to do when and how.
arranges what to do when and how.
The Vault Layer::
Manages worker pools, schedules jobs, does the memory management for the
@ -39,11 +39,13 @@ This three Layers are:
The extra components are:
The Vessel::
This is the »backbone« of the application, it is rooted below the three
layers and encompasses everything. It defines the periphery, starts all
Subsystems, controls the overall lifecycle and provides vital services
which must be available for engaging any part of the system.
Lumiera::
The main program itself, which starts all Subsystems and controls the
overall lifecycle.
Common::
Vital components and common services which must be available for pulling up
any part of the system.
Library::
A lot of (largely) stateless helper functionality used throughout the code.
@ -53,9 +55,9 @@ Coding Style
~~~~~~~~~~~~
The Lumiera team agreed on using GNU coding style with slight adaptations.
In general, we strive to maintain source code consistency and adhere to widely
accepted guidelines and practices of good craftsmanship. See our separate
link:{ldoc}/technical/code/CodingGuidelines.html[Coding Guidelines] page.
Generally speaking, we strive to keep the code base consistent and stick to
widely accepted guidelines and best practices. See our separate
link:{ldoc}/technical/code/codingGuidelines.html[Coding Guidelines] page.
@ -146,7 +148,7 @@ contained within the Session, which belongs to the _steam layer_ below.
User interfaces are implemented as plug-ins and are pulled up on demand,
they won't contain any relevant persistent state beyond presentation.
_As of 2026, the one and only interface under active development is
_As of 2023, the one and only interface under active development is
the Lumiera GTK GUI,_ based on GTK-3 / gtkmm. The sources are in tree
(directory 'src/stage') and it is integrated into the standard build and
installation process. By default, running the 'lumiera' executable will
@ -248,7 +250,7 @@ for each output channel is required.
The player service
^^^^^^^^^^^^^^^^^^
Client code accesses the player (subsystem) through the play-facade (`Play`).
Client code accesses the player (subsystem) through the play-facade (`lumiera::Play`).
The exposed service allows to _set up an output connection for playback or rendering,_
resulting in a play-controller object.
@ -283,6 +285,11 @@ performance critical.
- the OutputSlot exposed by the output manager is responsible for accepting timed frame delivery
Vault Layer
-----------
Engine Interface
~~~~~~~~~~~~~~~~
While on itself just a thin interface and adaptation layer forwarding calls to
@ -311,21 +318,16 @@ the job ticket acts as blueprint for the actual jobs to be enqueued
with the _Scheduler._
Vault Layer
-----------
Scheduler
~~~~~~~~~
The Scheduler serves as the central hub in the implementation of the RenderEngine
and coordinates the processing resources of the application. Its purpose is to
invoke and control the dependency and time based execution of the _Render Jobs._
As far as architecture is concerned, the Scheduler is located in the Vault-Layer and
is a _passive service_ -- like most components in the vault it needs to be put into
use by some coordinating and integrating facility. An EngineFaçade, itself located
above, in the »Steam« layer, acts as entrance point, to provide the high-level
render services to other parts of the application: render jobs can be activated
under various timing and dependency constraints, which can be grouped
Regarding architecture, the Scheduler is located in the Vault-Layer and running the Scheduler
is equivalent to activating the »Vault Subsystem«. An EngineFaçade acts as entrance point,
providing high-level render services to other parts of the application: render jobs can be
activated under various timing and dependency constraints, which can be grouped
into three basic modes of control:
Deadline::
@ -360,29 +362,6 @@ The scheduler is able to observe and maintain dependencies between render jobs,
to break down an extended calculation into a chain of small steps.
The Work Force
~~~~~~~~~~~~~~
Since the typical work job dimensions can be expected to lie in the range of _some milliseconds,_
the Lumiera engine can adopt a statistical model of capacity distribution. This is notably
different to an _operating system scheduler_ where the response times are measured in
microseconds and the coordination of work approaches hardware limits. These observations
lead to the (maybe slightly surprising approach) to rely on an _actively pulling_ work force
combined with a _passive scheduling service._
The _Work Force_ is a **pool of worker threads** with a size typically matching the nominal
number of independent CPU cores in the system. Spinning up the Work Force is equivalent to
activating the »Vault Subsystem«. Deliberately, there is no dedicated ``engine'' or
``manager'' thread. All workers participate in the coordination work on equal footing.
An idle worker enters the (passive) scheduling code, and thereby performs management
work up to the point where the next render job is determined. The worker then leaves
the management realm and continues with performing this job. However, the scheduling
code preloads each worker with some random sleep delay in order to distribute the
``incidence'' of idle workers and to avoid contention. This way, the available
computing capacity is distributed stochastically into that time window where
demand is foreseeable, based on the next job's starting time, the currently
dispatched jobs and the observed load factor.
Resource Management
~~~~~~~~~~~~~~~~~~~
@ -399,12 +378,12 @@ the system and current circumstances.
Vessel: Common Services
-----------------------
Common Services
---------------
Subsystem runner
~~~~~~~~~~~~~~~~
Conceptually, the application is structured into layers. However, as the actual runtime
Conceptually, the application is structured into layers. However, as actual runtime
entities we rely on a small number of link:{ldoc}/design/architecture/Subsystems.html[Subsystems],
which can be started and stopped and have well defined dependencies:
@ -439,14 +418,17 @@ link:{ldoc}/design/architecture/Subsystems.html#_lifecycle[documentation]
[small]#(likewise incomplete, but we're getting there, eventually [yellow-background]##2018##)#
Plugin loader
~~~~~~~~~~~~~
_tbw_
Advice framework
~~~~~~~~~~~~~~~~
This is a ``whiteboard'' system, allowing implementation-level services to _publish_
some piece of information as _advice_, while other parts of the system may pick up
this advice just by a name token, without requiring a direct knowledge of the
original _advisor._ The _Advice System_ is a singleton service that maintains
a lookup and registration data structure. Individual _piece of advice_ elements
original _advisor._ The _Advice System_ is a singleton service maintaining a
lookup and registration data structure. Individual _piece of advice_ elements
are stored _as value copy_. Publishing new advice requires locking, but accessing
advice is lock-free (actually there needs to be a memory barrier ``somewhere'',
otherwise the advice requesting client might not see new advice)
@ -476,27 +458,13 @@ Library
-------
The Lumiera support library contains lots of helper functionality
factored out from the internals and re-used. Some parts evolved into
basic frameworks, that are used pervasively throughout the code base.
- link:{ldoc}/design/architecture/time/index.html[time and timecode]
(-> xref:_time[below])
- link:Dependencies.html[dependency and service handling]
(-> xref:_singletons_and_dependencies[below]),
- the link:DiffFramework.html[»Diff framework«]
- property trees for link:{ldoc}/design/architecture/ETD.html[»External Tree Description«]
(-> xref:_external_tree_description[below])
- the link:iterator.html[iterator pipeline builders]
(-> xref:_iterators[below])
- various metaprogramming helpers (function signatures and generic sequences)
- string conversion, parsing and rendering functions
factored out from the internals and re-used. It is extended as we go.
practical shortcuts
~~~~~~~~~~~~~~~~~~~
The header 'lib/util.hpp' defines some shortcuts that are used almost
everywhere in the code base. The general idea is to highlight a common semantic meaning,
while hide the differentiation related to the technical details.
The header 'lib/util.hpp' defines some shortcuts heavily used throughout
the code base. The idea is to highlight a common semantic meaning, while
hide differentiation on the technical details.
isnil:: indicate a _missing value_, irrespective if this is a NULL pointer,
an empty string or an empty container. Several of our custom wrappers also
@ -505,29 +473,8 @@ isnil:: indicate a _missing value_, irrespective if this is a NULL pointer,
contains:: indicate that a value is _somehow contained_ within a collection,
irrespective if this is a set, a map, a vector or string (substring test)
limited:: to bracket some value.
sanitise:: make any string usable as identifier.
unConst:: a functional notation to cast away `const`, which is used typically
at the barrier between a type safe front-end and a low-level back-end,
and to avoid needless duplication of accessor code implementation
for sake of providing `const` information functions.
isSameObject:: identity test based on bare memory location,
which is used a lot in assertions and unit tests
string shorthands::
trim, startsWith, endsWith, boolVal, sanitise (turn arbitrary string into an identifier)
Literals and Symbols
~~~~~~~~~~~~~~~~~~~~
Besides the well-known C++ strings (and `string_view`), Lumiera introduces
two marker types for string tokens
Literal:: a C-string literal directly given in the Source code
Symbol:: an _interned_ token stored in a Symbol table, so that its
address hash can be used as unique identity
Locking
@ -945,17 +892,6 @@ and assignment incur the cost of an additional virtual call,
assuming the target objects cooperate by mixing in a
copy management interface.
.uninitialised storage
A cornerstone of the C++ language is the deterministic and reliable invocation
of constructors and destructors. However, when building low-level storage schemes,
a frequent requirement is to cover the precise storage of an object collection,
_without_ actually invoking any constructor or destructor. The `UninitialisedStorage`
template is a building block to support this task. It is parametrised with a type
and an element count, and provides a force-casted array-like access to the storage cells.
This can be used either to placement-construct some elements on-demand, or to ``project''
an object-like view over existing data in the storage.
Unique Identifiers
~~~~~~~~~~~~~~~~~~

View file

@ -1,5 +1,5 @@
Technical Documentation: Stage Layer
====================================
This section offers a loose collection with detailed information regarding the GUI implementation.
Eventually, this will have technical documentation for the GUI.

View file

@ -1,36 +1,27 @@
Technical Documentation: Steam-Layer
====================================
As implementation progresses, this section will gradually compile
the technical documentation for the Steam layer.
Eventually, this section will hold technical documentation for the Steam-Layer.
Development Scrapbook TiddlyWiki
--------------------------------
It is sometimes difficult to write complete documentation while a system is still under construction.
For taking work notes and formulating new ideas while working, _Ichthyostega_ frequently uses the
https://classic.tiddlywiki.com/[TiddlyWiki] -- which is a nifty JavaScript wiki embedded within a
single HTML page; as such it lives right within the source tree, where it can be worked on alongside
with the code. Notes and sketches for the planning often evolve into detailed descriptions, complete
with test data and UML diagrams to document the structure. Material drafted in the TiddlyWiki
will be moved gradually into this documentation section, as time permits.
Hermann Voßeler, core developer of the Steam-Layer uses an separate embedded wiki
for his day-to-day design sketches, notes and also for the more persistent planning.
This *TiddlyWiki* is a nifty JavaScript wiki embedded in a single HTML page; as such
it lives right within the source tree, where it can be worked on alongside with the
code. Besides the actual planning and descriptions, this wiki also links to the
UML diagrams created with *BOUML* during the ongoing planning and design.
This arrangement started as a temporary solution at a time where we did not have a suitable website
for permanent documentation -- and it was kept ever since, as the TiddlyWiki is very convenient
to work with, once you are accustomed to its quirks.footnote:[
It is quite fluid and inspiring to work with indeed. The content is an unordered collection
of small notepad pages, called ``Tiddlers'', which can be opened and closed conveniently.
Any "CamelCaseWord" becomes a new Tiddler, recent changes appear in a timeline, and Tiddlers
can be organised with tags. The only point to be careful is that you need to _save_
your work, which can be achieved with the `save' action in the menu to overwrite
the old version in the Git tree. Sometimes this might produce Git conflicts,
which are easy to resolve, since the content is plain text.
]
Additions to the TiddlyWiki are usually made during coding, and are deliberately committed always
together with the corresponding code. As such, these additions will propagate to Lumiera/Master eventually;
yet to make the newest development notes easier to access, we have put up a `rsync`ed version of the
TiddlyWiki online for direct access over the internet (which then is of course read-only).
This setup started as a temporary solution -- but as uWiki is not expected to come
to life soon, the current website can't serve as replacement for a real wiki, an
we'll stick to that situation for the time being. As the content in the TiddlyWiki
becomes more mature and stable, it will be moved over into this section here.
-> access the link:/wiki/renderengine.html[TiddlyWiki online here]
While additions to the TiddlyWiki generally propagate to Lumiera/Master through
the normal merges, we've put up a rsynced version of the TiddlyWiki online for
direct access (of course read-only).
-> access the Proy-Layer link:/wiki/renderengine.html[TiddlyWiki online here]

View file

@ -113,11 +113,8 @@ each have a distinct _type_ which explicitly identifies the possible connections
modules. Within these constraints, any combination is possible without
hidden restrictions.
However, the application strives for a certain degree of internal coherence. +
Lumiera is not a set of Lego bricks allowing you to build ``just anything''
(in a clumsy way) -- nor is it the next universal programming platform or
application framework driven by pre-canned success stories, where you
``just push the button'' and magic does the rest.
Lumiera is not a set of Lego bricks, nor is it a business application
driven by finite usage stories.
Medium Level Abstraction and Project Specific Conventions
@ -134,8 +131,9 @@ details such as header format conversion or access to individual channels.
To complement this approach, Lumiera does _not_ rely on hard-wired, global
conventions -- rather we allow the building up of project specific conventions and
rules xref:rules[<-] to fit a given requirement and preferred working style.
However, in its default configuration, Lumiera will be supplied with a conventional
UI template and key bindings to ease the learning curve for new users.
Lumiera will be supplied with a conventional template and a default
configuration to ease the learning curve for new users.
[[graphs]]
@ -146,12 +144,12 @@ Processing video (and audio) data can be conceived as a graph (more precisely
a _directed acyclic graph_). In this model of video processing, data flows
along the edges of the graph and is processed at the nodes.
The following figure depicts manipulating video data as a graph.
Input data is retrieved from the source nodes, which are located at the
top of the figure. From there, the data moves on to the next stage, where
video and audio data and meta information is pre-processed. All the further
operations on data can be represented by nodes, and data flows from one operation
to the next along the nodes of the graph.
The following figure depicts manipulating video data as a graph. The nodes at
the top of the graph are where data input occurs. From there, the data moves on
to the next nodes: the direct siblings of the root. Here, the video data is
pre-processed. All other operations on the data can be represented by
nodes, and data flows from one operation to the next along the nodes of the
graph.
image:{imgd}/lumiera_big_graph.png[Example for a graph]
@ -220,15 +218,16 @@ Lumiera consists of three major parts:
In this section, we discuss the user's perspective when working with the GUI.
Although Lumiera ships with a conventional desktop UI by default, we do not presume
that this GUI will be suitable for all uses. We expect there to be several specialised
UIs eventually, designed to handle very specific kinds of tasks.
Although Lumiera will initially ship with a standard, default GUI, we do not presume that this GUI will be suitable for all uses.
We expect there to be multiple, different GUIs, each designed for different
kinds of tasks. We expect that some of these will be written by users, and the
steam-layer is designed to facilitate this easily.
Indeed, Lumiera can even work
satisfactorily without a GUI, for example, for special purposes
(e.g. as headless render-node xref:rendernode[<-] or frameserver
xref:frameserver[<-]). A script interface will be added at some
point to facilitate automated processing.
xref:frameserver[<-]). Scripts will eventually be written
to facilitate automated processing.
Now it is time to take a look at the preliminary Lumiera GUI:
@ -506,19 +505,21 @@ A Plug-in is a kind of generalisation of a library.
All applications use, to varying degrees of intensity, libraries. A programmer
will not reinvent the wheel each time he sits down to programme an
application. A programmer will typically borrow and use features and
functionality from other programmers -- or even borrow from himself, stuff
functionality from other programmers---or even borrow from himself, stuff
written long ago in the past. Such features are collected together in
libraries.
A library is used in an application by _linking_ the library into the application.
However, there are different ways to _link_ a library: linking statically and
linking dynamically.
A library is used in an application by _linking_ the library into the
application. (There are other things to be done, but we'll call these 'details',
which wont concern us here.) There are different ways to _link_ a library
into an application: linking statically and linking dynamically.
_Static Linking_ is done while the application is being built, or
compiled. It is performed by the linker, which executes as the last step
of the compilation process. The linker can perform some sanity checks and
some optimisation. In the end, the functionality of the library is ``baked into''
the resulting executable. +
of the compilation process. The linker can perform some sanity checks
(mostly checks regarding formally correct function invocation) and warn the user
hat some particular feature is being used incorrectly. The user can then correct
the offending code, and recompile. +
There are a number of disadvantages associated with static linking. Features and
libraries are being constantly improved. If the application wants to use new
features, it will have to be recompiled with the new library which provides the
@ -531,14 +532,15 @@ features can be used by the application. The features provided by a dynamic
library are loaded when the application starts to run.
However both methods exhibit a number of shortcomings. Wouldn't it be better if
all features could be loaded only when needed? This scheme of making features
available to an application on-demand is known as run-time linking. A component
intended to be added this way, at run time, by the user, is known as a Plug-in.
all features could be loaded only when needed? If features could be loaded only
when needed, then they could also be unloaded when not required, thus saving
memory and possibly increasing performance. This scheme of making features
available to an application is known as run-time linking, aka plug-ins.
Plug-ins offer other benefits: the application can continue to use both the old
features and the new features together, side-by-side, by using the version
number associated with the plug-in. Furthermore, Plug-ins can load other Plug-ins
and thus extend the application in creative ways, beyond anything the original
developers of the application had planned.
number associated with the plug-in. This saves the application from the havoc
of library incompatibility that is
associated with other linking methods.
Most modern applications use plug-ins, some are heavily dependent on plug-ins
and only provide limited functionality without any plug-ins.

View file

@ -54,7 +54,7 @@ in addition to the following tools and libraries:
* https://www.boost.org/[Boost libraries]
* https://github.com/bplaum/gavl[GAVL library]
* https://nobug.pipapo.org/[NoBug] ~([purple]#⚠ see below#)~
* Lumiera https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[source code]
* Lumiera https://git.lumiera.org/?p=LUMIERA;a=summary[source code]
The GUI depends on the following:

View file

@ -115,9 +115,9 @@ sudo make install
but was orphaned in 2021. Since it is currently a prerequisite for building Lumiera,
we maintain a clone of the original repository and a Debian package on Lumiera.org.
This is relevant both for
https://git.lumiera.org/gitweb?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
https://git.lumiera.org/?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
and the
https://git.lumiera.org/gitweb?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+].
https://git.lumiera.org/?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+].
]
* first you have to build libGTL itself...

View file

@ -1,7 +1,6 @@
/* try.cpp - to try out and experiment with new features....
* scons will create the binary bin/try
*/
// 03/26 - runtime index access and iteration over tuple-likes
// 06/25 - provide a concept to accept _tuple-like_ objects
// 06/25 - investigate function type detection of std::bind Binders
// 12/24 - investigate problem when perfect-forwarding into a binder
@ -11,28 +10,22 @@
/** @file try.cpp
* Work out a construction scheme to build an efficient element-accessor to data
* in a tuple-like with run-time indexing. As an extension, run-time pulled iteration
* can be established, using the IterExplorer framework.
* @see lib::meta::FunTrampoline
* @see lib::meta::TupleIdxAdaptor
* Develop a concept to detect _tuple-like_ classes, based on the requirements
* of the »tuple protocol«. Using some ideas from [Stackoverflow] as starting point.
* However, we model both a _friend function_ `get` and a similar member function
* as alternatives for element access, and we break down the checks into sub-concepts.
* [Stackoverflow]: https://stackoverflow.com/q/68443804/444796
*/
#include "lib/format-cout.hpp"
#include "lib/format-util.hpp"
#include "test/test-helper.hpp"
#include "test/diagnostic-output.hpp"
#include "lib/meta/common-result.hpp"
#include "lib/meta/tuple-concept.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/test/diagnostic-output.hpp"
#include "lib/meta/tuple-helper.hpp"
#include "lib/meta/function.hpp"
#include "lib/iter-adapter.hpp"
#include "lib/hetero-data.hpp"
#include "lib/meta/trait.hpp"
#include "lib/util.hpp"
#include <array>
#include <concepts>
using std::string;
@ -48,263 +41,14 @@ template<lib::meta::tuple_like X>
void
show()
{
cout << "Tulik!! "<< ::test::showType<X>() <<endl;
cout << "Tup!! "<< lib::test::showType<X>() <<endl;
lib::meta::forEachIDX<X> ([](auto i)
{
using Elm = std::tuple_element_t<i, X>;
cout <<" "<<uint(i)<<": "<< ::test::showType<Elm>() <<endl;
cout <<" "<<uint(i)<<": "<< lib::test::showType<Elm>() <<endl;
});
}
namespace lib {
namespace meta{
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TODO : new generic library functions
/**
* Concept to require a generic type sequence `Types<TYPES...>`
*/
template<class TSEQ>
concept typeseq = requires (TSEQ seq)
{
// TSEQ can invoke a function with a Types<TYPES> subclass
[]<typename...TYPES>(Types<TYPES...>&){/*placeholder*/}(seq);
};
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////(End) : new generic library functions
template<template<class> class BUILD, typeseq TSEQ>
class FunTrampoline
{
using AllElm = ElmTypes<TSEQ>;
using Indices = AllElm::Idx;
using Builder = BUILD<TSEQ>;
using Functor = Builder::Functor;
using Table = std::array<Functor, AllElm::SIZ>;
template<size_t...idx>
static constexpr Table
buildFunctors (std::index_sequence<idx...>)
{
return {Builder().template build<idx>()...};
}
static constexpr Table functors = buildFunctors (Indices{});
public:
static constexpr size_t size() { return functors.size(); }
static constexpr size_t memSiz() { return sizeof(functors); }
static Functor const&
dispatch (size_t idx)
{
ENSURE (idx < functors.size());
return functors[idx];
}
using ResType = _Fun<Functor>::Ret;
};
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TODO : new generic library functions
template<typename T>
using isConst = std::is_const<remove_reference_t<T>>;
template<typename T>
using isLRef = std::is_lvalue_reference<T>;
template<class SEQ>
using Any_Const = ElmTypes<SEQ>::template OrAll<isConst>;
template<class SEQ>
using All_LRef = ElmTypes<SEQ>::template AndAll<isLRef>;
template<class SEQ>
static constexpr bool Any_Const_v = Any_Const<SEQ>::value;
template<class SEQ>
static constexpr bool All_LRef_v = All_LRef<SEQ>::value;
template<typename X, typename U, typename...TYPES>
struct ProbeCommonType
{
template<typename T1, typename T2>
using Reconciled = decltype(true ? std::declval<T1>() : std::declval<T2>());
template<typename RES>
struct FoundResult
: std::true_type
{
using Type = RES;
};
struct NoResultFound
: std::false_type
{ };
template<class T1
,class T2
,typename = Reconciled<T1,T2>>
static FoundResult<Reconciled<T1,T2>>
check(int);
template<class,class>
static NoResultFound
check(...);
using FirstResult = decltype(check<X,U>(0));
template<bool success, typename...TS>
struct Join
{
using Result = FirstResult;
};
template<typename T1, typename...TS>
struct Join<true, T1,TS...>
{
//wenn RES erfolgreich
using CT = FirstResult::Type;
using Result = ProbeCommonType<CT,T1,TS...>::Result;
};
using Result = Join<FirstResult::value, TYPES...>::Result;
};
template<typename...TYPES>
struct CommonResult
: ProbeCommonType<TYPES...>::Result
{ };
template<typename T1>
struct CommonResult<T1>
: CommonResult<T1,T1>
{ };
template<>
struct CommonResult<>
: std::false_type
{ };
template<typename...TYPES>
struct CommonResult<Types<TYPES...>>
: CommonResult<TYPES...>
{ };
template<typename...TYPES>
using CommonResult_t = CommonResult<TYPES...>::Type;
template<typename...TYPES>
static constexpr bool has_CommonResult_v = CommonResult<TYPES...>::value;
template<typename...TYPES>
concept reconcilable = requires
{
typename CommonResult<TYPES...>::Type;
};
template<typename...TYPES>
concept reconcilable_ref = reconcilable<TYPES...>
and isLRef_v<CommonResult_t<TYPES...>>;
template<typename...TYPES>
struct CommonResultTraits
{
static_assert (reconcilable<TYPES...>, "unable to reconcile these types");
using CommonVal = std::common_type_t<TYPES...>;
using ResType = CommonResult_t<TYPES...>;
//NOTE: std::common_type decays (strips CV and ref)
static constexpr bool makeConst = isConst_v<ResType>;
static constexpr bool exposeRef = isLRef_v<ResType>;
};
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////(End) : new generic library functions
template<class TUP>
class TupleIndexAdaptor
: public TUP
{
template<typeseq SEQ>
struct SubscriptBuilder
{
using Tuple = RefTraits<TUP>::value_type;
using AddRefs = ElmTypes<SEQ>::template Apply<std::add_lvalue_reference_t>;
using ResType = CommonResult_t<AddRefs>;
using Functor = ResType(*)(Tuple&);
template<size_t idx>
constexpr auto
build()
{
return [](Tuple& tuple) -> ResType
{
return getElm<idx> (tuple);
};
}
};
using TypeSeq = ElmTypes<TUP>::Seq;
using Accessor = FunTrampoline<SubscriptBuilder, TypeSeq>;
public:
using ResType = Accessor::ResType;
using reference = ResType;
using value_Type = RefTraits<ResType>::value_type;
template<typename T>
TupleIndexAdaptor(T&& dataSrc)
: TUP{forward<T> (dataSrc)}
{ }
using TUP::TUP;
static constexpr size_t size() { return Accessor::size(); }
ResType
operator[] (size_t idx)
{
return Accessor::dispatch(idx)(*this);
}
};
template<class TUP>
TupleIndexAdaptor(TUP) -> TupleIndexAdaptor<std::decay_t<TUP>>;
}}
using namespace lib::meta;
template<typeseq SEQ>
struct Stringify
{
using Tuple = ElmTypes<SEQ>::Tup;
using Functor = string(*)(Tuple const&);
template<size_t idx>
constexpr auto
build()
{
using ElmT = std::tuple_element_t<idx, Tuple>;
return [](Tuple const& tuple)
{
return util::toString<ElmT> (getElm<idx> (tuple));
};
}
};
struct Uber { };
struct Untr : Uber { };
struct Unta : Uber { };
int
main (int, char**)
@ -313,10 +57,20 @@ main (int, char**)
using Arr = std::array<int,3>;
using Hetero = lib::HeteroData<int,string>::Chain<short>::ChainExtent<bool,lib::meta::Nil>::ChainType;
SHOW_EXPR((lib::meta::tuple_sized<Tup> ))
SHOW_EXPR((lib::meta::tuple_sized<Arr> ))
SHOW_EXPR((lib::meta::tuple_sized<Hetero> ))
SHOW_EXPR((lib::meta::tuple_sized<int> ))
SHOW_EXPR((lib::meta::tuple_element_accessible<Tup,0>))
// SHOW_EXPR((lib::meta::tuple_element_accessible<Tup,2>))
SHOW_EXPR((lib::meta::tuple_element_accessible<Hetero,0>))
SHOW_EXPR((lib::meta::tuple_accessible<Tup>))
SHOW_EXPR((lib::meta::tuple_accessible<Hetero>))
SHOW_EXPR((lib::meta::tuple_like<Tup> ))
SHOW_EXPR((lib::meta::tuple_like<Arr> ))
SHOW_EXPR((lib::meta::tuple_like<Hetero> ))
SHOW_EXPR((lib::meta::tuple_like<string> ))
SHOW_EXPR((lib::meta::tuple_like<int> ))
show<Tup>();
@ -324,112 +78,25 @@ main (int, char**)
show<Hetero>();
show<int>();
using TupStringy = FunTrampoline<Stringify, ElmTypes<Tup>::Seq>;
SHOW_EXPR(TupStringy::size())
SHOW_EXPR((std::tuple_size_v<const Tup>))
using Elm1 = std::tuple_element_t<1, const Tup>;
SHOW_TYPE(Elm1)
using TupConstSeq = lib::meta::ElmTypes<const Tup>::Seq;
SHOW_TYPE(TupConstSeq)
Tup tup23{2,3};
Tup tup42{4,2};
SHOW_TYPE(decltype(std::get<1>(tup42)))
SHOW_EXPR(std::get<1>(tup42))
SHOW_EXPR(TupStringy::dispatch(0)(tup23))
SHOW_EXPR(TupStringy::dispatch(0)(tup42))
SHOW_EXPR(TupStringy::dispatch(1)(tup23))
SHOW_EXPR(TupStringy::dispatch(1)(tup42))
using T1 = Types<int const&,long&, char&>;
using T2 = Types<int*,void*>;
using T3 = Types<int,string>;
SHOW_EXPR((has_CommonResult_v<T1>))
SHOW_EXPR((has_CommonResult_v<T2>))
SHOW_EXPR((has_CommonResult_v<T3>))
SHOW_EXPR((has_CommonResult_v<>))
SHOW_EXPR((has_CommonResult_v<float*>))
SHOW_EXPR((has_CommonResult_v<float*,void* const>))
SHOW_TYPE(CommonResult_t<T1>)
SHOW_TYPE(CommonResult_t<T2>)
SHOW_TYPE(CommonResult_t<float*>)
using CoTx = CommonResult_t<float*,float const*>;
SHOW_TYPE(CoTx)
TupleIndexAdaptor<Tup> idxAdapt{tup42};
SHOW_EXPR(sizeof(tup42))
SHOW_EXPR(sizeof(idxAdapt))
SHOW_TYPE(TupleIndexAdaptor<Tup>::ResType)
SHOW_EXPR(idxAdapt.size())
SHOW_EXPR(idxAdapt[0])
SHOW_EXPR(idxAdapt[1])
SHOW_EXPR(getElm<0>(static_cast<Tup&> (idxAdapt)))
SHOW_EXPR(getElm<1>(static_cast<Tup&> (idxAdapt)))
SHOW_TYPE(decltype(idxAdapt[1]))
using Tup2 = std::tuple<int,int&, int>;
int ii{23};
Tup2 tup21{-1,ii,55};
TupleIndexAdaptor idxApt2{tup21};
SHOW_TYPE(decltype(tup21))
using IdxApt2 = decltype(idxApt2);
SHOW_TYPE(IdxApt2)
SHOW_TYPE(IdxApt2::ResType)
SHOW_EXPR(idxApt2[0])
SHOW_EXPR(idxApt2[1])
SHOW_EXPR(idxApt2[2])
SHOW_EXPR(++idxApt2[0])
SHOW_EXPR(idxApt2[1]++)
SHOW_EXPR(++++idxApt2[2])
SHOW_EXPR(tup21)
SHOW_EXPR(Tup2(idxApt2))
SHOW_EXPR(ii)
using TupIt = lib::IterableDecorator<lib::IdxStoreCore<IdxApt2>>;
TupIt tupIt{move(idxApt2)};
SHOW_EXPR( bool(tupIt) )
SHOW_EXPR( *tupIt )
SHOW_TYPE(decltype(*tupIt))
++*tupIt;
--ii;
SHOW_EXPR( *tupIt )
SHOW_EXPR(util::join(tupIt, "▶▶"))
SHOW_EXPR(( reconcilable<long,string> ))
SHOW_EXPR(( reconcilable<long&,string&> ))
SHOW_EXPR(( reconcilable<long,short> ))
SHOW_EXPR(( reconcilable<long&,short&> ))
SHOW_EXPR(( reconcilable_ref<long,string> ))
SHOW_EXPR(( reconcilable_ref<long&,string&> ))
SHOW_EXPR(( reconcilable_ref<long,short> ))
SHOW_EXPR(( reconcilable_ref<long&,const long&> ))
using TX = CommonResult_t<long&,const long&>;
SHOW_TYPE(TX)
SHOW_EXPR(( reconcilable<float*,void*> ))
SHOW_EXPR(( reconcilable<void,void*> ))
SHOW_EXPR(( reconcilable<float*&,void*&> ))
using TX2 = CommonResult_t<float*&,float*&>;
SHOW_TYPE(TX2)
SHOW_EXPR(( reconcilable<Uber,Unta> ))
SHOW_EXPR(( reconcilable<Untr,Unta> ))
SHOW_EXPR(( reconcilable<Untr&,Unta&> ))
SHOW_EXPR(( reconcilable<Uber&,Unta&> ))
SHOW_EXPR(( reconcilable_ref<Uber&,Unta&> ))
SHOW_EXPR(( reconcilable_ref<Uber&,Unta> ))
SHOW_EXPR(( reconcilable<Uber&,Unta> ))
SHOW_EXPR(( reconcilable<Uber,Untr&> ))
using TX3 = CommonResult_t<Uber&,Unta>;
SHOW_TYPE(TX3)
using TX4 = CommonResult_t<Unta&, const Uber&>;
SHOW_TYPE(TX4)
SHOW_EXPR(( reconcilable<Uber&,Unta&,Untr&> ))
using TX5 = CommonResult_t<const Uber&,Unta&,Untr&>;
SHOW_TYPE(TX5)
using TX6 = CommonResult_t<const int&,uint16_t,int64_t>;
SHOW_TYPE(TX6)
SHOW_EXPR(( CommonResult<int,string>::value ))
SHOW_EXPR(( CommonResult<int,string,long>::value ))
SHOW_EXPR(( CommonResult<const int,int&>::value ))
SHOW_EXPR(( reconcilable<const int&,uint16_t,int64_t> ))
SHOW_EXPR(( reconcilable<const Uber&,Unta&,Untr&> ))
SHOW_EXPR(( reconcilable<Uber&,const Unta&,Untr&> ))
using T1 = decltype(lib::meta::getElm<0> (std::declval<Tup>()));
SHOW_TYPE(T1)
using T2 = decltype(lib::meta::getElm<0> (std::declval<Tup&>()));
SHOW_TYPE(T2)
using T3 = decltype(lib::meta::getElm<0> (std::declval<Tup const&>()));
SHOW_TYPE(T3)
using H1 = decltype(lib::meta::getElm<4> (std::declval<Hetero>()));
SHOW_TYPE(H1)
using H2 = decltype(lib::meta::getElm<4> (std::declval<Hetero&>()));
SHOW_TYPE(H2)
using H3 = decltype(lib::meta::getElm<4> (std::declval<Hetero const&>()));
SHOW_TYPE(H3)
cout << "\n.gulp." <<endl;
return 0;

View file

@ -12,16 +12,16 @@ Import('env icons config')
# define the source file/dirs comprising each artifact to be built.
lLib = env.SharedLibrary('lumierasupport', srcSubtree('lib'), install=True)
lApp = env.SharedLibrary('lumieravessel', srcSubtree('vessel'),addLibs=lLib, install=True)
lVault = env.SharedLibrary('lumieravault', srcSubtree('vault'), addLibs=lLib+lApp, install=True)
lSteam = env.SharedLibrary('lumierasteam', srcSubtree('steam'), addLibs=lLib+lApp+lVault, install=True)
lApp = env.SharedLibrary('lumieracommon', srcSubtree('common'), addLibs=lLib, install=True)
lVault = env.SharedLibrary('lumieravault', srcSubtree('vault'), addLibs=lLib+lApp, install=True)
lSteam = env.SharedLibrary('lumierasteam', srcSubtree('steam'), addLibs=lLib+lApp+lVault,install=True)
# in reverse dependency order
core = lSteam+lVault+lApp+lLib # used to build the core application
app_lib = lApp+lLib # use to link against the platform
core_lib = core # use to link against the core application
vault_lib = lVault+app_lib # use to link against the low-level backend
support_lib = lLib # use to link against the support lib only
vessel_lib = lApp+support_lib # use to link against the application-framework
vault_lib = lVault+vessel_lib # use to link against the low-level backend
core_lib = lSteam+vault_lib # use to link against the core application
lumiera = ( env.Program('lumiera', ['lumiera/main.cpp'] + core, install=True)
+ config
@ -32,10 +32,6 @@ lumiera = ( env.Program('lumiera', ['lumiera/main.cpp'] + core, install=True)
env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera')
# Unit/Integration test support
test_support = env.SharedLibrary('testsupport', srcSubtree('test'), addLibs=vessel_lib, install=False)
# building Lumiera Plugins
plugins = [] # currently none
@ -53,4 +49,4 @@ gui = ( guimodule
)
Export('lumiera core core_lib vessel_lib vault_lib support_lib test_support plugins envGtk guimodule gui')
Export('lumiera core core_lib app_lib vault_lib support_lib plugins envGtk guimodule gui')

1
src/common/DIR_INFO Normal file
View file

@ -0,0 +1 @@
Common application services

View file

@ -86,8 +86,8 @@
*/
#ifndef VESSEL_ADVICE_H
#define VESSEL_ADVICE_H
#ifndef LUMIERA_ADVICE_H
#define LUMIERA_ADVICE_H
#include "lib/error.hpp"
@ -96,10 +96,10 @@
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include "vessel/advice/binding.hpp"
#include "common/advice/binding.hpp"
namespace vessel {
namespace lumiera{
namespace advice {
using lib::Literal;
@ -492,5 +492,5 @@ namespace advice {
}} // namespace vessel::advice
#endif /*VESSEL_ADVICE_H*/
}} // namespace lumiera::advice
#endif

View file

@ -90,8 +90,8 @@
#include "lib/sync.hpp"
#include "lib/util.hpp"
#include "include/logging.h"
#include "vessel/advice.hpp"
#include "vessel/advice/index.hpp"
#include "common/advice.hpp"
#include "common/advice/index.hpp"
using lib::Literal;
@ -101,7 +101,7 @@ using util::unConst;
typedef void (DeleterFunc)(void*);
namespace vessel {
namespace lumiera{
namespace advice {
namespace { // ======= implementation of the AdviceSystem ============
@ -352,4 +352,4 @@ namespace advice {
}} // namespace lib::vessel
}} // namespace lib::advice

View file

@ -21,7 +21,7 @@
*/
#include "vessel/advice/binding.hpp"
#include "common/advice/binding.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
@ -41,7 +41,7 @@ using boost::hash_combine;
using boost::lexical_cast;
namespace vessel {
namespace lumiera{
namespace advice {
LUMIERA_ERROR_DEFINE (BINDING_PATTERN_SYNTAX, "Unable to parse the given binding pattern definition");
@ -191,4 +191,4 @@ namespace advice {
}} // namespace vessel::advice
}} // namespace lumiera::advice

View file

@ -62,8 +62,8 @@
*/
#ifndef VESSEL_ADVICE_BINDING_H
#define VESSEL_ADVICE_BINDING_H
#ifndef LUMIERA_ADVICE_BINDING_H
#define LUMIERA_ADVICE_BINDING_H
#include "lib/error.hpp"
@ -75,7 +75,7 @@
#include <set>
namespace vessel {
namespace lumiera{
namespace advice {
using lib::Literal;
@ -285,5 +285,5 @@ namespace advice {
}} // namespace vessel::advice
#endif /*VESSEL_ADVICE_BINDING_H*/
}} // namespace lumiera::advice
#endif

View file

@ -14,23 +14,22 @@
/** @file index.hpp
** Implementation datastructure for use by the Advice system.
** To support the **Advice** collaboration, it is necessary to match advice requests with
** To support the \em Advice collaboration, it is necessary to match advice requests with
** existing advice provisions. Each successful match creates an advice solution, resulting in
** the bound piece of advice (data) to become visible to all the advised entities having placed
** a matching advice request into the advice system.
**
** This header is intended to be incorporated as part of the advice system implementation (advice.cpp).
** It is _not usable as an external interface_. But it is written in a rather self-contained manner,
** It is \em not usable as an external interface. But it is written in a rather self-contained manner,
** in order to be testable in isolation. To this end, the actual PointOfAdvice entities \a POA organised
** by this index datastructure remain abstract (defined as template parameter), and are only manipulated
** through the following functions:
** - `hash_value(POA)`
** - `POA::getMatcher()`
** - `POA::getSolution()`
** - `POA::setSolution(solution*)`
**
** # Implementation notes
** - \c hash_value(POA)
** - \c POA::getMatcher()
** - \c POA::getSolution()
** - \c POA::setSolution(solution*)
**
** \par implementation notes
** The advice binding index is implemented by two hashtables holding Binding::Matcher entries.
** Each entry associates a back-link to the corresponding POA (PointOfAdvice), which is assumed
** to be maintained outside the index. PointOfAdvice is an type-erased interface baseclass.
@ -75,8 +74,8 @@
*/
#ifndef VESSEL_ADVICE_INDEX_H
#define VESSEL_ADVICE_INDEX_H
#ifndef LUMIERA_ADVICE_INDEX_H
#define LUMIERA_ADVICE_INDEX_H
#include "lib/error.hpp"
@ -86,12 +85,12 @@
#include "lib/format-obj.hpp"
#include "lib/util-foreach.hpp"
#include "lib/util.hpp"
#include "vessel/advice/binding.hpp"
#include "common/advice/binding.hpp"
#include <unordered_map>
#include <string>
namespace vessel {
namespace lumiera{
namespace advice {
namespace error = lumiera::error;
@ -578,5 +577,5 @@ namespace advice {
#undef VERIFY
}} // namespace vessel::advice
#endif /*VESSEL_ADVICE_INDEX_H*/
}} // namespace lumiera::advice
#endif

View file

@ -1,5 +1,5 @@
/*
Voyage - global application initialisation and behaviour
AppState - application initialisation and behaviour
Copyright (C)
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -12,27 +12,27 @@
* *****************************************************************/
/** @file voyage.cpp
/** @file appstate.cpp
** Implementation of the _main application object_ of Lumiera.
** This is a service to manage some _really global_ state and to
** organise, start and stop the ["Subsystems"](\ref subsys.hpp).
** The vessel::Voyage object is set off by the `main()` function
** and coordinates the lifecycle of all parts of the application.
** The AppState object provides the building blocks for the
** `main()` function to control the global lifecycle.
**
** @see main.cpp
*/
#include "lib/error.hpp"
#include "vessel/voyage.hpp"
#include "vessel/subsystem-runner.hpp"
#include "common/appstate.hpp"
#include "common/subsystem-runner.hpp"
extern "C" {
#include "vessel/config-interface.h"
#include "common/config-interface.h"
#include "vessel/interface.h"
#include "vessel/interfaceregistry.h"
#include "vessel/plugin.h"
#include "common/interface.h"
#include "common/interfaceregistry.h"
#include "common/plugin.h"
}
#include "lib/symbol.hpp"
@ -41,12 +41,10 @@ extern "C" {
using lib::Literal;
using std::unique_ptr;
using lumiera::maybeThrow;
namespace vessel {
namespace error = lumiera::error;
namespace lumiera {
namespace { // implementation details
@ -70,19 +68,19 @@ namespace vessel {
* static initialisation code accesses the instance).
* @note all further application startup is conducted by \c main.cpp
*/
Voyage::Voyage()
AppState::AppState()
: setup_{LUMIERA_LOCATION_OF_BOOTSTRAP_INI}
, subsystems_{}
, emergency_{false}
, core_up_{false}
{ }
/** storage for the Voyage Singleton instance */
lib::Depend<Voyage> Voyage::access;
/** storage for the Appstate Singleton instance */
lib::Depend<AppState> AppState::instance;
string
Voyage::fetchSetupValue (Literal key)
AppState::fetchSetupValue (Literal key)
{
return setup_.get(key).as<string>();
}
@ -101,7 +99,7 @@ namespace vessel {
void
Voyage::init (Option& options)
AppState::init (Option& options)
{
TRACE (common, "initialising application core...");
@ -126,7 +124,7 @@ namespace vessel {
void
Voyage::maybeStart (Subsys& subsys)
AppState::maybeStart (lumiera::Subsys& subsys)
{
TRACE (common, "maybe startup %s...?", cStr(subsys));
REQUIRE (subsystems_);
@ -135,7 +133,7 @@ namespace vessel {
using ExitCode = Voyage::ExitCode;
typedef AppState::ExitCode ExitCode;
/** @remark
@ -151,7 +149,7 @@ namespace vessel {
* is activated.
*/
ExitCode
Voyage::maybeWait()
AppState::maybeWait()
{
if (subsystems_)
{
@ -177,7 +175,7 @@ namespace vessel {
ExitCode
Voyage::abort (lumiera::Error& problem)
AppState::abort (lumiera::Error& problem)
{
ERROR (common, "Aborting Lumiera after unhandled error: %s", cStr(problem.what()));
@ -202,7 +200,7 @@ namespace vessel {
ExitCode
Voyage::abort () noexcept
AppState::abort () noexcept
{
log_and_clear_unexpected_errorstate();
@ -222,11 +220,11 @@ namespace vessel {
/** anything which should be closed as late as possible and after
* the normal shutdown sequence can be placed into the Voyage dtor.
* the normal shutdown sequence can be placed into the AppState dtor.
* But note though, when the application is halted unconditionally,
* no dtors will be executed.
*/
Voyage::~Voyage()
AppState::~AppState()
{
if (core_up_)
try
@ -243,4 +241,4 @@ namespace vessel {
} // namespace vessel
} // namespace lumiera

View file

@ -1,5 +1,5 @@
/*
VOYAGE.hpp - application initialisation and behaviour
APPSTATE.hpp - application initialisation and behaviour
Copyright (C)
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -11,13 +11,13 @@
*/
/** @file voyage.hpp
/** @file appstate.hpp
** Registering and managing primary application-global services.
** This can be considered the "main" object of the Lumiera application
** Besides encapsulating the logic to start up the fundamental parts of
** the application, there is a mechanism for registering \em subsystems
** to be brought up and shut down in order. The vessel::Voyage will issue
** global application lifecycle events (where other parts may have attached
** to be brought up and shut down in order. AppState will issue the global
** application lifecycle events (where other parts may have registered
** callbacks) and provides the top-level catch-all error handling.
**
** @see LifecycleHook
@ -28,15 +28,15 @@
*/
#ifndef VESSEL_VOYAGE_H
#define VESSEL_VOYAGE_H
#ifndef LUMIERA_APPSTATE_H
#define LUMIERA_APPSTATE_H
#include "lib/symbol.hpp"
#include "lib/nocopy.hpp"
#include "lib/depend.hpp"
#include "vessel/option.hpp"
#include "vessel/subsys.hpp"
#include "vessel/basic-setup.hpp"
#include "common/option.hpp"
#include "common/subsys.hpp"
#include "common/basic-setup.hpp"
#include <memory>
#include <string>
@ -44,7 +44,7 @@
namespace vessel {
namespace lumiera {
using std::string;
@ -55,28 +55,29 @@ namespace vessel {
* The Lumiera Application state and basic initialisation.
* Singleton to hold global flags directing the overall application behaviour,
* responsible for triggering lifecycle events and performing early initialisation tasks.
* @warning don't use vessel::Voyage in destructors.
* AppState services are available already from static initialisation code.
* @warning don't use AppState in destructors.
*/
class Voyage
class AppState
: util::NonCopyable
{
private:
Voyage();
~Voyage();
AppState ();
friend class lib::DependencyFactory<Voyage>;
~AppState ();
friend class lib::DependencyFactory<AppState>;
public:
/** get the (single) vessel::Voyage instance.
/** get the (single) AppState instance.
* @warning don't use it after the end of main()! */
static lib::Depend<Voyage> access;
static lib::Depend<AppState> instance;
/** evaluate the result of option parsing and maybe additional configuration
* such as to be able to determine the further behaviour of the application.
* Set the internal state within this object accordingly. */
void init (Option& options);
void init (lumiera::Option& options);
/** access basic application setup values (from \c setup.ini) */
@ -87,7 +88,7 @@ namespace vessel {
* needs to be pulled up and, if necessary, register the Subsys and its
* prerequisites to be maintained throughout the application's lifetime.
*/
void maybeStart (Subsys&);
void maybeStart (lumiera::Subsys&);
enum ExitCode {
@ -132,5 +133,6 @@ namespace vessel {
};
} // namespace vessel
#endif /*VESSEL_VOYAGE_H*/
} // namespace lumiera
#endif

View file

@ -24,16 +24,19 @@
*/
#include "vessel/basic-setup.hpp"
#include "common/basic-setup.hpp"
#include "lib/searchpath.hpp"
#include "lib/error.hpp"
#include "lib/file.hpp"
#include "lib/util.hpp"
extern "C" {
#include <unistd.h>
}
#include <fstream>
namespace vessel {
namespace lumiera {
using std::string;
using std::ifstream;
@ -110,4 +113,4 @@ namespace vessel {
} // namespace vessel
} // namespace lumiera

View file

@ -35,14 +35,14 @@
** be mapped into FSH compliant installation folders by the
** packager.
**
** @see vessel::Voyage::Voyage()
** @see lumiera::AppState::AppState()
** @see main.cpp
**
*/
#ifndef VESSEL_BASIC_SETUP_H
#define VESSEL_BASIC_SETUP_H
#ifndef COMMON_BASIC_SETUP_H
#define COMMON_BASIC_SETUP_H
#include "lib/error.hpp"
#include "lib/symbol.hpp"
@ -58,12 +58,11 @@
namespace vessel {
namespace err = lumiera::error;
namespace opt = boost::program_options;
namespace lumiera {
using std::string;
namespace opt = boost::program_options;
/**
@ -84,7 +83,7 @@ namespace vessel {
* configuration as a replacement for the time being.
*
* @see configfacade.hpp
* @see vessel::Voyage
* @see AppState
*/
class BasicSetup
: util::NonCopyable
@ -115,10 +114,10 @@ namespace vessel {
__ensure_hasKey (string const& key) const
{
if (!util::contains (settings, key))
throw err::Logic ("Key \""+key+"\" not found in setup.ini");
throw error::Logic ("Key \""+key+"\" not found in setup.ini");
}
};
} // namespace vessel
#endif /*VESSEL_BASIC_SETUP_H*/
} // namespace lumiera
#endif

View file

@ -20,8 +20,8 @@
*/
#include "vessel/config-interface.h"
#include "vessel/config.h"
#include "common/config-interface.h"
#include "common/config.h"
@ -133,7 +133,7 @@ LUMIERA_EXPORT(
#ifndef LUMIERA_PLUGIN
#include "vessel/interfaceregistry.h"
#include "common/interfaceregistry.h"
void
lumiera_config_interface_init (void)
{

View file

@ -29,7 +29,7 @@
#define LUMIERA_CONFIG_INTERFACE_H
#include "vessel/interface.h"
#include "common/interface.h"

View file

@ -24,8 +24,8 @@
#include "lib/safeclib.h"
#include "lib/tmpbuf.h"
#include "vessel/config-lookup.h"
#include "vessel/config.h"
#include "common/config-lookup.h"
#include "common/config.h"
/* we only use one fatal error for now, when allocation in the config system fail, something else is pretty wrong */
LUMIERA_ERROR_DEFINE (CONFIG_LOOKUP, "config lookup failure");

View file

@ -39,7 +39,7 @@ typedef struct lumiera_config_lookupentry_struct lumiera_config_lookupentry;
typedef lumiera_config_lookupentry* LumieraConfigLookupentry;
#include "vessel/configitem.h"
#include "common/configitem.h"
#include <nobug.h>

View file

@ -41,7 +41,7 @@
** @todo as of 11/2016 the situation is basically the same: this is placeholder code
** and just implemented enough to keep us going without violating the architecture vision
**
** @see vessel::Query
** @see lumiera::Query
** @see mobject::session::DefsManager
** @see asset::StructFactory
** @see config-resolver.hpp specialised setup for the Steam-Layer
@ -50,13 +50,13 @@
*/
#ifndef VESSEL_CONFIG_RULES_H
#define VESSEL_CONFIG_RULES_H
#ifndef LUMIERA_CONFIG_RULES_H
#define LUMIERA_CONFIG_RULES_H
#include "lib/p.hpp"
#include "lib/symbol.hpp"
#include "lib/meta/generator.hpp"
#include "vessel/query.hpp"
#include "common/query.hpp"
#include <string>
@ -65,12 +65,11 @@
namespace lumiera {
namespace error {
LUMIERA_ERROR_DECLARE (CAPABILITY_QUERY); ///< unresolvable capability query.
}}
namespace vessel {
}
using std::string;
using lib::P;
/////////////////////////////////////////////////////////////////////TICKET #705 this is draft/preview code; a real resolution system needs to be integrated
@ -100,7 +99,7 @@ namespace vessel {
using lib::Symbol;
using lib::Literal;
using vessel::Query;
using lumiera::Query;
/** placeholder definition for later.
* @todo intention is to integrate with lib::Symbol
@ -148,8 +147,8 @@ namespace vessel {
* we use a mock implementation.
* (this code works and is already used 2/2008)
* @todo retrofit this to install and use a QueryResolver
* @see vessel::query::LookupPreconfigured
* @see vessel::query::MockTable
* @see lumiera::query::LookupPreconfigured
* @see lumiera::query::MockTable
*/
template<class TY>
class QueryHandler
@ -218,11 +217,11 @@ namespace vessel {
* will magically succeed with every candidate object provided. This
* is currently necessary to get objects into the defaults manager,
* as the query system is not able to do real query resolution */
void setFakeBypass(vessel::QueryKey const& q);
bool isFakeBypass (vessel::QueryKey const& q);
void setFakeBypass(lumiera::QueryKey const& q);
bool isFakeBypass (lumiera::QueryKey const& q);
/////////////////////////////////////////////////////////////////////////////TICKET 710
} // namespace query
} // namespace vessel
#endif /*VESSEL_CONFIG_RULES_H*/
} // namespace lumiera
#endif

View file

@ -22,7 +22,7 @@
#include "include/logging.h"
#include "lib/tmpbuf.h"
#include "vessel/config.h"
#include "common/config.h"
#include <stdint.h>

View file

@ -26,7 +26,7 @@
#include "lib/tmpbuf.h"
#include "vessel/config.h"
#include "common/config.h"
extern LumieraConfig lumiera_global_config;

View file

@ -22,7 +22,7 @@
#include "include/logging.h"
#include "lib/safeclib.h"
#include "lib/tmpbuf.h"
#include "vessel/config.h"
#include "common/config.h"
#include <stdint.h>
#include <stdlib.h>

View file

@ -26,7 +26,7 @@
**
** @todo as of 2016, this code is not in any meaningful use
**
** @see vessel::BasicSetup simple start-up configuration
** @see lumiera::BasicSetup simple start-up configuration
** @see http://lumiera.org/documentation/technical/vault/ConfigLoader.html ConfigLoader draft from 2008
*/
@ -35,8 +35,8 @@
#include "lib/error.h"
#include "lib/mutex.h"
#include "vessel/config-lookup.h"
#include "vessel/configitem.h"
#include "common/config-lookup.h"
#include "common/configitem.h"
#include <nobug.h>
#include <stdio.h>

View file

@ -20,7 +20,7 @@
#include "lib/safeclib.h"
#include "vessel/configentry.h"
#include "common/configentry.h"

View file

@ -22,7 +22,7 @@
#ifndef COMMON_CONFIGENTRY_H
#define COMMON_CONFIGENTRY_H
#include "vessel/configitem.h"
#include "common/configitem.h"
#include <nobug.h>

View file

@ -31,16 +31,16 @@
#include "include/logging.h"
#include "include/lifecycle.hpp"
#include "vessel/spine/config-facade.h"
#include "vessel/voyage.hpp"
#include "include/lifecycle.h"
#include "include/config-facade.h"
#include "common/appstate.hpp"
#include "lib/searchpath.hpp"
#include "lib/iter-explorer.hpp"
#include "lib/format-util.hpp"
#include "lib/util.hpp"
extern "C" {
#include "vessel/config.h"
#include "common/config.h"
}
@ -61,9 +61,7 @@ extern "C" {
namespace vessel {
namespace spine {
namespace error = lumiera::error;
namespace lumiera {
using util::isnil;
using lib::Literal;
@ -90,7 +88,7 @@ namespace spine {
Config::Config ()
{
string extendedConfigSearchPath = Voyage::access().fetchSetupValue (KEY_CONFIG_PATH);
string extendedConfigSearchPath = AppState::instance().fetchSetupValue (KEY_CONFIG_PATH);
lumiera_config_init (cStr(extendedConfigSearchPath));
TRACE (config, "Config system ready.");
}
@ -110,7 +108,7 @@ namespace spine {
string
Config::get (lib::Literal key)
{
string value = Voyage::access().fetchSetupValue (key);
string value = AppState::instance().fetchSetupValue (key);
if (isnil (value))
throw error::Config ("Configuration value for key=\""+key+"\" is missing");
@ -119,14 +117,14 @@ namespace spine {
} // namespace vessel
} // namespace lumiera
extern "C" { /* ==== implementation C interface for accessing setup.ini ======= */
using std::string;
using vessel::spine::Config;
using lumiera::Config;
using lib::SearchPathSplitter;
using util::isnil;
@ -141,4 +139,4 @@ extern "C" { /* ==== implementation C interface for accessing setup.ini =======
}();
return cStr(pathSpec);
}
}}// namespace vessel::spine
}

View file

@ -25,9 +25,9 @@
#include "lib/safeclib.h"
#include "lib/tmpbuf.h"
#include "vessel/config.h"
#include "vessel/configitem.h"
#include "vessel/configentry.h"
#include "common/config.h"
#include "common/configitem.h"
#include "common/configentry.h"
#include <ctype.h>
#include <stdint.h>

View file

@ -54,7 +54,7 @@ typedef lumiera_configitem* LumieraConfigitem;
struct lumiera_configitem_vtable;
#include "vessel/config-lookup.h"
#include "common/config-lookup.h"
#include <nobug.h>

View file

@ -27,8 +27,8 @@
#include "lib/sync.hpp"
#include "lib/error.hpp"
#include "lib/depend.hpp"
#include "vessel/instancehandle.hpp"
#include "vessel/option.hpp"
#include "common/instancehandle.hpp"
#include "common/option.hpp"
#include <memory>
#include <string>
@ -38,8 +38,8 @@ namespace stage {
using std::string;
using std::unique_ptr;
using vessel::Subsys;
using vessel::InstanceHandle;
using lumiera::Subsys;
using lumiera::InstanceHandle;
using lib::Sync;
using lib::RecursiveLock_NoWait;
@ -49,7 +49,7 @@ namespace stage {
struct GuiRunner
: util::NonCopyable
{
using GuiHandle = InstanceHandle<LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1)>;
typedef InstanceHandle<LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1)> GuiHandle;
GuiHandle theGUI_;
@ -89,13 +89,13 @@ namespace stage {
class GuiSubsysDescriptor
: public vessel::Subsys,
: public lumiera::Subsys,
public Sync<RecursiveLock_NoWait>
{
operator string() const { return "Lumiera GTK GUI"; }
bool
shouldStart (vessel::Option& opts) override
shouldStart (lumiera::Option& opts) override
{
if (opts.isHeadless() or 0 < opts.getPort())
{
@ -107,7 +107,7 @@ namespace stage {
}
bool
start (vessel::Option&, Subsys::SigTerm termNotification) override
start (lumiera::Option&, Subsys::SigTerm termNotification) override
{
Lock guard{this};
if (facade)
@ -188,7 +188,7 @@ namespace stage {
/** @internal intended for use by main(). */
vessel::Subsys&
lumiera::Subsys&
GuiFacade::getDescriptor()
{
return theDescriptor();

View file

@ -28,8 +28,8 @@
*/
#ifndef VESSEL_INSTANCEHANDLE_H
#define VESSEL_INSTANCEHANDLE_H
#ifndef LUMIERA_INSTANCEHANDLE_H
#define LUMIERA_INSTANCEHANDLE_H
#include "include/logging.h"
@ -38,15 +38,15 @@
#include "lib/depend-inject.hpp"
extern "C" {
#include "vessel/interface.h"
#include "vessel/interfaceregistry.h"
#include "common/interface.h"
#include "common/interfaceregistry.h"
}
#include <string>
namespace vessel {
namespace lumiera {
using std::string;
@ -120,7 +120,7 @@ namespace vessel {
* between an InstanceHandle and a facade interface,
* which is going to be implemented through the given
* interface/plugin. This way, creating the InstanceHandle
* automatically creates a vessel::facade::Proxy, to route
* automatically creates a lumiera::facade::Proxy, to route
* any facade calls through the interface/plugin. Similarly,
* when destroying the InstanceHandle, the proxy will be closed.
*/
@ -267,5 +267,5 @@ namespace vessel {
};
} // namespace vessel
#endif /*VESSEL_INSTANCEHANDLE_H*/
} // namespace lumiera
#endif /*LUMIERA_INSTANCEHANDLE_H*/

View file

@ -49,7 +49,7 @@ namespace error = lumiera::error;
#include "lib/time/quantiser.hpp"
#include "lib/time/timecode.hpp"
#include "lib/time/mutation.hpp"
#include "vessel/advice.hpp"
#include "common/advice.hpp"
namespace lib {
@ -59,7 +59,7 @@ namespace time {
using util::_Fmt;
namespace advice = vessel::advice;
namespace advice = lumiera::advice;
PQuant

View file

@ -24,7 +24,7 @@
#ifndef COMMON_INTERFACEDESCRIPTOR_H
#define COMMON_INTERFACEDESCRIPTOR_H
#include "vessel/interface.h"
#include "common/interface.h"
/**

View file

@ -26,10 +26,10 @@
#include "lib/recmutex.h"
#include "lib/safeclib.h"
#include "vessel/plugin.h"
#include "vessel/interface.h"
#include "common/plugin.h"
#include "common/interface.h"
#include "vessel/interfaceregistry.h"
#include "common/interfaceregistry.h"
#include <nobug.h>

View file

@ -25,8 +25,8 @@
#include <nobug.h>
#include "vessel/plugin.h"
#include "vessel/interfaceregistry.h"
#include "common/plugin.h"
#include "common/interfaceregistry.h"

View file

@ -26,8 +26,8 @@
#include "lib/recmutex.h"
#include "lib/psplay.h"
#include "vessel/interface.h"
#include "vessel/plugin.h"
#include "common/interface.h"
#include "common/plugin.h"
#include <nobug.h>

View file

@ -24,13 +24,13 @@
#include "include/gui-notification-facade.h"
#include "vessel/spine/interfaceproxy.hpp"
#include "include/interfaceproxy.hpp"
namespace stage {
/** static storage for the facade access front-end */
lib::Depend<GuiNotification> GuiNotification::facade;
}
namespace vessel {
namespace lumiera {
namespace facade {
using stage::ID;
using lib::diff::GenNode;
@ -71,4 +71,4 @@ namespace facade {
template
class Link<Interface,Facade>;
}} //namespace vessel::facade
}} //namespace facade::lumiera

View file

@ -20,7 +20,7 @@
#include "lib/error.hpp"
#include "lib/util.hpp"
#include "vessel/option.hpp"
#include "common/option.hpp"
@ -32,7 +32,7 @@ namespace op = boost::program_options;
using lib::VectS;
namespace vessel {
namespace lumiera {
/** set up an options parser to use the application commandline.
* Recognises the following options
@ -155,4 +155,4 @@ namespace vessel {
} // namespace vessel
} // namespace lumiera

View file

@ -28,14 +28,14 @@
** [Boost program options library] : https://www.boost.org/doc/libs/1_83_0/doc/html/program_options.html
**
** @see basic-setup.hpp
** @see vessel::Voyage
** @see vessel::spine::Config
** @see lumiera::AppState
** @see lumiera::Config
**
*/
#ifndef VESSEL_OPTION_H
#define VESSEL_OPTION_H
#ifndef LUMIERA_OPTION_H
#define LUMIERA_OPTION_H
#include "lib/nocopy.hpp"
#include "lib/cmdline.hpp"
@ -47,7 +47,7 @@
namespace vessel {
namespace lumiera {
using std::string;
using std::ostream;
@ -95,5 +95,5 @@ namespace vessel {
ostream& operator<< (ostream& os, const Option& to);
} // namespace vessel
#endif /*VESSEL_OPTION_H*/
} // namespace lumiera
#endif

View file

@ -18,7 +18,7 @@
#include "include/logging.h"
#include "lib/tmpbuf.h"
#include "vessel/plugin.h"
#include "common/plugin.h"
#include <dlfcn.h>
#include <nobug.h>

View file

@ -25,10 +25,10 @@
#include "lib/recmutex.h"
#include "lib/error.h"
#include "vessel/spine/config-facade.h"
#include "vessel/interfaceregistry.h"
#include "vessel/config.h"
#include "vessel/plugin.h"
#include "include/config-facade.h"
#include "common/interfaceregistry.h"
#include "common/config.h"
#include "common/plugin.h"
#include <glob.h>

View file

@ -44,7 +44,7 @@
#include "lib/psplay.h"
#include "lib/error.h"
#include "vessel/interface.h"
#include "common/interface.h"
#include <stdlib.h>
#include <nobug.h>

View file

@ -39,7 +39,7 @@
** tag to indicate the kind of query. In addition, queries are usually required to provide
** a syntactical representation, allowing to transform each query into a generic query.
**
** To resolve the query, a vessel::QueryResolver instance is necessary, and this
** To resolve the query, a lumiera::QueryResolver instance is necessary, and this
** query resolver needs the ability to deal with this specific kind of query. Typically
** this is achieved by installing a resolution function into the resolver on application start.
** The QueryResolver returns a result set, actually a Query::Cursor, which can be used to
@ -51,7 +51,7 @@
** @note as of 1/2013 this is rather a concept draft, but some parts of the code base
** are already actively using some more specific queries
**
** @see vessel::QueryResolver
** @see lumiera::QueryResolver
** @see mobject::session::DefsManager
** @see asset::StructFactory
** @see config-resolver.hpp specialised setup for the Steam-Layer
@ -62,8 +62,8 @@
*/
#ifndef VESSEL_QUERY_H
#define VESSEL_QUERY_H
#ifndef LUMIERA_QUERY_H
#define LUMIERA_QUERY_H
#include "lib/hash-combine.hpp"
@ -83,7 +83,7 @@
#include <string>
namespace vessel {
namespace lumiera {
using lib::IxID;
using lib::Symbol;
@ -232,7 +232,7 @@ namespace vessel {
* of specific resolution mechanisms. This way, clients may retrieve a set of results,
* where each result represents a possible solution to the original query.
*
* @remarks vessel::Query is an interface, but can be used as-is to represent a generic query.
* @remarks lumiera::Query is an interface, but can be used as-is to represent a generic query.
* Specialised subclasses are required to provide a syntactic representation, but are
* free to do so only on demand. In this case, generate an \em empty lib::QueryText
* definition and implement the Query#buildSyntacticRepresentation function.
@ -589,5 +589,5 @@ namespace vessel {
} // namespace vessel
#endif /*VESSEL_QUERY_H*/
} // namespace lumiera
#endif

View file

@ -20,17 +20,16 @@
#include "lib/error.hpp"
#include "vessel/query.hpp"
#include "vessel/config-rules.hpp"
#include "common/query.hpp"
#include "common/config-rules.hpp"
using vessel::QueryKey;
using lumiera::QueryKey;
namespace lumiera {
namespace error {
LUMIERA_ERROR_DEFINE (CAPABILITY_QUERY, "unresolvable capability query");
}}
namespace vessel {
}
namespace query {
@ -51,4 +50,4 @@ namespace vessel {
/////////////////////////////////////////////////////////////////////////////TICKET 710
}// namespace query
} // namespace vessel
} // namespace lumiera

View file

@ -30,23 +30,25 @@
#ifndef VESSEL_QUERY_DEFS_MANAGER_IMPL_H
#define VESSEL_QUERY_DEFS_MANAGER_IMPL_H
#ifndef LUMIERA_QUERY_DEFS_MANAGER_IMPL_H
#define LUMIERA_QUERY_DEFS_MANAGER_IMPL_H
#include "vessel/query/defs-manager.hpp"
#include "vessel/query/defs-registry.hpp"
#include "vessel/config-rules.hpp"
#include "common/query/defs-manager.hpp"
#include "common/query/defs-registry.hpp"
#include "common/config-rules.hpp"
#include "lib/format-string.hpp"
#include "lib/error.hpp"
using util::_Fmt;
namespace vessel {
using steam::ConfigResolver;
using lumiera::query::QueryHandler; ///////TODO preliminary interface defined in config-rules.hpp
namespace lumiera{
namespace query {
namespace err = lumiera::error;
using util::_Fmt;
using steam::ConfigResolver;
@ -137,12 +139,12 @@ namespace query {
res = create (capabilities); // not yet known as default, create new
if (!res)
throw err::Config (_Fmt("The following Query could not be resolved: %s.")
% capabilities.rebuild().asKey()
, LERR_(CAPABILITY_QUERY) );
throw error::Config (_Fmt("The following Query could not be resolved: %s.")
% capabilities.rebuild().asKey()
, LERR_(CAPABILITY_QUERY) );
else
return res;
}
}} // namespace vessel::query
#endif /* VESSEL_QUERY_DEFS_MANAGER_IMPL_H */
}} // namespace lumiera::query
#endif /* LUMIERA_QUERY_DEFS_MANAGER_IMPL_H */

View file

@ -47,7 +47,7 @@
** importance that we build our implementations with this goal in mind
**
** # Configuration Query Interface
** The [Defaults Manager](\ref vessel::query::DefsManager) exposes an interface
** The [Defaults Manager](\ref lumiera::query::DefsManager) exposes an interface
** similar to a database. The intended audience of this interface is the writer
** of low-level implementation code. This facade interface is meant to create
** a more familiar front-end to an essentially logic and rules driven
@ -90,21 +90,23 @@
*/
#ifndef VESSEL_QUERY_DEFS_MANAGER_H
#define VESSEL_QUERY_DEFS_MANAGER_H
#ifndef LUMIERA_QUERY_DEFS_MANAGER_H
#define LUMIERA_QUERY_DEFS_MANAGER_H
#include "lib/p.hpp"
#include "lib/nocopy.hpp"
#include "vessel/query.hpp"
#include "common/query.hpp"
#include <memory>
namespace vessel {
namespace lumiera{
namespace query {
using lumiera::Query;
using std::unique_ptr;
namespace impl { class DefsRegistry; }
@ -183,7 +185,7 @@ namespace query {
// < class TAR, ///< the target to query for
// template <class> class SMP ///< smart pointer class to wrap the result
// >
// SMP<TAR> operator() (const vessel::Query<TAR>&);
// SMP<TAR> operator() (const lumiera::Query<TAR>&);
// 12/09: according to my current knowledge of template metaprogramming, the answer is "no",
// but we could use a traits template to set up a fixed association of smart pointers
@ -196,5 +198,5 @@ namespace query {
}} // namespace vessel::query
#endif /*VESSEL_QUERY_DEFS_MANAGER_H*/
}} // namespace lumiera::query
#endif

View file

@ -35,8 +35,8 @@
#ifndef VESSEL_QUERY_DEFS_REGISTRY_H
#define VESSEL_QUERY_DEFS_REGISTRY_H
#ifndef LUMIERA_QUERY_DEFS_REGISTRY_H
#define LUMIERA_QUERY_DEFS_REGISTRY_H
#include "lib/p.hpp"
@ -45,7 +45,7 @@
#include "lib/sync-classlock.hpp"
#include "lib/format-string.hpp"
#include "lib/query-util.hpp"
#include "vessel/query.hpp"
#include "common/query.hpp"
#include "lib/nocopy.hpp"
#include <set>
@ -53,7 +53,7 @@
#include <memory>
namespace vessel {
namespace lumiera{
namespace query {
using lib::P;
@ -339,5 +339,5 @@ namespace query {
using impl::DefsRegistry;
}} // namespace vessel::query
#endif /*VESSEL_QUERY_DEFS_REGISTRY_H*/
}} // namespace lumiera::query
#endif

View file

@ -25,9 +25,9 @@
#include "lib/multifact.hpp"
#include "vessel/query/query-resolver.hpp"
#include "common/query/query-resolver.hpp"
namespace vessel {
namespace lumiera {
@ -118,4 +118,4 @@ namespace vessel {
} // namespace vessel
} // namespace lumiera

View file

@ -23,11 +23,11 @@
*/
#ifndef VESSEL_QUERY_RESOLVER_H
#define VESSEL_QUERY_RESOLVER_H
#ifndef LUMIERA_QUERY_RESOLVER_H
#define LUMIERA_QUERY_RESOLVER_H
#include "lib/iter-adapter.hpp"
#include "vessel/query.hpp"
#include "common/query.hpp"
#include "lib/nocopy.hpp"
#include <functional>
@ -36,7 +36,7 @@
using std::function;
namespace vessel {
namespace lumiera {
using std::unique_ptr;
using std::string;
@ -164,5 +164,5 @@ namespace vessel {
}
} // namespace vessel
#endif /*VESSEL_QUERY_RESOLVER_H*/
} // namespace lumiera
#endif

View file

@ -18,17 +18,17 @@
** which are prompted by main() to start/stop.
**
** @see subsystem-runner.hpp
** @see vessel::Voyage
** @see lumiera::AppState
** @see facade.cpp
** @see main.cpp
**
*/
#include "vessel/subsys.hpp"
#include "common/subsys.hpp"
namespace vessel {
namespace lumiera {
@ -56,4 +56,4 @@ namespace vessel {
} // namespace vessel
} // namespace lumiera

View file

@ -18,21 +18,21 @@
** While the activation of the key components is controlled by options, maybe
** some prerequisite subsystems need to be pulled up, and in case of an regular
** or irregular exit of a given subsystem, the whole dependency graph needs
** to be brought down in a clean manner. The purpose of vessel::Subsys is
** to be brought down in a clean manner. The purpose of lumiera::Subsys is
** to maintain these in a self-explanatory script-like fashion within main(),
** without forcing the individual subsystems into a fixed implementation scheme.
** The only requirement is that for each subsystem there is sort-of an entry
** point or facade object, providing a Subsys descriptor instance to be
** used within main.
**
** @see vessel::Voyage
** @see vessel::Option
** @see lumiera::AppState
** @see lumiera::Option
** @see main.cpp
*/
#ifndef VESSEL_SUBSYS_H
#define VESSEL_SUBSYS_H
#ifndef LUMIERA_SUBSYS_H
#define LUMIERA_SUBSYS_H
#include "lib/error.hpp"
#include "lib/nocopy.hpp"
@ -43,7 +43,7 @@
namespace vessel {
namespace lumiera {
using std::string;
using std::function;
@ -54,8 +54,8 @@ namespace vessel {
/**
* Dependencies and lifecycle of a partially independent Subsystem of the Application.
* After launch from the main() function, the vessel::Voyage uses these descriptors
* to pull up, maintain and shut down the primary parts of the Lumiera application.
* Using such descriptors, AppState as activated from main() is able to pull up,
* maintain and shut down the primary parts of the Application.
* @note synchronisation is up to the implementor.
*/
class Subsys
@ -83,7 +83,7 @@ namespace vessel {
* if this subsystem should be activated.
* @note even if not started explicitly, it could still
* be started as prerequisite of another one */
virtual bool shouldStart (vessel::Option&) =0;
virtual bool shouldStart (lumiera::Option&) =0;
/** attempt to bring up this subsystem up. On return, the
@ -95,7 +95,7 @@ namespace vessel {
* @param SigTerm to be signalled by the subsystem.
* @warning termination must be signalled reliably.
* @return `true` if actually started. */
virtual bool start (vessel::Option& options, SigTerm) =0;
virtual bool start (lumiera::Option& options, SigTerm) =0;
/** initiate termination of this subsystem.
@ -124,6 +124,6 @@ namespace vessel {
} // namespace vessel
} // namespace lumiera
#endif /*VESSEL_SUBSYS_H*/
#endif

View file

@ -15,8 +15,8 @@
/** @file subsystem-runner.hpp
** Manage execution of the independent [Subsystems](\ref subsys.hpp)
** of the Lumiera application. The SubsystemRunner is used by
** vessel::Voyage::init() for actually "performing" the various subsystems,
** as defined by their [Subsystem descriptors](\ref vessel::Subsys). Together
** lumiera::AppState::init() for actually "performing" the various subsystems,
** as defined by their [Subsystem descriptors](\ref lumiera::Subsys). Together
** these parts define the lifecycle protocol.
**
** @todo as of 2018, a design rework seems indicated eventually /////////////////////////TICKET #1177
@ -35,22 +35,21 @@
*/
#ifndef VESSEL_SUBSYSTEMRUNNER_H
#define VESSEL_SUBSYSTEMRUNNER_H
#ifndef LUMIERA_SUBSYSTEMRUNNER_H
#define LUMIERA_SUBSYSTEMRUNNER_H
#include "lib/error.hpp"
#include "lib/util.hpp"
#include "lib/util-foreach.hpp"
#include "lib/format-string.hpp"
#include "vessel/subsys.hpp"
#include "common/subsys.hpp"
#include "lib/sync.hpp"
#include <vector>
#include <string>
namespace vessel {
namespace error = lumiera::error;
namespace lumiera {
using lib::Sync;
using lib::RecursiveLock_Waitable;
@ -80,7 +79,7 @@ namespace vessel {
* complete layer of the application (e.g. the GUI).
*
* # Protocol of operation
* The SubsystemRunner is to be configured with a vessel::Option object first.
* The SubsystemRunner is to be configured with a lumiera::Option object first.
* Then, primary subsystems are [provided](\ref SubsystemRunner::maybeRun) for
* eventual startup, which may depend on conditions defined by the subsystem.
* When it turns out (by investigating the options) that a Subsystem is actually
@ -103,8 +102,8 @@ namespace vessel {
*
* @todo 2018 this component works well but could be (re)written in a cleaner way ////////////////////////TICKET #1177
*
* @see vessel::Voyage
* @see vessel::Subsys
* @see lumiera::AppState
* @see lumiera::Subsys
* @see main.cpp
*/
class SubsystemRunner
@ -210,5 +209,5 @@ namespace vessel {
} // namespace vessel
#endif /*VESSEL_SUBSYSTEMRUNNER_H*/
} // namespace lumiera
#endif

View file

@ -12,7 +12,7 @@
*/
/** @file config-facade.h
** The vessel::spine::Config wrapper class addresses two issues.
** The lumiera::Config wrapper class addresses two issues.
** First, it registers startup and shutdown hooks to bring up the config system
** as early as possible. Later, on application main initialisation, the global
** config interface is opened and wrapped for convenient access from C++ code.
@ -26,16 +26,16 @@
** was detached and replaced by an _ini file solution_ based on lib Boost.
**
** @todo there ought to be an external Interface for the Config subsystem.
** But the full-blown Config system isn't implemented yet anyway ////////////////////////////////////TICKET #1224 : Call for Design -- Layered Configuration System
** But the full-blown Config system isn't implemented yet anyway
**
** @see config.h
** @see vessel::Voyage
** @see lumiera::AppState
** @see main.cpp
*/
#ifndef VESSEL_SPINE_CONFIGFACADE_H
#define VESSEL_SPINE_CONFIGFACADE_H
#ifndef INTERFACE_CONFIGFACADE_H
#define INTERFACE_CONFIGFACADE_H
@ -49,8 +49,7 @@
#include <string>
namespace vessel{
namespace spine {
namespace lumiera {
using std::string;
@ -78,7 +77,7 @@ namespace spine {
}} // namespace vessel::spine
} // namespace lumiera
@ -94,5 +93,5 @@ namespace spine {
const char* lumiera_get_plugin_path_default ();
#endif /*C++ vs C*/
#endif /*VESSEL_SPINE_CONFIGFACADE_H*/
#endif
#endif

View file

@ -12,7 +12,8 @@
*/
/** @file display-handles.hpp
** Opaque handles and similar typedefs used to communicate via facade interfaces.
** Opaque handles and similar typedefs used to communicate via the
** lumiera::Display and lumiera::DummyPlayer facade interfaces.
**
** @deprecated this is part of prototyping code; as of 5/2025 it is clear
** that we will not use any of these interface schemes (yet something similar)
@ -22,8 +23,8 @@
*/
#ifndef VESSEL_SPINE_DISPLAY_HANDLES_H
#define VESSEL_SPINE_DISPLAY_HANDLES_H
#ifndef LUMIERA_DISPLAY_HANDLES_H
#define LUMIERA_DISPLAY_HANDLES_H
#include <cstddef>
@ -36,8 +37,7 @@ using DummyFrame = std::byte *;
namespace vessel {
namespace spine {
namespace lumiera {
/** Supported Displayer formats */
enum DisplayerInput {
@ -48,5 +48,5 @@ namespace spine {
DISPLAY_BGR0,
DISPLAY_RGB16
};
}} // namespace vessel::spine
#endif /*VESSEL_SPINE_DISPLAY_HANDLES_H*/
} // namespace lumiera
#endif /*LUMIERA_DISPLAY_HANDLES_H*/

Some files were not shown because too many files have changed in this diff Show more