Application: Adjustments to the Layer structure

During the last months, a lot of gradual changes to policies and guidelines
had been finalised and documented. Moreover, recent clarifications regarding
memory management in the render engine will lead to a clearer definition
of the »Vault« Layer's role, with some ''engine code'' expected to move down.

On this occasion, I reworked relevant sections in the documentation to
confirm the role that now falls to central parts of the overall architecture.
Notably I decided to rename those parts related to the application backbone
as »Vessel« — to underpin the more active and defining role they assumed.
This commit is contained in:
Fischlurch 2026-02-28 22:55:09 +01:00
parent 7d237647d4
commit 8e250839f4
209 changed files with 1354 additions and 1085 deletions

View file

@ -1,42 +1,47 @@
The Application : Start-up and Subsystems
=========================================
Application : Start-up and Subsystems
=====================================
:Date: 2009
:Author: Ichthyo
//MENU: label Start-up
.the purpose of »Application-main«
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.
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.
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''.
The Vessel
----------
So we treat all these concerns within a small 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''.
Subsystems
~~~~~~~~~~
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.
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.
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
@ -61,7 +66,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 `lumiera::Subsys`, which acts
Subsystems are defined by implementing the interface `vessel::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
@ -97,20 +102,21 @@ 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
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.]
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.
]
the design leaned toward loosely coupled parts and a formal lifecycle; which
saves us from investigating and coding up the various interdependencies
explicitly. Rather, the parts of the application have to comply to
explicitly. Rather, all 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
@ -128,9 +134,9 @@ Application Start
~~~~~~~~~~~~~~~~~
* some fundamental language-level facilities will be prepared during
_static initialisation._ At some point, execution enters `main(argc,arvv)`.
* `AppState::init()` brings up the plugin loader and opens the config-interface.
* `Voyage::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 (`AppState::maybeStart(subsystem)`),
* the main thread then pulls up the subsystems (`Voyage::maybeStart(subsystem)`),
according to the command line options.
* within each subsystem, façade interfaces will be opened through the
interface/plug-in system.
@ -142,7 +148,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 AppState destructor tears down the core systems (config-interface and pluginloader).
* the Voyage 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,15 +1,71 @@
Lumiera Design: Application and Session Configuration
=====================================================
Application and Session Configuration
=====================================
*TODO* : 'write design document'
.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.
The Lumiera application uses two quite different sources for configuration
**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.
- 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.
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.
-> see also the link:rfc/ConfigLoaderDraft2008.html[Config Loader brainstorming from 2008] (implementation details)
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]
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,10 +1,48 @@
Design Documents: Application Framework
=======================================
The Application Realm
=====================
// Menu : prepend child ApplicationStart
* link:Config.html[Configuration]
* link:plugin_loader.html[Plugin Loader]
* link:ApplicationStart.html[Application Subsystems and Lifecycle]
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.
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

@ -1,5 +0,0 @@
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 `lumiera::LifecycleHook`.
can be simplified by planting a static variable of type `vessel::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.
`AppState`::
`Voyage`::
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 `AppState::init()` function,
After starting those services within the `Voyage::init()` function,
the event `ON_GLOBAL_INIT` is emitted.
`ON_GLOBAL_INIT`::

View file

@ -0,0 +1,19 @@
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,22 +7,23 @@ Lumiera Design Documents
// Menu : prepend child design/gui
// Menu : prepend child architecture
// Menu : append child plugins
// Menu : append child extension
// Menu : append child workflow
// Menu : append child governance
Lumiera is to be a professional tool for video editing on
Lumiera aspires 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 GTK GUI but that will in no way be exclusive;
other GUIs can be written, as well as scripts to drive the 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.
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
*****************
@ -52,7 +53,8 @@ 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:gui/index.html[GUI/Stage-Layer design documents] +
-> link:{ldoc}/technical/stage/index.html[GUI technical documentation]
Steam: the Transformation Layer
@ -87,24 +89,23 @@ the screen or to external output. +
Extra Components
----------------
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]
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.
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,14 +1,30 @@
Design Documents: Vault
=======================
Low-level Services
==================
What follows is a summary of Lumiera's *Data Handling Backend*
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._
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:
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:
* The Session and the object models manipulated through the GUI are kept in memory.
They are backed by a _storage backend,_ which provides database-like storage and
especially logging, replaying and ``Undo'' of all ongoing modifications..
They will be backed by a _storage backend,_ which provides database-like storage
and especially logging, and controlled execution of _mutating actions._
* 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

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

View file

@ -1,7 +1,7 @@
Documentation
=============
This documentation section contains documentation for both users and developers.
This documentation section contains documentation for users and developers alike.
== 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 avoids a code narrative. This
section has two main sections:
documentation on the design of Lumiera, which omits most technical details of the implementation.
Consequently, the documentation is divided into two main parts:
* link:design/index.html[Lumiera Developer Design Documents]
* link:technical/index.html[Lumiera Developer Technical Documents]
@ -75,14 +75,14 @@ section has two main sections:
[width="90%",frame="topbot",options="header",cols="^,2<"]
|================================================================================================
|Sub-System|Remarks
|Section|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/plugins/[Plugins]|Dynamically loaded Extensions
|link:design/extension/[Extension]|Dynamically loaded Extensions
|link:design/workflow/[Workflow]|Workflow and Interaction Design
|link:design/governance/[Governance]|Meta project concerns
|================================================================================================
@ -93,12 +93,12 @@ section has two main sections:
[width="90%",frame="topbot",options="header",cols="^,2<"]
|================================================================================================
|Sub-System|Remarks
|Section|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/[Support lib]|Interface and support libraries
|link:technical/library/[Library]|Utilities and custom frameworks
|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

@ -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`, `app_lib`, `core_lib`,
global compound target variables like `core`, `vessel_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 `lumiera::AppState` will be initialised,
which in turn holds a member of type `lumiera::BasicSetup`. The latter will figure out
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
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

@ -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 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.
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.
* link:stage/index.html[*Stage Layer*] : Documents related to the GTK based Lumiera GUI
* link:steam/index.html[*Steam Layer*] : Documents regarding Session, models and the engine structure
* 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
To better understand the underlying concepts, it might be helpful to also consult the
link:{ldoc}/design/index.html[Design Documents].
== Tools
.Development
* link:/doxy/[*Doxygen* generated documentation] : API documentation of the Lumiera code.
* link:/doxy/[*Doxygen*] : 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 & compilation tools, dependencies and packaging.
* link:build/index.html[Buildsystem] : Installation and compilation tools, dependencies and packaging.
.HOWTO
* link:/x/DevHowto.html[Developer *HOWTOs*] : Collection of instructions, recipes, hints and similar
materials intended for developers
* link:/x/DevHowto.html[Developer *HOWTOs*] : Collection of instructions, recipes, hints, misdeeds
and confessions and similar helpful resources for developers

View file

@ -8,30 +8,32 @@ NOTE: This page holds content copied from the old "main" TiddlyWiki +
It needs to be reworked, formatted and generally brought into line
********************************************
.Lumiera relies on *test-driven development*
.Lumiera employs test-driven development
This page discusses the overall organisation
of test code, and the tools used for
running test cases
********************************************
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
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
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.
And sometimes, just an abstract specification is a better choice.
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.
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, 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.
- 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.
- 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
@ -41,15 +43,13 @@ 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. Up to now (2014), there
was no need for any kind of _dependency injection_, nor did we face any
difficulties with tainted state.
for accessing other components within the application.
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 spot code not being placed at the
use _strict dependencies_, this linking step will also spot code not 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
- all test executables should be named according to the pattern +test-*+
- free standing 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_

View file

@ -1,41 +1,70 @@
Library documentation
=====================
//Menu: label 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.
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.
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 can be addressed through the primary Façade Interfaces.
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.
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 still need to identify those select core concepts which need to be exposed
- we need to refactor the corresponding data types to resolve cross dependencies to the implementation
- 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).
- only then we could think about moving those data types into an _official Lumiera interface_

View file

@ -1,7 +1,7 @@
Lumiera: The Inner Core
=======================
:Author: Lumiera_Core_Developers
:Date: 2012 / 2025
:Date: 2012 / 2026
:toc:
[abstract]
@ -30,7 +30,7 @@ This three Layers are:
The Steam Layer::
Keeps the Session, generates the rendering graphs for sequences,
arranges what to do when and how.
prearranges elements and decides what to do when and how.
The Vault Layer::
Manages worker pools, schedules jobs, does the memory management for the
@ -39,13 +39,11 @@ This three Layers are:
The extra components are:
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.
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.
Library::
A lot of (largely) stateless helper functionality used throughout the code.
@ -55,9 +53,9 @@ Coding Style
~~~~~~~~~~~~
The Lumiera team agreed on using GNU coding style with slight adaptations.
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.
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.
@ -148,7 +146,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 2023, the one and only interface under active development is
_As of 2026, 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
@ -250,7 +248,7 @@ for each output channel is required.
The player service
^^^^^^^^^^^^^^^^^^
Client code accesses the player (subsystem) through the play-facade (`lumiera::Play`).
Client code accesses the player (subsystem) through the play-facade (`Play`).
The exposed service allows to _set up an output connection for playback or rendering,_
resulting in a play-controller object.
@ -285,11 +283,6 @@ 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
@ -318,16 +311,21 @@ 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._
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
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
into three basic modes of control:
Deadline::
@ -362,6 +360,29 @@ 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
~~~~~~~~~~~~~~~~~~~
@ -378,12 +399,12 @@ the system and current circumstances.
Common Services
---------------
Vessel: Common Services
-----------------------
Subsystem runner
~~~~~~~~~~~~~~~~
Conceptually, the application is structured into layers. However, as actual runtime
Conceptually, the application is structured into layers. However, as the 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:
@ -418,17 +439,14 @@ 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 maintaining a
lookup and registration data structure. Individual _piece of advice_ elements
original _advisor._ The _Advice System_ is a singleton service that maintains
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)
@ -458,13 +476,27 @@ Library
-------
The Lumiera support library contains lots of helper functionality
factored out from the internals and re-used. It is extended as we go.
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
practical shortcuts
~~~~~~~~~~~~~~~~~~~
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.
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.
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
@ -473,8 +505,29 @@ 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)
sanitise:: make any string usable as identifier.
limited:: to bracket some value.
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
@ -892,6 +945,17 @@ 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
====================================
Eventually, this will have technical documentation for the GUI.
This section offers a loose collection with detailed information regarding the GUI implementation.

View file

@ -1,27 +1,36 @@
Technical Documentation: Steam-Layer
====================================
Eventually, this section will hold technical documentation for the Steam-Layer.
As implementation progresses, this section will gradually compile
the technical documentation for the Steam layer.
Development Scrapbook TiddlyWiki
--------------------------------
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.
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.
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.
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).
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]
-> access the link:/wiki/renderengine.html[TiddlyWiki online here]

View file

@ -113,8 +113,11 @@ each have a distinct _type_ which explicitly identifies the possible connections
modules. Within these constraints, any combination is possible without
hidden restrictions.
Lumiera is not a set of Lego bricks, nor is it a business application
driven by finite usage stories.
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 finite high-level usage stories, where you
``just push the button'' and magic does the rest.
Medium Level Abstraction and Project Specific Conventions
@ -131,9 +134,8 @@ 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.
Lumiera will be supplied with a conventional template and a default
configuration to ease the learning curve for new users.
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.
[[graphs]]
@ -218,16 +220,15 @@ Lumiera consists of three major parts:
In this section, we discuss the user's perspective when working with the GUI.
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.
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.
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[<-]). Scripts will eventually be written
to facilitate automated processing.
xref:frameserver[<-]). A script interface will be added at some
point to facilitate automated processing.
Now it is time to take a look at the preliminary Lumiera GUI:
@ -505,21 +506,19 @@ 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. (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.
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.
_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
(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. +
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. +
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
@ -532,15 +531,14 @@ 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? 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.
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.
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. This saves the application from the havoc
of library incompatibility that is
associated with other linking methods.
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.
Most modern applications use plug-ins, some are heavily dependent on plug-ins
and only provide limited functionality without any plug-ins.

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('lumieracommon', srcSubtree('common'), addLibs=lLib, 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)
# 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
@ -49,4 +49,4 @@ gui = ( guimodule
)
Export('lumiera core core_lib app_lib vault_lib support_lib plugins envGtk guimodule gui')
Export('lumiera core core_lib vessel_lib vault_lib support_lib plugins envGtk guimodule gui')

View file

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

View file

@ -122,7 +122,7 @@ extern "C" {
#endif /* =========================== CL Interface ===================== */
#include "common/interface.h"
#include "vessel/interface.h"
#include "lib/hash-value.h"

View file

@ -1,5 +1,5 @@
/*
LIFECYCLE.h - interface for registering and triggering lifecycle callbacks
LIFECYCLE.hpp - interface for registering and triggering lifecycle callbacks
Copyright (C)
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -11,32 +11,30 @@
*/
/** @file lifecycle.h
/** @file lifecycle.hpp
** Installing and invoking of application lifecycle event callbacks.
** This service is a facade for and implemented by the lumiera::LifecycleRegistry.
** This service is a facade for and implemented by the vessel::LifecycleRegistry.
** By placing a static LifecycleHook variable or by calling LifecycleHook::add,
** a callback can be registered to be executed on a specific application lifecycle
** event. Examples being #ON_BASIC_INIT, #ON_GLOBAL_INIT. Other subsystems may
** register additional events for more specific purpose.
**
** @note the implementation resides in lib/lifecycle.cpp and gets linked into liblumiera.so
** @see lumiera::AppState
** @see vessel::Voyage
** @see main.cpp
*/
#ifndef LUMIERA_LIFECYCLE_H
#define LUMIERA_LIFECYCLE_H
#ifndef VESSEL_LIFECYCLE_H
#define VESSEL_LIFECYCLE_H
#ifdef __cplusplus
#include "lib/symbol.hpp"
#include "lib/nocopy.hpp"
namespace lumiera {
namespace vessel {
using lib::Symbol;
@ -81,21 +79,5 @@ namespace lumiera {
} // namespace lumiera
#else /* =========== C interface ====================== */
//defined in liblumiera.so
extern const char * lumiera_ON_BASIC_INIT;
extern const char * lumiera_ON_GLOBAL_INIT;
extern const char * lumiera_ON_GLOBAL_SHUTDOWN;
void lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void));
void lumiera_Lifecycle_trigger (const char* eventLabel);
#endif
#endif
} // namespace vessel
#endif /*VESSEL_LIFECYCLE_H*/

View file

@ -116,7 +116,7 @@ extern "C" {
#endif /* =========================== CL Interface ===================== */
#include "common/interface.h"
#include "vessel/interface.h"
LUMIERA_INTERFACE_DECLARE (lumieraorg_SessionCommand, 0,
LUMIERA_INTERFACE_SLOT (const char*, cycle, (const char*, const char*)),

View file

@ -24,7 +24,7 @@
#include "lib/error.hpp"
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
#include "lib/meta/util.hpp"
#include "lib/util.hpp"
@ -154,6 +154,9 @@ namespace lumiera {
namespace error {
namespace {
using vessel::LifecycleHook;
using vessel::ON_BASIC_INIT;
void install_unexpectedException_handler ()
{
std::set_terminate (lumiera_unexpectedException);

View file

@ -205,6 +205,7 @@ apologies for that."
"|stage::model"
"|stage::ctrl"
"|lumiera::"
"|vessel::"
, regex::ECMAScript | regex::optimize};
static regex lolong {"long long"

View file

@ -18,14 +18,14 @@
#include "lib/error.hpp"
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
#include "lib/lifecycleregistry.hpp"
#include "lib/util.hpp"
namespace lumiera {
namespace vessel {
// ==== implementation Lifecycle Registry =======
@ -64,7 +64,6 @@ namespace lumiera {
if (isNew and eventLabel == ON_BASIC_INIT)
callbackFun(); // when this code executes,
// then per definition we are already post "basic init"
// (which happens in the AppState ctor); thus fire it immediately
}
@ -83,31 +82,4 @@ namespace lumiera {
CStr ON_EMERGENCY ("ON_EMERGENCY");
} // namespace lumiera
extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */
const char * lumiera_ON_BASIC_INIT = lumiera::ON_BASIC_INIT;
const char * lumiera_ON_GLOBAL_INIT = lumiera::ON_GLOBAL_INIT;
const char * lumiera_ON_GLOBAL_SHUTDOWN = lumiera::ON_GLOBAL_SHUTDOWN;
const char * lumiera_ON_EMERGENCY = lumiera::ON_EMERGENCY;
void
lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void))
{
lumiera::LifecycleHook (eventLabel, callbackFun);
}
void
lumiera_Lifecycle_trigger (const char* eventLabel)
{
lumiera::LifecycleRegistry::instance().execute (eventLabel);
}
}
} // namespace vessel

View file

@ -14,7 +14,7 @@
/** @file lifecycleregistry.hpp
** Helper for registering lifecycle event callbacks, which are
** provided as a global service by lumiera::AppState. This service
** provided as an application service within the »vessel«. This service
** allows to enrol functions under a given label and then to call
** all those registered functions.
** @note this is in fact an event mechanism, and if we start using
@ -22,12 +22,12 @@
** boost::signals. (which has the downside of being an binary
** dependency).
**
** @see appstate.hpp
** @see voyage.hpp
*/
#ifndef LUMIERA_LIFECYCLEREGISTRY_H
#define LUMIERA_LIFECYCLEREGISTRY_H
#ifndef VESSEL_LIFECYCLE_REGISTRY_H
#define VESSEL_LIFECYCLE_REGISTRY_H
#include "lib/util.hpp"
@ -39,7 +39,7 @@
#include <map>
namespace lumiera {
namespace vessel {
using util::contains;
using std::function;
@ -50,7 +50,7 @@ namespace lumiera {
/**
* Registry of callback functions accessible by a label (ID)
* provided at registration. Registered functions will be added
* to a list, which can be triggered via label. Used by AppState
* to a list, which can be triggered via label. Used by vessel::Voyage
* to implement the lumiera lifecycle (init, shutdown) hooks.
*/
class LifecycleRegistry
@ -98,5 +98,5 @@ namespace lumiera {
} // namespace lumiera
#endif
} // namespace vessel
#endif /*VESSEL_LIFECYCLE_REGISTRY_H*/

View file

@ -41,7 +41,7 @@ This code is heavily inspired by
** instantiation is mixed or inherited into the resulting product.
**
** @see generator-test.cpp
** @see lumiera::query::ConfigRules usage example
** @see vessel::query::ConfigRules usage example
** @see typelist.hpp
**
*/

View file

@ -26,7 +26,7 @@
namespace lumiera {
namespace lib {
void
initialise_NoBug ()

View file

@ -27,17 +27,17 @@
#ifndef NOBUG_INIT_H
#define NOBUG_INIT_H
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
#include <nobug.h>
namespace lumiera {
namespace lib {
void initialise_NoBug ();
namespace {
LifecycleHook trigger_init_ (ON_BASIC_INIT, &initialise_NoBug);
vessel::LifecycleHook trigger_init_ (vessel::ON_BASIC_INIT, &initialise_NoBug);
} }

View file

@ -282,5 +282,5 @@ namespace lib {
};
} // namespace lumiera
} // namespace lib::sync
#endif

View file

@ -20,8 +20,8 @@
#include "include/logging.h"
#include "lib/error.hpp"
#include "common/appstate.hpp"
#include "common/option.hpp"
#include "vessel/voyage.hpp"
#include "vessel/option.hpp"
#include "vault/enginefacade.hpp"
#include "vault/netnodefacade.hpp"
@ -30,8 +30,8 @@
#include "stage/guifacade.hpp"
using lib::Cmdline;
using lumiera::Subsys;
using lumiera::AppState;
using vessel::Subsys;
using vessel::Voyage;
namespace {
Subsys& engine = vault::EngineFacade::getDescriptor();
@ -49,12 +49,12 @@ main (int argc, const char* argv[])
{
NOTICE (main, "*** Lumiera NLE for Linux ***");
AppState& application = AppState::instance();
Voyage& voyage = Voyage::access();
try
{
Cmdline args (argc,argv);
lumiera::Option options (args);
application.init (options);
vessel::Option options (args);
voyage.init (options);
netNode.depends (session);
netNode.depends (engine);
@ -65,21 +65,21 @@ main (int argc, const char* argv[])
script.depends (session);
script.depends (engine);
application.maybeStart (playOut);
application.maybeStart (netNode);
application.maybeStart (lumigui);
application.maybeStart (script);
voyage.maybeStart (playOut);
voyage.maybeStart (netNode);
voyage.maybeStart (lumigui);
voyage.maybeStart (script);
return application.maybeWait();
return voyage.maybeWait();
}
catch (lumiera::Error& problem)
{
return application.abort (problem);
return voyage.abort (problem);
}
catch (...)
{
return application.abort();
return voyage.abort();
}
}

View file

@ -16,8 +16,8 @@
/** @file config-keys.hpp
** Definition of access keys for global UI configuration.
**
** @see lumiera::AppState general Lumiera application main
** @see lumiera::Config
** @see vessel::Voyage general Lumiera application main
** @see vessel::spine::Config
**
*/

View file

@ -18,7 +18,7 @@
**
** # configuration and resource search
**
** The UI layer retrieves the necessary configuration values from lumiera::Config,
** The UI layer retrieves the necessary configuration values from vessel::spine::Config,
** the config facade in the application core. Currently as of 2/2011 these values are
** loaded from setup.ini, because the full-blown config system is not yet implemented.
** Amongst others, this configuration defines a _search path_ for icons and a
@ -27,9 +27,9 @@
** This allows for a relocatable Lumiera installation bundle.
**
** @see gtk-lumiera.cpp the plugin to pull up this GUI
** @see lumiera::BasicSetup definition of the acceptable configuration values
** @see lumiera::AppState general Lumiera application main
** @see lumiera::Config
** @see vessel::BasicSetup definition of the acceptable configuration values
** @see vessel::Voyage general Lumiera application main
** @see vessel::spine::Config
**
*/
@ -38,14 +38,14 @@
#include "lib/symbol.hpp"
#include "include/config-facade.h"
#include "vessel/spine/config-facade.h"
namespace stage {
using lib::Literal;
using lumiera::Config;
using vessel::spine::Config;
extern Literal KEY_TITLE;
extern Literal KEY_VERSION;

View file

@ -37,7 +37,7 @@ namespace ctrl {
using std::make_unique;
using steam::node::DummyTickService;
using steam::node::DummyImageGenerator;
using lumiera::DisplayerInput;
using vessel::spine::DisplayerInput;
DemoController::DemoController()
@ -54,7 +54,7 @@ namespace ctrl {
* @param displayFormat format for the frames expected in the passed image buffer.
*/
void
DemoController::activate (lumiera::DisplayerInput displayFormat)
DemoController::activate (DisplayerInput displayFormat)
{
REQUIRE (imageGen_);
imageGen_->configure (displayFormat);

View file

@ -32,7 +32,7 @@
#define DEMO_CONTROLLER_H
#include "stage/gtk-base.hpp"
#include "include/display-handles.hpp"
#include "vessel/spine/display-handles.hpp"
#include "lib/nocopy.hpp"
#include <memory>
@ -68,7 +68,7 @@ namespace ctrl {
void pause();
void stop();
void activate (lumiera::DisplayerInput);
void activate (vessel::spine::DisplayerInput);
sigc::signal<void(void* const)> output_;
private:
bool playing_;

View file

@ -25,7 +25,7 @@
**
** # configuration and resource search
**
** The GUI backbone retrieves the necessary configuration values from lumiera::Config,
** The GUI backbone retrieves the necessary configuration values from vessel::spine::Config,
** the config facade in the application core. Currently as of 2/2011 these values are
** loaded from setup.ini, because the full-blown config system is not yet implemented.
** Amongst others, this configuration defines a _search path_ for icons and a
@ -39,9 +39,9 @@
** @see gtk-lumiera.cpp the plugin to pull up this GUI
** @see stage::GuiFacade access point for starting the GUI
** @see stage::GuiNotification interface for communication with the gui from the lower layers
** @see lumiera::Config
** @see lumiera::BasicSetup definition of the acceptable configuration values
** @see lumiera::AppState general Lumiera application main
** @see vessel::spine::Config
** @see vessel::BasicSetup definition of the acceptable configuration values
** @see vessel::Voyage general Lumiera application main
*/

View file

@ -19,7 +19,7 @@
** This plugin is linked together with the Lumiera GUI code; when loaded as
** Lumiera plugin, it allows to kick off the GTK main event loop and thus to bring
** up the GUI. The loading and shutdown process is carried out by stage::GuiFacade and
** controlled by lumiera::AppState, which in turn is activated by Lumiera main().
** controlled by the vessel::Voyage, which in turn is activated by Lumiera main().
**
** After successfully loading this module, a call to GuiFacade::launchUI is expected to
** happen, passing a termination signal (callback) to be executed when the GUI terminates.
@ -31,7 +31,7 @@
** This entails also to open the primary "business" interface(s) of the GUI
** (currently as of 1/16 this is the interface stage::GuiNotification.)
**
** @see lumiera::AppState
** @see vessel::Voyage
** @see stage::GuiFacade
** @see guifacade.cpp
** @see ui-manager.hpp
@ -44,19 +44,19 @@
#include "stage/ui-bus.hpp"
#include "stage/guifacade.hpp"
#include "stage/ctrl/ui-manager.hpp"
#include "common/subsys.hpp"
#include "vessel/subsys.hpp"
#include "lib/nocopy.hpp"
extern "C" {
#include "common/interface.h"
#include "common/interface-descriptor.h"
#include "vessel/interface.h"
#include "vessel/interface-descriptor.h"
}
#include <string>
using lumiera::Subsys;
using vessel::Subsys;
using lib::launchDetached;
using lumiera::error::LUMIERA_ERROR_STATE;
using stage::LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1);

View file

@ -18,8 +18,8 @@
** contained within the GUI dynamic module), because it's job is to load and
** activate this module as plug-in and to startup the GUI.
**
** @see lumiera::AppState
** @see lumiera::Option
** @see vessel::Voyage
** @see vessel::Option
** @see guifacade.cpp
** @see main.cpp
*/
@ -29,11 +29,11 @@
#define STAGE_FACADE_H
#include "common/subsys.hpp"
#include "vessel/subsys.hpp"
#include "lib/nocopy.hpp"
extern "C" {
#include "common/interface.h"
#include "vessel/interface.h"
}
@ -72,10 +72,10 @@ namespace stage {
{
public:
/** provide a descriptor for lumiera::AppState,
/** provide a descriptor for vessel::Voyage,
* wired accordingly to allow main to load,
* start and stop the Lumiera GTK GUI. */
static lumiera::Subsys& getDescriptor();
static vessel::Subsys& getDescriptor();
/** weather the GUI has been started and all interfaces are opened */

View file

@ -57,7 +57,7 @@
#include "lib/util.hpp"
extern "C" {
#include "common/interface-descriptor.h"
#include "vessel/interface-descriptor.h"
}
#include <utility>

View file

@ -32,7 +32,7 @@
#include "include/gui-notification-facade.h"
#include "common/instancehandle.hpp"
#include "vessel/instancehandle.hpp"
#include "stage/ctrl/bus-term.hpp"
#include <memory>
@ -77,7 +77,7 @@ namespace stage {
/* === Interface Lifecycle === */
using ServiceInstanceHandle = lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_GuiNotification, 0)
using ServiceInstanceHandle = vessel::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_GuiNotification, 0)
, GuiNotification
> ;
ServiceInstanceHandle serviceInstance_;

View file

@ -38,7 +38,7 @@ namespace output {
DisplayerInput
Displayer::format()
{
return lumiera::DISPLAY_NONE;
return vessel::spine::DISPLAY_NONE;
}
void

View file

@ -28,12 +28,12 @@
#include "lib/nocopy.hpp"
#include "include/display-handles.hpp"
#include "vessel/spine/display-handles.hpp"
namespace stage {
namespace output {
using lumiera::DisplayerInput;
using vessel::spine::DisplayerInput;
/**

View file

@ -71,7 +71,7 @@ class PixbufDisplayer
DisplayerInput format() override
{
return lumiera::DISPLAY_RGB;
return vessel::spine::DISPLAY_RGB;
}
};

View file

@ -72,7 +72,7 @@ namespace output {
DisplayerInput format() override
{
return lumiera::DISPLAY_YUV;
return vessel::spine::DISPLAY_YUV;
}

View file

@ -43,7 +43,7 @@
#include "stage/timeline/track-body.hpp"
#include "stage/style-scheme.hpp"
#include "common/advice.hpp"
#include "vessel/advice.hpp"
#include "lib/util.hpp"
#include <utility>
@ -71,8 +71,8 @@ namespace timeline {
const int MINIMAL_CONTENT_WIDTH_px = 100;
/** request a pre-defined CSS style context for the track body */
lumiera::advice::Request<PStyleContext> trackBodyStyle{"style(trackBody)"};
lumiera::advice::Request<PStyleContext> trackRulerStyle{"style(trackRuler)"};
vessel::advice::Request<PStyleContext> trackBodyStyle{"style(trackBody)"};
vessel::advice::Request<PStyleContext> trackRulerStyle{"style(trackRuler)"};
cuString
slopeClassName(int depth)

View file

@ -25,7 +25,7 @@
#include "stage/timeline/timeline-layout.hpp"
#include "stage/timeline/track-body.hpp"
#include "common/advice.hpp"
#include "vessel/advice.hpp"
#include "lib/time/timevalue.hpp"
using lib::time::Time;

View file

@ -33,7 +33,7 @@ namespace stage {
namespace widget {
using stage::output::Displayer;
using lumiera::DisplayerInput;
using vessel::spine::DisplayerInput;
/**

View file

@ -52,7 +52,7 @@ namespace workspace {
* either from the default theme of via the given Lumiera icon search paths,
* typically from `setup.ini`.
*
* @see lumiera::Config
* @see vessel::spine::Config
*/
UiStyle::UiStyle()
: Gtk::UIManager()

View file

@ -28,7 +28,7 @@
#define STAGE_WORKSPACE_UI_STYLE_H
#include "stage/gtk-base.hpp"
#include "common/advice.hpp"
#include "vessel/advice.hpp"
#include "lib/symbol.hpp"
#include "lib/nocopy.hpp"
@ -49,7 +49,7 @@ namespace workspace {
using lib::Literal;
using std::string;
using StyleAdvice = lumiera::advice::Provision<PStyleContext>;
using StyleAdvice = vessel::advice::Provision<PStyleContext>;
@ -99,7 +99,7 @@ namespace workspace {
* Sets the theme to use for the Lumiera GUI.
* @param stylesheetName GTK CSS stylesheet to load from the resourceSearchPath_
* @throw error::Config if this stylesheet can't be resolved on the searchpath
* @see lumiera::Config
* @see vessel::spine::Config
*/
void setTheme (string const& stylesheetName);

View file

@ -23,7 +23,7 @@
#include "lib/time/quantiser.hpp"
#include "lib/time/timevalue.hpp"
#include "lib/format-string.hpp"
#include "common/advice.hpp"
#include "vessel/advice.hpp"
#include "lib/util.hpp"
#include <string>
@ -62,7 +62,7 @@ namespace meta {
using lib::time::FixedFrameQuantiser;
using std::dynamic_pointer_cast;
namespace advice = lumiera::advice;
namespace advice = vessel::advice;
namespace {

View file

@ -27,7 +27,7 @@
#include "steam/asset/struct.hpp"
#include "steam/asset/procpatt.hpp"
#include "steam/streamtype.hpp"
#include "common/query.hpp"
#include "vessel/query.hpp"
#include <string>
@ -36,7 +36,7 @@
namespace steam {
namespace asset {
using lumiera::Query;
using vessel::Query;
using std::string;
class Pipe;

View file

@ -33,8 +33,8 @@
#include "steam/mobject/session/element-query.hpp"
#include "steam/mobject/session/session-query.hpp"
#include "steam/mobject/session/scope.hpp"
#include "common/config-rules.hpp"
#include "common/query.hpp"
#include "vessel/config-rules.hpp"
#include "vessel/query.hpp"
#include "steam/asset/timeline.hpp"
#include "steam/asset/sequence.hpp"
#include "steam/asset/procpatt.hpp"
@ -60,7 +60,7 @@ namespace asset {
using util::uNum;
using util::isnil;
using util::contains;
using lumiera::Query;
using vessel::Query;
using LERR_(CAPABILITY_QUERY);
using lib::query::extractID;

View file

@ -39,12 +39,12 @@
#include "lib/query-util.hpp"
#include "lib/format-string.hpp"
#include "include/logging.h"
#include "common/query.hpp"
#include "vessel/query.hpp"
using util::_Fmt;
using lib::Symbol;
using lib::query::normaliseID;
using lumiera::query::QueryHandler;
using vessel::query::QueryHandler;
using steam::ConfigResolver;
using util::contains;

View file

@ -54,7 +54,7 @@
#include "lib/symbol.hpp"
#include "steam/asset.hpp"
#include "common/query.hpp"
#include "vessel/query.hpp"
#include "lib/nocopy.hpp"
#include <memory>
@ -67,7 +67,7 @@ namespace asset {
using std::string;
using std::unique_ptr;
using lumiera::Query;
using vessel::Query;
using lib::Symbol;
class Struct;

View file

@ -47,7 +47,7 @@
#include <memory>
namespace lumiera{ ///////TODO: shouldn't that be namespace lib? or steam?
namespace vessel { ///////TODO: shouldn't that be namespace lib? or steam?
namespace query {
/**

View file

@ -21,13 +21,13 @@
#include "lib/error.hpp"
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
#include "steam/config-resolver.hpp"
#include "steam/mobject/session/query/fake-configrules.hpp"
#include "lib/depend-inject.hpp"
using lumiera::LifecycleHook;
using lumiera::ON_GLOBAL_INIT;
using vessel::LifecycleHook;
using vessel::ON_GLOBAL_INIT;
namespace steam {
@ -66,7 +66,7 @@ namespace steam {
#include "common/query/defs-manager-impl.hpp"
#include "vessel/query/defs-manager-impl.hpp"
@ -80,7 +80,7 @@ namespace steam {
#include "steam/asset/sequence.hpp"
#include "steam/mobject/session/fork.hpp"
namespace lumiera{
namespace vessel {
namespace query {
using steam::asset::Pipe;
@ -105,4 +105,4 @@ namespace query {
template bool DefsManager::forget (PPipe const&);
}} // namespace lumiera::query
}} // namespace vessel::query

View file

@ -25,7 +25,7 @@
** @note this is placeholder code using a preliminary/mock implementation... don't take this code too literal!
** @todo clarify the relation of config query and query-for-defaults ///////////////TICKET #705
**
** @see lumiera::Query
** @see vessel::Query
** @see mobject::session::DefsManager
** @see asset::StructFactory
** @see fake-configrules.hpp currently used dummy-implementation
@ -37,8 +37,8 @@
#ifndef STEAM_CONFIG_RESOLVER
#define STEAM_CONFIG_RESOLVER
#include "common/query.hpp"
#include "common/config-rules.hpp"
#include "vessel/query.hpp"
#include "vessel/config-rules.hpp"
#include "lib/depend.hpp"
// types for explicit specialisations....
@ -73,7 +73,7 @@ namespace steam {
* Configured as Singleton (with hidden Implementation class)
*/
class ConfigResolver
: public lumiera::query::ConfigRules<InterfaceTypes>
: public vessel::query::ConfigRules<InterfaceTypes>
{
public:

View file

@ -28,7 +28,7 @@
#include "lib/error.hpp"
#include "include/logging.h"
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
#include "steam/control/command.hpp"
#include "steam/control/command-setup.hpp"
#include "steam/control/command-instance-manager.hpp"
@ -45,8 +45,8 @@ using std::get;
using std::function;
using std::move;
using lib::Symbol;
using lumiera::LifecycleHook;
using lumiera::ON_GLOBAL_INIT;
using vessel::LifecycleHook;
using vessel::ON_GLOBAL_INIT;
using std::string;
using util::unConst;
using util::_Fmt;

View file

@ -24,14 +24,14 @@
#include "include/session-command-facade.h"
#include "include/interfaceproxy.hpp"
#include "vessel/spine/interfaceproxy.hpp"
namespace steam {
namespace control{
/** static storage for the facade access front-end */
lib::Depend<SessionCommand> SessionCommand::facade;
}}
namespace lumiera {
namespace vessel {
namespace facade {
@ -65,4 +65,4 @@ namespace facade {
template
class Link<Interface,Facade>;
}} //namespace facade::lumiera
}} //namespace vessel::facade

View file

@ -30,7 +30,7 @@
#include "lib/util.hpp"
extern "C" {
#include "common/interface-descriptor.h"
#include "vessel/interface-descriptor.h"
}
#include <string>

View file

@ -36,7 +36,7 @@
#include "include/session-command-facade.h"
#include "steam/control/command-dispatch.hpp"
#include "steam/control/command-instance-manager.hpp"
#include "common/instancehandle.hpp"
#include "vessel/instancehandle.hpp"
#include "lib/diff/gen-node.hpp"
#include "lib/nocopy.hpp"
#include "lib/symbol.hpp"
@ -77,7 +77,7 @@ namespace control {
/* === Interface Lifecycle === */
using ServiceInstanceHandle = lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_SessionCommand, 0)
using ServiceInstanceHandle = vessel::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_SessionCommand, 0)
, SessionCommand
>;
ServiceInstanceHandle serviceInstance_;

View file

@ -45,7 +45,7 @@
#ifndef STEAM_CONTROL_PROC_DISPATCHER_H
#define STEAM_CONTROL_PROC_DISPATCHER_H
#include "common/subsys.hpp"
#include "vessel/subsys.hpp"
#include "lib/depend.hpp"
#include "lib/sync.hpp"
@ -57,7 +57,7 @@ namespace steam {
namespace control {
using std::unique_ptr;
using lumiera::Subsys;
using vessel::Subsys;
class DispatcherLoop;

View file

@ -20,7 +20,7 @@
#include "steam/common.hpp"
#include "steam/control/stypemanager.hpp"
#include "steam/control/styperegistry.hpp"
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
namespace steam {
@ -49,7 +49,7 @@ namespace control {
STypeManager::reset()
{
reg_.reset(new Registry);
lumiera::LifecycleHook::trigger (ON_STREAMTYPES_RESET);
vessel::LifecycleHook::trigger (ON_STREAMTYPES_RESET);
}
/** \par
@ -111,12 +111,3 @@ namespace control {
}
}} // namespace steam::control
// ==== C interface for registering setup of basic stream type configuration =======
void
lumiera_StreamType_registerInitFunction (void setupFun(void))
{
lumiera::LifecycleHook (steam::control::ON_STREAMTYPES_RESET, setupFun);
}

View file

@ -110,20 +110,4 @@ namespace proc_interface {
} // namespace proc_interface
extern "C" { //TODO provide a separate header if some C code or plugin happens to need this...
/** any stream type implementation, which needs to be present on the
* pristine default level (without any session specific configuration),
* should register a setup function, which will be called on each
* STypemanager::reset()
*/
void
lumiera_StreamType_registerInitFunction (void setupFun(void));
// TODO provide a C interface usable from such a setupFun to access the STypeManager registration functions.
}
#endif
#endif /*STEAM_CONTROL_STYPEMANAGER_H*/

View file

@ -17,7 +17,7 @@
** Only used in stypemanager.cpp and accompanying unit tests.
**
** @see control::STypeManager
** @see lumiera::StreamType
** @see steam::StreamType
**
*/
@ -30,7 +30,7 @@
#include "steam/control/stypemanager.hpp"
#include "lib/nocopy.hpp"
//#include "common/query.hpp"
//#include "vessel/query.hpp"
//#include "lib/util.hpp"
//#include "lib/p.hpp"

View file

@ -42,7 +42,7 @@
#include "steam/engine/render-drive.hpp"
//#include "include/dummy-player-facade.h"
//#include "include/display-facade.h"
//#include "common/instancehandle.hpp"
//#include "vessel/instancehandle.hpp"
//#include "lib/singleton-ref.hpp"
//
//#include <string>
@ -56,9 +56,9 @@ namespace engine{
namespace error = lumiera::error;
// using std::string;
// using lumiera::Subsys;
// using lumiera::Display;
// using lumiera::DummyPlayer;
// using vessel::Subsys;
// using vessel::Display;
// using vessel::DummyPlayer;
class RenderEnvironment;

View file

@ -37,7 +37,7 @@
//#include "steam/mobject/model-port.hpp"
#include "steam/play/timings.hpp"
//#include "steam/play/output-slot.hpp"
//#include "common/instancehandle.hpp"
//#include "vessel/instancehandle.hpp"
//#include "lib/singleton-ref.hpp"
//#include "lib/polymorphic-value.hpp"
//#include "lib/depend.hpp"
@ -49,9 +49,9 @@ namespace steam {
namespace engine{
// using std::string;
// using lumiera::Subsys;
// using lumiera::Display;
// using lumiera::DummyPlayer;
// using vessel::Subsys;
// using vessel::Display;
// using vessel::DummyPlayer;
using steam::play::Timings;

View file

@ -31,7 +31,7 @@ namespace steam {
namespace engine{
// using std::string;
// using lumiera::Subsys;
// using vessel::Subsys;
using std::function;
using std::bind;
using std::ref;

View file

@ -53,7 +53,7 @@
#include "steam/mobject/model-port.hpp"
#include "steam/play/timings.hpp"
#include "steam/play/output-slot.hpp"
//#include "common/instancehandle.hpp"
//#include "vessel/instancehandle.hpp"
//#include "lib/singleton-ref.hpp"
#include "lib/polymorphic-value.hpp"
#include "lib/depend.hpp"
@ -66,9 +66,9 @@ namespace steam {
namespace engine{
// using std::string;
// using lumiera::Subsys;
// using lumiera::Display;
// using lumiera::DummyPlayer;
// using vessel::Subsys;
// using vessel::Display;
// using vessel::DummyPlayer;
// using std::function;
using mobject::ModelPort;
using steam::play::Timings;

View file

@ -75,6 +75,10 @@ namespace node {
} // (End) implementation details
using vessel::spine::DisplayerInput;
using vessel::spine::DISPLAY_NONE;
using vessel::spine::DISPLAY_YUV;
using vessel::spine::DISPLAY_RGB;
@ -86,14 +90,14 @@ namespace node {
{ }
void
DummyImageGenerator::configure (lumiera::DisplayerInput displayFormat)
DummyImageGenerator::configure (DisplayerInput displayFormat)
{
INFO (steam, "ImageGen: use format %d", displayFormat);
REQUIRE ( displayFormat == lumiera::DISPLAY_NONE
or displayFormat == lumiera::DISPLAY_YUV
or displayFormat == lumiera::DISPLAY_RGB);
REQUIRE ( displayFormat == DISPLAY_NONE
or displayFormat == DISPLAY_YUV
or displayFormat == DISPLAY_RGB);
useRGB_ = (displayFormat == lumiera::DISPLAY_RGB);
useRGB_ = (displayFormat == DISPLAY_RGB);
}
void

View file

@ -33,7 +33,7 @@
#include "lib/error.hpp"
#include "include/display-handles.hpp"
#include "vessel/spine/display-handles.hpp"
#include <array>
@ -53,7 +53,7 @@ namespace node {
static const uint H = 240;
DummyImageGenerator(uint fps);
void configure (lumiera::DisplayerInput);
void configure (vessel::spine::DisplayerInput);
/** generate the next frame and occupy the alternate buffer.

View file

@ -32,7 +32,7 @@ namespace external {
using control::STypeManager;
using control::ON_STREAMTYPES_RESET;
using lumiera::LifecycleHook;
using vessel::LifecycleHook;
void
provide_GAVL_stream_implementation_types ()

View file

@ -20,12 +20,12 @@
** - The »play out subsystem« is able to _perform_ such a render nodes network
** for video playback and rendering.
**
** lumiera::Subsys and lumiera::SubsystemRunner together define a protocol for some
** vessel::Subsys and vessel::SubsystemRunner together define a protocol for some
** large scale building blocks of the whole application to be started and terminated.
** Typically this entails to create a dedicated thread to manage the top level concerns
** for the given subsystem, and to create registration and services for public access:
** - to operate on the session, use the steam::control::SessionCommand facade
** - playback and render operations can be operated by the lumiera::Play facade
** - playback and render operations can be operated by the vessel::spine::Play facade
**
** @see SteamDispatcher
** @see OutputDirector
@ -47,8 +47,8 @@ namespace steam {
using std::string;
using std::unique_ptr;
using lumiera::Subsys;
using lumiera::Option;
using vessel::Subsys;
using vessel::Option;
using steam::control::SteamDispatcher;

View file

@ -28,7 +28,7 @@
#define STEAM_INTERFACE_FACADE_H
#include "common/subsys.hpp"
#include "vessel/subsys.hpp"
@ -51,18 +51,18 @@ namespace steam {
*/
struct Facade
{
/** provide a descriptor for lumiera::AppState,
/** provide a descriptor for the vessel::Voyage,
* wired accordingly to allow `main()` to boot
* the support infrastructure for loading of
* and working on the editing session. */
static lumiera::Subsys& getSessionDescriptor();
static vessel::Subsys& getSessionDescriptor();
/** provide a descriptor for lumiera::AppState,
/** provide a descriptor for vessel::Voyage,
* wired accordingly to allow `main()` to bring up
* the render / playback coordination and
* output management subsystem. */
static lumiera::Subsys& getPlayOutDescriptor();
static vessel::Subsys& getPlayOutDescriptor();
//////////////////TODO: define the global access interfaces for the Steam-Layer

View file

@ -26,7 +26,7 @@
#include "steam/asset/proc.hpp"
#include "steam/engine/node-factory.hpp"
#include "steam/streamtype.hpp"
//#include "common/util.hpp"
//#include "vessel/util.hpp"
//#include <boost/ptr_container/ptr_vector.hpp>

View file

@ -28,7 +28,7 @@
#define MOBJECT_BUILDER_OPERATIONPOINT_H
//#include "steam/engine/proc-node.hpp" /////TODO can we get rid of this header here?
//#include "common/query.hpp"
//#include "vessel/query.hpp"
#include "lib/hash-standard.hpp"
#include <memory>

View file

@ -31,7 +31,7 @@
#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/query-util.hpp"
#include "common/query/query-resolver.hpp"
#include "vessel/query/query-resolver.hpp"
#include "steam/mobject/mobject.hpp"
#include "steam/mobject/placement-ref.hpp"
#include "steam/mobject/output-designation.hpp"
@ -42,8 +42,9 @@
#include <boost/functional/hash.hpp>
#include <cstdlib>
using lumiera::Symbol;
using lumiera::query::QueryHandler;
using lib::Symbol;
using vessel::Query;
using vessel::query::QueryHandler;
using lib::query::removeTerm;
using lib::query::extractID;
using steam::ConfigResolver;
@ -53,9 +54,9 @@ using util::uNum;
namespace steam {
namespace mobject {
typedef OutputDesignation::PPipe PPipe;
typedef OutputDesignation::PID PID;
typedef OutputDesignation::TargetSpec TargetSpec;
using PPipe = OutputDesignation::PPipe;
using PID = OutputDesignation::PID;
using TargetSpec = OutputDesignation::TargetSpec;
struct AbsoluteSpec

View file

@ -47,7 +47,7 @@
#include "lib/util.hpp"
#include "lib/hash-value.h"
#include "steam/asset/pipe.hpp"
#include "common/query.hpp"
#include "vessel/query.hpp"
#include <compare>
#include <map>
@ -87,7 +87,7 @@ namespace mobject {
}//(End) type rebinding helper
namespace error = lumiera::error;
using lumiera::Query;
using vessel::Query;
using lib::HashVal;

View file

@ -43,7 +43,7 @@
#include "steam/mobject/placement.hpp"
#include "steam/mobject/mobject-ref.hpp"
#include "common/query/defs-manager.hpp" ////////////////////////////TICKET #643 forward declare this?
#include "vessel/query/defs-manager.hpp" ////////////////////////////TICKET #643 forward declare this?
#include "lib/depend.hpp"
#include "lib/symbol.hpp"
#include "lib/p.hpp"
@ -101,7 +101,7 @@ namespace mobject {
: util::NonCopyable
{
protected:
typedef lumiera::query::DefsManager& DefaultsAccess;
typedef vessel::query::DefsManager& DefaultsAccess;
typedef session::ElementQuery& ElementsAccess;
typedef std::vector<asset::PTimeline> const& TimelineAccess;
typedef std::vector<asset::PSequence> const& SequenceAccess;

View file

@ -30,7 +30,7 @@
**
** @see SessManager
** @see LifecycleHook
** @see lumiera::AppState
** @see vessel::Voyage
** @see session.hpp
** @see sess-manager-impl.cpp concrete definition of Lifecycle
**
@ -42,7 +42,7 @@
#include "lib/error.hpp"
#include "lib/nocopy.hpp"
#include "include/lifecycle.h"
#include "include/lifecycle.hpp"
#include "steam/mobject/session.hpp"
#include "lib/symbol.hpp"
@ -119,7 +119,7 @@ namespace session {
void
emitEvent (Symbol eventLabel)
{
lumiera::LifecycleHook::trigger (eventLabel);
vessel::LifecycleHook::trigger (eventLabel);
}

View file

@ -27,9 +27,9 @@
#include "steam/mobject/session/binding.hpp"
#include "steam/asset/clip.hpp"
#include "steam/asset/effect.hpp"
#include "common/query/defs-manager.hpp"
#include "vessel/query/defs-manager.hpp"
using lumiera::query::DefsManager;
using vessel::query::DefsManager;
namespace steam {
namespace mobject {

View file

@ -28,7 +28,7 @@
#include "lib/symbol.hpp"
namespace lumiera {
namespace vessel{
namespace query {
class DefsManager;
}}
@ -66,7 +66,7 @@ namespace session {
public:
Placement<Root> operator() (lumiera::query::DefsManager&);
Placement<Root> operator() (vessel::query::DefsManager&);
Placement<Clip> operator() (asset::Clip const&, asset::Media const&);
Placement<Clip> operator() (asset::Clip const&, vector<asset::Media const*>);
Placement<Fork> operator() (lib::idi::EntryID<Fork> const&);

View file

@ -36,10 +36,10 @@ namespace session {
using std::unique_ptr;
using lumiera::Goal;
using lumiera::Query;
using lumiera::Resolution;
using lumiera::getResultTypeID;
using vessel::Goal;
using vessel::Query;
using vessel::Resolution;
using vessel::getResultTypeID;
typedef PlacementIndex::ID PID;
@ -191,7 +191,7 @@ namespace session {
* there is a smart-ptr managing this ResultSet.
*/
class ResultSet
: public lumiera::Resolution
: public vessel::Resolution
{
ContentFilter acceptable_;
ExplorerBuilder buildExploartion_;

View file

@ -50,7 +50,7 @@
#include "steam/mobject/session/placement-index.hpp"
#include "steam/mobject/session/scope-query.hpp"
#include "common/query.hpp"
#include "vessel/query.hpp"
#include <functional>
@ -60,7 +60,7 @@ namespace mobject {
namespace session {
using std::function;
using lumiera::Goal;
using vessel::Goal;
typedef PlacementIndex& IndexLink(void);
@ -79,7 +79,7 @@ namespace session {
* * more generally, any ScopeQuery with these properties, in some variations
*/
class PlacementIndexQueryResolver
: public lumiera::QueryResolver
: public vessel::QueryResolver
{
function<IndexLink> _getIndex;
@ -98,7 +98,7 @@ namespace session {
void defineHandling();
template<typename MO>
lumiera::Resolution* resolutionFunction (Goal const& goal);
vessel::Resolution* resolutionFunction (Goal const& goal);
public:

View file

@ -34,7 +34,7 @@
#include "steam/asset/procpatt.hpp"
#include "steam/asset/pipe.hpp"
#include "lib/query-util.hpp"
#include "common/query.hpp"
#include "vessel/query.hpp"
#include "include/logging.h"
#include "lib/symbol.hpp"

View file

@ -28,8 +28,8 @@
** away, some day the real thing will be there, displacing this mess without further notice.
** @todo to be removed in Alpha, when integrating a real resolution engine /////////////////TICKET #710
**
** @see lumiera::Query
** @see lumiera::ConfigRules
** @see vessel::Query
** @see vessel::ConfigRules
**
*/
@ -64,9 +64,9 @@ namespace session {
using lib::meta::InstantiateChained;
using lib::P;
using lumiera::Query;
using lumiera::QueryKey;
using lumiera::query::isFakeBypass; /////////TODO placeholder until there is a real resolution engine
using vessel::Query;
using vessel::QueryKey;
using vessel::query::isFakeBypass; /////////TODO placeholder until there is a real resolution engine
using util::contains;
using util::isnil;

View file

@ -19,9 +19,9 @@
#include "steam/mobject/session/root.hpp"
#include "common/query/defs-manager.hpp"
#include "vessel/query/defs-manager.hpp"
using lumiera::query::DefsManager;
using vessel::query::DefsManager;
using lib::idi::EntryID;
namespace steam {

View file

@ -33,7 +33,7 @@
#include "lib/idi/entry-id.hpp"
namespace lumiera {
namespace vessel {
namespace query {
class DefsManager;
}}
@ -59,7 +59,7 @@ namespace session {
*/
class Root : public Meta
{
lumiera::query::DefsManager& defaults_;
vessel::query::DefsManager& defaults_;
///////////TODO: timespan fields here or already in class Meta??
///////////TODO: any idea about the purpose of root's "timespan"?? ///////TICKET #448
@ -73,7 +73,7 @@ namespace session {
virtual bool isValid() const;
public:
Root (lumiera::query::DefsManager&);
Root (vessel::query::DefsManager&);
static lib::idi::EntryID<Root> getID();
static lib::idi::EntryID<Root> getAssetID();

View file

@ -93,7 +93,7 @@ namespace session {
friend class lib::DependencyFactory<ScopeLocator>;
private:
lumiera::QueryResolver const& theResolver();
vessel::QueryResolver const& theResolver();
};

View file

@ -34,7 +34,7 @@
#include "steam/mobject/placement.hpp"
#include "common/query/query-resolver.hpp"
#include "vessel/query/query-resolver.hpp"
#include "lib/format-string.hpp"
#include <functional>
@ -48,8 +48,8 @@ namespace session {
using std::function;
using std::placeholders::_1;
using lumiera::Goal;
using lumiera::Query;
using vessel::Goal;
using vessel::Query;

View file

@ -35,7 +35,7 @@
#include "steam/mobject/session/session-service-explore-scope.hpp"
#include "steam/mobject/mobject.hpp"
#include "lib/iter-source.hpp" ////////////////////TICKET #493 : only using the IterSource wrapIter adapter here
#include "common/query/query-resolver.hpp"
#include "vessel/query/query-resolver.hpp"
#include <vector>
@ -115,7 +115,7 @@ namespace session {
* of contents discovery queries to the PlacementIndex
* managed within the session
*/
lumiera::QueryResolver const&
vessel::QueryResolver const&
ScopeLocator::theResolver()
{
return SessionServiceExploreScope::getResolver();

View file

@ -36,8 +36,8 @@
#include "steam/control/steam-dispatcher.hpp"
#include "steam/config-resolver.hpp"
#include "steam/asset/timeline.hpp"
#include "common/query/defs-manager.hpp"
#include "common/query.hpp"
#include "vessel/query/defs-manager.hpp"
#include "vessel/query.hpp"
#include <memory>
#include <exception>
@ -119,7 +119,7 @@ namespace session {
REQUIRE (0 == session_->timelines.size(), "injecting default timeline, but session isn't pristine");
// issue a default query to retrieve or create a Timeline and a default Sequence
asset::PTimeline initialTimeline = session_->defaults (lumiera::Query<asset::Timeline> (""));
asset::PTimeline initialTimeline = session_->defaults (vessel::Query<asset::Timeline> (""));
// these got registered automatically
ENSURE (1 == session_->timelines.size());

View file

@ -65,7 +65,7 @@
#include "steam/asset/timeline.hpp"
#include "steam/asset/sequence.hpp"
#include "steam/mobject/session/element-query.hpp"
#include "common/query/defs-manager.hpp"
#include "vessel/query/defs-manager.hpp"
@ -87,7 +87,7 @@ namespace session {
struct SessionInterfaceModules
: util::NonCopyable
{
lumiera::query::DefsManager defaultsManager_;
vessel::query::DefsManager defaultsManager_;
mobject::session::ElementQuery elementQueryAPI_;
TimelineTracker timelineRegistry_;
SequenceTracker sequenceRegistry_;

View file

@ -38,7 +38,7 @@
#define MOBJECT_SESSION_SESSION_SERVICE_EXPLORE_SCOPE_H
#include "steam/mobject/placement.hpp"
#include "common/query/query-resolver.hpp"
#include "vessel/query/query-resolver.hpp"
@ -59,7 +59,7 @@ namespace session {
*/
struct SessionServiceExploreScope
{
static lumiera::QueryResolver const& getResolver();
static vessel::QueryResolver const& getResolver();
static PlacementMO& getScope (PlacementMO const&);
static PlacementMO& getScope (PlacementMO::ID const&);

View file

@ -25,7 +25,7 @@
#include "steam/mobject/session.hpp"
#include "steam/mobject/session/session-impl.hpp"
#include "steam/mobject/session/sess-manager-impl.hpp"
//#include "common/query/defs-manager.hpp"
//#include "vessel/query/defs-manager.hpp"
#include "lib/symbol.hpp"
#include "lib/depend.hpp"

View file

@ -28,7 +28,7 @@
#include "steam/mobject/session/scope-query.hpp"
#include "steam/mobject/placement.hpp"
#include "common/query/query-resolver.hpp"
#include "vessel/query/query-resolver.hpp"
#include <functional>
@ -39,7 +39,7 @@ namespace session {
using std::function;
using lumiera::QueryResolver;
using vessel::QueryResolver;
/**

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