Compare commits
No commits in common. "integration" and "prg@ichthyostega.de/integration_signature" have entirely different histories.
integratio
...
prg@ichthy
734 changed files with 11705 additions and 67088 deletions
4
README
4
README
|
|
@ -61,8 +61,8 @@ For building Lumiera, you'll need:
|
|||
* https://gtkmm.gnome.org/en/[gtkmm]
|
||||
* https://cgit.freedesktop.org/xorg/lib/libXv[libXv]
|
||||
* https://wiki.gnome.org/Projects/LibRsvg[lib rSVG]
|
||||
* https://git.lumiera.org/gitweb?p=debian/gdl;a=summary[lib GDL]
|
||||
* https://git.lumiera.org/gitweb?p=debian/gdlmm;a=summary[GDL-mm bindings]
|
||||
* https://git.lumiera.org/?p=debian/gdl;a=summary[lib GDL]
|
||||
* https://git.lumiera.org/?p=debian/gdlmm;a=summary[GDL-mm bindings]
|
||||
|
||||
Further information:
|
||||
|
||||
|
|
|
|||
|
|
@ -97,8 +97,6 @@ def configure(env):
|
|||
problems.append('We need boost::lexical_cast')
|
||||
if not conf.CheckCXXHeader('boost/format.hpp'):
|
||||
problems.append('We need boost::format (header).')
|
||||
if not conf.CheckCXXHeader('boost/lockfree/queue.hpp'):
|
||||
problems.append('We need boost::lockfree (header).')
|
||||
if not conf.CheckLibWithHeader('boost_program_options','boost/program_options.hpp','C++'):
|
||||
problems.append('We need boost::program_options (including binary lib for linking).')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,47 +1,42 @@
|
|||
Application : Start-up and Subsystems
|
||||
=====================================
|
||||
The Application : Start-up and Subsystems
|
||||
=========================================
|
||||
:Date: 2009
|
||||
:Author: Ichthyo
|
||||
|
||||
//MENU: label Start-up
|
||||
|
||||
.the purpose of »Application-main«
|
||||
Lumiera is envisaged as a heavyweight yet coherent »**Application**« -- which implies
|
||||
it is not so much seen as ``a platform'', framework or operating system. And, in line
|
||||
with this understanding, we place no emphasis on possible configuration changes and state
|
||||
transitions within the running application _as a whole._ The ability to react ``life'' to
|
||||
some global setting changes can be limited to relevant special cases. And, while it is
|
||||
indeed possible to close and load a new Session from a running application instance, in
|
||||
most parts of the code base we assume the application just to be ``up and running'' -- all
|
||||
required services are assumed to be available and interfaces to be accessible. If some of
|
||||
these assumptions break, an exception is raised and the application unwinds.
|
||||
Without doubt, these decisions represent a forcible simplification, and might be limiting
|
||||
at times, yet serve us well to cut down complexity in large parts of the code base --
|
||||
however, there needs to be _one dedicated realm_ to deal with all these specific concerns
|
||||
related to configuration, interdependency and lifecyle.
|
||||
Lumiera is envisioned as a heavyweight yet coherent »**Application**« -- not so much
|
||||
as platform, framework or operating system. And, in accordance with this focus, we
|
||||
place no emphasis on possible configuration changes and state transitions within
|
||||
the running application _as a whole._ And, while in fact it is possible to close
|
||||
and load a new Session, most of the time we assume the application just to be
|
||||
``up and running'' -- all required services to be available and interfaces to
|
||||
be accessible. Without doubt, these are simplifications, but serve us well
|
||||
to cut down complexity -- yet still there needs to be one dedicated realm
|
||||
to deal with these specific concerns of configuration, dependency and lifecyle.
|
||||
|
||||
|
||||
The Vessel
|
||||
----------
|
||||
So we treat all these concerns within a focused and self contained structure, called
|
||||
the »**Vessel**«, and clearly set apart from all the other layers, services and subsystems.
|
||||
This dedicated _Application Realm_ is organised around the ``Application main object''.footnote:[
|
||||
This is the singleton `vessel::Voyage`, which is triggered by the `main` function
|
||||
of the Lumiera Application. The sourcecode is kept in a separate folder 'src/vessel'
|
||||
and linked into the shared library 'liblumieravessel.so']
|
||||
Its purpose is to bootstrap and tear-down the application in a controlled way,
|
||||
which includes to provide the backbone services, evaluate the start-up parameters
|
||||
and to connect and start the necessary core components. The beginning and end of
|
||||
this vessel's voyage therefore marks the *Lifecycle* of the application, as a
|
||||
succession of ``lifecycle phases'' -- where almost any activity happens within
|
||||
the _operational phase,_ when everything is considered ``up and running''.
|
||||
The Application Realm
|
||||
---------------------
|
||||
So we treat all these concerns within a small and self contained structure, clearly
|
||||
set apart from all the other layers, services and subsystems. This dedicated
|
||||
_Application Realm_ is organised around the ``Application main object''.footnote:[
|
||||
This is the singleton `lumiera::AppState`, which is triggered by the `main` function
|
||||
of the Lumiera Application. The sourcecode is kept in a separate folder 'src/common'
|
||||
and linked into the shared library 'liblumieracommon.so']
|
||||
It serves the purpose of pulling up and tearing down the application in a controlled
|
||||
fashion. And additionally, it provides the Interface and Config core services.
|
||||
The act of building or tearing down this core realm and main object is what creates
|
||||
the *Lifecycle* of the application. This is a succession of ``lifecycle phases'' --
|
||||
and almost all activities happen within the _operational phase,_ when everything
|
||||
is ``up and running'' or ``just available''.
|
||||
|
||||
Subsystems
|
||||
~~~~~~~~~~
|
||||
However, before becoming operational, the application must be bootstrapped, and at the end,
|
||||
all parts need to be unwound cleanly. To organise this process, we identify a limited number
|
||||
of *Subsystems* within the Application, which are self-sufficient and operate independently,
|
||||
at least to some degree.
|
||||
However, initially the application needs to be brought up, and at the end, all
|
||||
parts need to be unwound cleanly. To organise this process, we identify a limited
|
||||
number of *Subsystems* within the Application, which are more or less independent.
|
||||
Each link:{ldoc}/design/architecture/Subsystems.html[Subsystem] is self contained
|
||||
and groups some other parts and services, which typically work together and may
|
||||
be mutually dependent. These subsystems represent a grouping, applied for the purpose
|
||||
|
|
@ -66,7 +61,7 @@ the startup phase. It is the responsibility of the _Application main object_ to
|
|||
pull up required functionality, which in turn might result in pulling up
|
||||
further subsystems as dependencies.
|
||||
|
||||
Subsystems are defined by implementing the interface `vessel::Subsys`, which acts
|
||||
Subsystems are defined by implementing the interface `lumiera::Subsys`, which acts
|
||||
as façade to conduct the lifecycle, find out about dependencies and shut down
|
||||
the subsystem in the end. So this interface, together with the _Subsystem Runner,_
|
||||
define a lifecycle protocol; each subsystem is free to implement this as it
|
||||
|
|
@ -102,21 +97,20 @@ within the engine independently, relying on worker jobs and a thread pool.
|
|||
|
||||
Initialisation and Lifecycle
|
||||
----------------------------
|
||||
After some discussion,footnote:[
|
||||
See the link:{rfc}/GlobalInitialization.html[GlobalInitialisation] RfC
|
||||
from spring 2008. In the beginning, we all agreed to ``keep matters simple''
|
||||
and build an `init()` function within one central piece of code everyone knows
|
||||
and hooks into. However, while the outline of the application emerged, there
|
||||
was a tension between the concern about _over-engineering_ versus the concern
|
||||
about _tangled and unmanageable complexity._ At some point, an alternative
|
||||
implementation based on lifecycle callbacks was elaborated, which then turned
|
||||
into the solution described here. At that point, Lumiera ceased to be the
|
||||
typical UI based application started-up by GTK-main, and the existing GTK
|
||||
code was retrofitted to be launched from within a plug-in.
|
||||
]
|
||||
After some discussion,footnote:[See the
|
||||
link:{rfc}/GlobalInitialization.html[GlobalInitialisation] RfC
|
||||
from spring 2008. In the beginning, we all agreed to ``keep matters simple''
|
||||
and build an `init()` function within one central piece of code everyone knows
|
||||
and hooks into. However, while the outline of the application emerged, there
|
||||
was a tension between the concern about _over-engineering_ versus the concern
|
||||
about _tangled and unmanageable complexity._ At some point, an alternative
|
||||
implementation based on lifecycle callbacks was elaborated, which then turned
|
||||
into the solution described here. Lumiera then ceased to be the typical UI
|
||||
application started by GTK, and the existing GTK code was retrofitted to
|
||||
launch from within a plug-in.]
|
||||
the design leaned toward loosely coupled parts and a formal lifecycle; which
|
||||
saves us from investigating and coding up the various interdependencies
|
||||
explicitly. Rather, all parts of the application have to comply to
|
||||
explicitly. Rather, the parts of the application have to comply to
|
||||
link:{ldoc}/design/architecture/Subsystems.html#lifecycle[Lifecycle Phases],
|
||||
and each part has to care for its own state transitions, invoked through
|
||||
_lifecycle callbacks._ We can distinguish two distinct models how to deal
|
||||
|
|
@ -134,9 +128,9 @@ Application Start
|
|||
~~~~~~~~~~~~~~~~~
|
||||
* some fundamental language-level facilities will be prepared during
|
||||
_static initialisation._ At some point, execution enters `main(argc,arvv)`.
|
||||
* `Voyage::init()` brings up the plugin loader and opens the config-interface.
|
||||
* `AppState::init()` brings up the plugin loader and opens the config-interface.
|
||||
* ...followed by triggering *ON_GLOBAL_INIT*
|
||||
* the main thread then pulls up the subsystems (`Voyage::maybeStart(subsystem)`),
|
||||
* the main thread then pulls up the subsystems (`AppState::maybeStart(subsystem)`),
|
||||
according to the command line options.
|
||||
* within each subsystem, façade interfaces will be opened through the
|
||||
interface/plug-in system.
|
||||
|
|
@ -148,7 +142,7 @@ Application Start
|
|||
the main window.
|
||||
* there is an *ON_GLOBAL_SHUTDOWN* event, which can be used for normal cleanup;
|
||||
In case of an emergency exit, the *ON_EMERGENCY_EXIT* event is triggered alternatively.
|
||||
* the Voyage destructor tears down the core systems (config-interface and pluginloader).
|
||||
* the AppState destructor tears down the core systems (config-interface and pluginloader).
|
||||
* we establish a policy to _prohibit any non-local and non-trivial activities_ during the
|
||||
tear-down phase after leaving the `main()` function.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,71 +1,15 @@
|
|||
Application and Session Configuration
|
||||
=====================================
|
||||
Lumiera Design: Application and Session Configuration
|
||||
=====================================================
|
||||
|
||||
.After initial discussion, this topic was postponed.
|
||||
[CAUTION]
|
||||
In its current form, as of 2026, the Lumiera application is headed towards a first
|
||||
integration of the parts developed thus far. A simple configuration file, 'setup.ini'
|
||||
is used to supply some minimal parameters for bootstrap of the application; all further
|
||||
settings are defined as local constants in the source code.
|
||||
*TODO* : 'write design document'
|
||||
|
||||
**Configuration and Parametrisation** of software describe a state of setting, that lies
|
||||
between the fixed structure embodied into the code and the transient work state of the
|
||||
application. It encompasses all settings and options that determine how a software system
|
||||
behaves in a specific environment, without changing its underlying source code.
|
||||
The Lumiera application uses two quite different sources for configuration
|
||||
|
||||
The purpose of configuration
|
||||
----------------------------
|
||||
For a video editing application, the scope of ``configuration'' can be far reaching.
|
||||
Not only are there numerous parameters in the engine, that must be fine-tuned for optimal
|
||||
performance, but also several patterns of behaviour are available that can not be decided by
|
||||
first principle alone and must thus be left open for the user to configure to their preference.
|
||||
Some of these are linked to the actual user, some to the setup in the system, and some to the
|
||||
current project.
|
||||
Furthermore, many of these ``settings'' turn out, upon closer inspection, to be a form of
|
||||
rule-based knowledge. In a project with the scale of a movie, it is essential for a fluid
|
||||
and intuitive working style to handle some default setup and configuration of connections
|
||||
and conversions automatically, while the user can have very valid reasons to prohibit
|
||||
some other specific class of automatic conversions to be applied without explicit confirmation.
|
||||
- individual __settings values__ can be loaded from an application- and user configuration in the conventional way
|
||||
- various facilities, especially in the Steam-Layer, base the actual behavour on __queries__, which are
|
||||
to be resolve employing a rules based system '(planned)'. Configuration rules will be provided by the
|
||||
application (defaults), a session template and rules stored in the actual session.
|
||||
|
||||
After some initial, prototyping for a ``config loader'', it was deemed too risky to engage
|
||||
into any kind of preliminary design without knowing the possible ramifications. +
|
||||
-> link:/x/rfc/ConfigLoaderDraft2008.html[Config Loader brainstorming from 2008]
|
||||
-> see also the link:rfc/ConfigLoaderDraft2008.html[Config Loader brainstorming from 2008] (implementation details)
|
||||
|
||||
The following preliminary measures have now been established for the ongoing development:
|
||||
|
||||
- whenever a _tweaking parameter_ is discovered, it will be extracted and marked
|
||||
with a **language constant** in the setup or integration header of the software component.
|
||||
- whenever a _decision point_ is encountered, that can not be related to technical dependencies,
|
||||
it is marked as a **query call** -- with a corresponding, hard-wired _faked configuration rule_.
|
||||
|
||||
The integration of some kind of configuration rule language is considered part of the primary agenda.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
To track any insights gained regarding the requirements for configuration,
|
||||
https://issues.lumiera.org/ticket/1224[Ticket #1224 (»Layered Configuration«)]
|
||||
was added to the list of medium-term
|
||||
https://issues.lumiera.org/report/17[»Focus Topics«]
|
||||
|
||||
The following requirements have been identified to date (2026)
|
||||
|
||||
- It is pointless to build one huge flat global "configuration file";
|
||||
rather, groups of configuration settings are scoped and closely related to a _local context_
|
||||
- the degree of _consistency checking_ must be tied to such a local context, where the
|
||||
situation is reasonably clear: the consumer of specific configuration usually has
|
||||
clear-cut requirements to demand some configuration to be mandatory, while other
|
||||
configuration is optional. Misspelled or misplaced configuration that does not
|
||||
fit in such a category must be flagged as error.
|
||||
- such a locally defined set of expected and optional configuration might become
|
||||
subject to versioning (forward- / backward compatibility)
|
||||
- Configuration must be assembled from several configuration sources,
|
||||
with clearly defined precedence and shadowing. Notably we have default configuration,
|
||||
system-wide configuration, user specific configuration and project related configuration.
|
||||
- a _preferences UI_ must be able to alter configuration settings, thereby intelligently
|
||||
routing the changes into the appropriate configuration source or create a suitable overlay
|
||||
- when configuration causes a decision from a rule to flip, this fact must be recorded
|
||||
permanently in the session; the reason for this mechanism is that configuration might
|
||||
change later, and the application must be able then to point out all places
|
||||
affected by the change.
|
||||
- Any detected configuration change must be captured and logged as Event and thus
|
||||
be un-doable cleanly, with all possible ripple effects.
|
||||
|
|
|
|||
|
|
@ -1,48 +1,10 @@
|
|||
The Application Realm
|
||||
=====================
|
||||
Design Documents: Application Framework
|
||||
=======================================
|
||||
|
||||
// Menu : prepend child ApplicationStart
|
||||
|
||||
Shaping the outside world through software requires a variety of effective mechanisms
|
||||
that capture, represent, and transform elements of reality. A well-designed part is
|
||||
focused on a single aspect, is coherent and cohesive in itself, with links to other
|
||||
parts based on concepts and abstraction rather then on shared technology. Yet this
|
||||
structural perspective must be complemented by a meaningful overall arrangement that
|
||||
supports the desired workflow and can be adapted to circumstances.
|
||||
* link:Config.html[Configuration]
|
||||
* link:plugin_loader.html[Plugin Loader]
|
||||
* link:ApplicationStart.html[Application Subsystems and Lifecycle]
|
||||
|
||||
In software systems, such coherency does not emerge spontaneously. It must be supported
|
||||
by definition work to establish suitable terms and interfaces, components must be
|
||||
interconnected and configured, and the overall state needs coordination.
|
||||
An application is therefore more than just a collection of software components.
|
||||
|
||||
In the Lumiera Architecture, this application realm is embodied into a structure
|
||||
called the »**Vessel**«:
|
||||
|
||||
- it is built as a library with only basic linkage to the support library
|
||||
- it can be invoked from a `main()` function, with an argument parser
|
||||
- at source code level, it provides all the types and definitions
|
||||
required to express the _binding_ between components
|
||||
- _conceptually,_ all layers are encased in the _application vessel_
|
||||
- and while the Vessel can not just ``control'' the configuration of parts
|
||||
on upper layers, it has to bootstrap their ability to adapt to circumstances.
|
||||
|
||||
--
|
||||
|
||||
--
|
||||
|
||||
Dependencies::
|
||||
While the code base is organised into _three layers,_ the actual implementation
|
||||
structures are arranged into **Subsystems** that _depend_ on each other and
|
||||
can be _started and shut down_
|
||||
+
|
||||
-> link:ApplicationStart.html[Subsystems and Lifecycle]
|
||||
|
||||
Configuration::
|
||||
As a means to adapt to the environment and enable flexibility,
|
||||
this topic is surprisingly intricate and development has barely scratched
|
||||
the surface: while the effective configuration is assembled from several
|
||||
layered sources, the meaning (and documentation) of individual settings
|
||||
is scoped, and users can expect the ability to override some settings
|
||||
from within the application.
|
||||
+
|
||||
-> link:Config.html[Configuration]
|
||||
|
|
|
|||
5
doc/design/application/plugin_loader.txt
Normal file
5
doc/design/application/plugin_loader.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Lumiera Design: Plugin system
|
||||
=============================
|
||||
|
||||
Eventually, this will have design documentation for the Plugin system.
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ Lifecycle Events
|
|||
The Application as a whole conducts a well defined lifecycle; whenever transitioning to the next phase,
|
||||
a _Lifecycle Event_ is issued. Components may register a notification hook with the central _Lifecycle Manager_
|
||||
(see 'include/lifecycle.h') to be invoked whenever a specific event is emitted. The process of registration
|
||||
can be simplified by planting a static variable of type `vessel::LifecycleHook`.
|
||||
can be simplified by planting a static variable of type `lumiera::LifecycleHook`.
|
||||
|
||||
WARNING: A callback enrolled this way needs to be callable at the respective point in the lifecycle,
|
||||
otherwise the application will crash.
|
||||
|
|
@ -246,7 +246,7 @@ WARNING: A callback enrolled this way needs to be callable at the respective poi
|
|||
Invoked as early as possible, somewhere in the static initialisation phase prior to entering `main()`.
|
||||
In order to install a callback hook for this event, the client must plant a static variable somewhere.
|
||||
|
||||
`Voyage`::
|
||||
`AppState`::
|
||||
This is the Lumiera »Application Object«. It is a singleton, and should be used by `main()` solely.
|
||||
While not a lifecycle event in itself, it serves to bring up some very fundamental application services:
|
||||
+
|
||||
|
|
@ -255,7 +255,7 @@ WARNING: A callback enrolled this way needs to be callable at the respective poi
|
|||
- the application configuration
|
||||
--
|
||||
+
|
||||
After starting those services within the `Voyage::init()` function,
|
||||
After starting those services within the `AppState::init()` function,
|
||||
the event `ON_GLOBAL_INIT` is emitted.
|
||||
|
||||
`ON_GLOBAL_INIT`::
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
Extending the Application
|
||||
=========================
|
||||
|
||||
During the inception phase, the link:/x/rfc/AllPluginInterfacesAreC.html[idea was commended]
|
||||
to bootstrap the application as a multi-lingual compound of plug-ins, for maximum flexibility
|
||||
and ease of contribution. Although this approach garnered much support initially, the ensuing
|
||||
discussions questioned its viability, with well-known plugin-based systems and frameworks
|
||||
cited as cautionary example.
|
||||
|
||||
A prototype implementation
|
||||
(-> link:PluginBrainstorm.html[draft for the plugin interface])
|
||||
was nevertheless developed, but it proved problematic in practical use.
|
||||
The goal of a flexibly expandable application is still maintained,
|
||||
but the path to achieving it should be based on actual requirements.
|
||||
|
||||
Development of an https://issues.lumiera.org/ticket/1212[Extension Concept #1212]
|
||||
was thus placed on the list of medium-term
|
||||
https://issues.lumiera.org/report/17[»Focus Topics«]
|
||||
|
||||
|
|
@ -7,23 +7,22 @@ Lumiera Design Documents
|
|||
// Menu : prepend child design/gui
|
||||
// Menu : prepend child architecture
|
||||
|
||||
// Menu : append child extension
|
||||
// Menu : append child plugins
|
||||
// Menu : append child workflow
|
||||
// Menu : append child governance
|
||||
|
||||
Lumiera aspires to be a professional tool for video editing on
|
||||
Lumiera is to be a professional tool for video editing on
|
||||
GNU/Linux systems. The vision of the development team defines a modern design
|
||||
for the core of a Non-Linear Editing software. A key aspect of Lumiera
|
||||
is the strong separation between the user interface and the processing core.
|
||||
We are developing Lumiera with a general purpose GTK UI -- which is loaded as
|
||||
an optional component, so that the core can also be invoked from scripts to
|
||||
use the editing and processing capabilities of the engine.
|
||||
We are developing Lumiera with a GTK GUI but that will in no way be exclusive;
|
||||
other GUIs can be written, as well as scripts to drive the core.
|
||||
This becomes possible by an ongoing effort to decrease coupling. Each major
|
||||
component in the application strives to be open to extensions, but closed
|
||||
against external modification. The presentation, the model and the ``performing''
|
||||
of the model are separate and self-contained parts of the application.
|
||||
Lumiera as a processing core will be able to perform any conceivable task
|
||||
on video and audio, maybe even tasks entirely unrelated to video editing.
|
||||
of the model are separate and self-contained parts of the application. Lumiera
|
||||
as a processing core will be able to perform any conceivable
|
||||
task on video and audio, maybe even tasks entirely unrelated to video editing.
|
||||
|
||||
.Workflow
|
||||
*****************
|
||||
|
|
@ -53,8 +52,7 @@ specialised GUIs. The interface is the component that is closest to the user. I
|
|||
provides purely visual interaction with the user. Within this work environment, the user
|
||||
manipulates, organizes, loads, configures all sorts of data, especially MObjects (media
|
||||
objects) and Assets. These elements are contained within a structure called the Session. +
|
||||
-> link:gui/index.html[GUI/Stage-Layer design documents] +
|
||||
-> link:{ldoc}/technical/stage/index.html[GUI technical documentation]
|
||||
-> link:gui/index.html[GUI/Stage-Layer design documents]
|
||||
|
||||
|
||||
Steam: the Transformation Layer
|
||||
|
|
@ -89,23 +87,24 @@ the screen or to external output. +
|
|||
Extra Components
|
||||
----------------
|
||||
|
||||
The Vessel
|
||||
~~~~~~~~~~
|
||||
A structure that is anchored below all layers, yet contains everything, conceptually.
|
||||
Definitions for building common interfaces are located here, as is the mechanism for initialisation
|
||||
and shutdown of the application, the loading of bootstrap configuration and optional components.
|
||||
It encloses and coordinates all parts to work together as a coherent whole.
|
||||
This -> link:application/index.html[Application framework] is complemented by
|
||||
a link:{ldoc}/technical/library/index.html[Support-Lbrary] with commonly used components,
|
||||
algorithms and data structures.
|
||||
The Application
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The application controls the initialization and shutdown procedures as well as
|
||||
loading external elements such as plug-ins, which are widely used throughout
|
||||
Lumiera. It acts as the framework which supports core component operations. This
|
||||
framework is complemented by a library of commonly used components, algorithms and data structures. +
|
||||
-> link:application/index.html[Application framework]
|
||||
|
||||
|
||||
link:plugins/index.html[Plugins]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Plug-ins play an important role within Lumiera since the application relies
|
||||
heavily on current FLOSS implementations and external libraries. Moreover, the
|
||||
application will be configurable and can be extended in various
|
||||
ways; whenever some extension isn't permanent or will be used only on demand, it
|
||||
is packaged as a separate module into a plug-in. For example, the GUI of Lumiera
|
||||
is a plugin. +
|
||||
-> design documents regarding the link:plugins/index.html[Plugins]
|
||||
|
||||
Extensions
|
||||
~~~~~~~~~~
|
||||
Lumiera uses proven and field-tested implementations for the actual media processing,
|
||||
which are available as FLOSS or open-source libraries. To avoid extensive external dependencies
|
||||
on the main application however, such libraries need to be loaded through _adaptor plug-ins._
|
||||
Furthermore, the application will be configurable and it is conceivable that external
|
||||
extensions will be created. Designing and building a future-proof framework for configuration
|
||||
and extension is an important medium-term goal for further development.
|
||||
|
|
|
|||
|
|
@ -1,30 +1,14 @@
|
|||
Low-level Services
|
||||
==================
|
||||
Design Documents: Vault
|
||||
=======================
|
||||
|
||||
Towards the _upper side_ of the Lumiera core, in »Steam Layer«,
|
||||
several components and subsystems work together to provide functionality
|
||||
that is close to the requirements of the _problem domain_ -- editing and
|
||||
rendering of media. The implementation of these features however requires
|
||||
a foundation of generic, technical services: Memory needs to be allocated,
|
||||
working buffers must be provided and managed, work tasks coordinated.
|
||||
It is hard to associate these responsibilities directly to
|
||||
some specific domain, other than just _data processing._
|
||||
What follows is a summary of Lumiera's *Data Handling Backend*
|
||||
|
||||
A common trait of all those special aspects of processing is that they
|
||||
require special care and attention to achieve the necessary level of
|
||||
performance, while they are _technical_ in nature and do not directly
|
||||
reflect and model structures of the real world.
|
||||
|
||||
Data Handling
|
||||
-------------
|
||||
The task of editing video and processing media requires to read and write
|
||||
a significant amount of data, while using the capabilities of the hardware
|
||||
to the best degree possible. Lumiera thus needs a foundation layer for
|
||||
high volume data access; two kinds of data handling can be distinguished:
|
||||
This is the foundation layer responsible for any high performance or high volume
|
||||
data access. Within Lumiera, there are two main kinds of data handling:
|
||||
|
||||
* The Session and the object models manipulated through the GUI are kept in memory.
|
||||
They will be backed by a _storage backend,_ which provides database-like storage
|
||||
and especially logging, and controlled execution of _mutating actions._
|
||||
They are backed by a _storage backend,_ which provides database-like storage and
|
||||
especially logging, replaying and ``Undo'' of all ongoing modifications..
|
||||
* Media data is handled _frame wise_ -- prefetching data asynchronously.
|
||||
|
||||
The goal is to optimize CPU utilization; large scale data IO will be performed
|
||||
|
|
|
|||
4
doc/design/plugins/index.txt
Normal file
4
doc/design/plugins/index.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Design Documents: Plug-In
|
||||
=========================
|
||||
|
||||
* link:PluginBrainstorm.html[early draft for the plugin interface]
|
||||
|
|
@ -1,15 +1,16 @@
|
|||
Lumiera Workflow Proposals
|
||||
==========================
|
||||
:Author: Wouter Verwijlen
|
||||
:Date: 16 March 2026
|
||||
:Date: 19 August 2025
|
||||
:TOC:
|
||||
|
||||
I would like to share a collection of workflow ideas for Lumiera. These ideas come from
|
||||
having cut hundreds (or possibly thousands) of videos over the past 20 years as a professional
|
||||
editor, working in Avid Media Composer, Adobe Premiere, Lightworks and DaVinci Resolve.
|
||||
I would like to share a first version of a collection of workflow ideas for Lumiera. These ideas come
|
||||
from having cut hundreds (or possibly thousands) of videos over the past 20 years as a professional
|
||||
editor, working in Avid Media Composer, Adobe Premiere Pro (from before it was called "Pro"),
|
||||
Lightworks and DaVinci Resolve.
|
||||
|
||||
This document focuses on analysing the behaviour of Non-linear Editors (NLE's): software
|
||||
in which a user can edit films and videos, in order to discuss possible solutions for the
|
||||
This document focuses on analysing the behaviour of Non-linear Editors (NLE's), in other words
|
||||
software in which a user can edit films and videos, in order to discuss possible solutions for the
|
||||
design of Lumiera.
|
||||
|
||||
The main ideas behind these proposals are:
|
||||
|
|
@ -177,354 +178,14 @@ specific project in order to select the parts needed for the final edit. I will
|
|||
which different NLE's handle this and will propose possible directions for Lumiera to support
|
||||
certain workflows.
|
||||
|
||||
Project creation
|
||||
~~~~~~~~~~~~~~~~
|
||||
When starting a new project, a user often needs to set the project resolution and framerate. Adobe
|
||||
Premiere (optionally) shows an import panel immediately after this. The first time you drop a clip
|
||||
on a timeline, Resolve and Premiere will ask if you want to change your project settings to match
|
||||
the clip settings, when these are different.
|
||||
|
||||
.Premiere's import panel
|
||||
image::{imgg}/wouter/v4-01-importPanel.jpg[width="100%", alt="Premiere's import panel"]
|
||||
|
||||
Projects themselves exist within an application's database (Resolve), or as a file/folder on local or
|
||||
shared storage (Avid, Premiere, Lightworks, FCP).
|
||||
|
||||
One of the first things that needs to be setup is the organisational structure of the project, in other
|
||||
words: the structure that's going to house all of the project's contents. Most applications use bins for
|
||||
this, a bin being simply a container for items like video clips. In a sense they are similar to folders
|
||||
on a computer's storage, except bins usually only exist within the project in your NLE. Avid's bins
|
||||
also exist as folders on local or shared storage, but this is an exception.
|
||||
|
||||
For top level organisation, bins can either be placed in other bins (Premiere, Resolve) or in
|
||||
groups/folders (Avid, Lightworks).
|
||||
|
||||
As we'll see throughout this document, Final Cut Pro is usually the only application that takes a
|
||||
different approach. Projects are called ``libraries'' and FCP sorts footage based on events (top level
|
||||
containers of timelines, footage and keyword collections), keywords (tags) and collections, instead
|
||||
of bins (timelines are confusingly called ``projects''). Footage, when imported, is placed in an event
|
||||
and from there all emphasis is on the metadata, in how you rate and tag (parts of) the footage. This
|
||||
also serves as a replacement of the subclips feature found in other NLE's.
|
||||
|
||||
.Final Cut Pro's Keywords dialog. +
|
||||
image::{imgg}/wouter/v4-02-keywords.jpg[width="100%", alt="Final Cut Pro's Keywords dialog"]
|
||||
^↑``Travel part 1'' and ``Travel part 2'' on the left are events.^
|
||||
|
||||
|
||||
In any case, when working in a professional environment, you will probably want to start with a
|
||||
template that defines your top level structure, instead of having to recreate your entire bin setup
|
||||
for every project. Surprisingly, at the time of writing only Adobe Premiere has introduced a project
|
||||
template feature (in version 2024). In other apps you will need to manually create your own template project
|
||||
and duplicate that, or even literally copy and paste bins from a template project in a file browser (Avid).
|
||||
|
||||
Importing footage
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Every application works with clips: virtual representations of (parts of) the video files that exist on
|
||||
your preferred type of storage. Getting footage into your project (``ingest'') will create these clips in
|
||||
your project. Most apps will offer several options to do this:
|
||||
|
||||
. Creating links to the original video files, wherever these may reside (on your computer,
|
||||
external storage, network storage or in the cloud).
|
||||
. Copying your files to a dedicated folder managed by the application (this could again be on
|
||||
local or network storage). Importing to a dedicated application folder is very useful for
|
||||
feature film editing and TV production, but is less common elsewhere in the media industry.
|
||||
Its strong point is that when your media is managed by the application, you won't have to
|
||||
re-link files when moving to a different editing station.
|
||||
. Optionally, files can be transcoded during import. New media files will be created in either
|
||||
the app's dedicated folder or to a user specified location. The transcoded files will be much
|
||||
more optimised for editing, resulting in better playback performance.
|
||||
|
||||
The latter is part of what is known as the *offline-online* workflow, in which you work with
|
||||
optimised files, and once an edit is finished (``picture lock''), the clips on the timeline
|
||||
will be exchanged with clips that link to the original camera files. Often, after colour grading
|
||||
in an external application, all colour graded shots are rendered with their colour corrections
|
||||
and placed back onto the timeline in the NLE.
|
||||
|
||||
A specific type of offline-online workflow is the *proxy workflow*, that allows switching
|
||||
on-the-fly between the proxy files and the original camera files and will ensure that exports
|
||||
of your video will use these original camera files when rendering. When using a proxy workflow,
|
||||
you can either create optimised files inside the application itself (or in Premiere's case, via
|
||||
Adobe Media Encoder) or attach existing proxy files that were created by a third party application
|
||||
or by the camera during recording.
|
||||
|
||||
After importing media and possibly creating/attaching proxies, clip attributes might need altering.
|
||||
You might need to change incorrectly determined frame rates or, more commonly, change the audio
|
||||
channel mapping of your clips (e.g. setup clips with two audio channels as dual mono instead of
|
||||
stereo).
|
||||
|
||||
Clip types
|
||||
^^^^^^^^^^
|
||||
We usually find the following types of clips in NLE's:
|
||||
|
||||
Source clips:: they represent media files (containing video and/or audio streams) to its full
|
||||
extent, and for other types of media (most notably still images) -- these usually get a default
|
||||
duration upon import.
|
||||
Subclips:: they represent a portion of a video or audio file.
|
||||
Timeline clips:: duplicates of source clips that only exist within a timeline. Properties of
|
||||
these clips can often be altered without altering the same properties of the source clip.
|
||||
Compound clips/nested sequences:: these are in fact (sub)timelines that can contain any
|
||||
number of tracks and clips.
|
||||
Multicam clips:: (group clips in Avid), these are compound clips, in which multiple clips are
|
||||
synchronised and combined into one. This compound contains clips with different camera angles
|
||||
(for video) or audio recordings for the same event.
|
||||
Filler (Avid), FX clips (Lightworks) or Adjustment Clips (Premiere, Resolve):: these special clips
|
||||
can hold effects that are applied to all clips on lower tracks of a timeline, directly underneath.
|
||||
|
||||
Bin types
|
||||
^^^^^^^^^
|
||||
Often there are two types of bins in which these clips sit
|
||||
|
||||
. ``Normal'' bins.
|
||||
. Search bins (Premiere) / filters (Lightworks) / smart bins (Resolve) / smart collections
|
||||
(FCP): for these you setup certain rules based on clip names or metadata. All clips to which
|
||||
these rules apply are automatically added to these bins. This means that the same clip can
|
||||
simultaneously exist in a regular bin and a search bin, in contrast to normal bins, where each
|
||||
clip will only exist in a single bin and you'd have to duplicate this clip for it to be also
|
||||
placed in another bin (Lightworks being the exception here).
|
||||
|
||||
.Filter options in Lightworks
|
||||
image::{imgg}/wouter/v4-03-filterOptions.jpg[alt="Filter options in Lightworks"]
|
||||
|
||||
|
||||
Resolve adds a third kind of bins, known as ``Power bins'': these are bins that are accessible by all projects.
|
||||
|
||||
Bin views
|
||||
^^^^^^^^^
|
||||
Bins offer several views to see its contents. These include:
|
||||
|
||||
* List View / Text View: all items in the bin are listed vertically. Multiple columns will show
|
||||
different kinds of metadata -- the user can choose which fields are displayed and can
|
||||
rearrange their order.
|
||||
|
||||
* Icon View (Premiere) / Frame View (Avid) / Thumbnail View (Resolve) / Tile View
|
||||
(Lightworks): this will show a small frame from each clip in a raster. In general you're able
|
||||
to change which frame is displayed if you wish to see another.
|
||||
|
||||
* Freeform View (Premiere): same as Icon View, but you can freely position the clips
|
||||
wherever you want. Note that Avid and Lightworks allow you to do this within Icon/Frame
|
||||
View itself.
|
||||
|
||||
* Script View (Avid): similar to Text View, but with a frame being displayed for each clip and
|
||||
a large field for entering comments. In Script View, the vertical order of clips can be
|
||||
rearranged, in contrast to Text View, which only supports automatic sorting.
|
||||
|
||||
* Metadata View (Resolve): similar to Avid's Script View, except you can't reorder clips.
|
||||
|
||||
* Filmstrip View (Final Cut Pro): similar to Icon View, but [red]#TODO: missing text??#
|
||||
|
||||
Avid is famous for allowing you to save your Text or Script View configuration as a preset that can
|
||||
be quickly recalled. Premiere allows this through its Metadata Display window, Final Cut Pro by
|
||||
Control+left clicking any column header and Lightworks via the Columns > Presets menu, but these
|
||||
methods are less straightforward than Avid's. Another neat feature that Avid has is a bin map: an
|
||||
overview of bin contents that can be toggled when in Frame View.
|
||||
|
||||
.Creating a custom view preset in Avid Media Composer, which can be selected from the drop-down menu in the top bar.
|
||||
image::{imgg}/wouter/v4-04-customView.jpg[width="120%", alt="Creating a custom view preset"]
|
||||
|
||||
|
||||
Note that all apps offer a search/filter box (or button) on top of each bin view. Final Cut Pro and
|
||||
Resolve allow skimming clips from the bin view, simply by hovering the mouse on top of the
|
||||
thumbnail and moving it from left to right.
|
||||
|
||||
|
||||
Organising footage
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Once your footage is represented by clips in bins, organisation can begin. Wildly different methods
|
||||
exist for this. In the simplest version you will just drop your footage in one or several bins and be
|
||||
done with it. In professional environments there are often strict bin structures and naming
|
||||
conventions, and additional methods for organising are being used:
|
||||
|
||||
* First and foremost: with multi-camera shoots and/or when audio has been recorded
|
||||
separately, now is the time to synchronise these. Create multicam clips and/or synchronise
|
||||
sound, either in the NLE itself, or in an external application. I personally create source reels
|
||||
first (see further down this list), export these to another application for syncing, import the
|
||||
synced reel back, and in case of a multicam shoot, split this reel into multiple reels and
|
||||
convert each to a multicam clip (Premiere and Resolve both support this).
|
||||
|
||||
* Metadata. This is a very powerful way to search for or filter specific types of content and it
|
||||
could be a chapter on its own. Metadata is often created by the camera during recording,
|
||||
added during offloading by a DIT (digital imaging technician) or applied after ingest by
|
||||
assistant editors. Nowadays metadata is also added by AI/machine learning algorithms to
|
||||
help identify the contents of a clip, create transcriptions from audio, etc. Avid provides the
|
||||
option to (automatically or manually) connect clips to lines in a script (ScriptSync).
|
||||
|
||||
* The aforementioned subclips are often used to extract sections out of a longer clip.
|
||||
|
||||
* Sequence/timeline markers to mark points in time, or sections (so-called ranged or spanned
|
||||
markers; terminology is different per app).
|
||||
+
|
||||
.Plenty of marker options in Adobe Premiere
|
||||
image::{imgg}/wouter/v4-05-markerOptions.png[width="70%", alt="Marker options in Premiere"]
|
||||
+
|
||||
|
||||
* Timeline clip notes (Avid): these can be added to a timeline clip, and will stay connected to
|
||||
this clip. You can't trim them off and they will automatically move whenever a clip moves.
|
||||
They can be burned into a render upon export. Premiere and Resolve offer clip markers
|
||||
instead -- these are similar to sequence markers, but are attached to clips.
|
||||
|
||||
* Tagging or rating (parts of) clips (FCP and to a lesser extent Resolve). FCP's rating only
|
||||
goes as far as letting you mark clips or sections as ``favourite'' or reject clips entirely,
|
||||
but its keyword system (as described later in this chapter) is much more elaborate and useful.
|
||||
Resolve has an option to add keywords, but its workflow is quite clunky when trying to
|
||||
apply this to a section within a clip.
|
||||
|
||||
* Clip colours. Often there exist multiple levels at which a clip can get a colour. Colours can be
|
||||
applied based on source clip (usually different colours for different media types), timeline
|
||||
clip, timeline track, offline footage, different framerates, and more. Avid has the most
|
||||
options in this field and lets you choose exactly which types of colours to display on the
|
||||
timeline. Manually set clip colours are a very useful organisational tool, e.g. to differentiate
|
||||
between several cameras, interviewed persons in a documentary or different locations.
|
||||
+
|
||||
.Avid has many options for choosing how clips are coloured in the timeline
|
||||
image::{imgg}/wouter/v4-06-clipColor.png[width="50%", alt="Coosing clip colours in Avid"]
|
||||
+
|
||||
|
||||
* Flags (Resolve). Similar to markers, but these apply to entire (source) clips, while markers
|
||||
apply to a single point in time or a time range within a clip. Multiple flags can be added to
|
||||
each source clip.
|
||||
|
||||
* Reels: source footage is divided over one or multiple timelines to be able to quickly navigate
|
||||
many clips without having to load individual clips in the source viewer. These are called
|
||||
``source reels''. A special kind of source reel is a ``sync map'', which contains all footage
|
||||
of a day of shooting from multiple cameras synced and laid out chronologically.
|
||||
FCP doesn't quite support source reels and instead offers continuous playback from the
|
||||
browser window. Resolve has a ``source tape'' option that works in a similar way.
|
||||
|
||||
|
||||
.Simple example of a source reel (top), converted to a sync map (bottom)
|
||||
image::{imgg}/wouter/v4-07-syncMap.png[width="100%", alt="Example of a sync map", link="{imgg}/wouter/v4-07-syncMap.png"]
|
||||
|
||||
Viewing footage
|
||||
^^^^^^^^^^^^^^^
|
||||
Once basic organisation is in place, the editor can start watching and adding further notes/comments
|
||||
to narrow down large amounts of footage and seek out options of useful content for the edit. Most
|
||||
apps offer two types of monitors for video playback: source and record/program monitors. FCP has
|
||||
only a single monitor that switches between these two functions. Some others (Avid, Resolve) give
|
||||
users the choice between single or multi viewer modes. Lightworks and Avid support an unlimited
|
||||
amount of floating viewers.
|
||||
|
||||
.You can open (and position) as many viewers as you like in Lightworks
|
||||
image::{imgg}/wouter/v4-08-multiViewer.jpg[width="120%", alt="Multiple viewers in Lightworks", link="{imgg}/wouter/v4-08-multiViewer.jpg"]
|
||||
|
||||
Viewers are usually coupled with timecode display and have a ton of settings.
|
||||
I won't go into details about these.
|
||||
|
||||
In most applications you can also watch your source footage from the bin when in Frame/Icon
|
||||
View. You'll be able to use JKL shortcuts for playback, mark in and out points and add it to the
|
||||
timeline, similar as to when the clip is loaded in the source viewer. Final Cut Pro lets you click and
|
||||
drag in-out regions in the thumbnail.
|
||||
|
||||
Selects
|
||||
^^^^^^^
|
||||
Time to create a selection of material to consider for the rough cut. One way to do this, as
|
||||
previously described, is by creating subclips or by tagging. Drop the subclips in a bin in
|
||||
Icon / Frame View and you have a good visual overview of selected shots. This is great for selecting
|
||||
B-roll material, or for projects that require a very visual approach, f.e. trailers, music videos
|
||||
or aftermovies (not hoping to ever cut one of those again though, but that's a different story 😉).
|
||||
|
||||
Another way to select footage is to cut selections from source clips or source reels to one or more
|
||||
selects reels: these are timelines that hold your selections and are only used for that purpose. Selects
|
||||
reels can then be loaded again as if they were a source clip, in order for an another selection to be
|
||||
made. This is called *reel-to-reel editing*. Many apps allow seeing the source timeline, either in their
|
||||
own panel (Premiere) or window (Lightworks), or by switching the timeline panel between a source
|
||||
and record mode (Avid, Resolve). A method known as _pancake timeline editing_ works when an
|
||||
application supports viewing multiple timelines simultaneously. By stacking timelines above each
|
||||
other you can easily drag selections from one timeline to another. This is possible in Premiere,
|
||||
Lightworks and Resolve.
|
||||
|
||||
.Pancake timeline editing in Lightworks
|
||||
image::{imgg}/wouter/v4-09-pancake.png[width="110%", alt="Example of a sync map", link="{imgg}/wouter/v4-09-pancake.png"]
|
||||
|
||||
Reels can be further managed by using markers to describe certain points in time or sections, and
|
||||
these markers can be viewed as a list in their own panel. When selecting a marker in this panel, the
|
||||
playhead of the corresponding monitor will jump to the (start) frame of this marker. Markers can
|
||||
have multiple input fields and a colour. They are one of the most important tools to be able to make
|
||||
notes and navigate large amounts of footage over extended periods of time. As an aside: Lightworks
|
||||
has an option to turn ranged markers into subclips, quite useful, as it allows you to use markers
|
||||
to make your selection.
|
||||
|
||||
Some NLE's have a ``ripple markers'' option for timeline markers. This means markers will move
|
||||
when clips in the timeline are shortened or extended.
|
||||
|
||||
FCP has ``todo markers'' that can be checked. And when tagging clips with keywords in FCP,
|
||||
keyword collections are automatically created in which all sections of clips with the same keyword
|
||||
can be found. It's also possible to manually create keyword collections and drag and drop clips or
|
||||
tagged sections (``content ranges'') there.
|
||||
|
||||
Back to the reels: one advantage of reel-to-reel editing is that it's very useful to see the audio
|
||||
waveforms of your source clips on an actual timeline: this way you can freely zoom and scroll.
|
||||
Final Cut Pro will only display a clip's waveform at the bottom of the clip preview in the browser,
|
||||
but when an interview is an hour or longer, this waveform will be squeezed in a way that's of little
|
||||
use.
|
||||
|
||||
Another advantage of reel-to-reel editing is a sense of space: you get an idea of where certain
|
||||
footage can be found (more to the left, in the middle, or at the end of a reel). Combined with
|
||||
markers, clip colours and gaps between sections, this makes it easier to find things back later. A third
|
||||
advantage is that it's easy to filter in rounds: you can narrow down your footage in multiple reel-to-reel
|
||||
selection passes.
|
||||
|
||||
I personally often use a variation of reel-to-reel editing, in which I lift sections in my source reel.
|
||||
I then duplicate this reel, remove the first video and audio track(s) and keep the lifted parts to create
|
||||
my selects reel. The advantage here is that I can rate sections as _not useful_ (V1), _possibly useful_
|
||||
(V2), _quite useful_ (V3) or _highly useful_ (V4) by lifting the video clip one, two or three tracks up --
|
||||
see it as a 4-star rating system. I have seen other editors use this method for selecting footage,
|
||||
although in all fairness I'm not sure how widespread this technique is.
|
||||
|
||||
.Lifting selections; also note the use of clip colours, gaps and markers for organising the selects reel.
|
||||
image::{imgg}/wouter/v4-10-selectsReel.png[width="100%", alt="Example of a sync map", link="{imgg}/wouter/v4-10-selectsReel.png"]
|
||||
|
||||
|
||||
In FCP you can create your own rating system by using keywords (as shown in the screenshot at the
|
||||
start of this chapter) and then having everything filtered through keyword collections, as described
|
||||
in this https://blog.frame.io/2016/10/18/make-fcp-x-log-better-1/[blog post at Frame.io].
|
||||
Quite handy as well!
|
||||
|
||||
Proposals
|
||||
~~~~~~~~~
|
||||
* Which system(s) of organising a project and selecting footage should Lumiera support? I
|
||||
would say: most. They don't interfere with each other, so let the user choose. Definitely
|
||||
support source timelines and let people rate, tag and mark all they want. Subclips might not
|
||||
be necessary when a tagging/keyword system is present, as Final Cut has proven.
|
||||
|
||||
* Metadata-based organising, searching and filtering of content are _must-haves_.
|
||||
|
||||
* I would include a native rating system (1 to 5 stars should suffice) that works both on clip
|
||||
sections and entire clips, rather than FCP's favourite/reject system, as it's more granular.
|
||||
|
||||
* As for bins-in-bins vs bins-in-folders: the first one is more flexible (bins can contain both
|
||||
media files and other bins, while folders can only contain bins) and more closely resembles
|
||||
how folders work on a PC, so my preference would be to go that route, although there's also
|
||||
something to be said for the strict division of function that folders+bins have.
|
||||
|
||||
* I would like to propose an option to automatically create source reels based on rules you can
|
||||
set, for example: one source reel for every day of shooting. These automatic source reels
|
||||
could have a filter function to select which clips are being displayed on the timeline. This
|
||||
way it becomes easy to say something like ``show me all clips from the second day of the
|
||||
shoot from camera A''.
|
||||
|
||||
* A versioning system for timelines is something that only Resolve has recently picked up
|
||||
with its Create (and Restore) Timeline Backup feature, and honestly I've been amazed by
|
||||
how this hasn't been a core feature in NLE's for decades now, as it makes so much sense to
|
||||
have. Let users make snapshots and perhaps make one automatically every day, without the
|
||||
need to manually duplicate and rename timelines and putting them in some sort of archive
|
||||
bin.
|
||||
|
||||
* Importing: auto-import based on watch folders could be very useful during certain stages of
|
||||
an edit. Setup which folders to watch and whenever a new file is dropped in that folder it
|
||||
will be imported into a bin of choice. Especially handy when working with sound effects.
|
||||
However, we might not want to be scanning folders all the time.
|
||||
|
||||
* About sound effects: there's a free application called Metadigger that let's you quickly filter
|
||||
your sound collection by metadata and then copy sound files to your project folder with a
|
||||
keyboard shortcut. Something like this, built-in, would be quite handy for those of us with
|
||||
local sound effect libraries.
|
||||
|
||||
* A small one: I'd like each project to remember the last location you imported from. I often
|
||||
switch between projects and each time I want to import something in current NLE's, the file
|
||||
dialog points to the last used directory, which is often the wrong one.
|
||||
Not a big deal, but not ideal either.
|
||||
|
||||
|
||||
[red]#To be written:#
|
||||
|
||||
- Asset organisation: bins vs metadata-based structures (+ search bins/filters)
|
||||
- Viewing footage: single clips vs source reels; continuous playback from browser
|
||||
- Source monitor + program monitor vs a single monitor
|
||||
- Creating selects: selects reels, subclips and keyword collections
|
||||
- On markers and notes
|
||||
- From selects to editing in the timeline: Timelines in the source viewer: reel to reel editing
|
||||
|
||||
Chapter 2: the timeline
|
||||
-----------------------
|
||||
|
|
@ -622,7 +283,7 @@ Editors often proudly share screenshots of their timelines on social media, and
|
|||
impressive, but these are in fact pretty fragile structures.
|
||||
|
||||
.One of my own timelines, which is relatively simple by comparison to those of many Hollywood movies
|
||||
image::{imgg}/wouter/v3-01-timeline.jpg[width="110%", alt="Screenshot of a timeline", link="{imgg}/wouter/v3-01-timeline.jpg"]
|
||||
image::{imgg}/wouter/01-timeline.jpg[width="110%", alt="Screenshot of a timeline", link="{imgg}/wouter/01-timeline.jpg"]
|
||||
|
||||
So naturally, a question would be: what will happen if we would let go of the track paradigm? This
|
||||
is what Final Cut Pro has done, starting from the rewrite of Final Cut Pro X. At the time, a
|
||||
|
|
@ -639,10 +300,10 @@ primary storyline, and all connected clips automatically move with it. With a mo
|
|||
ignore clip connections, so that you can also easily move a primary clip elsewhere without its
|
||||
connected siblings coming along.
|
||||
|
||||
image::{imgg}/wouter/v3-02-trim-magnetic-1.jpg[width="100%", alt="(before trim)"]
|
||||
image::{imgg}/wouter/02-trim-magnetic-1.jpg[width="100%", alt="(before trim)"]
|
||||
|
||||
.Extending one clip will automatically move all connected clips in order to keep sync
|
||||
image::{imgg}/wouter/v3-02-trim-magnetic-2.jpg[width="100%", alt="(after trim)"]
|
||||
image::{imgg}/wouter/02-trim-magnetic-2.jpg[width="100%", alt="(after trim)"]
|
||||
|
||||
_Sounds good._ Why not just copy this? One reason is that FCP assumes that all clips that are not on
|
||||
the primary storyline should be connected to this primary storyline. This might work well for fiction
|
||||
|
|
@ -657,7 +318,7 @@ How else could we group clips together that ought to be connected? +
|
|||
We could create groups that are directly editable, like so:
|
||||
|
||||
.Compound clips
|
||||
image::{imgg}/wouter/v3-03-grouped-1.png[width="100%", alt="Timeline with compound clips"]
|
||||
image::{imgg}/wouter/03-grouped-1.png[width="100%", alt="Timeline with compound clips"]
|
||||
|
||||
However, there are a few problems with this: we expect rendering to happen from top to bottom, in
|
||||
which case the b-roll would cover the subtitles. On top of that, it's hard to see at which points video
|
||||
|
|
@ -666,7 +327,7 @@ clips overlap. Last but not least: it looks rather unorganised.
|
|||
Can we restructure this? Perhaps like this:
|
||||
|
||||
.Overlapping compound clips
|
||||
image::{imgg}/wouter/v3-03-grouped-2.png[width="100%", alt="Timeline with stacked overlapping compound clips"]
|
||||
image::{imgg}/wouter/03-grouped-2.png[width="100%", alt="Timeline with stacked overlapping compound clips"]
|
||||
|
||||
But how exactly would a user interact with a timeline like this? I will leave the answer to that
|
||||
question for an actual design document, as for now I just wanted to show the concept of grouping so
|
||||
|
|
@ -693,7 +354,7 @@ FCP's precision editor. It doesn't change the working of keyboard shortcuts or t
|
|||
alters the timeline via animations in a very fluid way.
|
||||
|
||||
.Final Cut Pro's precision editor
|
||||
image::{imgg}/wouter/v3-04-fcp-precision-editor.jpg[precision editor]
|
||||
image::{imgg}/wouter/04-fcp-precision-editor.jpg[precision editor]
|
||||
|
||||
Another example is the Trim View in DaVinci Resolve: whenever you perform a trimming
|
||||
operation, the program monitor displays a trim view (showing the frames left and right of the cut
|
||||
|
|
@ -725,7 +386,7 @@ the use of a _contextual bar_ that appears over the bottom part of the timeline
|
|||
mode is active.
|
||||
|
||||
.Contextual bar with options for the mode/tool
|
||||
image::{imgg}/wouter/v3-05-contextual-bar.png[width="100%", alt="contextual bar"]
|
||||
image::{imgg}/wouter/05-contextual-bar.png[width="100%", alt="contextual bar"]
|
||||
|
||||
Currently I'm thinking of using this bar on two or three occasions:
|
||||
|
||||
|
|
@ -806,10 +467,10 @@ One last thing I would like to address is the destruction that an insert operati
|
|||
this can be prevented by proper track management, but you can wonder why you would ever want
|
||||
an insert action to cause the following:
|
||||
|
||||
image::{imgg}/wouter/v3-06-sync-insert-1.png[height=110, alt="sync insert"]
|
||||
image::{imgg}/wouter/06-sync-insert-1.png[height=110, alt="sync insert"]
|
||||
|
||||
.Inserting a clip with sync locks enabled for V2 might split a clip in Avid Media Composer.
|
||||
image::{imgg}/wouter/v3-06-sync-insert-2.png[height=110, alt="sync insert"]
|
||||
image::{imgg}/wouter/06-sync-insert-2.png[height=110, alt="sync insert"]
|
||||
|
||||
In this case, if you'd like the clips on V2 to stay in sync, the overlapping clip will be split in two.
|
||||
If you don't want this to happen you would have to move the overlapping clip to another track
|
||||
|
|
@ -961,7 +622,7 @@ will move both the viewport and playhead. Clicking the left mouse button will ac
|
|||
position and close the widget.
|
||||
+
|
||||
.Skim widget
|
||||
image::{imgg}/wouter/v3-07-1-skim.png[width="100%", alt="A skim widget rendered as overlay"]
|
||||
image::{imgg}/wouter/07-1-skim.png[width="100%", alt="A skim widget rendered as overlay"]
|
||||
|
||||
|
||||
Autoscroll widget:: when the user moves the mouse cursor slightly left or right, it will enter zones
|
||||
|
|
@ -970,14 +631,14 @@ When the user moves the mouse farther away from the initial starting point, the
|
|||
increase. This will also work vertically. The playhead will move along as well.
|
||||
+
|
||||
.Autoscroll widget
|
||||
image::{imgg}/wouter/v3-07-2-autoscroll.png[width="100%", alt="A widget for auto-scrolling"]
|
||||
image::{imgg}/wouter/07-2-autoscroll.png[width="100%", alt="A widget for auto-scrolling"]
|
||||
|
||||
|
||||
Zoom widget:: moving the mouse left or right from the centre will zoom horizontally, up and
|
||||
down will zoom vertically.
|
||||
+
|
||||
.Zoom widget
|
||||
image::{imgg}/wouter/v3-07-3-zoom.png[width="100%", alt="An overlay widget to control zooming"]
|
||||
image::{imgg}/wouter/07-3-zoom.png[width="100%", alt="An overlay widget to control zooming"]
|
||||
|
||||
Mouse-only navigation:
|
||||
|
||||
|
|
@ -987,7 +648,7 @@ mouse button. When released, it will commit to the new location/view. If a user
|
|||
immediately releases the button, a regular context menu will appear.
|
||||
+
|
||||
.Combined skim, zoom and scroll widget
|
||||
image::{imgg}/wouter/v3-07-4-combined.png[width="100%", alt="Overlay widget to combin skim, zoom and autoscrol function"]
|
||||
image::{imgg}/wouter/07-4-combined.png[width="100%", alt="Overlay widget to combin skim, zoom and autoscrol function"]
|
||||
|
||||
|
||||
Why popup widgets?
|
||||
|
|
@ -1047,7 +708,7 @@ what any other NLE does at the moment, but enabling multi-clip selection by keyb
|
|||
good reason to go in this direction.
|
||||
|
||||
.Selection mockup: selected clips are highlighted in yellow, the cursor is a white dot.
|
||||
image::{imgg}/wouter/v3-08-selection.png[width="100%", alt="selecting clips"]
|
||||
image::{imgg}/wouter/08-selection.png[width="100%", alt="selecting clips"]
|
||||
|
||||
For selecting, we can introduce an ``add to selection'' key which adds the highlighted clip to the
|
||||
current selection (apart from the convention of using Ctrl+mouse click). We could also think of
|
||||
|
|
@ -1062,10 +723,10 @@ Most NLE's have functions for selecting many clips at once, called ``select forw
|
|||
backward''. In Adobe Premiere these are tools: click and you select all clips to either the left or right
|
||||
of the mouse cursor, and using Shift will toggle between selecting all clips on a single track or on
|
||||
all tracks (it doesn't respect track activation status though, which it should). Other NLE's (Resolve,
|
||||
Avid, Lightworks) have keyboard shortcuts for these functions (in Avid you can place a button in the
|
||||
GUI as well), which do affect activated tracks only. This is a bit faster: in Premiere you need to
|
||||
switch to the Select Forward/Backward Tool, make your selection, then switch back to your previous
|
||||
tool. With a keyboard shortcut you only have to press a single key (if your track selection is correct).
|
||||
Avid, Lightworks) only have keyboard shortcuts for these functions, which do only affect activated
|
||||
tracks. This is a bit faster: in Premiere you need to switch to the Select Forward/Backward Tool,
|
||||
make your selection, then switch back to your previous tool. With a keyboard shortcut you only
|
||||
have to press a single key (if your track selection is correct).
|
||||
|
||||
Arranging clips
|
||||
~~~~~~~~~~~~~~~
|
||||
|
|
@ -1128,7 +789,7 @@ entering trim mode.
|
|||
* Lightworks has a trim mode that defaults to ripple trimming, unless you specifically use the
|
||||
“drag to black” feature by Control-clicking trim edges when entering trim mode. When
|
||||
using the keyboard, one needs to mark a section and use the Remove command (similar to
|
||||
Avid's ``lift'') to create a gap.
|
||||
Avid''s ``lift'') to create a gap.
|
||||
|
||||
Next to ripple/non-ripple trimming there are three other edit operations closely related to trimming
|
||||
that need to be mentioned:
|
||||
|
|
@ -1155,10 +816,10 @@ tracks automatically stay in sync. This means (manually) enabling or disabling t
|
|||
track. Once set, trimming a single clip can be enough to have all tracks move along, although you
|
||||
might still need to manually select trim sides for overlapping clips to get the desired result.
|
||||
|
||||
image::{imgg}/wouter/v3-09-sync-trim-1.png[height=140, alt="trimming with sync-lock(before)"]
|
||||
image::{imgg}/wouter/09-sync-trim-1.png[height=140, alt="trimming with sync-lock(before)"]
|
||||
|
||||
.Avid's sync locks will split longer clips by default, in order to keep sync. Such destructive behaviour should be avoided in Lumiera.
|
||||
image::{imgg}/wouter/v3-09-sync-trim-2.png[height=140, alt="trimming with sync-lock(after)"]
|
||||
image::{imgg}/wouter/09-sync-trim-2.png[height=140, alt="trimming with sync-lock(after)"]
|
||||
|
||||
Without sync locks you will have to select trim sides on every track that needs to stay in sync,
|
||||
although, as we'll see, even that can be accomplished by a single keystroke. FCP is the exception
|
||||
|
|
@ -1189,7 +850,7 @@ These commands can be combined: when pressing multiple keys, new trim sides are
|
|||
selection. This allows for quickly selecting many trim sides on many tracks.
|
||||
|
||||
.One keystroke led to the selection of these four trim sides in Lightworks
|
||||
image::{imgg}/wouter/v3-10-trim-side.png["select trim side"]
|
||||
image::{imgg}/wouter/10-trim-side.png["select trim side"]
|
||||
|
||||
Another feature that was already mentioned in a previous chapter, is FCP's precision editor, which
|
||||
can be triggered by double clicking a cut or by keyboard shortcut. This shows how much footage
|
||||
|
|
@ -1276,7 +937,7 @@ exited automatically whenever the user clicks in an empty spot of the timeline o
|
|||
mode key (T). This key can also be used to return to the last-used trim configuration.
|
||||
|
||||
.Mockup of the trim mode. The striped area marks the pre- and post-roll that will be previewed.
|
||||
image::{imgg}/wouter/v3-11-trim-mode.png[width="100%", alt="using trim mode"]
|
||||
image::{imgg}/wouter/11-trim-mode.png[width="100%", alt="using trim mode"]
|
||||
|
||||
|
||||
Splitting and merging clips
|
||||
|
|
@ -1312,7 +973,7 @@ I would like to propose the ability to divide a timeline into multiple sections.
|
|||
will have a header in the ruler that can be edited, to give each section a name (similar to how
|
||||
duration markers in Premiere are displayed).
|
||||
|
||||
image::{imgg}/wouter/v3-12-sections.png[width="100%", alt="Timeline with sections"]
|
||||
image::{imgg}/wouter/12-sections.png[width="100%", alt="Timeline with sections"]
|
||||
|
||||
The benefits of sections:
|
||||
|
||||
|
|
@ -1369,7 +1030,7 @@ transition from a clip's start or end to the position of the playhead.
|
|||
|
||||
* Avid has a configuration panel for adding transitions:
|
||||
|
||||
image::{imgg}/wouter/v3-13-transition.png[align="center", alt="transition properties"]
|
||||
image::{imgg}/wouter/13-transition.png[align="center", alt="transition properties"]
|
||||
|
||||
* Some apps allow adding transitions to every cut in the in-out range (Avid, Lightworks). Avid
|
||||
gives you the option to skip cuts that already have a transition. Very useful for adding short
|
||||
|
|
@ -1439,12 +1100,6 @@ Chapter 3: finishing
|
|||
--------------------
|
||||
[red]#To be written.#
|
||||
|
||||
- Nodes vs Layers
|
||||
- Audio mixing
|
||||
- Color grading
|
||||
- Visual effects compositing
|
||||
- Titling
|
||||
|
||||
Chapter 4: a broader GUI concept
|
||||
--------------------------------
|
||||
[red]#To be written.#
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ Current Release
|
|||
[red]#Lumiera is not usable yet#.
|
||||
|
||||
- A »Preview Release« was
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=tag;h=refs/tags/v0.pre.04[published at Dec 2, 2025]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=tag;h=refs/tags/v0.pre.04[published at Dec 2, 2025]
|
||||
|
||||
- link:/debian[DEB packages]
|
||||
were built for »Trixie« and »Noble«
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ Interface Definition Language
|
|||
-----------------------------
|
||||
In his work on the plugin loader, _Cehteh_ created a first draft how to export an interface, and calls for review.
|
||||
An example can be found in
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=tests/backend/test-interfaces.c;h=09fa25afa3cb57b79a2717d0bf3a8253afeba000;hb=ebcc5c7fd2d8700f3375e3309b724ac2517a0f40[tests/backend/test-interfaces.c]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=tests/backend/test-interfaces.c;h=09fa25afa3cb57b79a2717d0bf3a8253afeba000;hb=ebcc5c7fd2d8700f3375e3309b724ac2517a0f40[tests/backend/test-interfaces.c]
|
||||
|
||||
An interface is a list of »slots« mapping functions. The interface descriptor is itself realised as interface,
|
||||
and thus can be versioned, extended and specialised.
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ For now the focus is on getting a single frame into the gui and there will be ti
|
|||
|
||||
The devs agreed to meet up on Saturday to get the latest version up and running.
|
||||
|
||||
NOTE: Demonstration in https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=src/common/guifacade.cpp;h=60a16d0f67bd95b43e44662daa9c0525235e14f5;hb=5f10e65852de2c51364c2e2a5a1cf29cae81c6b2#l64[guifacade.cpp]
|
||||
NOTE: Demonstration in https://git.lumiera.org/?p=LUMIERA;a=blob;f=src/common/guifacade.cpp;h=60a16d0f67bd95b43e44662daa9c0525235e14f5;hb=5f10e65852de2c51364c2e2a5a1cf29cae81c6b2#l64[guifacade.cpp]
|
||||
|
||||
(The thread shall be forked from within the GUI code not from the facade)
|
||||
This was discussed and ichthyo has already pushed a new cleaned up state and resolved most of the dependency problems with the liblumiera. It raised the question: do we prefer a UI facade to a GUI facade or do we want an extra script facade someday?
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ don't think we get much program options, maybe something to set a GUI skin.
|
|||
Moreover, I've written last year a thin wrapper around the commandline and
|
||||
integrated it with the boost options parser such that user code can receive the
|
||||
remaining options as a vector of `std::string`s. Please have a look at
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=tests/common/mainsuite.cpp;h=455bfd98effd0b7dbe6597f712a1bdfa35232308;hb=80e1e382f42512ebf2e10a802f77e50327b8fb73[the test class runner main]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=tests/common/mainsuite.cpp;h=455bfd98effd0b7dbe6597f712a1bdfa35232308;hb=80e1e382f42512ebf2e10a802f77e50327b8fb73[the test class runner main]
|
||||
for an usage example. I really want our Lumiera main to be clean and expressive
|
||||
in the way showed there. Probably the most important part of the startup is
|
||||
pulling up the session core; because of that I think most of the startup
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ This proposal intends to capture envisioned Architecture of the Application.
|
|||
image:{ldoc}/devel/draw/rendered/Lumi.Architecture-1.png[Overview of Lumiera Architecture]
|
||||
|
||||
^The SVG source of this drawing is
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-1.svg;hb=HEAD[maintained in GIT(2008)]·
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=HEAD[(current: 2022)]^
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-1.svg;hb=HEAD[maintained in GIT(2008)]·
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=HEAD[(current: 2022)]^
|
||||
|
||||
|
||||
Description
|
||||
|
|
@ -75,7 +75,7 @@ Conclusion
|
|||
----------
|
||||
Accepted. The drawing was moved into the GIT tree. +
|
||||
It was upgraded and reworked
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=0b9f2e2c3139cad542013caac593cb5972a2e3f6[in 2022]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob_plain;f=doc/devel/draw/Lumi.Architecture-2.svg;hb=0b9f2e2c3139cad542013caac593cb5972a2e3f6[in 2022]
|
||||
|
||||
|
||||
Back to link:/x/DesignProcess.html[Lumiera Design Process overview]
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ details of carrying out the operations are much more involved.
|
|||
Please see the
|
||||
link/wiki/renderengine.html#Rendering[Development internal doc (TiddlyWiki)]
|
||||
and the
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=src/proc/engine/procnode.hpp;h=9cf3a2ea8c33091d0ee992ec0fc8f37bb5874d34;hb=f9452f654cf39a4abbbeecfd81bef51aa347b321[Draft: ProcNode (src)]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=src/proc/engine/procnode.hpp;h=9cf3a2ea8c33091d0ee992ec0fc8f37bb5874d34;hb=f9452f654cf39a4abbbeecfd81bef51aa347b321[Draft: ProcNode (src)]
|
||||
for details
|
||||
(and/or contact Ichthyo for in-depth discussion of those technical details)
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ We soon settled upon the following toolchain, which is used up to today:
|
|||
history is consolidated eventually into the
|
||||
link:{rfc}/MasterRepositorySetup.html#historical_remark[»official Lumiera repository«],
|
||||
which is made accessible at
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[`git://git.lumiera.org/LUMIERA`]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=summary[`git://git.lumiera.org/LUMIERA`]
|
||||
- We never used link:{rfc}/GitSubmoduleTransistion.html#_comments[Git submodules]...
|
||||
- https://www.scons.org/[SCons] became the primary buildsystem soon,
|
||||
with Autotools discontinued in 2011
|
||||
|
|
@ -158,14 +158,14 @@ We soon settled upon the following toolchain, which is used up to today:
|
|||
- Website and documentation pages are generated by
|
||||
https://asciidoc-py.github.io/[Asciidoc], with source files for
|
||||
documentation maintained
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=doc/index.txt;h=9bc0f11e6fb67588388e7616320b695841571278;hb=20f3252892d5b53a05ecd8aeb571122806baba17[in-tree],
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=doc/index.txt;h=9bc0f11e6fb67588388e7616320b695841571278;hb=20f3252892d5b53a05ecd8aeb571122806baba17[in-tree],
|
||||
published
|
||||
https://git.lumiera.org/gitweb?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[automatically on push].
|
||||
https://git.lumiera.org/?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[automatically on push].
|
||||
- A https://classic.tiddlywiki.com/[TiddlyWiki] is used for development notes
|
||||
- for Unit-Tests, we use our own minimalist
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=src/lib/test/run.hpp;h=035633af9bde7a8053bcd304baffc21693dcf031;hb=20f3252892d5b53a05ecd8aeb571122806baba17[Test-runner].
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=src/lib/test/run.hpp;h=035633af9bde7a8053bcd304baffc21693dcf031;hb=20f3252892d5b53a05ecd8aeb571122806baba17[Test-runner].
|
||||
and a
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=tests/test.sh;h=8c13810eb475bbacd97c528607e6750f47bb145e;hb=20f3252892d5b53a05ecd8aeb571122806baba17[shell script]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=tests/test.sh;h=8c13810eb475bbacd97c528607e6750f47bb145e;hb=20f3252892d5b53a05ecd8aeb571122806baba17[shell script]
|
||||
to support definition of test collections.
|
||||
- A Debian package is maintained with
|
||||
https://wiki.debian.org/PackagingWithGit[git-buildpackage] and published
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ rather -- a task no one was willing to take on.
|
|||
|
||||
Yet the Lumiera project succeeded in building a web presence based on
|
||||
https://asciidoc-py.github.io/[Asciidoc] sources
|
||||
https://git.lumiera.org/gitweb?p=website;a=summary[checked into Git],
|
||||
https://git.lumiera.org/?p=website;a=summary[checked into Git],
|
||||
with a lightweight
|
||||
https://git.lumiera.org/gitweb?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[commit-hook script]
|
||||
https://git.lumiera.org/?p=website;a=blob;f=build_website.sh;h=60b90e18d5732d66566baf2c20a217212a5dcece;hb=aefc91e13a95a3c742dc8143c374ec982e0aa56b[commit-hook script]
|
||||
to automatically publish any changes on git-push -- a scheme
|
||||
which comes close to the gist of this RfC.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ This describes how the shared MASTER is set up and syncronized.
|
|||
Description
|
||||
~~~~~~~~~~~
|
||||
We have now a shared master repository in
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[/git/LUMIERA].
|
||||
https://git.lumiera.org/?p=LUMIERA;a=summary[/git/LUMIERA].
|
||||
|
||||
- The public/anonymous git url is [yellow-background]#`git://git.lumiera.org/LUMIERA`#
|
||||
- for people with ssh access it is pushable at [purple]#`UID@git.lumiera.org:/git/LUMIERA`#.
|
||||
|
|
@ -71,10 +71,10 @@ That being said -- the shared master at [yellow-background]#`git://git.lumiera.o
|
|||
still contains the _official_ state of the Lumiera codebase, while
|
||||
actual development is published first in a repository per developer
|
||||
(so effectively in
|
||||
https://git.lumiera.org/gitweb?p=lumiera/ichthyo;a=summary[the Ichthyo repository]
|
||||
https://git.lumiera.org/?p=lumiera/ichthyo;a=summary[the Ichthyo repository]
|
||||
for the time being);
|
||||
development is consolidated intermittently into the
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[LUMIERA Git].
|
||||
https://git.lumiera.org/?p=LUMIERA;a=summary[LUMIERA Git].
|
||||
|
||||
|
||||
''''
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Propose a documentation/planning about the setup.
|
|||
Description
|
||||
~~~~~~~~~~~
|
||||
Take a look at my draft at:
|
||||
https://git.lumiera.org/gitweb?p=LUMIERA;a=blob;f=doc/devel/nobug_flags.txt;h=325141acb52a7be7f75425359b6057c74ed30253;hb=a03e3c5e73a4c0be2264ac4e4e0f02eb8749837b[nobug_flags.txt]
|
||||
https://git.lumiera.org/?p=LUMIERA;a=blob;f=doc/devel/nobug_flags.txt;h=325141acb52a7be7f75425359b6057c74ed30253;hb=a03e3c5e73a4c0be2264ac4e4e0f02eb8749837b[nobug_flags.txt]
|
||||
|
||||
I've added the things I planning for the backend, others might add their own
|
||||
plans there too. So far this is an early draft, comments welcome.
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ during this effort leads to the following refinements:
|
|||
- Workers manage their capacity through a statistical distribution of _sleep times._
|
||||
|
||||
In this form, the proposal can be considered as implemented. +
|
||||
^(see -> https://git.lumiera.org/gitweb?p=LUMIERA;a=commit;h=d71eb37[d71eb37]
|
||||
^(see -> https://git.lumiera.org/?p=LUMIERA;a=commit;h=d71eb37[d71eb37]
|
||||
and https://issues.lumiera.org/ticket/1344[#1344])^
|
||||
|
||||
Ichthyostega:: '2024-04-20 01:55 CEST'
|
||||
|
|
|
|||
|
|
@ -49,4 +49,6 @@ On occasion, we'll replace them by drawings from our current UML model.
|
|||
128517: classdiagram 142725 "Time flavours"
|
||||
133637: classdiagram 143877 "Player Entities"
|
||||
133637: objectdiagram 144005 "Play Process Structure"
|
||||
133637: sequencediagram 145157 "output data exchange"
|
||||
133637: classdiagram 151685 "Player Output"
|
||||
128773: classdiagram 158213 "UIBus"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 256 KiB |
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 83 KiB |
BIN
doc/devel/uml/fig145157.png
Normal file
BIN
doc/devel/uml/fig145157.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
doc/devel/uml/fig151685.png
Normal file
BIN
doc/devel/uml/fig151685.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
Documentation
|
||||
=============
|
||||
|
||||
This documentation section contains documentation for users and developers alike.
|
||||
This documentation section contains documentation for both users and developers.
|
||||
|
||||
== User ==
|
||||
|
||||
|
|
@ -60,8 +60,8 @@ deeper documentation dungeons.
|
|||
|
||||
At the second layer, the reader must make the first major decision on which
|
||||
router to pursue: documentation with a heavy code based leaning; or more descriptive
|
||||
documentation on the design of Lumiera, which omits most technical details of the implementation.
|
||||
Consequently, the documentation is divided into two main parts:
|
||||
documentation on the design of Lumiera which avoids a code narrative. This
|
||||
section has two main sections:
|
||||
|
||||
* link:design/index.html[Lumiera Developer Design Documents]
|
||||
* link:technical/index.html[Lumiera Developer Technical Documents]
|
||||
|
|
@ -75,14 +75,14 @@ Consequently, the documentation is divided into two main parts:
|
|||
|
||||
[width="90%",frame="topbot",options="header",cols="^,2<"]
|
||||
|================================================================================================
|
||||
|Section|Remarks
|
||||
|Sub-System|Remarks
|
||||
|link:design/architecture/[Architecture]|Structure of Lumiera
|
||||
|link:design/gui/[GUI]|The Lumiera ⟷ user interaction layer
|
||||
|link:design/model/[Model]|Low-level and high-level models
|
||||
|link:design/engine/[Engine]|Renderer, output generation, ...
|
||||
|link:design/lowlevel/[Low-level]|Low-level and system services
|
||||
|link:design/application/[Application]|Application framework
|
||||
|link:design/extension/[Extension]|Dynamically loaded Extensions
|
||||
|link:design/plugins/[Plugins]|Dynamically loaded Extensions
|
||||
|link:design/workflow/[Workflow]|Workflow and Interaction Design
|
||||
|link:design/governance/[Governance]|Meta project concerns
|
||||
|================================================================================================
|
||||
|
|
@ -93,12 +93,12 @@ Consequently, the documentation is divided into two main parts:
|
|||
|
||||
[width="90%",frame="topbot",options="header",cols="^,2<"]
|
||||
|================================================================================================
|
||||
|Section|Remarks
|
||||
|Sub-System|Remarks
|
||||
|link:technical/build/[Build System]|Build, Packaging and CI
|
||||
|link:technical/stage/[Stage]|GUI (technical aspects)
|
||||
|link:technical/steam/[Steam]|Session and processing coordination
|
||||
|link:technical/vault/[Vault]|Low-level operations
|
||||
|link:technical/library/[Library]|Utilities and custom frameworks
|
||||
|link:technical/library/[Support lib]|Interface and support libraries
|
||||
|link:technical/code/[Code base]|Code management, organisation, ...
|
||||
|link:technical/infra/[Infrastructure]|Website and developer tooling ...
|
||||
|link:technical/howto/[Developer HowTos]|Instructions and guides for developers
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ Lumiera expects a ``standard'' desktop installation running a XServer.footnote:[
|
|||
Wayland is ``just around the corner'' since 10 years now. Well, recently it
|
||||
seems it is _really_ just around the corner. We are aware of the necessary
|
||||
changes, which are not very complicated to implement (since we are using
|
||||
GTK-3). However, as long as Wayland simply crashes or hangs in our
|
||||
GTK-3). However, as long as Wayland simply crashes or hands in our
|
||||
everyday work setup with XFCE, we will not consider this topic
|
||||
a priority. In the meantime, please report any problems
|
||||
you encounter with Lumiera running on XWayland.
|
||||
|
|
@ -97,8 +97,7 @@ Languages and Tools
|
|||
|
||||
* BOOST (listed below are the Debian package names)
|
||||
- libboost-dev (at least *1.83*)
|
||||
- notably including `boost::lockfree`
|
||||
- libboost-program-options-dev (link dependency)
|
||||
- libboost-program-options-dev
|
||||
|
||||
* Script languages
|
||||
- Python (*3.10*) required for building (->SCons)
|
||||
|
|
@ -124,7 +123,7 @@ Build Tools
|
|||
* pkg-config
|
||||
* Doxygen (optional)
|
||||
* Asciidoc (optional)
|
||||
* Git -> https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[git://git.lumiera.org/LUMIERA]
|
||||
* Git -> https://git.lumiera.org/?p=LUMIERA;a=summary[git://git.lumiera.org/LUMIERA]
|
||||
footnote:[
|
||||
_Ichthyo_ maintains a repo at https://github.com/Ichthyostega/Lumiera/[Github ^~Ichthyostega/Lumiera^]
|
||||
]
|
||||
|
|
@ -161,9 +160,9 @@ Libraries
|
|||
which is possible, but would require some considerable effort. As of 2025, GDL is still usable,
|
||||
but no longer available through the standard distribution channels. +
|
||||
We provide a Git repository at our Website for
|
||||
https://git.lumiera.org/gitweb?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
|
||||
https://git.lumiera.org/?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
|
||||
and the
|
||||
https://git.lumiera.org/gitweb?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+]
|
||||
https://git.lumiera.org/?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+]
|
||||
and we maintain custom Debian packages for both in our
|
||||
link:/debian/[Debian DEB depot].
|
||||
]
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ How the Lumiera Debian package works
|
|||
Since we maintain both the Debian package and our build system, we can always try to do
|
||||
_the heavy lifting_ in our link:{ldoc}/technical/build/SCons.html[SCons build system],
|
||||
as this helps to keep the Debian packaging as simple as possible. Please have a look at the
|
||||
-> https://git.lumiera.org/gitweb?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/control[control file]
|
||||
· https://git.lumiera.org/gitweb?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/rules[debian/rules]
|
||||
-> https://git.lumiera.org/?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/control[control file]
|
||||
· https://git.lumiera.org/?p=debian/lumiera;a=blob;hb=refs/heads/deb;f=debian/rules[debian/rules]
|
||||
|
||||
- we rely on the _Debhelper Sequencer_ "`dh_*`" in our 'debian/rules' +
|
||||
-> https://manpages.debian.org/trixie/debhelper/dh.1.en.html[Manpage]
|
||||
|
|
@ -106,7 +106,7 @@ into `master` and marked with a tag there.
|
|||
For the actual packaging, we use these release tags as _upstream tag_ and perform a merge
|
||||
from that tag into the **debian branch**.footnote:[
|
||||
This _debian branch_ is called `deb` by convention. As mentioned above, it is published through
|
||||
a separate https://git.lumiera.org/gitweb?p=debian/lumiera;a=summary[Git repository `git://git.lumiera.org/debian/lumiera`],
|
||||
a separate https://git.lumiera.org/?p=debian/lumiera;a=summary[Git repository `git://git.lumiera.org/debian/lumiera`],
|
||||
which is kept separate, since packaging is considered a ``downstream process''.
|
||||
]
|
||||
This branch carries only the additions and tweaks done for debian packaging. Yet still, this `deb`
|
||||
|
|
@ -115,7 +115,7 @@ repository as the `master` branch. When the packaging process is complete, the p
|
|||
DEB version is marked with a tag `debian/<full_debian_version_spec>`
|
||||
|
||||
Note however that there is another branch in the aforementioned `debian/lumiera` repository,
|
||||
which is called https://git.lumiera.org/gitweb?p=debian/lumiera;a=shortlog;h=refs/heads/depot[depot]
|
||||
which is called https://git.lumiera.org/?p=debian/lumiera;a=shortlog;h=refs/heads/depot[depot]
|
||||
and is related to our link:/debian[DEB package depot] on Lumiera.org. This branch carries a completely
|
||||
different directory structure, since it is used with the
|
||||
https://wiki.debian.org/DebianRepository/SetupWithReprepro[»reprepro« tool from Debian]
|
||||
|
|
|
|||
|
|
@ -352,6 +352,6 @@ shared object (dynamic library), which is then again a SCons target
|
|||
and can be passed to other executable builders as library dependency
|
||||
for compilation and linking. Look into 'src/SConscript' or 'test/SConscript'
|
||||
to see examples of that technique -- which we also use to define that
|
||||
global compound target variables like `core`, `vessel_lib`, `core_lib`,
|
||||
global compound target variables like `core`, `app_lib`, `core_lib`,
|
||||
`vault_lib`, and `support_lib`. These in turn are essential for
|
||||
building the layered dependency hierarchy in our code.
|
||||
|
|
|
|||
|
|
@ -322,8 +322,8 @@ actively step by step
|
|||
modules of the application will be placed by default
|
||||
|
||||
. after the core application has been loaded and all direct dependencies are resolved,
|
||||
but still before entering `main()`, the class `vessel::Voyage` will be initialised,
|
||||
which in turn holds a member of type `vessel::BasicSetup`. The latter will figure out
|
||||
but still before entering `main()`, the class `lumiera::AppState` will be initialised,
|
||||
which in turn holds a member of type `lumiera::BasicSetup`. The latter will figure out
|
||||
the location of the executable footnote:[this is a Linux-only trick, using `/proc/self/exe`]
|
||||
and require a 'setup.ini' file in the same directory. This setup file is mandatory.
|
||||
|
||||
|
|
|
|||
|
|
@ -88,33 +88,6 @@ test with random numbers::
|
|||
several threads; each thread should use its own generator then (yet this can be handled sloppy if
|
||||
the _quality_ of the random number actually does not matter!)
|
||||
|
||||
special test setup::
|
||||
It can be very helpful to use _policy based design_ for some complex evaluation or algorithm,
|
||||
even in cases where it is clear that the actual usage will only ever involve one specific data type
|
||||
and configuration. Not only does such a structured approach help with clarifying the design itself,
|
||||
since the core of the evaluation logic can be abstracted from data representation -- yet also the
|
||||
testing and verification of correctness is simplified, as the test can be written to use simple,
|
||||
human-readable data (strings, symbols), and, furthermore, many kinds of instrumentation can be
|
||||
included into the test data to gain detailed insight what is happening in the test subject.
|
||||
|
||||
verify behaviour sequence::
|
||||
Use the `lib::EventLog`:
|
||||
+
|
||||
- within the test, notable points are marked into the log, possibly with arguments
|
||||
- after the test, the Event Log can be verified with a search-sequence
|
||||
- this way it is possible to ensure that some events did happen, and happened
|
||||
in a very specific order, or that some event did _not_ happen after another event
|
||||
- the `test::Tracker` defined in 'src/test/tracking-dummy.hpp' will mark all constructor,
|
||||
destructor and copy events into an embedded Event Log instance. By inheriting or mix-in
|
||||
from that type, the allocation and instance behaviour of some service can be scrutinised.
|
||||
|
||||
verify incidences and concurrency::
|
||||
Aside from using some generic tracing utility, sometimes it is much easier to setup
|
||||
a _specifically tailored instrumentation_. This can be achieved with 'incidence-count.hpp'
|
||||
+
|
||||
- for instrumentation, the `markEnter()` and `markLeave()` functions need to be invoked
|
||||
- after the test run, various statistics can be computed and evaluated, including
|
||||
cumulated time and concurrency for the "cases" marked with enter / leave.
|
||||
|
||||
|
||||
Common Tasks
|
||||
|
|
@ -136,12 +109,6 @@ structured data::
|
|||
- also useful as output format, both for debugging and because it can be matched against
|
||||
an expected structure, which is generated with the DSL notation.
|
||||
- [yellow-background]#(planned)# will be able to map this from/to JSON easily.
|
||||
scoped collection::
|
||||
unique-ownership collection that holds a sequence of objects in a preallocated fixed
|
||||
storage block. Notably even non-copyable objects can be managed (which is not possible
|
||||
with a `std::vector`), and type-erased instances of subclasses can be mixed. Furthermore
|
||||
there is a constructor variant that allows to populate a `ScopedCollection` in RAII-style.
|
||||
This can e.g. be used to fire-off a set of Threads or open a set of wrapped connections.
|
||||
|
||||
Iterating
|
||||
~~~~~~~~~
|
||||
|
|
@ -167,26 +134,6 @@ IterSource::
|
|||
even the production-state can be hooked up into the IterSource instance (with a smart-ptr).
|
||||
This allows e.g. to send a Diff to the UI through the UI-Bus, while the actual generation
|
||||
and application both happen demand-driven or _lazy..._
|
||||
State Core::
|
||||
When some algorithm involves a statefull evaluation, it might be helpful to package that into
|
||||
a _State Core_ container. This is a class that is expected to expose three operations, which
|
||||
allow to build an iteration on top. The header 'iter-adapter.hpp' provides several adapters
|
||||
and wrappers, notable `lib::IterStateWrapper` wraps any _state core_ and provides a
|
||||
Lumiera Iterator interface; likewise, `IterExplorer` heavily relies on that concept and
|
||||
is able to accept and iterate any state core in a pipeline.
|
||||
special iterators::
|
||||
Some additional adaptors are provided as building block so that specific evaluations
|
||||
can be made to conform with the »Lumiera Iterator« concept
|
||||
+
|
||||
- several given iterators can be combined into a iteration over tuples with 'lib/iter-zip.hpp'
|
||||
- there is also a variation 'lib::izip' that adds a running index into the _zipping operation_
|
||||
- IterExplorer provides a `flatten()` operation, that can be used to join an iterator-of-iterators
|
||||
into a single seamless iteration lazily.
|
||||
- when a STL container also supports _backwards iteration_, then a lumiera iterator can be
|
||||
created that can _switch direction_ dynamically, with the help of 'iter-cursor.hpp'
|
||||
- a STL »deque« container can be used both as a stack and a queue; the header 'iter-stack.hpp'
|
||||
provides an iteration adapter for both usage schemes, so that either the stack or the queue
|
||||
can be _"discharged"_ as a Lumiera Iterator (possibly with an IterExplorer pipeline)
|
||||
|
||||
|
||||
Formatting
|
||||
|
|
@ -208,25 +155,6 @@ Formatting
|
|||
because there are way more capable solutions _out there_ ☺)
|
||||
|
||||
|
||||
Setup and wiring
|
||||
~~~~~~~~~~~~~~~~
|
||||
Generally speaking, we prefer _constructor wiring_ whenever possible, to avoid creating
|
||||
unnecessary statefulness (as would be the case when connecting dependencies through setters).
|
||||
This design also favours decomposition into self-contained components with a single purpose,
|
||||
and simplifies error handling with the help of the RAII pattern.
|
||||
|
||||
However, sometimes a piece of code depends on some remote and even global service; in these
|
||||
cases, the `lib::Depend` framework can be used to access that service via type name. The
|
||||
actual service can either be created on-demand as a singleton, or it can be installed
|
||||
explicitly as a service instance. Furthermore, it is possible to "push aside" the
|
||||
current service instance temporarily and replace it by a _test mock_.
|
||||
|
||||
One point to note is that `lib::Depend` is a _monostate_, and not a _singleton_.
|
||||
The actual service should be written as a free-standing class, that can be instantiated
|
||||
directly for the purpose of testing.
|
||||
|
||||
|
||||
|
||||
Language constructs
|
||||
-------------------
|
||||
Templates
|
||||
|
|
@ -307,14 +235,4 @@ unpack iterator into tuple::
|
|||
- see tuple-record-init-test.cpp
|
||||
- used in 'command-simple-closure.hpp' to receive parameter values sent via UI-Bus and package them
|
||||
into a tuple for invocation of a Steam-Layer command.
|
||||
+
|
||||
index and iterate over tuple elements::
|
||||
This is another example of bridging the compile-time / runtime barrier, using a trampoline.
|
||||
Obviously such a solution requires that it is somehow possible to define a generic functor / λ that
|
||||
can accept any of the tuple elements. And, in order to build a runtime index access, we additionally
|
||||
need to convert each of the tuple elements into a _common reconciled type_.
|
||||
+
|
||||
- If such a type exists, can be figured out with the help of the `meta::CommonReturn` _metafunction_
|
||||
- `lib::meta::TupleIdxAdaptor` provides the necessary machinery to define a subscript `operator[]`
|
||||
- see `TupleIdxAdaptor_test` for some usage examples, including a runtime iteration...
|
||||
|
||||
|
|
|
|||
|
|
@ -9,34 +9,34 @@ Technical Documentation
|
|||
// Menu : prepend child overview
|
||||
|
||||
|
||||
This documentation section contains technical documentation about Lumiera. +
|
||||
To get an *overview* of all the internals and components, you might want to read
|
||||
This documentation section contains technical documentation about Lumiera. To
|
||||
get an *overview* of all the internals and components, you might want to read
|
||||
link:overview.html[Lumiera the Inner Core]
|
||||
|
||||
== Three Layers
|
||||
|
||||
The technical documentation is divided into three main parts and some supplements,
|
||||
corresponding to the code organisation in three layers. The information here can be
|
||||
very detailed and technical at times, and the topics are organised by individual components.
|
||||
The technical documentation is split in three parts, one for each of the three
|
||||
main layers of Lumiera. You may want to read the
|
||||
link:{ldoc}/design/index.html[Design Documents] first to get an overview of all the
|
||||
components.
|
||||
|
||||
* link:stage/index.html[*Stage Layer*] : Documents related to the GTK based Lumiera GUI
|
||||
* link:steam/index.html[*Steam Layer*] : Documents regarding Session, the models and the engine
|
||||
* link:vault/index.html[*Vault Layer*] : Documents about the data and processing backend
|
||||
|
||||
* link:steam/index.html[*Steam Layer*] : Documents regarding Session, models and the engine structure
|
||||
|
||||
To better understand the underlying concepts, it might be helpful to also consult the
|
||||
link:{ldoc}/design/index.html[Design Documents].
|
||||
* link:vault/index.html[*Vault Layer*] : Documents about the data and processing backend
|
||||
|
||||
|
||||
== Tools
|
||||
|
||||
.Development
|
||||
* link:/doxy/[*Doxygen*] : API documentation of the Lumiera code.
|
||||
* link:/doxy/[*Doxygen* generated documentation] : API documentation of the Lumiera code.
|
||||
* organisation of the link:code/index.html[Code Base] in general
|
||||
* link:/x/CodingGuidelines.html[Coding Style] and further guidelines
|
||||
|
||||
.Building
|
||||
* link:build/index.html[Buildsystem] : Installation and compilation tools, dependencies and packaging.
|
||||
* link:build/index.html[Buildsystem] : Installation & compilation tools, dependencies and packaging.
|
||||
|
||||
.HOWTO
|
||||
* link:/x/DevHowto.html[Developer *HOWTOs*] : Collection of instructions, recipes, hints, misdeeds
|
||||
and confessions and similar helpful resources for developers
|
||||
* link:/x/DevHowto.html[Developer *HOWTOs*] : Collection of instructions, recipes, hints and similar
|
||||
materials intended for developers
|
||||
|
|
|
|||
|
|
@ -8,32 +8,30 @@ NOTE: This page holds content copied from the old "main" TiddlyWiki +
|
|||
It needs to be reworked, formatted and generally brought into line
|
||||
|
||||
********************************************
|
||||
.Lumiera employs test-driven development
|
||||
.Lumiera relies on *test-driven development*
|
||||
This page discusses the overall organisation
|
||||
of test code, and the tools used for
|
||||
running test cases
|
||||
********************************************
|
||||
|
||||
Tests are the only known form of documentation that offers some resilience against
|
||||
getting outdated. Tests help to focus on the usage, instead of engaging in spurious
|
||||
Tests are the only form of documentation, known to provides some resilience against
|
||||
becoming outdated. Tests help to focus on the usage, instead of engaging in spurious
|
||||
implementation details. Developers are highly encouraged to write the tests _before_
|
||||
the actual implementation, or at least alongside and interleaved with expanding the
|
||||
feature set of the actual code.
|
||||
|
||||
There may be exceptions to this rule. Not every single bit needs to be covered by tests.
|
||||
Some features are highly cross-cutting and exceptionally difficult to cover with tests.
|
||||
Test code must not duplicate the logic of implementation code, it should represent an
|
||||
abstracted, outside, logical view of the matter at hand. And sometimes it is the better
|
||||
choice to simply write an abstract specification in understandable language.
|
||||
And sometimes, just an abstract specification is a better choice.
|
||||
|
||||
As a rule of thumb, consider to write test code which is easy to read and understand,
|
||||
_like a narration_ to show off the relevant properties of the test subject.
|
||||
|
||||
|
||||
Test Structure
|
||||
--------------
|
||||
- a *test case* is an executable, expected to run without failure; test code not only invokes
|
||||
a _subject under test_ -- the important part is to _verify_ its behaviour.
|
||||
- a *test case* is an executable, expected to run without failure, and optionally producing
|
||||
some verifiable output
|
||||
- simple test cases may be written as stand-alone application, while the more tightly
|
||||
integrated test cases can be written as classes within the Lumiera application framework.
|
||||
- test cases should use the +CHECK+ macro of NoBug to verify test results, since the normal
|
||||
assertions may be de-configured for optimised release builds.
|
||||
- our test runner script 'test.sh' provides mechanisms to check for expected output
|
||||
|
|
@ -43,13 +41,15 @@ several functions within the same test fixture. This allows to create a ``narrat
|
|||
in the code: first do this, than do that, and now that, and now this should happen...
|
||||
Generally speaking, it is up to the individual test to take care or isolate himself
|
||||
from any _dependencies_. Test code and application code uses the same mechanisms
|
||||
for accessing other components within the application.
|
||||
for accessing other components within the application. Up to now (2014), there
|
||||
was no need for any kind of _dependency injection_, nor did we face any
|
||||
difficulties with tainted state.
|
||||
|
||||
Test classes are organised into a tree closely mirroring the main application source
|
||||
code tree. Large sections of this test tree are linked together into *test libraries*.
|
||||
Some of these are linked against a specific (sub)scope of the application, like e.g.
|
||||
only against the support library, the application framework or the vault. Since we
|
||||
use _strict dependencies_, this linking step will also spot code not placed at the
|
||||
use _strict dependencies_, this linking step will spot code not being placed at the
|
||||
correct scope within the whole system. As a final step, the build system creates a
|
||||
*test runner* application (`target/test-suite`), which links dynamically against _all_
|
||||
the test libraries and thus against all application dependencies.
|
||||
|
|
@ -81,9 +81,9 @@ to help with automating the build and test execution, test code should adhere to
|
|||
- test classes should be placed into a sub namespace +...::test+
|
||||
- specific definitions for a single test case may rely on global variables,
|
||||
but these should live within an anonymous namespace
|
||||
- free standing test executables should be named according to the pattern `test-*`
|
||||
- all test executables should be named according to the pattern +test-*+
|
||||
- all test source code is within the 'tests' subtree
|
||||
- immediately within the 'tests/' directory are the test collection definitions `*.tests`,
|
||||
- immediately within the 'tests/' directory are the test collection definitions +*.tests+,
|
||||
ordered by number prefixes
|
||||
- below are the directories with test cases, to be grouped into the aforementioned test-executables.
|
||||
- we distinguish two ways to write and link tests: _standalone_ and _suite_
|
||||
|
|
@ -107,7 +107,7 @@ See the following
|
|||
.hello-world-test example
|
||||
[source,C]
|
||||
----------------------------------------------------------------
|
||||
#include "test/run.hpp"
|
||||
#include "lib/test/run.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
|
|
|
|||
|
|
@ -18,25 +18,22 @@ The main Website.
|
|||
|
||||
- Data is in '/var/www'. The Website is a git repository.
|
||||
- Configuration is at '/etc/apache2/sites-available/lumiera.conf'
|
||||
- cehteh and ichthyo are responsible for the administration.
|
||||
- cehteh cares for the administration.
|
||||
- To proprose some changes clone the git repository and send a
|
||||
notfication/merge-request to the mailinglist.
|
||||
|
||||
Some directories symlink to other directories (see below).
|
||||
|
||||
|
||||
The »staging site«
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
https://staging.lumiera.org
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Testing repository for the Website. It is configured in Apache
|
||||
to be served from a separate virtual host, with an obvious DNS
|
||||
name (which _must not_ be mentioned in published content!).
|
||||
Web development is done and reviewed here before it gets
|
||||
pushed to the main Website.
|
||||
Testing repository for the Website. Web development is done and
|
||||
reviewed here before it gets pushed to the main Website.
|
||||
|
||||
- Data is in '/var/www-staging'. The Website is a git repository.
|
||||
- Configuration is at '/etc/apache2/sites-available/staging.conf'
|
||||
- cehteh and ichthyo are responsible for the administration.
|
||||
- cehteh cares for the administration.
|
||||
- To proprose some changes clone the git repository and send a
|
||||
notfication/merge-request to the mailinglist.
|
||||
|
||||
|
|
@ -111,113 +108,5 @@ Upload directory where people can rsync data.
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Clone of the lumiera source repository to serve the documentation within.
|
||||
|
||||
/var/local/trac/
|
||||
~~~~~~~~~~~~~~~~
|
||||
This is the configuration root of our https://trac.edgewall.org/[Trac] installation
|
||||
for the Lumiera issue tracker. This is actually a Git repository, since our setup
|
||||
became gradually more elaborate over time. We even have some local tweaks to
|
||||
the CSS styles and the Subtickets-Plugin (Python code).
|
||||
|
||||
- a copy of the Apache configuration is checked in as well
|
||||
- note some scripts in the 'scripts' subdirectory
|
||||
- an export of current Trac resources was dumped into 'static'
|
||||
and is served directly by Apache from there
|
||||
- the actual »Trac-environment« with config and SQLite-DB is in 'trac-env'
|
||||
- all source trees of all essential plug-ins are checked into 'PluginBuild',
|
||||
so that any plugin could be regenerated by `python3 setup.py bdist_egg`
|
||||
- a dump of the TracDB is also checked into that Git
|
||||
|
||||
|
||||
|
||||
Setup and Configuration
|
||||
-----------------------
|
||||
|
||||
- Apache is configured with the `worker'-MPM
|
||||
- Trac runs under WSGI configured with a pool of _multithread daemon processes_
|
||||
|
||||
Load and Calibration
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
As of 1/2026, we employ a simplistic load monitoring based on evaluating the
|
||||
running processes and some server statistics. This is implemented as a bash script,
|
||||
checked in as '/var/local/trac/scripts/collect-server-stats' and configured to run
|
||||
every two minutes (via SystemD timer). The resulting data trail can be found in
|
||||
'/var/log/apache2/loadwatch.csv', with the following columns:
|
||||
|
||||
- Timestamp: ISO UTC min
|
||||
- Sum webserver...
|
||||
* Processes
|
||||
* Threads
|
||||
* overall resident memory (KiB)
|
||||
* factor of overall memory resident
|
||||
- Apache
|
||||
* workload factor
|
||||
* Processes
|
||||
* Threads
|
||||
* resident memory
|
||||
- WSGI-Trac
|
||||
* workload factor
|
||||
* Processes
|
||||
* Threads
|
||||
* resident memory
|
||||
- Server-statistics
|
||||
* ∅ requests per second
|
||||
* ∅ request duration in ms
|
||||
* currently active slots
|
||||
* currently idle workers
|
||||
* scoreboard of slot allocation
|
||||
|
||||
The parameters of the Apache MPM and the WSGI daemon are then tuned such
|
||||
as to make good use of the available memory, while avoiding excess idle workers.
|
||||
|
||||
Anubis
|
||||
~~~~~~
|
||||
https://anubis.techaro.lol/[Anubis] is a service that was discussed controversially
|
||||
in the community this year. It was created by a
|
||||
https://github.com/Xe[Canadian Open-Source programmer] as an immediate stopgap
|
||||
to help protect the _»small internet«_ from the endless storm of requests that
|
||||
flood in from AI companies. It is configured as a gateway proxy, which classifies
|
||||
incoming requests based on request properties and sends suspicious clients first
|
||||
to a JavaScript proof-of-work challenge. After passing Anubis, the client gets
|
||||
a Cookie to prevent further challenges for some limited time.
|
||||
|
||||
Anubis was reported to be very effective for keeping aggressive scraper bots away,
|
||||
yet the bots have adapted already to some degree. So this remains a game of
|
||||
cat and mouse. Our first evaluations however indicate very promising numbers,
|
||||
by keeping out 92% of PageImpressions and UniqueUsers, thereby reducing
|
||||
the traffic deliverey by the Lumiera issue tracker by more than 80%.
|
||||
|
||||
Introducing such an entrance gateway may be seen as an extreme measure;
|
||||
the rationale is that we have reached such a level of threat that generic rate limits
|
||||
would have to be so severe that they practically render those resources useless.
|
||||
Without these protective measures, we would no longer be able to provide Lumiera.org
|
||||
as a free resource to everyone.
|
||||
|
||||
[underline]#Legal stance#: I consider this usage covered by the provisions of GDPR.
|
||||
Setting this cookie is justified by our legitimate interest of keeping the service operational;
|
||||
we evaluate IP data patterns for the sole purpose of detecting abuse of our website,
|
||||
and we state that fact clearly on our GDPR page.
|
||||
|
||||
Setup
|
||||
^^^^^
|
||||
Anubis runs as single-instance SystemD service unit `anubis@lumiera`, with transient
|
||||
storage backend only. It is integrated into the Website as a _gateway_ (reverse proxy).
|
||||
Anubis is configured by a set of rules in https://cel.dev/[Common Excpression Language].
|
||||
The active rule set is configured in '/etc/anubis' and also checked into the
|
||||
xref:_var_local_trac[Trac-Git]. Rules are evaluated according to the _commited-choice_
|
||||
pattern, i.e. the first rule where the guard condition matches will terminate the
|
||||
evaluation and yield a decision. Anubis was installed from a custom DEB package
|
||||
and ships with
|
||||
https://github.com/TecharoHQ/anubis/tree/main/data[a set of rule building blocks],
|
||||
that can be imported from the `(data)` prefix -- which translates into the path
|
||||
'/usr/share/doc/anubis/data'
|
||||
|
||||
TIP: https://anubis.techaro.lol/[Homepage]
|
||||
· https://anubis.techaro.lol/docs/admin/native-install[Installation]
|
||||
· https://anubis.techaro.lol/docs/admin/environments/apache[Apache-setup]
|
||||
· https://github.com/TecharoHQ/anubis[Github]
|
||||
|
||||
As of 1/2026, Anubis protects our
|
||||
https://issues.lumiera.org/timeline[Issue tracker],
|
||||
the https://git.lumiera.org/[Git repository browser] and the
|
||||
https://lumiera.org/doxy/[API-doc] -- which together constitute
|
||||
the majority of pages accessible on the website.
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ Configuration
|
|||
~~~~~~~~~~~~~
|
||||
All the current configuration and the state of the Debian depot index files is tracked
|
||||
in the aforementioned ``debian/lumiera'' Git repository, on a separate branch called
|
||||
https://git.lumiera.org/gitweb?p=debian/lumiera;a=shortlog;h=refs/heads/depot[`depot']
|
||||
https://git.lumiera.org/?p=debian/lumiera;a=shortlog;h=refs/heads/depot[`depot']
|
||||
|
||||
TIP: this is a slightly unconventional setup, insofar the `depot' branch carries
|
||||
a directory tree that is completely separate from the main Lumiera source tree, which
|
||||
|
|
|
|||
|
|
@ -1,70 +1,41 @@
|
|||
Library documentation
|
||||
=====================
|
||||
|
||||
//Menu: label Support Lib
|
||||
|
||||
Alongside with the core Lumiera Application, and as part of ongoing development work,
|
||||
a lot of *Library code* is written. Many of this happens on occasion. Library solutions
|
||||
are frequently ``discovered'', while in the middle of the implementation, driven by the
|
||||
desire to re-use some code structure that was built just recently and in a similar way.
|
||||
|
||||
|
||||
Support Library
|
||||
---------------
|
||||
Over time, a huge and growing number of generic building blocks has been collected.
|
||||
Hoever, not all parts of this collection are equally well maintained and presentable.
|
||||
It happened time and again that some pattern extracted into the library turned out
|
||||
to be rather some kind or ephemeral habit -- maybe even a bad habit in hindsight --
|
||||
and turned into a dead-end eventually. Furthermore, a lot of our library code has
|
||||
been superseded by very similar features of newer language standards.footnote:[
|
||||
It seems like developers working on similar problems tend to have similar ideas
|
||||
to improve productivity. Unfortunately, the solutions resulting from this convergence
|
||||
of ideas have a tendency not to ``converge'' so well in practical terms.
|
||||
For example, Lumiera had a tuple type a long time before a mature tuple implementation
|
||||
was available in the Boost libraries, yet in the end, we could retrofit most of our
|
||||
tuple-handling library. However, other cases did not play out so well: we evolved
|
||||
the idea of ``iterators'' to become a lazy processing pipeline, but unfortunately
|
||||
our design leans more into the direction of functional programming and is much
|
||||
more expressive and powerful as abbreviation than the »Range-TS« from C++20.
|
||||
]
|
||||
The entrance barrier for something to be added to our _Support Library_ is rather low:
|
||||
|
||||
- extracting it as a library function _must make the client code clearer_
|
||||
- it must be possible to describe its purpose and its usage in _generic terms_ --
|
||||
without referring to data types and definitions from our domain models.
|
||||
- it must be _essentially stateless_ and self-contained
|
||||
- it must be easy to document with an unit-test.
|
||||
|
||||
Over time, parts of the Support Library have evolved into some kind of a framework:
|
||||
Notably the link:{ldoc}/design/architecture/time/index.html[time and timecode] handling,
|
||||
our link:Dependencies.html[dependency and service handling],
|
||||
the link:DiffFramework.html[»Diff framework«], together with the recursive property trees
|
||||
used for link:{ldoc}/design/architecture/ETD.html[»External Tree Description«], the
|
||||
link:iterator.html[iterator pipeline builders], the metaprogramming helpers for transforming
|
||||
function signatures and generic sequences, and our collection of string conversion, parsing
|
||||
and rendering functions. These all turned into distinguishing traits of the Lumiera code base.
|
||||
|
||||
The link:{ldoc}/technical/overview.html#_library[»Library« section of the »Overview« document]
|
||||
contains a long list of short descriptions for relevant features of the Support Library.
|
||||
|
||||
|
||||
.how to crack nuts...
|
||||
[NOTE]
|
||||
In the how-to section, there is a page with a loose collection of
|
||||
link:{ldoc}/technical/howto/crackNuts.html[successful solution patterns],
|
||||
many of which rely on unique features of our Support Lib.
|
||||
|
||||
Alongside with the core Lumiera Application, we're also creating several *Libraries*. +
|
||||
This section holds pages with in-depth technical documentation regarding those. Please don't
|
||||
expect a coherent or complete coverage for the time being -- library functionality is typically
|
||||
``discovered'' while in the middle of the implementation, then factored out, reused and remoulded
|
||||
over time.
|
||||
|
||||
Interface Library
|
||||
-----------------
|
||||
The Lumiera Application is designed deliberately in a way to be controllable by scripts. All of
|
||||
the Session, the models and the vault are fully operational without the GUI. Any significant
|
||||
functionality shall be usable through the primary Façade Interfaces alone. Yet in order to create
|
||||
such an open and extensible application as envisioned, we also need to build up an _interface layer._
|
||||
Eventually, this should evolve into a binding library for using Lumiera -- however, none of this
|
||||
interface building work has been accomplished yet, as of 2026. We do not even have a complete
|
||||
picture how _event sourcing_ meshes together with our UI commands and the configuration rules.
|
||||
functionality can be addressed through the primary Façade Interfaces.
|
||||
|
||||
- we still need to identify those select core concepts which need to be exposed
|
||||
But, in order to make such an open and extensible application a reality, we need to build up
|
||||
an 'interface layer' -- provided as library for client code and script adapters to link against.
|
||||
This library allows to access the primary external interfaces and exposes everything needed to
|
||||
work with the specifics of the application.
|
||||
|
||||
[,yellow]#TODO as of 1/2012:# _this is just a nebulous plan for now._ Nothing of the work required
|
||||
really to address facilities from the outside has been done. All we've managed to achieve is actually
|
||||
to use clean interfaces and decouple the parts of the application appropriately.
|
||||
|
||||
- we still need to identify those core concepts which need to be exposed
|
||||
- we need to refactor the corresponding data types to resolve cross dependencies to the implementation
|
||||
- only then we could think about moving those data types into an _official Lumiera interface_
|
||||
- then we could think about moving those data types into an _official Lumiera interface_
|
||||
|
||||
Support Library
|
||||
---------------
|
||||
There is a huge collection of generic building blocks, re-used more or less frequently.
|
||||
The're written in a generic way, but in accordance to the rest of the source base, relying only
|
||||
on the general error handling and logging framework used within Lumiera. (Some facilities may depend
|
||||
on other parts of the Application; this can be qualified as a bug -- please complain when you've found
|
||||
something of that sort).
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Lumiera: The Inner Core
|
||||
=======================
|
||||
:Author: Lumiera_Core_Developers
|
||||
:Date: 2012 / 2026
|
||||
:Date: 2012 / 2025
|
||||
:toc:
|
||||
|
||||
[abstract]
|
||||
|
|
@ -30,7 +30,7 @@ This three Layers are:
|
|||
|
||||
The Steam Layer::
|
||||
Keeps the Session, generates the rendering graphs for sequences,
|
||||
prearranges elements and decides what to do when and how.
|
||||
arranges what to do when and how.
|
||||
|
||||
The Vault Layer::
|
||||
Manages worker pools, schedules jobs, does the memory management for the
|
||||
|
|
@ -39,11 +39,13 @@ This three Layers are:
|
|||
|
||||
The extra components are:
|
||||
|
||||
The Vessel::
|
||||
This is the »backbone« of the application, it is rooted below the three
|
||||
layers and encompasses everything. It defines the periphery, starts all
|
||||
Subsystems, controls the overall lifecycle and provides vital services
|
||||
which must be available for engaging any part of the system.
|
||||
Lumiera::
|
||||
The main program itself, which starts all Subsystems and controls the
|
||||
overall lifecycle.
|
||||
|
||||
Common::
|
||||
Vital components and common services which must be available for pulling up
|
||||
any part of the system.
|
||||
|
||||
Library::
|
||||
A lot of (largely) stateless helper functionality used throughout the code.
|
||||
|
|
@ -53,9 +55,9 @@ Coding Style
|
|||
~~~~~~~~~~~~
|
||||
|
||||
The Lumiera team agreed on using GNU coding style with slight adaptations.
|
||||
In general, we strive to maintain source code consistency and adhere to widely
|
||||
accepted guidelines and practices of good craftsmanship. See our separate
|
||||
link:{ldoc}/technical/code/CodingGuidelines.html[Coding Guidelines] page.
|
||||
Generally speaking, we strive to keep the code base consistent and stick to
|
||||
widely accepted guidelines and best practices. See our separate
|
||||
link:{ldoc}/technical/code/codingGuidelines.html[Coding Guidelines] page.
|
||||
|
||||
|
||||
|
||||
|
|
@ -146,7 +148,7 @@ contained within the Session, which belongs to the _steam layer_ below.
|
|||
User interfaces are implemented as plug-ins and are pulled up on demand,
|
||||
they won't contain any relevant persistent state beyond presentation.
|
||||
|
||||
_As of 2026, the one and only interface under active development is
|
||||
_As of 2023, the one and only interface under active development is
|
||||
the Lumiera GTK GUI,_ based on GTK-3 / gtkmm. The sources are in tree
|
||||
(directory 'src/stage') and it is integrated into the standard build and
|
||||
installation process. By default, running the 'lumiera' executable will
|
||||
|
|
@ -248,7 +250,7 @@ for each output channel is required.
|
|||
|
||||
The player service
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Client code accesses the player (subsystem) through the play-facade (`Play`).
|
||||
Client code accesses the player (subsystem) through the play-facade (`lumiera::Play`).
|
||||
The exposed service allows to _set up an output connection for playback or rendering,_
|
||||
resulting in a play-controller object.
|
||||
|
||||
|
|
@ -283,6 +285,11 @@ performance critical.
|
|||
- the OutputSlot exposed by the output manager is responsible for accepting timed frame delivery
|
||||
|
||||
|
||||
|
||||
|
||||
Vault Layer
|
||||
-----------
|
||||
|
||||
Engine Interface
|
||||
~~~~~~~~~~~~~~~~
|
||||
While on itself just a thin interface and adaptation layer forwarding calls to
|
||||
|
|
@ -311,21 +318,16 @@ the job ticket acts as blueprint for the actual jobs to be enqueued
|
|||
with the _Scheduler._
|
||||
|
||||
|
||||
|
||||
Vault Layer
|
||||
-----------
|
||||
Scheduler
|
||||
~~~~~~~~~
|
||||
The Scheduler serves as the central hub in the implementation of the RenderEngine
|
||||
and coordinates the processing resources of the application. Its purpose is to
|
||||
invoke and control the dependency and time based execution of the _Render Jobs._
|
||||
|
||||
As far as architecture is concerned, the Scheduler is located in the Vault-Layer and
|
||||
is a _passive service_ -- like most components in the vault it needs to be put into
|
||||
use by some coordinating and integrating facility. An EngineFaçade, itself located
|
||||
above, in the »Steam« layer, acts as entrance point, to provide the high-level
|
||||
render services to other parts of the application: render jobs can be activated
|
||||
under various timing and dependency constraints, which can be grouped
|
||||
Regarding architecture, the Scheduler is located in the Vault-Layer and running the Scheduler
|
||||
is equivalent to activating the »Vault Subsystem«. An EngineFaçade acts as entrance point,
|
||||
providing high-level render services to other parts of the application: render jobs can be
|
||||
activated under various timing and dependency constraints, which can be grouped
|
||||
into three basic modes of control:
|
||||
|
||||
Deadline::
|
||||
|
|
@ -360,29 +362,6 @@ The scheduler is able to observe and maintain dependencies between render jobs,
|
|||
to break down an extended calculation into a chain of small steps.
|
||||
|
||||
|
||||
The Work Force
|
||||
~~~~~~~~~~~~~~
|
||||
Since the typical work job dimensions can be expected to lie in the range of _some milliseconds,_
|
||||
the Lumiera engine can adopt a statistical model of capacity distribution. This is notably
|
||||
different to an _operating system scheduler_ where the response times are measured in
|
||||
microseconds and the coordination of work approaches hardware limits. These observations
|
||||
lead to the (maybe slightly surprising approach) to rely on an _actively pulling_ work force
|
||||
combined with a _passive scheduling service._
|
||||
|
||||
The _Work Force_ is a **pool of worker threads** with a size typically matching the nominal
|
||||
number of independent CPU cores in the system. Spinning up the Work Force is equivalent to
|
||||
activating the »Vault Subsystem«. Deliberately, there is no dedicated ``engine'' or
|
||||
``manager'' thread. All workers participate in the coordination work on equal footing.
|
||||
An idle worker enters the (passive) scheduling code, and thereby performs management
|
||||
work up to the point where the next render job is determined. The worker then leaves
|
||||
the management realm and continues with performing this job. However, the scheduling
|
||||
code preloads each worker with some random sleep delay in order to distribute the
|
||||
``incidence'' of idle workers and to avoid contention. This way, the available
|
||||
computing capacity is distributed stochastically into that time window where
|
||||
demand is foreseeable, based on the next job's starting time, the currently
|
||||
dispatched jobs and the observed load factor.
|
||||
|
||||
|
||||
Resource Management
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
@ -399,12 +378,12 @@ the system and current circumstances.
|
|||
|
||||
|
||||
|
||||
Vessel: Common Services
|
||||
-----------------------
|
||||
Common Services
|
||||
---------------
|
||||
|
||||
Subsystem runner
|
||||
~~~~~~~~~~~~~~~~
|
||||
Conceptually, the application is structured into layers. However, as the actual runtime
|
||||
Conceptually, the application is structured into layers. However, as actual runtime
|
||||
entities we rely on a small number of link:{ldoc}/design/architecture/Subsystems.html[Subsystems],
|
||||
which can be started and stopped and have well defined dependencies:
|
||||
|
||||
|
|
@ -439,14 +418,17 @@ link:{ldoc}/design/architecture/Subsystems.html#_lifecycle[documentation]
|
|||
[small]#(likewise incomplete, but we're getting there, eventually [yellow-background]##2018##)#
|
||||
|
||||
|
||||
Plugin loader
|
||||
~~~~~~~~~~~~~
|
||||
_tbw_
|
||||
|
||||
Advice framework
|
||||
~~~~~~~~~~~~~~~~
|
||||
This is a ``whiteboard'' system, allowing implementation-level services to _publish_
|
||||
some piece of information as _advice_, while other parts of the system may pick up
|
||||
this advice just by a name token, without requiring a direct knowledge of the
|
||||
original _advisor._ The _Advice System_ is a singleton service that maintains
|
||||
a lookup and registration data structure. Individual _piece of advice_ elements
|
||||
original _advisor._ The _Advice System_ is a singleton service maintaining a
|
||||
lookup and registration data structure. Individual _piece of advice_ elements
|
||||
are stored _as value copy_. Publishing new advice requires locking, but accessing
|
||||
advice is lock-free (actually there needs to be a memory barrier ``somewhere'',
|
||||
otherwise the advice requesting client might not see new advice)
|
||||
|
|
@ -476,27 +458,13 @@ Library
|
|||
-------
|
||||
|
||||
The Lumiera support library contains lots of helper functionality
|
||||
factored out from the internals and re-used. Some parts evolved into
|
||||
basic frameworks, that are used pervasively throughout the code base.
|
||||
|
||||
- link:{ldoc}/design/architecture/time/index.html[time and timecode]
|
||||
(-> xref:_time[below])
|
||||
- link:Dependencies.html[dependency and service handling]
|
||||
(-> xref:_singletons_and_dependencies[below]),
|
||||
- the link:DiffFramework.html[»Diff framework«]
|
||||
- property trees for link:{ldoc}/design/architecture/ETD.html[»External Tree Description«]
|
||||
(-> xref:_external_tree_description[below])
|
||||
- the link:iterator.html[iterator pipeline builders]
|
||||
(-> xref:_iterators[below])
|
||||
- various metaprogramming helpers (function signatures and generic sequences)
|
||||
- string conversion, parsing and rendering functions
|
||||
|
||||
factored out from the internals and re-used. It is extended as we go.
|
||||
|
||||
practical shortcuts
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
The header 'lib/util.hpp' defines some shortcuts that are used almost
|
||||
everywhere in the code base. The general idea is to highlight a common semantic meaning,
|
||||
while hide the differentiation related to the technical details.
|
||||
The header 'lib/util.hpp' defines some shortcuts heavily used throughout
|
||||
the code base. The idea is to highlight a common semantic meaning, while
|
||||
hide differentiation on the technical details.
|
||||
|
||||
isnil:: indicate a _missing value_, irrespective if this is a NULL pointer,
|
||||
an empty string or an empty container. Several of our custom wrappers also
|
||||
|
|
@ -505,29 +473,8 @@ isnil:: indicate a _missing value_, irrespective if this is a NULL pointer,
|
|||
contains:: indicate that a value is _somehow contained_ within a collection,
|
||||
irrespective if this is a set, a map, a vector or string (substring test)
|
||||
|
||||
limited:: to bracket some value.
|
||||
sanitise:: make any string usable as identifier.
|
||||
|
||||
unConst:: a functional notation to cast away `const`, which is used typically
|
||||
at the barrier between a type safe front-end and a low-level back-end,
|
||||
and to avoid needless duplication of accessor code implementation
|
||||
for sake of providing `const` information functions.
|
||||
|
||||
isSameObject:: identity test based on bare memory location,
|
||||
which is used a lot in assertions and unit tests
|
||||
|
||||
string shorthands::
|
||||
trim, startsWith, endsWith, boolVal, sanitise (turn arbitrary string into an identifier)
|
||||
|
||||
|
||||
Literals and Symbols
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Besides the well-known C++ strings (and `string_view`), Lumiera introduces
|
||||
two marker types for string tokens
|
||||
|
||||
Literal:: a C-string literal directly given in the Source code
|
||||
|
||||
Symbol:: an _interned_ token stored in a Symbol table, so that its
|
||||
address hash can be used as unique identity
|
||||
|
||||
|
||||
Locking
|
||||
|
|
@ -945,17 +892,6 @@ and assignment incur the cost of an additional virtual call,
|
|||
assuming the target objects cooperate by mixing in a
|
||||
copy management interface.
|
||||
|
||||
.uninitialised storage
|
||||
A cornerstone of the C++ language is the deterministic and reliable invocation
|
||||
of constructors and destructors. However, when building low-level storage schemes,
|
||||
a frequent requirement is to cover the precise storage of an object collection,
|
||||
_without_ actually invoking any constructor or destructor. The `UninitialisedStorage`
|
||||
template is a building block to support this task. It is parametrised with a type
|
||||
and an element count, and provides a force-casted array-like access to the storage cells.
|
||||
This can be used either to placement-construct some elements on-demand, or to ``project''
|
||||
an object-like view over existing data in the storage.
|
||||
|
||||
|
||||
|
||||
Unique Identifiers
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Technical Documentation: Stage Layer
|
||||
====================================
|
||||
|
||||
This section offers a loose collection with detailed information regarding the GUI implementation.
|
||||
Eventually, this will have technical documentation for the GUI.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,27 @@
|
|||
Technical Documentation: Steam-Layer
|
||||
====================================
|
||||
|
||||
As implementation progresses, this section will gradually compile
|
||||
the technical documentation for the Steam layer.
|
||||
Eventually, this section will hold technical documentation for the Steam-Layer.
|
||||
|
||||
Development Scrapbook TiddlyWiki
|
||||
--------------------------------
|
||||
It is sometimes difficult to write complete documentation while a system is still under construction.
|
||||
For taking work notes and formulating new ideas while working, _Ichthyostega_ frequently uses the
|
||||
https://classic.tiddlywiki.com/[TiddlyWiki] -- which is a nifty JavaScript wiki embedded within a
|
||||
single HTML page; as such it lives right within the source tree, where it can be worked on alongside
|
||||
with the code. Notes and sketches for the planning often evolve into detailed descriptions, complete
|
||||
with test data and UML diagrams to document the structure. Material drafted in the TiddlyWiki
|
||||
will be moved gradually into this documentation section, as time permits.
|
||||
Hermann Voßeler, core developer of the Steam-Layer uses an separate embedded wiki
|
||||
for his day-to-day design sketches, notes and also for the more persistent planning.
|
||||
This *TiddlyWiki* is a nifty JavaScript wiki embedded in a single HTML page; as such
|
||||
it lives right within the source tree, where it can be worked on alongside with the
|
||||
code. Besides the actual planning and descriptions, this wiki also links to the
|
||||
UML diagrams created with *BOUML* during the ongoing planning and design.
|
||||
|
||||
This arrangement started as a temporary solution at a time where we did not have a suitable website
|
||||
for permanent documentation -- and it was kept ever since, as the TiddlyWiki is very convenient
|
||||
to work with, once you are accustomed to its quirks.footnote:[
|
||||
It is quite fluid and inspiring to work with indeed. The content is an unordered collection
|
||||
of small notepad pages, called ``Tiddlers'', which can be opened and closed conveniently.
|
||||
Any "CamelCaseWord" becomes a new Tiddler, recent changes appear in a timeline, and Tiddlers
|
||||
can be organised with tags. The only point to be careful is that you need to _save_
|
||||
your work, which can be achieved with the `save' action in the menu to overwrite
|
||||
the old version in the Git tree. Sometimes this might produce Git conflicts,
|
||||
which are easy to resolve, since the content is plain text.
|
||||
]
|
||||
Additions to the TiddlyWiki are usually made during coding, and are deliberately committed always
|
||||
together with the corresponding code. As such, these additions will propagate to Lumiera/Master eventually;
|
||||
yet to make the newest development notes easier to access, we have put up a `rsync`ed version of the
|
||||
TiddlyWiki online for direct access over the internet (which then is of course read-only).
|
||||
This setup started as a temporary solution -- but as uWiki is not expected to come
|
||||
to life soon, the current website can't serve as replacement for a real wiki, an
|
||||
we'll stick to that situation for the time being. As the content in the TiddlyWiki
|
||||
becomes more mature and stable, it will be moved over into this section here.
|
||||
|
||||
-> access the link:/wiki/renderengine.html[TiddlyWiki online here]
|
||||
While additions to the TiddlyWiki generally propagate to Lumiera/Master through
|
||||
the normal merges, we've put up a rsynced version of the TiddlyWiki online for
|
||||
direct access (of course read-only).
|
||||
|
||||
-> access the Proy-Layer link:/wiki/renderengine.html[TiddlyWiki online here]
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -113,11 +113,8 @@ each have a distinct _type_ which explicitly identifies the possible connections
|
|||
modules. Within these constraints, any combination is possible without
|
||||
hidden restrictions.
|
||||
|
||||
However, the application strives for a certain degree of internal coherence. +
|
||||
Lumiera is not a set of Lego bricks allowing you to build ``just anything''
|
||||
(in a clumsy way) -- nor is it the next universal programming platform or
|
||||
application framework driven by pre-canned success stories, where you
|
||||
``just push the button'' and magic does the rest.
|
||||
Lumiera is not a set of Lego bricks, nor is it a business application
|
||||
driven by finite usage stories.
|
||||
|
||||
|
||||
Medium Level Abstraction and Project Specific Conventions
|
||||
|
|
@ -134,8 +131,9 @@ details such as header format conversion or access to individual channels.
|
|||
To complement this approach, Lumiera does _not_ rely on hard-wired, global
|
||||
conventions -- rather we allow the building up of project specific conventions and
|
||||
rules xref:rules[<-] to fit a given requirement and preferred working style.
|
||||
However, in its default configuration, Lumiera will be supplied with a conventional
|
||||
UI template and key bindings to ease the learning curve for new users.
|
||||
|
||||
Lumiera will be supplied with a conventional template and a default
|
||||
configuration to ease the learning curve for new users.
|
||||
|
||||
|
||||
[[graphs]]
|
||||
|
|
@ -146,12 +144,12 @@ Processing video (and audio) data can be conceived as a graph (more precisely
|
|||
a _directed acyclic graph_). In this model of video processing, data flows
|
||||
along the edges of the graph and is processed at the nodes.
|
||||
|
||||
The following figure depicts manipulating video data as a graph.
|
||||
Input data is retrieved from the source nodes, which are located at the
|
||||
top of the figure. From there, the data moves on to the next stage, where
|
||||
video and audio data and meta information is pre-processed. All the further
|
||||
operations on data can be represented by nodes, and data flows from one operation
|
||||
to the next along the nodes of the graph.
|
||||
The following figure depicts manipulating video data as a graph. The nodes at
|
||||
the top of the graph are where data input occurs. From there, the data moves on
|
||||
to the next nodes: the direct siblings of the root. Here, the video data is
|
||||
pre-processed. All other operations on the data can be represented by
|
||||
nodes, and data flows from one operation to the next along the nodes of the
|
||||
graph.
|
||||
|
||||
|
||||
image:{imgd}/lumiera_big_graph.png[Example for a graph]
|
||||
|
|
@ -220,15 +218,16 @@ Lumiera consists of three major parts:
|
|||
In this section, we discuss the user's perspective when working with the GUI.
|
||||
|
||||
|
||||
Although Lumiera ships with a conventional desktop UI by default, we do not presume
|
||||
that this GUI will be suitable for all uses. We expect there to be several specialised
|
||||
UIs eventually, designed to handle very specific kinds of tasks.
|
||||
Although Lumiera will initially ship with a standard, default GUI, we do not presume that this GUI will be suitable for all uses.
|
||||
We expect there to be multiple, different GUIs, each designed for different
|
||||
kinds of tasks. We expect that some of these will be written by users, and the
|
||||
steam-layer is designed to facilitate this easily.
|
||||
|
||||
Indeed, Lumiera can even work
|
||||
satisfactorily without a GUI, for example, for special purposes
|
||||
(e.g. as headless render-node xref:rendernode[<-] or frameserver
|
||||
xref:frameserver[<-]). A script interface will be added at some
|
||||
point to facilitate automated processing.
|
||||
xref:frameserver[<-]). Scripts will eventually be written
|
||||
to facilitate automated processing.
|
||||
|
||||
|
||||
Now it is time to take a look at the preliminary Lumiera GUI:
|
||||
|
|
@ -506,19 +505,21 @@ A Plug-in is a kind of generalisation of a library.
|
|||
All applications use, to varying degrees of intensity, libraries. A programmer
|
||||
will not reinvent the wheel each time he sits down to programme an
|
||||
application. A programmer will typically borrow and use features and
|
||||
functionality from other programmers -- or even borrow from himself, stuff
|
||||
functionality from other programmers---or even borrow from himself, stuff
|
||||
written long ago in the past. Such features are collected together in
|
||||
libraries.
|
||||
|
||||
A library is used in an application by _linking_ the library into the application.
|
||||
However, there are different ways to _link_ a library: linking statically and
|
||||
linking dynamically.
|
||||
A library is used in an application by _linking_ the library into the
|
||||
application. (There are other things to be done, but we'll call these 'details',
|
||||
which wont concern us here.) There are different ways to _link_ a library
|
||||
into an application: linking statically and linking dynamically.
|
||||
|
||||
_Static Linking_ is done while the application is being built, or
|
||||
compiled. It is performed by the linker, which executes as the last step
|
||||
of the compilation process. The linker can perform some sanity checks and
|
||||
some optimisation. In the end, the functionality of the library is ``baked into''
|
||||
the resulting executable. +
|
||||
of the compilation process. The linker can perform some sanity checks
|
||||
(mostly checks regarding formally correct function invocation) and warn the user
|
||||
hat some particular feature is being used incorrectly. The user can then correct
|
||||
the offending code, and recompile. +
|
||||
There are a number of disadvantages associated with static linking. Features and
|
||||
libraries are being constantly improved. If the application wants to use new
|
||||
features, it will have to be recompiled with the new library which provides the
|
||||
|
|
@ -531,14 +532,15 @@ features can be used by the application. The features provided by a dynamic
|
|||
library are loaded when the application starts to run.
|
||||
|
||||
However both methods exhibit a number of shortcomings. Wouldn't it be better if
|
||||
all features could be loaded only when needed? This scheme of making features
|
||||
available to an application on-demand is known as run-time linking. A component
|
||||
intended to be added this way, at run time, by the user, is known as a Plug-in.
|
||||
all features could be loaded only when needed? If features could be loaded only
|
||||
when needed, then they could also be unloaded when not required, thus saving
|
||||
memory and possibly increasing performance. This scheme of making features
|
||||
available to an application is known as run-time linking, aka plug-ins.
|
||||
Plug-ins offer other benefits: the application can continue to use both the old
|
||||
features and the new features together, side-by-side, by using the version
|
||||
number associated with the plug-in. Furthermore, Plug-ins can load other Plug-ins
|
||||
and thus extend the application in creative ways, beyond anything the original
|
||||
developers of the application had planned.
|
||||
number associated with the plug-in. This saves the application from the havoc
|
||||
of library incompatibility that is
|
||||
associated with other linking methods.
|
||||
|
||||
Most modern applications use plug-ins, some are heavily dependent on plug-ins
|
||||
and only provide limited functionality without any plug-ins.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ in addition to the following tools and libraries:
|
|||
* https://www.boost.org/[Boost libraries]
|
||||
* https://github.com/bplaum/gavl[GAVL library]
|
||||
* https://nobug.pipapo.org/[NoBug] ~([purple]#⚠ see below#)~
|
||||
* Lumiera https://git.lumiera.org/gitweb?p=LUMIERA;a=summary[source code]
|
||||
* Lumiera https://git.lumiera.org/?p=LUMIERA;a=summary[source code]
|
||||
|
||||
The GUI depends on the following:
|
||||
|
||||
|
|
|
|||
|
|
@ -115,9 +115,9 @@ sudo make install
|
|||
but was orphaned in 2021. Since it is currently a prerequisite for building Lumiera,
|
||||
we maintain a clone of the original repository and a Debian package on Lumiera.org.
|
||||
This is relevant both for
|
||||
https://git.lumiera.org/gitweb?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
|
||||
https://git.lumiera.org/?p=debian/gdl;a=summary[libGDL (3.40) +git://git.lumiera.org/debian/gdl+]
|
||||
and the
|
||||
https://git.lumiera.org/gitweb?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+].
|
||||
https://git.lumiera.org/?p=debian/gdlmm;a=summary[GDL C++ bindings (3.7.3) +git://git.lumiera.org/debian/gdlmm+].
|
||||
]
|
||||
|
||||
* first you have to build libGTL itself...
|
||||
|
|
|
|||
411
research/try.cpp
411
research/try.cpp
|
|
@ -1,7 +1,6 @@
|
|||
/* try.cpp - to try out and experiment with new features....
|
||||
* scons will create the binary bin/try
|
||||
*/
|
||||
// 03/26 - runtime index access and iteration over tuple-likes
|
||||
// 06/25 - provide a concept to accept _tuple-like_ objects
|
||||
// 06/25 - investigate function type detection of std::bind Binders
|
||||
// 12/24 - investigate problem when perfect-forwarding into a binder
|
||||
|
|
@ -11,28 +10,22 @@
|
|||
|
||||
|
||||
/** @file try.cpp
|
||||
* Work out a construction scheme to build an efficient element-accessor to data
|
||||
* in a tuple-like with run-time indexing. As an extension, run-time pulled iteration
|
||||
* can be established, using the IterExplorer framework.
|
||||
* @see lib::meta::FunTrampoline
|
||||
* @see lib::meta::TupleIdxAdaptor
|
||||
* Develop a concept to detect _tuple-like_ classes, based on the requirements
|
||||
* of the »tuple protocol«. Using some ideas from [Stackoverflow] as starting point.
|
||||
* However, we model both a _friend function_ `get` and a similar member function
|
||||
* as alternatives for element access, and we break down the checks into sub-concepts.
|
||||
* [Stackoverflow]: https://stackoverflow.com/q/68443804/444796
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/format-util.hpp"
|
||||
#include "test/test-helper.hpp"
|
||||
#include "test/diagnostic-output.hpp"
|
||||
#include "lib/meta/common-result.hpp"
|
||||
#include "lib/meta/tuple-concept.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "lib/hetero-data.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <concepts>
|
||||
|
||||
using std::string;
|
||||
|
||||
|
|
@ -48,263 +41,14 @@ template<lib::meta::tuple_like X>
|
|||
void
|
||||
show()
|
||||
{
|
||||
cout << "Tulik!! "<< ::test::showType<X>() <<endl;
|
||||
cout << "Tup!! "<< lib::test::showType<X>() <<endl;
|
||||
lib::meta::forEachIDX<X> ([](auto i)
|
||||
{
|
||||
using Elm = std::tuple_element_t<i, X>;
|
||||
cout <<" "<<uint(i)<<": "<< ::test::showType<Elm>() <<endl;
|
||||
cout <<" "<<uint(i)<<": "<< lib::test::showType<Elm>() <<endl;
|
||||
});
|
||||
}
|
||||
|
||||
namespace lib {
|
||||
namespace meta{
|
||||
|
||||
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TODO : new generic library functions
|
||||
/**
|
||||
* Concept to require a generic type sequence `Types<TYPES...>`
|
||||
*/
|
||||
template<class TSEQ>
|
||||
concept typeseq = requires (TSEQ seq)
|
||||
{
|
||||
// TSEQ can invoke a function with a Types<TYPES> subclass
|
||||
[]<typename...TYPES>(Types<TYPES...>&){/*placeholder*/}(seq);
|
||||
};
|
||||
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////(End) : new generic library functions
|
||||
|
||||
|
||||
template<template<class> class BUILD, typeseq TSEQ>
|
||||
class FunTrampoline
|
||||
{
|
||||
using AllElm = ElmTypes<TSEQ>;
|
||||
using Indices = AllElm::Idx;
|
||||
using Builder = BUILD<TSEQ>;
|
||||
using Functor = Builder::Functor;
|
||||
using Table = std::array<Functor, AllElm::SIZ>;
|
||||
|
||||
template<size_t...idx>
|
||||
static constexpr Table
|
||||
buildFunctors (std::index_sequence<idx...>)
|
||||
{
|
||||
return {Builder().template build<idx>()...};
|
||||
}
|
||||
|
||||
static constexpr Table functors = buildFunctors (Indices{});
|
||||
|
||||
public:
|
||||
static constexpr size_t size() { return functors.size(); }
|
||||
static constexpr size_t memSiz() { return sizeof(functors); }
|
||||
|
||||
static Functor const&
|
||||
dispatch (size_t idx)
|
||||
{
|
||||
ENSURE (idx < functors.size());
|
||||
return functors[idx];
|
||||
}
|
||||
|
||||
using ResType = _Fun<Functor>::Ret;
|
||||
};
|
||||
|
||||
|
||||
#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TODO : new generic library functions
|
||||
template<typename T>
|
||||
using isConst = std::is_const<remove_reference_t<T>>;
|
||||
template<typename T>
|
||||
using isLRef = std::is_lvalue_reference<T>;
|
||||
|
||||
|
||||
template<class SEQ>
|
||||
using Any_Const = ElmTypes<SEQ>::template OrAll<isConst>;
|
||||
|
||||
template<class SEQ>
|
||||
using All_LRef = ElmTypes<SEQ>::template AndAll<isLRef>;
|
||||
|
||||
template<class SEQ>
|
||||
static constexpr bool Any_Const_v = Any_Const<SEQ>::value;
|
||||
|
||||
template<class SEQ>
|
||||
static constexpr bool All_LRef_v = All_LRef<SEQ>::value;
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename X, typename U, typename...TYPES>
|
||||
struct ProbeCommonType
|
||||
{
|
||||
|
||||
template<typename T1, typename T2>
|
||||
using Reconciled = decltype(true ? std::declval<T1>() : std::declval<T2>());
|
||||
|
||||
|
||||
template<typename RES>
|
||||
struct FoundResult
|
||||
: std::true_type
|
||||
{
|
||||
using Type = RES;
|
||||
};
|
||||
struct NoResultFound
|
||||
: std::false_type
|
||||
{ };
|
||||
|
||||
template<class T1
|
||||
,class T2
|
||||
,typename = Reconciled<T1,T2>>
|
||||
static FoundResult<Reconciled<T1,T2>>
|
||||
check(int);
|
||||
|
||||
template<class,class>
|
||||
static NoResultFound
|
||||
check(...);
|
||||
|
||||
using FirstResult = decltype(check<X,U>(0));
|
||||
|
||||
template<bool success, typename...TS>
|
||||
struct Join
|
||||
{
|
||||
using Result = FirstResult;
|
||||
};
|
||||
|
||||
template<typename T1, typename...TS>
|
||||
struct Join<true, T1,TS...>
|
||||
{
|
||||
//wenn RES erfolgreich
|
||||
using CT = FirstResult::Type;
|
||||
using Result = ProbeCommonType<CT,T1,TS...>::Result;
|
||||
};
|
||||
|
||||
using Result = Join<FirstResult::value, TYPES...>::Result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename...TYPES>
|
||||
struct CommonResult
|
||||
: ProbeCommonType<TYPES...>::Result
|
||||
{ };
|
||||
|
||||
template<typename T1>
|
||||
struct CommonResult<T1>
|
||||
: CommonResult<T1,T1>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
struct CommonResult<>
|
||||
: std::false_type
|
||||
{ };
|
||||
|
||||
template<typename...TYPES>
|
||||
struct CommonResult<Types<TYPES...>>
|
||||
: CommonResult<TYPES...>
|
||||
{ };
|
||||
|
||||
template<typename...TYPES>
|
||||
using CommonResult_t = CommonResult<TYPES...>::Type;
|
||||
|
||||
template<typename...TYPES>
|
||||
static constexpr bool has_CommonResult_v = CommonResult<TYPES...>::value;
|
||||
|
||||
|
||||
template<typename...TYPES>
|
||||
concept reconcilable = requires
|
||||
{
|
||||
typename CommonResult<TYPES...>::Type;
|
||||
};
|
||||
|
||||
template<typename...TYPES>
|
||||
concept reconcilable_ref = reconcilable<TYPES...>
|
||||
and isLRef_v<CommonResult_t<TYPES...>>;
|
||||
|
||||
template<typename...TYPES>
|
||||
struct CommonResultTraits
|
||||
{
|
||||
static_assert (reconcilable<TYPES...>, "unable to reconcile these types");
|
||||
|
||||
using CommonVal = std::common_type_t<TYPES...>;
|
||||
using ResType = CommonResult_t<TYPES...>;
|
||||
//NOTE: std::common_type decays (strips CV and ref)
|
||||
static constexpr bool makeConst = isConst_v<ResType>;
|
||||
static constexpr bool exposeRef = isLRef_v<ResType>;
|
||||
};
|
||||
#endif ///////////////////////////////////////////////////////////////////////////////////////////////////(End) : new generic library functions
|
||||
|
||||
|
||||
|
||||
template<class TUP>
|
||||
class TupleIndexAdaptor
|
||||
: public TUP
|
||||
{
|
||||
template<typeseq SEQ>
|
||||
struct SubscriptBuilder
|
||||
{
|
||||
using Tuple = RefTraits<TUP>::value_type;
|
||||
using AddRefs = ElmTypes<SEQ>::template Apply<std::add_lvalue_reference_t>;
|
||||
using ResType = CommonResult_t<AddRefs>;
|
||||
using Functor = ResType(*)(Tuple&);
|
||||
|
||||
template<size_t idx>
|
||||
constexpr auto
|
||||
build()
|
||||
{
|
||||
return [](Tuple& tuple) -> ResType
|
||||
{
|
||||
return getElm<idx> (tuple);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
using TypeSeq = ElmTypes<TUP>::Seq;
|
||||
using Accessor = FunTrampoline<SubscriptBuilder, TypeSeq>;
|
||||
public:
|
||||
using ResType = Accessor::ResType;
|
||||
using reference = ResType;
|
||||
using value_Type = RefTraits<ResType>::value_type;
|
||||
|
||||
template<typename T>
|
||||
TupleIndexAdaptor(T&& dataSrc)
|
||||
: TUP{forward<T> (dataSrc)}
|
||||
{ }
|
||||
|
||||
using TUP::TUP;
|
||||
|
||||
static constexpr size_t size() { return Accessor::size(); }
|
||||
|
||||
ResType
|
||||
operator[] (size_t idx)
|
||||
{
|
||||
return Accessor::dispatch(idx)(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<class TUP>
|
||||
TupleIndexAdaptor(TUP) -> TupleIndexAdaptor<std::decay_t<TUP>>;
|
||||
}}
|
||||
|
||||
using namespace lib::meta;
|
||||
|
||||
template<typeseq SEQ>
|
||||
struct Stringify
|
||||
{
|
||||
using Tuple = ElmTypes<SEQ>::Tup;
|
||||
using Functor = string(*)(Tuple const&);
|
||||
|
||||
template<size_t idx>
|
||||
constexpr auto
|
||||
build()
|
||||
{
|
||||
using ElmT = std::tuple_element_t<idx, Tuple>;
|
||||
|
||||
return [](Tuple const& tuple)
|
||||
{
|
||||
return util::toString<ElmT> (getElm<idx> (tuple));
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct Uber { };
|
||||
struct Untr : Uber { };
|
||||
struct Unta : Uber { };
|
||||
|
||||
|
||||
int
|
||||
main (int, char**)
|
||||
|
|
@ -313,10 +57,20 @@ main (int, char**)
|
|||
using Arr = std::array<int,3>;
|
||||
using Hetero = lib::HeteroData<int,string>::Chain<short>::ChainExtent<bool,lib::meta::Nil>::ChainType;
|
||||
|
||||
SHOW_EXPR((lib::meta::tuple_sized<Tup> ))
|
||||
SHOW_EXPR((lib::meta::tuple_sized<Arr> ))
|
||||
SHOW_EXPR((lib::meta::tuple_sized<Hetero> ))
|
||||
SHOW_EXPR((lib::meta::tuple_sized<int> ))
|
||||
|
||||
SHOW_EXPR((lib::meta::tuple_element_accessible<Tup,0>))
|
||||
// SHOW_EXPR((lib::meta::tuple_element_accessible<Tup,2>))
|
||||
SHOW_EXPR((lib::meta::tuple_element_accessible<Hetero,0>))
|
||||
SHOW_EXPR((lib::meta::tuple_accessible<Tup>))
|
||||
SHOW_EXPR((lib::meta::tuple_accessible<Hetero>))
|
||||
|
||||
SHOW_EXPR((lib::meta::tuple_like<Tup> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<Arr> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<Hetero> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<string> ))
|
||||
SHOW_EXPR((lib::meta::tuple_like<int> ))
|
||||
|
||||
show<Tup>();
|
||||
|
|
@ -324,112 +78,25 @@ main (int, char**)
|
|||
show<Hetero>();
|
||||
show<int>();
|
||||
|
||||
using TupStringy = FunTrampoline<Stringify, ElmTypes<Tup>::Seq>;
|
||||
SHOW_EXPR(TupStringy::size())
|
||||
SHOW_EXPR((std::tuple_size_v<const Tup>))
|
||||
using Elm1 = std::tuple_element_t<1, const Tup>;
|
||||
SHOW_TYPE(Elm1)
|
||||
using TupConstSeq = lib::meta::ElmTypes<const Tup>::Seq;
|
||||
SHOW_TYPE(TupConstSeq)
|
||||
|
||||
Tup tup23{2,3};
|
||||
Tup tup42{4,2};
|
||||
SHOW_TYPE(decltype(std::get<1>(tup42)))
|
||||
SHOW_EXPR(std::get<1>(tup42))
|
||||
SHOW_EXPR(TupStringy::dispatch(0)(tup23))
|
||||
SHOW_EXPR(TupStringy::dispatch(0)(tup42))
|
||||
SHOW_EXPR(TupStringy::dispatch(1)(tup23))
|
||||
SHOW_EXPR(TupStringy::dispatch(1)(tup42))
|
||||
|
||||
using T1 = Types<int const&,long&, char&>;
|
||||
using T2 = Types<int*,void*>;
|
||||
using T3 = Types<int,string>;
|
||||
SHOW_EXPR((has_CommonResult_v<T1>))
|
||||
SHOW_EXPR((has_CommonResult_v<T2>))
|
||||
SHOW_EXPR((has_CommonResult_v<T3>))
|
||||
SHOW_EXPR((has_CommonResult_v<>))
|
||||
SHOW_EXPR((has_CommonResult_v<float*>))
|
||||
SHOW_EXPR((has_CommonResult_v<float*,void* const>))
|
||||
|
||||
SHOW_TYPE(CommonResult_t<T1>)
|
||||
SHOW_TYPE(CommonResult_t<T2>)
|
||||
SHOW_TYPE(CommonResult_t<float*>)
|
||||
using CoTx = CommonResult_t<float*,float const*>;
|
||||
SHOW_TYPE(CoTx)
|
||||
|
||||
|
||||
TupleIndexAdaptor<Tup> idxAdapt{tup42};
|
||||
SHOW_EXPR(sizeof(tup42))
|
||||
SHOW_EXPR(sizeof(idxAdapt))
|
||||
SHOW_TYPE(TupleIndexAdaptor<Tup>::ResType)
|
||||
SHOW_EXPR(idxAdapt.size())
|
||||
SHOW_EXPR(idxAdapt[0])
|
||||
SHOW_EXPR(idxAdapt[1])
|
||||
SHOW_EXPR(getElm<0>(static_cast<Tup&> (idxAdapt)))
|
||||
SHOW_EXPR(getElm<1>(static_cast<Tup&> (idxAdapt)))
|
||||
SHOW_TYPE(decltype(idxAdapt[1]))
|
||||
|
||||
using Tup2 = std::tuple<int,int&, int>;
|
||||
int ii{23};
|
||||
Tup2 tup21{-1,ii,55};
|
||||
TupleIndexAdaptor idxApt2{tup21};
|
||||
SHOW_TYPE(decltype(tup21))
|
||||
using IdxApt2 = decltype(idxApt2);
|
||||
SHOW_TYPE(IdxApt2)
|
||||
SHOW_TYPE(IdxApt2::ResType)
|
||||
SHOW_EXPR(idxApt2[0])
|
||||
SHOW_EXPR(idxApt2[1])
|
||||
SHOW_EXPR(idxApt2[2])
|
||||
SHOW_EXPR(++idxApt2[0])
|
||||
SHOW_EXPR(idxApt2[1]++)
|
||||
SHOW_EXPR(++++idxApt2[2])
|
||||
SHOW_EXPR(tup21)
|
||||
SHOW_EXPR(Tup2(idxApt2))
|
||||
SHOW_EXPR(ii)
|
||||
|
||||
using TupIt = lib::IterableDecorator<lib::IdxStoreCore<IdxApt2>>;
|
||||
TupIt tupIt{move(idxApt2)};
|
||||
SHOW_EXPR( bool(tupIt) )
|
||||
SHOW_EXPR( *tupIt )
|
||||
SHOW_TYPE(decltype(*tupIt))
|
||||
++*tupIt;
|
||||
--ii;
|
||||
SHOW_EXPR( *tupIt )
|
||||
SHOW_EXPR(util::join(tupIt, "▶▶"))
|
||||
|
||||
SHOW_EXPR(( reconcilable<long,string> ))
|
||||
SHOW_EXPR(( reconcilable<long&,string&> ))
|
||||
SHOW_EXPR(( reconcilable<long,short> ))
|
||||
SHOW_EXPR(( reconcilable<long&,short&> ))
|
||||
SHOW_EXPR(( reconcilable_ref<long,string> ))
|
||||
SHOW_EXPR(( reconcilable_ref<long&,string&> ))
|
||||
SHOW_EXPR(( reconcilable_ref<long,short> ))
|
||||
SHOW_EXPR(( reconcilable_ref<long&,const long&> ))
|
||||
using TX = CommonResult_t<long&,const long&>;
|
||||
SHOW_TYPE(TX)
|
||||
SHOW_EXPR(( reconcilable<float*,void*> ))
|
||||
SHOW_EXPR(( reconcilable<void,void*> ))
|
||||
SHOW_EXPR(( reconcilable<float*&,void*&> ))
|
||||
using TX2 = CommonResult_t<float*&,float*&>;
|
||||
SHOW_TYPE(TX2)
|
||||
SHOW_EXPR(( reconcilable<Uber,Unta> ))
|
||||
SHOW_EXPR(( reconcilable<Untr,Unta> ))
|
||||
SHOW_EXPR(( reconcilable<Untr&,Unta&> ))
|
||||
SHOW_EXPR(( reconcilable<Uber&,Unta&> ))
|
||||
SHOW_EXPR(( reconcilable_ref<Uber&,Unta&> ))
|
||||
SHOW_EXPR(( reconcilable_ref<Uber&,Unta> ))
|
||||
SHOW_EXPR(( reconcilable<Uber&,Unta> ))
|
||||
SHOW_EXPR(( reconcilable<Uber,Untr&> ))
|
||||
using TX3 = CommonResult_t<Uber&,Unta>;
|
||||
SHOW_TYPE(TX3)
|
||||
using TX4 = CommonResult_t<Unta&, const Uber&>;
|
||||
SHOW_TYPE(TX4)
|
||||
SHOW_EXPR(( reconcilable<Uber&,Unta&,Untr&> ))
|
||||
using TX5 = CommonResult_t<const Uber&,Unta&,Untr&>;
|
||||
SHOW_TYPE(TX5)
|
||||
using TX6 = CommonResult_t<const int&,uint16_t,int64_t>;
|
||||
SHOW_TYPE(TX6)
|
||||
SHOW_EXPR(( CommonResult<int,string>::value ))
|
||||
SHOW_EXPR(( CommonResult<int,string,long>::value ))
|
||||
SHOW_EXPR(( CommonResult<const int,int&>::value ))
|
||||
SHOW_EXPR(( reconcilable<const int&,uint16_t,int64_t> ))
|
||||
SHOW_EXPR(( reconcilable<const Uber&,Unta&,Untr&> ))
|
||||
SHOW_EXPR(( reconcilable<Uber&,const Unta&,Untr&> ))
|
||||
using T1 = decltype(lib::meta::getElm<0> (std::declval<Tup>()));
|
||||
SHOW_TYPE(T1)
|
||||
using T2 = decltype(lib::meta::getElm<0> (std::declval<Tup&>()));
|
||||
SHOW_TYPE(T2)
|
||||
using T3 = decltype(lib::meta::getElm<0> (std::declval<Tup const&>()));
|
||||
SHOW_TYPE(T3)
|
||||
|
||||
using H1 = decltype(lib::meta::getElm<4> (std::declval<Hetero>()));
|
||||
SHOW_TYPE(H1)
|
||||
using H2 = decltype(lib::meta::getElm<4> (std::declval<Hetero&>()));
|
||||
SHOW_TYPE(H2)
|
||||
using H3 = decltype(lib::meta::getElm<4> (std::declval<Hetero const&>()));
|
||||
SHOW_TYPE(H3)
|
||||
|
||||
cout << "\n.gulp." <<endl;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@ Import('env icons config')
|
|||
# define the source file/dirs comprising each artifact to be built.
|
||||
|
||||
lLib = env.SharedLibrary('lumierasupport', srcSubtree('lib'), install=True)
|
||||
lApp = env.SharedLibrary('lumieravessel', srcSubtree('vessel'),addLibs=lLib, install=True)
|
||||
lVault = env.SharedLibrary('lumieravault', srcSubtree('vault'), addLibs=lLib+lApp, install=True)
|
||||
lSteam = env.SharedLibrary('lumierasteam', srcSubtree('steam'), addLibs=lLib+lApp+lVault, install=True)
|
||||
lApp = env.SharedLibrary('lumieracommon', srcSubtree('common'), addLibs=lLib, install=True)
|
||||
lVault = env.SharedLibrary('lumieravault', srcSubtree('vault'), addLibs=lLib+lApp, install=True)
|
||||
lSteam = env.SharedLibrary('lumierasteam', srcSubtree('steam'), addLibs=lLib+lApp+lVault,install=True)
|
||||
|
||||
# in reverse dependency order
|
||||
core = lSteam+lVault+lApp+lLib # used to build the core application
|
||||
app_lib = lApp+lLib # use to link against the platform
|
||||
core_lib = core # use to link against the core application
|
||||
vault_lib = lVault+app_lib # use to link against the low-level backend
|
||||
support_lib = lLib # use to link against the support lib only
|
||||
vessel_lib = lApp+support_lib # use to link against the application-framework
|
||||
vault_lib = lVault+vessel_lib # use to link against the low-level backend
|
||||
core_lib = lSteam+vault_lib # use to link against the core application
|
||||
|
||||
lumiera = ( env.Program('lumiera', ['lumiera/main.cpp'] + core, install=True)
|
||||
+ config
|
||||
|
|
@ -32,10 +32,6 @@ lumiera = ( env.Program('lumiera', ['lumiera/main.cpp'] + core, install=True)
|
|||
env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera')
|
||||
|
||||
|
||||
# Unit/Integration test support
|
||||
test_support = env.SharedLibrary('testsupport', srcSubtree('test'), addLibs=vessel_lib, install=False)
|
||||
|
||||
|
||||
# building Lumiera Plugins
|
||||
plugins = [] # currently none
|
||||
|
||||
|
|
@ -53,4 +49,4 @@ gui = ( guimodule
|
|||
)
|
||||
|
||||
|
||||
Export('lumiera core core_lib vessel_lib vault_lib support_lib test_support plugins envGtk guimodule gui')
|
||||
Export('lumiera core core_lib app_lib vault_lib support_lib plugins envGtk guimodule gui')
|
||||
|
|
|
|||
1
src/common/DIR_INFO
Normal file
1
src/common/DIR_INFO
Normal file
|
|
@ -0,0 +1 @@
|
|||
Common application services
|
||||
|
|
@ -86,8 +86,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_ADVICE_H
|
||||
#define VESSEL_ADVICE_H
|
||||
#ifndef LUMIERA_ADVICE_H
|
||||
#define LUMIERA_ADVICE_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
|
|
@ -96,10 +96,10 @@
|
|||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "vessel/advice/binding.hpp"
|
||||
#include "common/advice/binding.hpp"
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace advice {
|
||||
|
||||
using lib::Literal;
|
||||
|
|
@ -492,5 +492,5 @@ namespace advice {
|
|||
|
||||
|
||||
|
||||
}} // namespace vessel::advice
|
||||
#endif /*VESSEL_ADVICE_H*/
|
||||
}} // namespace lumiera::advice
|
||||
#endif
|
||||
|
|
@ -90,8 +90,8 @@
|
|||
#include "lib/sync.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "include/logging.h"
|
||||
#include "vessel/advice.hpp"
|
||||
#include "vessel/advice/index.hpp"
|
||||
#include "common/advice.hpp"
|
||||
#include "common/advice/index.hpp"
|
||||
|
||||
|
||||
using lib::Literal;
|
||||
|
|
@ -101,7 +101,7 @@ using util::unConst;
|
|||
typedef void (DeleterFunc)(void*);
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace advice {
|
||||
|
||||
namespace { // ======= implementation of the AdviceSystem ============
|
||||
|
|
@ -352,4 +352,4 @@ namespace advice {
|
|||
|
||||
|
||||
|
||||
}} // namespace lib::vessel
|
||||
}} // namespace lib::advice
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "vessel/advice/binding.hpp"
|
||||
#include "common/advice/binding.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ using boost::hash_combine;
|
|||
using boost::lexical_cast;
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace advice {
|
||||
|
||||
LUMIERA_ERROR_DEFINE (BINDING_PATTERN_SYNTAX, "Unable to parse the given binding pattern definition");
|
||||
|
|
@ -191,4 +191,4 @@ namespace advice {
|
|||
|
||||
|
||||
|
||||
}} // namespace vessel::advice
|
||||
}} // namespace lumiera::advice
|
||||
|
|
@ -62,8 +62,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_ADVICE_BINDING_H
|
||||
#define VESSEL_ADVICE_BINDING_H
|
||||
#ifndef LUMIERA_ADVICE_BINDING_H
|
||||
#define LUMIERA_ADVICE_BINDING_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
#include <set>
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace advice {
|
||||
|
||||
using lib::Literal;
|
||||
|
|
@ -285,5 +285,5 @@ namespace advice {
|
|||
|
||||
|
||||
|
||||
}} // namespace vessel::advice
|
||||
#endif /*VESSEL_ADVICE_BINDING_H*/
|
||||
}} // namespace lumiera::advice
|
||||
#endif
|
||||
|
|
@ -14,23 +14,22 @@
|
|||
|
||||
/** @file index.hpp
|
||||
** Implementation datastructure for use by the Advice system.
|
||||
** To support the **Advice** collaboration, it is necessary to match advice requests with
|
||||
** To support the \em Advice collaboration, it is necessary to match advice requests with
|
||||
** existing advice provisions. Each successful match creates an advice solution, resulting in
|
||||
** the bound piece of advice (data) to become visible to all the advised entities having placed
|
||||
** a matching advice request into the advice system.
|
||||
**
|
||||
** This header is intended to be incorporated as part of the advice system implementation (advice.cpp).
|
||||
** It is _not usable as an external interface_. But it is written in a rather self-contained manner,
|
||||
** It is \em not usable as an external interface. But it is written in a rather self-contained manner,
|
||||
** in order to be testable in isolation. To this end, the actual PointOfAdvice entities \a POA organised
|
||||
** by this index datastructure remain abstract (defined as template parameter), and are only manipulated
|
||||
** through the following functions:
|
||||
** - `hash_value(POA)`
|
||||
** - `POA::getMatcher()`
|
||||
** - `POA::getSolution()`
|
||||
** - `POA::setSolution(solution*)`
|
||||
**
|
||||
** # Implementation notes
|
||||
** - \c hash_value(POA)
|
||||
** - \c POA::getMatcher()
|
||||
** - \c POA::getSolution()
|
||||
** - \c POA::setSolution(solution*)
|
||||
**
|
||||
** \par implementation notes
|
||||
** The advice binding index is implemented by two hashtables holding Binding::Matcher entries.
|
||||
** Each entry associates a back-link to the corresponding POA (PointOfAdvice), which is assumed
|
||||
** to be maintained outside the index. PointOfAdvice is an type-erased interface baseclass.
|
||||
|
|
@ -75,8 +74,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_ADVICE_INDEX_H
|
||||
#define VESSEL_ADVICE_INDEX_H
|
||||
#ifndef LUMIERA_ADVICE_INDEX_H
|
||||
#define LUMIERA_ADVICE_INDEX_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
|
|
@ -86,12 +85,12 @@
|
|||
#include "lib/format-obj.hpp"
|
||||
#include "lib/util-foreach.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "vessel/advice/binding.hpp"
|
||||
#include "common/advice/binding.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace advice {
|
||||
|
||||
namespace error = lumiera::error;
|
||||
|
|
@ -578,5 +577,5 @@ namespace advice {
|
|||
#undef VERIFY
|
||||
|
||||
|
||||
}} // namespace vessel::advice
|
||||
#endif /*VESSEL_ADVICE_INDEX_H*/
|
||||
}} // namespace lumiera::advice
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Voyage - global application initialisation and behaviour
|
||||
AppState - application initialisation and behaviour
|
||||
|
||||
Copyright (C)
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
|
@ -12,27 +12,27 @@
|
|||
* *****************************************************************/
|
||||
|
||||
|
||||
/** @file voyage.cpp
|
||||
/** @file appstate.cpp
|
||||
** Implementation of the _main application object_ of Lumiera.
|
||||
** This is a service to manage some _really global_ state and to
|
||||
** organise, start and stop the ["Subsystems"](\ref subsys.hpp).
|
||||
** The vessel::Voyage object is set off by the `main()` function
|
||||
** and coordinates the lifecycle of all parts of the application.
|
||||
** The AppState object provides the building blocks for the
|
||||
** `main()` function to control the global lifecycle.
|
||||
**
|
||||
** @see main.cpp
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "vessel/voyage.hpp"
|
||||
#include "vessel/subsystem-runner.hpp"
|
||||
#include "common/appstate.hpp"
|
||||
#include "common/subsystem-runner.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "vessel/config-interface.h"
|
||||
#include "common/config-interface.h"
|
||||
|
||||
#include "vessel/interface.h"
|
||||
#include "vessel/interfaceregistry.h"
|
||||
#include "vessel/plugin.h"
|
||||
#include "common/interface.h"
|
||||
#include "common/interfaceregistry.h"
|
||||
#include "common/plugin.h"
|
||||
}
|
||||
|
||||
#include "lib/symbol.hpp"
|
||||
|
|
@ -41,12 +41,10 @@ extern "C" {
|
|||
|
||||
using lib::Literal;
|
||||
using std::unique_ptr;
|
||||
using lumiera::maybeThrow;
|
||||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace error = lumiera::error;
|
||||
namespace lumiera {
|
||||
|
||||
namespace { // implementation details
|
||||
|
||||
|
|
@ -70,19 +68,19 @@ namespace vessel {
|
|||
* static initialisation code accesses the instance).
|
||||
* @note all further application startup is conducted by \c main.cpp
|
||||
*/
|
||||
Voyage::Voyage()
|
||||
AppState::AppState()
|
||||
: setup_{LUMIERA_LOCATION_OF_BOOTSTRAP_INI}
|
||||
, subsystems_{}
|
||||
, emergency_{false}
|
||||
, core_up_{false}
|
||||
{ }
|
||||
|
||||
/** storage for the Voyage Singleton instance */
|
||||
lib::Depend<Voyage> Voyage::access;
|
||||
/** storage for the Appstate Singleton instance */
|
||||
lib::Depend<AppState> AppState::instance;
|
||||
|
||||
|
||||
string
|
||||
Voyage::fetchSetupValue (Literal key)
|
||||
AppState::fetchSetupValue (Literal key)
|
||||
{
|
||||
return setup_.get(key).as<string>();
|
||||
}
|
||||
|
|
@ -101,7 +99,7 @@ namespace vessel {
|
|||
|
||||
|
||||
void
|
||||
Voyage::init (Option& options)
|
||||
AppState::init (Option& options)
|
||||
{
|
||||
TRACE (common, "initialising application core...");
|
||||
|
||||
|
|
@ -126,7 +124,7 @@ namespace vessel {
|
|||
|
||||
|
||||
void
|
||||
Voyage::maybeStart (Subsys& subsys)
|
||||
AppState::maybeStart (lumiera::Subsys& subsys)
|
||||
{
|
||||
TRACE (common, "maybe startup %s...?", cStr(subsys));
|
||||
REQUIRE (subsystems_);
|
||||
|
|
@ -135,7 +133,7 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
using ExitCode = Voyage::ExitCode;
|
||||
typedef AppState::ExitCode ExitCode;
|
||||
|
||||
|
||||
/** @remark
|
||||
|
|
@ -151,7 +149,7 @@ namespace vessel {
|
|||
* is activated.
|
||||
*/
|
||||
ExitCode
|
||||
Voyage::maybeWait()
|
||||
AppState::maybeWait()
|
||||
{
|
||||
if (subsystems_)
|
||||
{
|
||||
|
|
@ -177,7 +175,7 @@ namespace vessel {
|
|||
|
||||
|
||||
ExitCode
|
||||
Voyage::abort (lumiera::Error& problem)
|
||||
AppState::abort (lumiera::Error& problem)
|
||||
{
|
||||
|
||||
ERROR (common, "Aborting Lumiera after unhandled error: %s", cStr(problem.what()));
|
||||
|
|
@ -202,7 +200,7 @@ namespace vessel {
|
|||
|
||||
|
||||
ExitCode
|
||||
Voyage::abort () noexcept
|
||||
AppState::abort () noexcept
|
||||
{
|
||||
log_and_clear_unexpected_errorstate();
|
||||
|
||||
|
|
@ -222,11 +220,11 @@ namespace vessel {
|
|||
|
||||
|
||||
/** anything which should be closed as late as possible and after
|
||||
* the normal shutdown sequence can be placed into the Voyage dtor.
|
||||
* the normal shutdown sequence can be placed into the AppState dtor.
|
||||
* But note though, when the application is halted unconditionally,
|
||||
* no dtors will be executed.
|
||||
*/
|
||||
Voyage::~Voyage()
|
||||
AppState::~AppState()
|
||||
{
|
||||
if (core_up_)
|
||||
try
|
||||
|
|
@ -243,4 +241,4 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
VOYAGE.hpp - application initialisation and behaviour
|
||||
APPSTATE.hpp - application initialisation and behaviour
|
||||
|
||||
Copyright (C)
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
*/
|
||||
|
||||
/** @file voyage.hpp
|
||||
/** @file appstate.hpp
|
||||
** Registering and managing primary application-global services.
|
||||
** This can be considered the "main" object of the Lumiera application
|
||||
** Besides encapsulating the logic to start up the fundamental parts of
|
||||
** the application, there is a mechanism for registering \em subsystems
|
||||
** to be brought up and shut down in order. The vessel::Voyage will issue
|
||||
** global application lifecycle events (where other parts may have attached
|
||||
** to be brought up and shut down in order. AppState will issue the global
|
||||
** application lifecycle events (where other parts may have registered
|
||||
** callbacks) and provides the top-level catch-all error handling.
|
||||
**
|
||||
** @see LifecycleHook
|
||||
|
|
@ -28,15 +28,15 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_VOYAGE_H
|
||||
#define VESSEL_VOYAGE_H
|
||||
#ifndef LUMIERA_APPSTATE_H
|
||||
#define LUMIERA_APPSTATE_H
|
||||
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "vessel/option.hpp"
|
||||
#include "vessel/subsys.hpp"
|
||||
#include "vessel/basic-setup.hpp"
|
||||
#include "common/option.hpp"
|
||||
#include "common/subsys.hpp"
|
||||
#include "common/basic-setup.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
|
||||
|
|
@ -55,28 +55,29 @@ namespace vessel {
|
|||
* The Lumiera Application state and basic initialisation.
|
||||
* Singleton to hold global flags directing the overall application behaviour,
|
||||
* responsible for triggering lifecycle events and performing early initialisation tasks.
|
||||
* @warning don't use vessel::Voyage in destructors.
|
||||
* AppState services are available already from static initialisation code.
|
||||
* @warning don't use AppState in destructors.
|
||||
*/
|
||||
class Voyage
|
||||
class AppState
|
||||
: util::NonCopyable
|
||||
{
|
||||
private:
|
||||
Voyage();
|
||||
~Voyage();
|
||||
AppState ();
|
||||
|
||||
friend class lib::DependencyFactory<Voyage>;
|
||||
~AppState ();
|
||||
friend class lib::DependencyFactory<AppState>;
|
||||
|
||||
|
||||
public:
|
||||
/** get the (single) vessel::Voyage instance.
|
||||
/** get the (single) AppState instance.
|
||||
* @warning don't use it after the end of main()! */
|
||||
static lib::Depend<Voyage> access;
|
||||
static lib::Depend<AppState> instance;
|
||||
|
||||
|
||||
/** evaluate the result of option parsing and maybe additional configuration
|
||||
* such as to be able to determine the further behaviour of the application.
|
||||
* Set the internal state within this object accordingly. */
|
||||
void init (Option& options);
|
||||
void init (lumiera::Option& options);
|
||||
|
||||
|
||||
/** access basic application setup values (from \c setup.ini) */
|
||||
|
|
@ -87,7 +88,7 @@ namespace vessel {
|
|||
* needs to be pulled up and, if necessary, register the Subsys and its
|
||||
* prerequisites to be maintained throughout the application's lifetime.
|
||||
*/
|
||||
void maybeStart (Subsys&);
|
||||
void maybeStart (lumiera::Subsys&);
|
||||
|
||||
|
||||
enum ExitCode {
|
||||
|
|
@ -132,5 +133,6 @@ namespace vessel {
|
|||
};
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_VOYAGE_H*/
|
||||
} // namespace lumiera
|
||||
|
||||
#endif
|
||||
|
|
@ -24,16 +24,19 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "vessel/basic-setup.hpp"
|
||||
#include "common/basic-setup.hpp"
|
||||
#include "lib/searchpath.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/file.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
}
|
||||
#include <fstream>
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
using std::ifstream;
|
||||
|
|
@ -110,4 +113,4 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
|
@ -35,14 +35,14 @@
|
|||
** be mapped into FSH compliant installation folders by the
|
||||
** packager.
|
||||
**
|
||||
** @see vessel::Voyage::Voyage()
|
||||
** @see lumiera::AppState::AppState()
|
||||
** @see main.cpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_BASIC_SETUP_H
|
||||
#define VESSEL_BASIC_SETUP_H
|
||||
#ifndef COMMON_BASIC_SETUP_H
|
||||
#define COMMON_BASIC_SETUP_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
|
@ -58,12 +58,11 @@
|
|||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace err = lumiera::error;
|
||||
namespace opt = boost::program_options;
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace opt = boost::program_options;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -84,7 +83,7 @@ namespace vessel {
|
|||
* configuration as a replacement for the time being.
|
||||
*
|
||||
* @see configfacade.hpp
|
||||
* @see vessel::Voyage
|
||||
* @see AppState
|
||||
*/
|
||||
class BasicSetup
|
||||
: util::NonCopyable
|
||||
|
|
@ -115,10 +114,10 @@ namespace vessel {
|
|||
__ensure_hasKey (string const& key) const
|
||||
{
|
||||
if (!util::contains (settings, key))
|
||||
throw err::Logic ("Key \""+key+"\" not found in setup.ini");
|
||||
throw error::Logic ("Key \""+key+"\" not found in setup.ini");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_BASIC_SETUP_H*/
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "vessel/config-interface.h"
|
||||
#include "vessel/config.h"
|
||||
#include "common/config-interface.h"
|
||||
#include "common/config.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ LUMIERA_EXPORT(
|
|||
|
||||
#ifndef LUMIERA_PLUGIN
|
||||
|
||||
#include "vessel/interfaceregistry.h"
|
||||
#include "common/interfaceregistry.h"
|
||||
void
|
||||
lumiera_config_interface_init (void)
|
||||
{
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
#define LUMIERA_CONFIG_INTERFACE_H
|
||||
|
||||
|
||||
#include "vessel/interface.h"
|
||||
#include "common/interface.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -24,8 +24,8 @@
|
|||
#include "lib/safeclib.h"
|
||||
#include "lib/tmpbuf.h"
|
||||
|
||||
#include "vessel/config-lookup.h"
|
||||
#include "vessel/config.h"
|
||||
#include "common/config-lookup.h"
|
||||
#include "common/config.h"
|
||||
|
||||
/* we only use one fatal error for now, when allocation in the config system fail, something else is pretty wrong */
|
||||
LUMIERA_ERROR_DEFINE (CONFIG_LOOKUP, "config lookup failure");
|
||||
|
|
@ -39,7 +39,7 @@ typedef struct lumiera_config_lookupentry_struct lumiera_config_lookupentry;
|
|||
typedef lumiera_config_lookupentry* LumieraConfigLookupentry;
|
||||
|
||||
|
||||
#include "vessel/configitem.h"
|
||||
#include "common/configitem.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
** @todo as of 11/2016 the situation is basically the same: this is placeholder code
|
||||
** and just implemented enough to keep us going without violating the architecture vision
|
||||
**
|
||||
** @see vessel::Query
|
||||
** @see lumiera::Query
|
||||
** @see mobject::session::DefsManager
|
||||
** @see asset::StructFactory
|
||||
** @see config-resolver.hpp specialised setup for the Steam-Layer
|
||||
|
|
@ -50,13 +50,13 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_CONFIG_RULES_H
|
||||
#define VESSEL_CONFIG_RULES_H
|
||||
#ifndef LUMIERA_CONFIG_RULES_H
|
||||
#define LUMIERA_CONFIG_RULES_H
|
||||
|
||||
#include "lib/p.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/meta/generator.hpp"
|
||||
#include "vessel/query.hpp"
|
||||
#include "common/query.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -65,12 +65,11 @@
|
|||
namespace lumiera {
|
||||
namespace error {
|
||||
LUMIERA_ERROR_DECLARE (CAPABILITY_QUERY); ///< unresolvable capability query.
|
||||
}}
|
||||
|
||||
namespace vessel {
|
||||
}
|
||||
|
||||
using std::string;
|
||||
using lib::P;
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////TICKET #705 this is draft/preview code; a real resolution system needs to be integrated
|
||||
|
|
@ -100,7 +99,7 @@ namespace vessel {
|
|||
|
||||
using lib::Symbol;
|
||||
using lib::Literal;
|
||||
using vessel::Query;
|
||||
using lumiera::Query;
|
||||
|
||||
/** placeholder definition for later.
|
||||
* @todo intention is to integrate with lib::Symbol
|
||||
|
|
@ -148,8 +147,8 @@ namespace vessel {
|
|||
* we use a mock implementation.
|
||||
* (this code works and is already used 2/2008)
|
||||
* @todo retrofit this to install and use a QueryResolver
|
||||
* @see vessel::query::LookupPreconfigured
|
||||
* @see vessel::query::MockTable
|
||||
* @see lumiera::query::LookupPreconfigured
|
||||
* @see lumiera::query::MockTable
|
||||
*/
|
||||
template<class TY>
|
||||
class QueryHandler
|
||||
|
|
@ -218,11 +217,11 @@ namespace vessel {
|
|||
* will magically succeed with every candidate object provided. This
|
||||
* is currently necessary to get objects into the defaults manager,
|
||||
* as the query system is not able to do real query resolution */
|
||||
void setFakeBypass(vessel::QueryKey const& q);
|
||||
bool isFakeBypass (vessel::QueryKey const& q);
|
||||
void setFakeBypass(lumiera::QueryKey const& q);
|
||||
bool isFakeBypass (lumiera::QueryKey const& q);
|
||||
/////////////////////////////////////////////////////////////////////////////TICKET 710
|
||||
|
||||
} // namespace query
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_CONFIG_RULES_H*/
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "include/logging.h"
|
||||
#include "lib/tmpbuf.h"
|
||||
#include "vessel/config.h"
|
||||
#include "common/config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
#include "lib/tmpbuf.h"
|
||||
|
||||
|
||||
#include "vessel/config.h"
|
||||
#include "common/config.h"
|
||||
|
||||
extern LumieraConfig lumiera_global_config;
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
#include "include/logging.h"
|
||||
#include "lib/safeclib.h"
|
||||
#include "lib/tmpbuf.h"
|
||||
#include "vessel/config.h"
|
||||
#include "common/config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
**
|
||||
** @todo as of 2016, this code is not in any meaningful use
|
||||
**
|
||||
** @see vessel::BasicSetup simple start-up configuration
|
||||
** @see lumiera::BasicSetup simple start-up configuration
|
||||
** @see http://lumiera.org/documentation/technical/vault/ConfigLoader.html ConfigLoader draft from 2008
|
||||
*/
|
||||
|
||||
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
#include "lib/mutex.h"
|
||||
#include "vessel/config-lookup.h"
|
||||
#include "vessel/configitem.h"
|
||||
#include "common/config-lookup.h"
|
||||
#include "common/configitem.h"
|
||||
|
||||
#include <nobug.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
|
||||
#include "lib/safeclib.h"
|
||||
#include "vessel/configentry.h"
|
||||
#include "common/configentry.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef COMMON_CONFIGENTRY_H
|
||||
#define COMMON_CONFIGENTRY_H
|
||||
|
||||
#include "vessel/configitem.h"
|
||||
#include "common/configitem.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
|
@ -31,16 +31,16 @@
|
|||
|
||||
|
||||
#include "include/logging.h"
|
||||
#include "include/lifecycle.hpp"
|
||||
#include "vessel/spine/config-facade.h"
|
||||
#include "vessel/voyage.hpp"
|
||||
#include "include/lifecycle.h"
|
||||
#include "include/config-facade.h"
|
||||
#include "common/appstate.hpp"
|
||||
#include "lib/searchpath.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/format-util.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "vessel/config.h"
|
||||
#include "common/config.h"
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -61,9 +61,7 @@ extern "C" {
|
|||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace spine {
|
||||
namespace error = lumiera::error;
|
||||
namespace lumiera {
|
||||
|
||||
using util::isnil;
|
||||
using lib::Literal;
|
||||
|
|
@ -90,7 +88,7 @@ namespace spine {
|
|||
|
||||
Config::Config ()
|
||||
{
|
||||
string extendedConfigSearchPath = Voyage::access().fetchSetupValue (KEY_CONFIG_PATH);
|
||||
string extendedConfigSearchPath = AppState::instance().fetchSetupValue (KEY_CONFIG_PATH);
|
||||
lumiera_config_init (cStr(extendedConfigSearchPath));
|
||||
TRACE (config, "Config system ready.");
|
||||
}
|
||||
|
|
@ -110,7 +108,7 @@ namespace spine {
|
|||
string
|
||||
Config::get (lib::Literal key)
|
||||
{
|
||||
string value = Voyage::access().fetchSetupValue (key);
|
||||
string value = AppState::instance().fetchSetupValue (key);
|
||||
if (isnil (value))
|
||||
throw error::Config ("Configuration value for key=\""+key+"\" is missing");
|
||||
|
||||
|
|
@ -119,14 +117,14 @@ namespace spine {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
extern "C" { /* ==== implementation C interface for accessing setup.ini ======= */
|
||||
|
||||
|
||||
using std::string;
|
||||
using vessel::spine::Config;
|
||||
using lumiera::Config;
|
||||
using lib::SearchPathSplitter;
|
||||
using util::isnil;
|
||||
|
||||
|
|
@ -141,4 +139,4 @@ extern "C" { /* ==== implementation C interface for accessing setup.ini =======
|
|||
}();
|
||||
return cStr(pathSpec);
|
||||
}
|
||||
}}// namespace vessel::spine
|
||||
}
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
#include "lib/safeclib.h"
|
||||
#include "lib/tmpbuf.h"
|
||||
|
||||
#include "vessel/config.h"
|
||||
#include "vessel/configitem.h"
|
||||
#include "vessel/configentry.h"
|
||||
#include "common/config.h"
|
||||
#include "common/configitem.h"
|
||||
#include "common/configentry.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -54,7 +54,7 @@ typedef lumiera_configitem* LumieraConfigitem;
|
|||
|
||||
struct lumiera_configitem_vtable;
|
||||
|
||||
#include "vessel/config-lookup.h"
|
||||
#include "common/config-lookup.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
|
@ -27,8 +27,8 @@
|
|||
#include "lib/sync.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "vessel/instancehandle.hpp"
|
||||
#include "vessel/option.hpp"
|
||||
#include "common/instancehandle.hpp"
|
||||
#include "common/option.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
@ -38,8 +38,8 @@ namespace stage {
|
|||
|
||||
using std::string;
|
||||
using std::unique_ptr;
|
||||
using vessel::Subsys;
|
||||
using vessel::InstanceHandle;
|
||||
using lumiera::Subsys;
|
||||
using lumiera::InstanceHandle;
|
||||
using lib::Sync;
|
||||
using lib::RecursiveLock_NoWait;
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ namespace stage {
|
|||
struct GuiRunner
|
||||
: util::NonCopyable
|
||||
{
|
||||
using GuiHandle = InstanceHandle<LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1)>;
|
||||
typedef InstanceHandle<LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1)> GuiHandle;
|
||||
|
||||
GuiHandle theGUI_;
|
||||
|
||||
|
|
@ -89,13 +89,13 @@ namespace stage {
|
|||
|
||||
|
||||
class GuiSubsysDescriptor
|
||||
: public vessel::Subsys,
|
||||
: public lumiera::Subsys,
|
||||
public Sync<RecursiveLock_NoWait>
|
||||
{
|
||||
operator string() const { return "Lumiera GTK GUI"; }
|
||||
|
||||
bool
|
||||
shouldStart (vessel::Option& opts) override
|
||||
shouldStart (lumiera::Option& opts) override
|
||||
{
|
||||
if (opts.isHeadless() or 0 < opts.getPort())
|
||||
{
|
||||
|
|
@ -107,7 +107,7 @@ namespace stage {
|
|||
}
|
||||
|
||||
bool
|
||||
start (vessel::Option&, Subsys::SigTerm termNotification) override
|
||||
start (lumiera::Option&, Subsys::SigTerm termNotification) override
|
||||
{
|
||||
Lock guard{this};
|
||||
if (facade)
|
||||
|
|
@ -188,7 +188,7 @@ namespace stage {
|
|||
|
||||
|
||||
/** @internal intended for use by main(). */
|
||||
vessel::Subsys&
|
||||
lumiera::Subsys&
|
||||
GuiFacade::getDescriptor()
|
||||
{
|
||||
return theDescriptor();
|
||||
|
|
@ -28,8 +28,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_INSTANCEHANDLE_H
|
||||
#define VESSEL_INSTANCEHANDLE_H
|
||||
#ifndef LUMIERA_INSTANCEHANDLE_H
|
||||
#define LUMIERA_INSTANCEHANDLE_H
|
||||
|
||||
|
||||
#include "include/logging.h"
|
||||
|
|
@ -38,15 +38,15 @@
|
|||
#include "lib/depend-inject.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "vessel/interface.h"
|
||||
#include "vessel/interfaceregistry.h"
|
||||
#include "common/interface.h"
|
||||
#include "common/interfaceregistry.h"
|
||||
}
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ namespace vessel {
|
|||
* between an InstanceHandle and a facade interface,
|
||||
* which is going to be implemented through the given
|
||||
* interface/plugin. This way, creating the InstanceHandle
|
||||
* automatically creates a vessel::facade::Proxy, to route
|
||||
* automatically creates a lumiera::facade::Proxy, to route
|
||||
* any facade calls through the interface/plugin. Similarly,
|
||||
* when destroying the InstanceHandle, the proxy will be closed.
|
||||
*/
|
||||
|
|
@ -267,5 +267,5 @@ namespace vessel {
|
|||
};
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_INSTANCEHANDLE_H*/
|
||||
} // namespace lumiera
|
||||
#endif /*LUMIERA_INSTANCEHANDLE_H*/
|
||||
|
|
@ -49,7 +49,7 @@ namespace error = lumiera::error;
|
|||
#include "lib/time/quantiser.hpp"
|
||||
#include "lib/time/timecode.hpp"
|
||||
#include "lib/time/mutation.hpp"
|
||||
#include "vessel/advice.hpp"
|
||||
#include "common/advice.hpp"
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -59,7 +59,7 @@ namespace time {
|
|||
|
||||
using util::_Fmt;
|
||||
|
||||
namespace advice = vessel::advice;
|
||||
namespace advice = lumiera::advice;
|
||||
|
||||
|
||||
PQuant
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
#ifndef COMMON_INTERFACEDESCRIPTOR_H
|
||||
#define COMMON_INTERFACEDESCRIPTOR_H
|
||||
|
||||
#include "vessel/interface.h"
|
||||
#include "common/interface.h"
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -26,10 +26,10 @@
|
|||
#include "lib/recmutex.h"
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
#include "vessel/plugin.h"
|
||||
#include "vessel/interface.h"
|
||||
#include "common/plugin.h"
|
||||
#include "common/interface.h"
|
||||
|
||||
#include "vessel/interfaceregistry.h"
|
||||
#include "common/interfaceregistry.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
#include <nobug.h>
|
||||
|
||||
#include "vessel/plugin.h"
|
||||
#include "vessel/interfaceregistry.h"
|
||||
#include "common/plugin.h"
|
||||
#include "common/interfaceregistry.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -26,8 +26,8 @@
|
|||
#include "lib/recmutex.h"
|
||||
#include "lib/psplay.h"
|
||||
|
||||
#include "vessel/interface.h"
|
||||
#include "vessel/plugin.h"
|
||||
#include "common/interface.h"
|
||||
#include "common/plugin.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
|
@ -24,13 +24,13 @@
|
|||
|
||||
|
||||
#include "include/gui-notification-facade.h"
|
||||
#include "vessel/spine/interfaceproxy.hpp"
|
||||
#include "include/interfaceproxy.hpp"
|
||||
|
||||
namespace stage {
|
||||
/** static storage for the facade access front-end */
|
||||
lib::Depend<GuiNotification> GuiNotification::facade;
|
||||
}
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
namespace facade {
|
||||
using stage::ID;
|
||||
using lib::diff::GenNode;
|
||||
|
|
@ -71,4 +71,4 @@ namespace facade {
|
|||
template
|
||||
class Link<Interface,Facade>;
|
||||
|
||||
}} //namespace vessel::facade
|
||||
}} //namespace facade::lumiera
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "vessel/option.hpp"
|
||||
#include "common/option.hpp"
|
||||
|
||||
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ namespace op = boost::program_options;
|
|||
using lib::VectS;
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
/** set up an options parser to use the application commandline.
|
||||
* Recognises the following options
|
||||
|
|
@ -155,4 +155,4 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
|
@ -28,14 +28,14 @@
|
|||
** [Boost program options library] : https://www.boost.org/doc/libs/1_83_0/doc/html/program_options.html
|
||||
**
|
||||
** @see basic-setup.hpp
|
||||
** @see vessel::Voyage
|
||||
** @see vessel::spine::Config
|
||||
** @see lumiera::AppState
|
||||
** @see lumiera::Config
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_OPTION_H
|
||||
#define VESSEL_OPTION_H
|
||||
#ifndef LUMIERA_OPTION_H
|
||||
#define LUMIERA_OPTION_H
|
||||
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/cmdline.hpp"
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
|
|
@ -95,5 +95,5 @@ namespace vessel {
|
|||
ostream& operator<< (ostream& os, const Option& to);
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_OPTION_H*/
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "include/logging.h"
|
||||
#include "lib/tmpbuf.h"
|
||||
#include "vessel/plugin.h"
|
||||
#include "common/plugin.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <nobug.h>
|
||||
|
|
@ -25,10 +25,10 @@
|
|||
#include "lib/recmutex.h"
|
||||
#include "lib/error.h"
|
||||
|
||||
#include "vessel/spine/config-facade.h"
|
||||
#include "vessel/interfaceregistry.h"
|
||||
#include "vessel/config.h"
|
||||
#include "vessel/plugin.h"
|
||||
#include "include/config-facade.h"
|
||||
#include "common/interfaceregistry.h"
|
||||
#include "common/config.h"
|
||||
#include "common/plugin.h"
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
#include "lib/psplay.h"
|
||||
#include "lib/error.h"
|
||||
|
||||
#include "vessel/interface.h"
|
||||
#include "common/interface.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <nobug.h>
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
** tag to indicate the kind of query. In addition, queries are usually required to provide
|
||||
** a syntactical representation, allowing to transform each query into a generic query.
|
||||
**
|
||||
** To resolve the query, a vessel::QueryResolver instance is necessary, and this
|
||||
** To resolve the query, a lumiera::QueryResolver instance is necessary, and this
|
||||
** query resolver needs the ability to deal with this specific kind of query. Typically
|
||||
** this is achieved by installing a resolution function into the resolver on application start.
|
||||
** The QueryResolver returns a result set, actually a Query::Cursor, which can be used to
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
** @note as of 1/2013 this is rather a concept draft, but some parts of the code base
|
||||
** are already actively using some more specific queries
|
||||
**
|
||||
** @see vessel::QueryResolver
|
||||
** @see lumiera::QueryResolver
|
||||
** @see mobject::session::DefsManager
|
||||
** @see asset::StructFactory
|
||||
** @see config-resolver.hpp specialised setup for the Steam-Layer
|
||||
|
|
@ -62,8 +62,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_QUERY_H
|
||||
#define VESSEL_QUERY_H
|
||||
#ifndef LUMIERA_QUERY_H
|
||||
#define LUMIERA_QUERY_H
|
||||
|
||||
|
||||
#include "lib/hash-combine.hpp"
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
#include <string>
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using lib::IxID;
|
||||
using lib::Symbol;
|
||||
|
|
@ -232,7 +232,7 @@ namespace vessel {
|
|||
* of specific resolution mechanisms. This way, clients may retrieve a set of results,
|
||||
* where each result represents a possible solution to the original query.
|
||||
*
|
||||
* @remarks vessel::Query is an interface, but can be used as-is to represent a generic query.
|
||||
* @remarks lumiera::Query is an interface, but can be used as-is to represent a generic query.
|
||||
* Specialised subclasses are required to provide a syntactic representation, but are
|
||||
* free to do so only on demand. In this case, generate an \em empty lib::QueryText
|
||||
* definition and implement the Query#buildSyntacticRepresentation function.
|
||||
|
|
@ -589,5 +589,5 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_QUERY_H*/
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -20,17 +20,16 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "vessel/query.hpp"
|
||||
#include "vessel/config-rules.hpp"
|
||||
#include "common/query.hpp"
|
||||
#include "common/config-rules.hpp"
|
||||
|
||||
using vessel::QueryKey;
|
||||
using lumiera::QueryKey;
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace error {
|
||||
LUMIERA_ERROR_DEFINE (CAPABILITY_QUERY, "unresolvable capability query");
|
||||
}}
|
||||
namespace vessel {
|
||||
}
|
||||
namespace query {
|
||||
|
||||
|
||||
|
|
@ -51,4 +50,4 @@ namespace vessel {
|
|||
/////////////////////////////////////////////////////////////////////////////TICKET 710
|
||||
|
||||
}// namespace query
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
|
@ -30,23 +30,25 @@
|
|||
|
||||
|
||||
|
||||
#ifndef VESSEL_QUERY_DEFS_MANAGER_IMPL_H
|
||||
#define VESSEL_QUERY_DEFS_MANAGER_IMPL_H
|
||||
#ifndef LUMIERA_QUERY_DEFS_MANAGER_IMPL_H
|
||||
#define LUMIERA_QUERY_DEFS_MANAGER_IMPL_H
|
||||
|
||||
|
||||
#include "vessel/query/defs-manager.hpp"
|
||||
#include "vessel/query/defs-registry.hpp"
|
||||
#include "vessel/config-rules.hpp"
|
||||
#include "common/query/defs-manager.hpp"
|
||||
#include "common/query/defs-registry.hpp"
|
||||
#include "common/config-rules.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/error.hpp"
|
||||
|
||||
using util::_Fmt;
|
||||
|
||||
namespace vessel {
|
||||
using steam::ConfigResolver;
|
||||
using lumiera::query::QueryHandler; ///////TODO preliminary interface defined in config-rules.hpp
|
||||
|
||||
|
||||
namespace lumiera{
|
||||
namespace query {
|
||||
namespace err = lumiera::error;
|
||||
|
||||
using util::_Fmt;
|
||||
using steam::ConfigResolver;
|
||||
|
||||
|
||||
|
||||
|
|
@ -137,12 +139,12 @@ namespace query {
|
|||
res = create (capabilities); // not yet known as default, create new
|
||||
|
||||
if (!res)
|
||||
throw err::Config (_Fmt("The following Query could not be resolved: %s.")
|
||||
% capabilities.rebuild().asKey()
|
||||
, LERR_(CAPABILITY_QUERY) );
|
||||
throw error::Config (_Fmt("The following Query could not be resolved: %s.")
|
||||
% capabilities.rebuild().asKey()
|
||||
, LERR_(CAPABILITY_QUERY) );
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
}} // namespace vessel::query
|
||||
#endif /* VESSEL_QUERY_DEFS_MANAGER_IMPL_H */
|
||||
}} // namespace lumiera::query
|
||||
#endif /* LUMIERA_QUERY_DEFS_MANAGER_IMPL_H */
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
** importance that we build our implementations with this goal in mind
|
||||
**
|
||||
** # Configuration Query Interface
|
||||
** The [Defaults Manager](\ref vessel::query::DefsManager) exposes an interface
|
||||
** The [Defaults Manager](\ref lumiera::query::DefsManager) exposes an interface
|
||||
** similar to a database. The intended audience of this interface is the writer
|
||||
** of low-level implementation code. This facade interface is meant to create
|
||||
** a more familiar front-end to an essentially logic and rules driven
|
||||
|
|
@ -90,21 +90,23 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_QUERY_DEFS_MANAGER_H
|
||||
#define VESSEL_QUERY_DEFS_MANAGER_H
|
||||
#ifndef LUMIERA_QUERY_DEFS_MANAGER_H
|
||||
#define LUMIERA_QUERY_DEFS_MANAGER_H
|
||||
|
||||
|
||||
#include "lib/p.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "vessel/query.hpp"
|
||||
#include "common/query.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace query {
|
||||
|
||||
|
||||
using lumiera::Query;
|
||||
using std::unique_ptr;
|
||||
|
||||
namespace impl { class DefsRegistry; }
|
||||
|
|
@ -183,7 +185,7 @@ namespace query {
|
|||
// < class TAR, ///< the target to query for
|
||||
// template <class> class SMP ///< smart pointer class to wrap the result
|
||||
// >
|
||||
// SMP<TAR> operator() (const vessel::Query<TAR>&);
|
||||
// SMP<TAR> operator() (const lumiera::Query<TAR>&);
|
||||
|
||||
// 12/09: according to my current knowledge of template metaprogramming, the answer is "no",
|
||||
// but we could use a traits template to set up a fixed association of smart pointers
|
||||
|
|
@ -196,5 +198,5 @@ namespace query {
|
|||
|
||||
|
||||
|
||||
}} // namespace vessel::query
|
||||
#endif /*VESSEL_QUERY_DEFS_MANAGER_H*/
|
||||
}} // namespace lumiera::query
|
||||
#endif
|
||||
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
|
||||
|
||||
#ifndef VESSEL_QUERY_DEFS_REGISTRY_H
|
||||
#define VESSEL_QUERY_DEFS_REGISTRY_H
|
||||
#ifndef LUMIERA_QUERY_DEFS_REGISTRY_H
|
||||
#define LUMIERA_QUERY_DEFS_REGISTRY_H
|
||||
|
||||
|
||||
#include "lib/p.hpp"
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
#include "lib/sync-classlock.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/query-util.hpp"
|
||||
#include "vessel/query.hpp"
|
||||
#include "common/query.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
|
||||
#include <set>
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
#include <memory>
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera{
|
||||
namespace query {
|
||||
|
||||
using lib::P;
|
||||
|
|
@ -339,5 +339,5 @@ namespace query {
|
|||
using impl::DefsRegistry;
|
||||
|
||||
|
||||
}} // namespace vessel::query
|
||||
#endif /*VESSEL_QUERY_DEFS_REGISTRY_H*/
|
||||
}} // namespace lumiera::query
|
||||
#endif
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
|
||||
#include "lib/multifact.hpp"
|
||||
#include "vessel/query/query-resolver.hpp"
|
||||
#include "common/query/query-resolver.hpp"
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
|
||||
|
||||
|
|
@ -118,4 +118,4 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
|
@ -23,11 +23,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_QUERY_RESOLVER_H
|
||||
#define VESSEL_QUERY_RESOLVER_H
|
||||
#ifndef LUMIERA_QUERY_RESOLVER_H
|
||||
#define LUMIERA_QUERY_RESOLVER_H
|
||||
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "vessel/query.hpp"
|
||||
#include "common/query.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
using std::function;
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::string;
|
||||
|
|
@ -164,5 +164,5 @@ namespace vessel {
|
|||
}
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_QUERY_RESOLVER_H*/
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -18,17 +18,17 @@
|
|||
** which are prompted by main() to start/stop.
|
||||
**
|
||||
** @see subsystem-runner.hpp
|
||||
** @see vessel::Voyage
|
||||
** @see lumiera::AppState
|
||||
** @see facade.cpp
|
||||
** @see main.cpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "vessel/subsys.hpp"
|
||||
#include "common/subsys.hpp"
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
|
||||
|
||||
|
|
@ -56,4 +56,4 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
|
@ -18,21 +18,21 @@
|
|||
** While the activation of the key components is controlled by options, maybe
|
||||
** some prerequisite subsystems need to be pulled up, and in case of an regular
|
||||
** or irregular exit of a given subsystem, the whole dependency graph needs
|
||||
** to be brought down in a clean manner. The purpose of vessel::Subsys is
|
||||
** to be brought down in a clean manner. The purpose of lumiera::Subsys is
|
||||
** to maintain these in a self-explanatory script-like fashion within main(),
|
||||
** without forcing the individual subsystems into a fixed implementation scheme.
|
||||
** The only requirement is that for each subsystem there is sort-of an entry
|
||||
** point or facade object, providing a Subsys descriptor instance to be
|
||||
** used within main.
|
||||
**
|
||||
** @see vessel::Voyage
|
||||
** @see vessel::Option
|
||||
** @see lumiera::AppState
|
||||
** @see lumiera::Option
|
||||
** @see main.cpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_SUBSYS_H
|
||||
#define VESSEL_SUBSYS_H
|
||||
#ifndef LUMIERA_SUBSYS_H
|
||||
#define LUMIERA_SUBSYS_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
using std::function;
|
||||
|
|
@ -54,8 +54,8 @@ namespace vessel {
|
|||
|
||||
/**
|
||||
* Dependencies and lifecycle of a partially independent Subsystem of the Application.
|
||||
* After launch from the main() function, the vessel::Voyage uses these descriptors
|
||||
* to pull up, maintain and shut down the primary parts of the Lumiera application.
|
||||
* Using such descriptors, AppState as activated from main() is able to pull up,
|
||||
* maintain and shut down the primary parts of the Application.
|
||||
* @note synchronisation is up to the implementor.
|
||||
*/
|
||||
class Subsys
|
||||
|
|
@ -83,7 +83,7 @@ namespace vessel {
|
|||
* if this subsystem should be activated.
|
||||
* @note even if not started explicitly, it could still
|
||||
* be started as prerequisite of another one */
|
||||
virtual bool shouldStart (vessel::Option&) =0;
|
||||
virtual bool shouldStart (lumiera::Option&) =0;
|
||||
|
||||
|
||||
/** attempt to bring up this subsystem up. On return, the
|
||||
|
|
@ -95,7 +95,7 @@ namespace vessel {
|
|||
* @param SigTerm to be signalled by the subsystem.
|
||||
* @warning termination must be signalled reliably.
|
||||
* @return `true` if actually started. */
|
||||
virtual bool start (vessel::Option& options, SigTerm) =0;
|
||||
virtual bool start (lumiera::Option& options, SigTerm) =0;
|
||||
|
||||
|
||||
/** initiate termination of this subsystem.
|
||||
|
|
@ -124,6 +124,6 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
} // namespace lumiera
|
||||
|
||||
#endif /*VESSEL_SUBSYS_H*/
|
||||
#endif
|
||||
|
|
@ -15,8 +15,8 @@
|
|||
/** @file subsystem-runner.hpp
|
||||
** Manage execution of the independent [Subsystems](\ref subsys.hpp)
|
||||
** of the Lumiera application. The SubsystemRunner is used by
|
||||
** vessel::Voyage::init() for actually "performing" the various subsystems,
|
||||
** as defined by their [Subsystem descriptors](\ref vessel::Subsys). Together
|
||||
** lumiera::AppState::init() for actually "performing" the various subsystems,
|
||||
** as defined by their [Subsystem descriptors](\ref lumiera::Subsys). Together
|
||||
** these parts define the lifecycle protocol.
|
||||
**
|
||||
** @todo as of 2018, a design rework seems indicated eventually /////////////////////////TICKET #1177
|
||||
|
|
@ -35,22 +35,21 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_SUBSYSTEMRUNNER_H
|
||||
#define VESSEL_SUBSYSTEMRUNNER_H
|
||||
#ifndef LUMIERA_SUBSYSTEMRUNNER_H
|
||||
#define LUMIERA_SUBSYSTEMRUNNER_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/util-foreach.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "vessel/subsys.hpp"
|
||||
#include "common/subsys.hpp"
|
||||
#include "lib/sync.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace error = lumiera::error;
|
||||
namespace lumiera {
|
||||
|
||||
using lib::Sync;
|
||||
using lib::RecursiveLock_Waitable;
|
||||
|
|
@ -80,7 +79,7 @@ namespace vessel {
|
|||
* complete layer of the application (e.g. the GUI).
|
||||
*
|
||||
* # Protocol of operation
|
||||
* The SubsystemRunner is to be configured with a vessel::Option object first.
|
||||
* The SubsystemRunner is to be configured with a lumiera::Option object first.
|
||||
* Then, primary subsystems are [provided](\ref SubsystemRunner::maybeRun) for
|
||||
* eventual startup, which may depend on conditions defined by the subsystem.
|
||||
* When it turns out (by investigating the options) that a Subsystem is actually
|
||||
|
|
@ -103,8 +102,8 @@ namespace vessel {
|
|||
*
|
||||
* @todo 2018 this component works well but could be (re)written in a cleaner way ////////////////////////TICKET #1177
|
||||
*
|
||||
* @see vessel::Voyage
|
||||
* @see vessel::Subsys
|
||||
* @see lumiera::AppState
|
||||
* @see lumiera::Subsys
|
||||
* @see main.cpp
|
||||
*/
|
||||
class SubsystemRunner
|
||||
|
|
@ -210,5 +209,5 @@ namespace vessel {
|
|||
|
||||
|
||||
|
||||
} // namespace vessel
|
||||
#endif /*VESSEL_SUBSYSTEMRUNNER_H*/
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
/** @file config-facade.h
|
||||
** The vessel::spine::Config wrapper class addresses two issues.
|
||||
** The lumiera::Config wrapper class addresses two issues.
|
||||
** First, it registers startup and shutdown hooks to bring up the config system
|
||||
** as early as possible. Later, on application main initialisation, the global
|
||||
** config interface is opened and wrapped for convenient access from C++ code.
|
||||
|
|
@ -26,16 +26,16 @@
|
|||
** was detached and replaced by an _ini file solution_ based on lib Boost.
|
||||
**
|
||||
** @todo there ought to be an external Interface for the Config subsystem.
|
||||
** But the full-blown Config system isn't implemented yet anyway ////////////////////////////////////TICKET #1224 : Call for Design -- Layered Configuration System
|
||||
** But the full-blown Config system isn't implemented yet anyway
|
||||
**
|
||||
** @see config.h
|
||||
** @see vessel::Voyage
|
||||
** @see lumiera::AppState
|
||||
** @see main.cpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_SPINE_CONFIGFACADE_H
|
||||
#define VESSEL_SPINE_CONFIGFACADE_H
|
||||
#ifndef INTERFACE_CONFIGFACADE_H
|
||||
#define INTERFACE_CONFIGFACADE_H
|
||||
|
||||
|
||||
|
||||
|
|
@ -49,8 +49,7 @@
|
|||
#include <string>
|
||||
|
||||
|
||||
namespace vessel{
|
||||
namespace spine {
|
||||
namespace lumiera {
|
||||
|
||||
using std::string;
|
||||
|
||||
|
|
@ -78,7 +77,7 @@ namespace spine {
|
|||
|
||||
|
||||
|
||||
}} // namespace vessel::spine
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
|
||||
|
|
@ -94,5 +93,5 @@ namespace spine {
|
|||
const char* lumiera_get_plugin_path_default ();
|
||||
|
||||
|
||||
#endif /*C++ vs C*/
|
||||
#endif /*VESSEL_SPINE_CONFIGFACADE_H*/
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -12,7 +12,8 @@
|
|||
*/
|
||||
|
||||
/** @file display-handles.hpp
|
||||
** Opaque handles and similar typedefs used to communicate via facade interfaces.
|
||||
** Opaque handles and similar typedefs used to communicate via the
|
||||
** lumiera::Display and lumiera::DummyPlayer facade interfaces.
|
||||
**
|
||||
** @deprecated this is part of prototyping code; as of 5/2025 it is clear
|
||||
** that we will not use any of these interface schemes (yet something similar)
|
||||
|
|
@ -22,8 +23,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef VESSEL_SPINE_DISPLAY_HANDLES_H
|
||||
#define VESSEL_SPINE_DISPLAY_HANDLES_H
|
||||
#ifndef LUMIERA_DISPLAY_HANDLES_H
|
||||
#define LUMIERA_DISPLAY_HANDLES_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
|
@ -36,8 +37,7 @@ using DummyFrame = std::byte *;
|
|||
|
||||
|
||||
|
||||
namespace vessel {
|
||||
namespace spine {
|
||||
namespace lumiera {
|
||||
|
||||
/** Supported Displayer formats */
|
||||
enum DisplayerInput {
|
||||
|
|
@ -48,5 +48,5 @@ namespace spine {
|
|||
DISPLAY_BGR0,
|
||||
DISPLAY_RGB16
|
||||
};
|
||||
}} // namespace vessel::spine
|
||||
#endif /*VESSEL_SPINE_DISPLAY_HANDLES_H*/
|
||||
} // namespace lumiera
|
||||
#endif /*LUMIERA_DISPLAY_HANDLES_H*/
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue