LANDING: transition to GTK-3

This switches the Lumiera UI from GTK-2 to GTK-3
Unfortunately, this move breaks two crucial features, which have been
disabled for now: the display of video and our custom timeline widget.

Since both of these require some reworking, which in fact has already
started, we prefer to do the library and framework switch right away.
This commit is contained in:
Fischlurch 2015-05-30 17:11:41 +02:00
commit dece405801
95 changed files with 2144 additions and 1064 deletions

View file

@ -1,9 +1,20 @@
Startup and Shutdown of Subsystems
==================================
:Date: Dec 2008
:Author: Ichthyo
Lumiera: Startup and Shutdown of Subsystems //MENU: label Subsystem start
===========================================
There is now sort-of an "application realm", which doesn't belong strictly to .copied from 'pipapo.org'
one of the Layers. It serves the purpose of pullig up and tearing down the NOTE: This page was moved from _Cehteh_'s MoinMoin-wiki,
which at that time was the first home of Lumiera development +
The design and techniques outlined here are in use without major
changes as of 2015 (and can be expected to remain this way). The
documentation needs rewording in a more neutral and descriptive
way and probably an introductory paragraph might be helpful [yellow-background]#TODO#
...There is now sort-of an ``application realm'', which doesn't belong strictly to
any one of the Layers. It serves the purpose of pulling up and tearing down the
application in a controlled fashion. And additionally, it provides the Interface application in a controlled fashion. And additionally, it provides the Interface
and Config core services. Within the application, we find a small number of and Config core services. Within the application, we find a small number of
_Subsystems_, which are more or less independent. These subsystems are _Subsystems_, which are more or less independent. These subsystems are
@ -21,38 +32,38 @@ __Currently I've identified the following subsystems:__
- Script runner - Script runner
- Renderfarm node server - Renderfarm node server
To deal with those subsystems, I've created an Interface to definesthe To deal with those subsystems, I've created an Interface to define the
operations and liabilities of a subsystem. Additionally, I assume that for each operations and liabilities of a subsystem. Additionally, I assume that for each
subsystem there is a _Facade_, which the subsystem is free to implement as it subsystem there is a _Façade_, which the subsystem is free to implement as it
sees fit. Typically, this facade will load plugins, register and provide further sees fit. Typically, this façade will load plugins, register and provide further
"business interfaces", and especially set up the _Layer separation interfaces_ "business interfaces", and especially set up the _Layer separation interfaces_
which canalise any communication going on between the layers. which canalise any communication going on between the layers.
The code from my "startup" branch has meanwhile been merged to master. Look TIP: The code from my `startup` branch has meanwhile been merged to master. Look
http://git.lumiera.org/gitweb?p=LUMIERA;a=tree;h=a0a0e456a5b149df81b25a08358cd488631639fb;hb=a0a0e456a5b149df81b25a08358cd488631639fb[here] http://git.lumiera.org/gitweb?p=LUMIERA;a=tree;h=a0a0e456a5b149df81b25a08358cd488631639fb;hb=a0a0e456a5b149df81b25a08358cd488631639fb[here]
for the code mentioned in the following discussion. for the code referred in the following discussion.
- +common/subsys.hpp+ contains the mentioned subsystem interface. - +common/subsys.hpp+ contains the subsystem interface mentioned above.
- +lumiera/main.cpp+ uses the subsystem instances provided by the facades, and - +lumiera/main.cpp+ uses the subsystem instances provided by the facades, and
additionally the services of +lumiera::AppState+ (+common/appstate.hpp+) additionally the services of +lumiera::AppState+ (+common/appstate.hpp+)
- AppState represents the state as relevant for the "application realm", i.e. - AppState represents the state as relevant for the "application realm", i.e.
it performs global initialisation and shutdown. See especially +AppState::init()+ it performs global initialisation and shutdown. See especially +AppState::init()+
- see +backend/enginefacade.hpp|cpp+ as an (unimplemented) facade skeleton. +backend::EngineFacade::getDescriptor()+ - see +backend/enginefacade.hpp|cpp+ as an (unimplemented) façade skeleton. +backend::EngineFacade::getDescriptor()+
yields the subsytem interface yields the subsystem interface
- the GuiFacade is somewhat special, because we want to load the GUI from a - the GuiFacade is somewhat special, because we want to load the GUI from a
shared libary. This facade is basically completed and working, but it currently shared library. This façade is basically completed and working, but it currently
just loads a dummy plugin. The implementation of the GuiFacade needs to be in just loads a dummy plugin. The implementation of the GuiFacade needs to be in
core (because it pulls the plugin); that's why I've put it into core (because it pulls the plugin); that's why I've put it into
+common/guifacade.cpp+, while the interface is in +gui/guifacade.hpp+ as usual. +common/guifacade.cpp+, while the interface is in +gui/guifacade.hpp+ as usual.
- as an example for a _Layer separation interface_, I've implemented the - as an example for a _Layer separation interface_, I've implemented the
GuiNotificationFacade, which will be used by the lower layers to push GuiNotificationFacade, which will be used by the lower layers to push
informations into the gui (and finally to request the GUI to shut down). Layer informations into the GUI (and finally to request the GUI to shut down). Layer
separation interfaces are considered part of the public Lumiera API, thus the separation interfaces are considered part of the public Lumiera API, thus the
headers go into +src/include/**+ headers go into +src/include/**+
* include/guinotification.h (C/C++ combined header) defines an C++ interface (abstract class) and a CLI interface. * include/guinotification.h (C/C++ combined header) defines an C++ interface (abstract class) and a CLI interface.
* embedded into the interface is a factory, i.e. by gui::GuiNotification::facade() you get an instance... * embedded into the interface is a factory, i.e. by gui::GuiNotification::facade() you get an instance...
* which actually is a proxy and routes any call through the instance of the * which actually is a proxy and routes any call through the instance of the
accompaning CLI interface which is defined within the interface/plugin system accompanying CLI interface which is defined within the interface/plugin system
* this in turn forwards to the implementation class in * this in turn forwards to the implementation class in
gui/guinotificationfacade.cpp, which is assumed to live within the GUI gui/guinotificationfacade.cpp, which is assumed to live within the GUI
(shared lib) (shared lib)
@ -64,8 +75,9 @@ Actually this system builds on the assumption, that starting each subsystem
doesn't block the overall start/main/stop thread. I.e. any subsystem is supposed doesn't block the overall start/main/stop thread. I.e. any subsystem is supposed
to spawn its control/event threads if necessary. Not every subsystem needs to to spawn its control/event threads if necessary. Not every subsystem needs to
spawn threads though (for example, the session doesn't). In the current spawn threads though (for example, the session doesn't). In the current
implementation *no spawning of threads happens*. Similarily, I've commented out implementation _no spawning of threads happens_. Likewise, I've commented out
the synchronisation primitives. the synchronisation primitives. +
[yellow-background]#TODO 2015# _meanwhile we do spawn threads and perform synchronisation_
Initialisation and Lifecycle Initialisation and Lifecycle
@ -78,23 +90,23 @@ a coupling between anything which needs to be done in a certain initialisation
function. Actually, I prefer the usual approach of lifecycle events (or signals) function. Actually, I prefer the usual approach of lifecycle events (or signals)
used in many application frameworks, i.e. the publisher-subscriber model. This used in many application frameworks, i.e. the publisher-subscriber model. This
allows to keep the registration immediately within the implementation of a allows to keep the registration immediately within the implementation of a
facility, and it allows to add an arbitrary numer of additional lifecycle facility, and it allows to add an arbitrary number of additional lifecycle
events, like *ON_SESSION_CLOSE*, *ON_BUILD*, *ON_EMERGENCY_EXIT*. events, like *ON_SESSION_CLOSE*, *ON_BUILD*, *ON_EMERGENCY_EXIT*.
Basically we've now the following steps and events happening Basically we have now the following steps and events happening
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* *ON_BASIC_INIT* runs "somewhere" in the static initialisation phase before * *ON_BASIC_INIT* runs "somewhere" in the static initialisation phase before
main(). To schedule something there, you need to place a statc C++ variable. main(). To schedule something there, you need to place a statc C++ variable.
This should be reseverd for very basic initialisation tasks which need to be This should be reserved for very basic initialisation tasks which need to be
done even prior to any global initialisiation, e.g. the NOBUG_INIT is done this done even prior to any global initialisation, e.g. the NOBUG_INIT is done this
way, the config system, maybe setting up a dispatcher table based on (compile way, the config system, maybe setting up a dispatcher table based on (compile
time) type information (for the rules engine). time) type information (for the rules engine).
* +AppState::init()+ cares for bringing up the pluginloader and opens the config-interface. * +AppState::init()+ cares for bringing up the plugin loader and opens the config-interface.
* ...followed by triggereing *ON_GLOBAL_INIT* * ...followed by triggering *ON_GLOBAL_INIT*
* +main()+ pulls up the subsystems according to the command line options. * +main()+ pulls up the subsystems according to the command line options.
* within each subsystem, facade interfaces shall be opened with the interface * within each subsystem, façade interfaces shall be opened with the interface
system. Any initialisation of components should be tied to them. system. Any initialisation of components should be tied to these.
* as a rule and if possible, _any service should be written such as to come up on demand._ * as a rule and if possible, _any service should be written such as to come up on demand._
* shutdown or failure of _any given subsystem_ initiates the shutdown sequence * shutdown or failure of _any given subsystem_ initiates the shutdown sequence
by requesting all other running subsystems to terminate by requesting all other running subsystems to terminate
@ -139,7 +151,7 @@ Demo Run
00000643: interface.c:230: TRACE: thread_1: lumiera_interface_close: 00000643: interface.c:230: TRACE: thread_1: lumiera_interface_close:
00000646: interface.c:258: TRACE: thread_1: lumiera_interfacenode_close: lumieraorg_interface 1 () 00000646: interface.c:258: TRACE: thread_1: lumiera_interfacenode_close: lumieraorg_interface 1 ()
------ ------
* similarily, running... `lumiera \--help` * incidentally, running... `lumiera --help` produces the following output
------ ------
00000392: configfacade.cpp:74: INFO: thread_1: Config: Config system ready. 00000392: configfacade.cpp:74: INFO: thread_1: Config: Config system ready.
00000394: main.cpp:55: NOTICE: thread_1: main: *** Lumiera NLE for Linux *** 00000394: main.cpp:55: NOTICE: thread_1: main: *** Lumiera NLE for Linux ***

View file

@ -1,7 +1,7 @@
GUI Brainstorming Proposal GUI Proposal by AkhIL
========================== =====================
:Author: IL'dar AKHmetgaleev (»AkhIL«) :Author: IL'dar AKHmetgaleev (»AkhIL«)
:Date: 2008-30-03 :Date: 2008-03-30
Wiring nodes within the timeline Wiring nodes within the timeline

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,7 +1,7 @@
GUI Brainstorming Proposal GUI Proposal by Alcarinque
========================== ==========================
:Author: Francisco G. Rodriguez :Author: Francisco G. Rodriguez
:Date: 07.05.2008 :Date: 2008-05-07
This are some of my ideas for the interface of Lumiera. Some of this ideas are This are some of my ideas for the interface of Lumiera. Some of this ideas are

View file

@ -0,0 +1,31 @@
GUI Proposal by Clay Barnes
===========================
:Author: R. Clayton Barnes (»rcbarnes«)
:Date: 2008-05-21
-> https://www.hci-matters.com/blog/2008/05/21/archives/41/[original blog entry]
.About the Author
***********************************************************************************************************
*Clay Barnes* holds a B.S. in Computer Science and a B.A. in Linguistics from the University of Arizona,
and an M.S. in Human-Computer Interaction from Rensselaer Polytechnic Institute.
For the last year and a half, he was the User Interface Architect in GE Energys Software Innovation Team.
He previously worked for Intrigo as a User Experience Designer while living in Tucson.
***********************************************************************************************************
Ive pulled together some drafts of my ideas for the design of the timeline portion
of the Lumiera non-linear video editor (hopefully, the successor to http://cinelerra-cv.org[Cinelerra]).
The un-annotated version::
image:{imgg}/Barnes.proposal.png[
"Lumiera UI proposal",width=300,
link="{imgg}/Barnes.proposal.png"] +
(click to enlarge)
The annotated version::
(explaining some of the finer points)
image:{imgg}/Barnes.proposal-annotated.png[
"Lumiera UI proposal (annotated)",width=300,
link="{imgg}/Barnes.proposal-annotated.png"]

View file

@ -1,7 +1,7 @@
GUI Brainstorming Proposal GUI Proposal by Richard Spindler
========================== ================================
:Author: Richard Spindler :Author: Richard Spindler
:Date: 2008-30-03 :Date: 2008-03-30
Node Graph proposal Node Graph proposal

View file

@ -0,0 +1,13 @@
GUI Concept Proposals
=====================
//Menu: sort children
Over time, we got several UI proposals and design contributions.
Since webpages tend to disappear after some time, we took the liberty
to incorporate some of these contributions in our documentation tree.
* link:AkhiL.html[AkhIL]
* link:Alcarinque.html[Alcarinque]
* link:Barnes.html[Clay Barnes]
* link:RichardSpindler.html[Richard Spindler]

View file

@ -17,7 +17,7 @@ Brainstorming
Akhil Akhil
~~~~~ ~~~~~
-> link:Proposal.AkhiL.html[AkhIL's Proposal] -> link:ConceptProposals/AkhiL.html[AkhIL's Proposal]
.Things I like .Things I like
* The roots of group tracks show what's being rendered inside (_Ichthyo_ calls these root tracks "group bars"). * The roots of group tracks show what's being rendered inside (_Ichthyo_ calls these root tracks "group bars").
@ -42,7 +42,7 @@ Akhil
Richard Spindler Richard Spindler
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
-> link:Proposal.RichardSpindler.html[Richard's Proposal] -> link:ConceptProposals/RichardSpindler.html[Richard's Proposal]
.Things I like .Things I like
* You've got a concept of sub-EDLs and metaclips. We're definitely going to do * You've got a concept of sub-EDLs and metaclips. We're definitely going to do
@ -66,7 +66,7 @@ Richard Spindler
Alcarinque Alcarinque
~~~~~~~~~~ ~~~~~~~~~~
-> http://telniratha.atspace.com/spec.html[] -> link:ConceptProposals/Alcarinque.html[Proposal by »Alcarinque« (Francisco G. Rodriguez)] (http://telniratha.atspace.com/spec.html[original page])
.Things I like .Things I like
* Node Layouts in the media library. This isn't a page about the ML, but I like your ideas of having stored node layouts in the library. My own name for these is compound effects - but it's the same idea. Your idea of having collecting a library of these on the website is pretty cool as well. * Node Layouts in the media library. This isn't a page about the ML, but I like your ideas of having stored node layouts in the library. My own name for these is compound effects - but it's the same idea. Your idea of having collecting a library of these on the website is pretty cool as well.
@ -96,7 +96,7 @@ Hermann Vosseler (Ichthyo)
Clay Barnes (rcbarnes) Clay Barnes (rcbarnes)
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
-> http://www.hci-matters.com/blog/2008/05/21/lumiera-timeline-first-draft/[] -> link:ConceptProposals/Barnes.html[Proposal by Clay Barnes] (http://www.hci-matters.com/blog/2008/05/21/lumiera-timeline-first-draft/[original blog entry])
.Things I like .Things I like
* Nudge buttons are shown when the user hovers over the clip. This could be quite a timesaver. * Nudge buttons are shown when the user hovers over the clip. This could be quite a timesaver.

View file

@ -1,17 +1,34 @@
GUI Design and Feature Discussion GUI Design and Feature Discussion
================================= =================================
In the early stages of the project, there was a lot of debate regarding //Menu: put child ConceptProposals after GuiBrainstormingWontImplement
GUI concepts and -features and proposals. //Menu: put child TimelineDiscussion after ConceptProposals
- link:GuiBrainstormingReviewed.html[GUI Brainstorming page] '[red]#TODO#: explain whats this all about' In the early days of the Lumiera project, there was a lot of debate regarding
- several Proposals GUI concepts, -features and proposals.
* link:Proposal.AkhiL.html[AkhIL]
* link:Proposal.Alcarinque.html[Alcarinque] GUI Brainstorming::
* link:Proposal.RichardSpindler.html[Richard Spindler] We got a lot of proposed cool features. In order to channel this great influx of ideas,
* link:Workspaces.html[about Workspace organsiation] we set up a wiki page to allow basically open proposals. *Joel Holdsworth*, our GUI developer
at that time, performed the herculean task to walk through this tremendous pile of entries,
consolidate them and conduct a discussion. The link:GuiBrainstormingReviewed.html[GUI Brainstorming page]
documents the discussion and some conclusions. Several proposals were sorted out -- it might be
inspiring to look on the reasons why we
link:GuiBrainstormingWontImplement.html[rejected some proposals].
GUI Proposals::
In addition, several people contributed complete or focussed concepts and design proposals
* link:ConceptProposals/AkhiL.html[AkhIL]
* link:ConceptProposals/Alcarinque.html[Alcarinque]
* link:ConceptProposals/Barnes.html[Clay Barnes]
* link:ConceptProposals/RichardSpindler.html[Richard Spindler]
* link:Workspaces.html[about Workspace organisation]
* link:scrolling.html[about scrolling..] * link:scrolling.html[about scrolling..]
* link:MenuAndShortcuts.html[Ideas for menus and shortcuts] * link:MenuAndShortcuts.html[Ideas for menus and shortcuts]
- link:TimelineDiscussion.html[Conclusions by Joel Holdsworth]
Timeline Discussion::
In 2008, Joel reviewed all the available proposals and distilled a more coherent vision
especially about the timeline, which certainly is at the heart of any video editor.
This page with link:TimelineDiscussion.html[Conclusions by Joel Holdsworth] is
_must read_ for anyone engaged into Lumiera GUI development.

View file

@ -7,12 +7,14 @@ GUI concepts and -features and proposals.
link:GuiDiscussion/index.html[Here] is a collection of documents from these early link:GuiDiscussion/index.html[Here] is a collection of documents from these early
discussions. discussions.
In our discussions, *Workflow* denotes all considerations how certain tasks
can be achieved within the application in the most suitable and stringent fashion.
This effort is closely related to GUI and interface design, but at the same quite
integral, so its rather treated separately of individual GUI features.
-> link:../workflow/index.html[more here...]
.*TODO* more contributions please... ;-) .[red]#TODO# more contributions please... ;-)
We had several additional discussions and contributions on the mailinglist, We had several additional discussions and contributions on the mailinglist,
several people did even concept drawings. Collect these and add them here several people did even concept drawings. Collect these and add them here
NOTE: We use the term *Workflow* in our discussions to denote the more integral
concerns of how to achieve given tasks within the application in the most
suitable and stringent fashion. We tend to separate those more global
considerations from the discussion of individual GUI features.
-> link:../workflow/index.html[read more here...]

View file

@ -0,0 +1,21 @@
Interface Concept
=================
:Author: Christoph Varga
:Date: March 2015
This Concept Proposal approaches questions of interface design focussing on the Workflow.
Currently, the whole field of film production is in a state of transformation. Such a
time of change enables us to conceive new routes. Video editing technology today has
reached a level of maturity, powerful enough to shape it in accordance with our human
mode of expression, our needs and abilities when working with media. Things shouldn't
be done just because it's possible to do them -- to the contrary, we are entitled
to ask which route we want to go and we build our own tools accordingly.
*************************
_Christoph Varga_ is a young documentary film maker.
He lives and studies in Vienna at the Academy of Fine Arts.
*************************
-> link:{imgg}/ChristophVarga.UserInterfaceConcept.pdf[User Interface Concept (PDF)]

View file

@ -1,11 +1,13 @@
Design Documents: Workflow Design Documents: Workflow
========================== ==========================
In our discussions, *Workflow* denotes all considerations how certain tasks In our discussions, the term *Workflow* denotes specific considerations about _the way_
can be achieved within the application in the most suitable and stringent fashion. a given task can be achieved, within the application, in the most suitable and stringent fashion.
This effort is closely related to GUI and interface design, but at the same quite This effort is closely related to GUI and interface design, but likewise quite integral,
integral, so it's rather treated separately of individual GUI features. so we tend to treat it as a distinct effort, separate from the design of individual GUI features.
* link:LumieraWorkflowOutline.html[Workflow/Requirements outline by BJMR]
* link:InterfaceConcept_Varga.html[Interface Concept by Christoph Varga]
-> see also link:../gui/index.html[general GUI discussion...] -> see also link:../gui/index.html[general GUI discussion...]
* link:LumieraWorkflowOutline.html[Workflow outline by BJMR]

View file

@ -20,7 +20,7 @@ Define coding style standard which we will use.
Description Description
~~~~~~~~~~~ ~~~~~~~~~~~
We need to agree on some coding style, imo constistency is the most important We need to agree on some coding style, IMHO consistency is the most important
part with this, no matter which style we use. part with this, no matter which style we use.
See http://en.wikipedia.org/wiki/Indent_style[] See http://en.wikipedia.org/wiki/Indent_style[]
@ -29,19 +29,18 @@ See http://en.wikipedia.org/wiki/Indent_style[]
* no tabs, use spaces! * no tabs, use spaces!
.Proposed: .Proposed:
* K&R by ichthyo * K&R by _ichthyo_
* compact and well known * compact and well known
* GNU by cehteh * GNU by _cehteh_
* imo the best readability (albeit little strange) * imo the best readability (albeit little strange)
* cinelerra might apply as official GNU project someday * Lumiera might apply as official GNU project someday
Another question: __how to write identifiers?__ Another question: __how to write identifiers?__
.Proposed: .Proposed:
* ichthyo: use link:CamelCase[], start ClassNames upper case and variableNames * ichthyo: use CamelCase, start ClassNames upper case and variableNames
in lower case. Make all namespaces and package (dir) names completely in lower case. Make all namespaces and package (dir) names completely lowercase
lowercase
@ -76,11 +75,11 @@ MichaelPloujnikov:: '2007-06-27 17:17'
I just proposed K&R because it is widely accepted. Personally, I was never very I just proposed K&R because it is widely accepted. Personally, I was never very
fond of K&R style, I always prefered putting opening braces to the left. I fond of K&R style, I always preferred putting opening braces to the left. I
never used GNU style until now, but it looks somewhat apealing to me. (btw, never used GNU style until now, but it looks somewhat appealing to me. (btw,
ECLIPSE comes with presets for all this styles :-P ). Anyhow, I can adapt to ECLIPSE comes with presets for all this styles :-P ). Anyhow, I can adapt to
most any style. The only thing I really dislike is using tabs (with the most any style. The only thing I really dislike is using tabs (with the
exeption of database DDLs and CSound files, where tab are actually helpful) :) exception of database DDLs and CSound files, where tab are actually helpful) :)
Ichthyo:: '2007-06-27 20:55' Ichthyo:: '2007-06-27 20:55'

View file

@ -105,17 +105,17 @@ the lower layers, the GUI is _optional_ and the application is fully operational
GTK Gui is built and loaded as Lumiera a plug-in. GTK Gui is built and loaded as Lumiera a plug-in.
.unit tests .unit tests
Since we're developing test-driven, about half of the overall code can be found in unit- and integration Since our development is test-driven, about half of the overall code can be found in unit- and integration
tests, residing below `test/`. There is a separate SConscript file, to define the various kinds of test tests, residing below `test/`. There is a separate SConscript file, to define the various
artefacts to be created. link:{ldoc}/technical/infra/TestSupport.html[kinds of test artefacts] to be created.
- plain-C tests are defined in _test-collections_, grouped thematically into several subdirectories. - plain-C tests are defined in _test-collections_, grouped thematically into several subdirectories.
Here, each translation unit provides a separate +main()+ function and is linked into a stand-alone Here, each translation unit provides a separate +main()+ function and is linked into a stand-alone
executable (yet still linked against the appropriate shared libraries of the main application layers) executable (yet still linked against the appropriate shared libraries of the main application layers)
- the tests covering C++ components are organised into test-suites, residing in separate sub-trees. - the tests covering C++ components are organised into test-suites, residing in separate sub-trees.
Currently (as of 10/2014), there is the *library suite* and the *proc components suite*. Here Currently (as of 5/2015), we link each sub-tree into a shared test library. Here
individual translation units define individual test case classes, which are linked together with individual translation units define individual test case classes. At the end, all these unit tests
a testrunner `main()` function. are linked together with a testrunner `main()` into the `test-suite` executable.
.research .research
There is a separate subtree for research and experiments. The rationale being to avoid re-building most There is a separate subtree for research and experiments. The rationale being to avoid re-building most

View file

@ -11,7 +11,7 @@ The Lumiera project uses GNU indentation style with slight adaptations.
- *no tabs* please. The typical ``semi indent'' of GNU style thus becomes 2 spaces. - *no tabs* please. The typical ``semi indent'' of GNU style thus becomes 2 spaces.
- maximum line length is rather around *110 characters*. - maximum line length is rather around *110 characters*.
- originally, GNU style focussed on plain-C code. + - originally, GNU style focused on plain-C code. +
We thus apply some relaxations and clarifications ... We thus apply some relaxations and clarifications ...
* the braces for a class scope are indented by 2 spaces * the braces for a class scope are indented by 2 spaces
@ -46,7 +46,7 @@ and that library or language uses other conventions.
- type names start with an uppercase letter - type names start with an uppercase letter
- variable and function names start with lowercase. - variable and function names start with lowercase.
- fields within a class, especially the private ones are decorated with a trailing underscore - fields within a class, especially the private ones are decorated with a trailing underscore
- a leading underscore may be used to emphasize the strictly internal or technical nature of a type, - a leading underscore may be used to emphasise the strictly internal or technical nature of a type,
variable or function variable or function
- namespaces are all-lowercase - namespaces are all-lowercase
- macros and constants are preferably all-caps (at least where this makes sense) - macros and constants are preferably all-caps (at least where this makes sense)
@ -69,6 +69,11 @@ In case a definition actually denotes an object, there should be
The object pointer/handle should be passed as 1^st^ argument with the name +self+ The object pointer/handle should be passed as 1^st^ argument with the name +self+
Spelling
~~~~~~~~
Lumiera uses _British spelling._ Please set your spell checker accordingly.
General Code Arrangement and Layout General Code Arrangement and Layout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Headers and translation units are named `*.hpp` and `*.cpp` rsp. `*.h` and `*.c` + - Headers and translation units are named `*.hpp` and `*.cpp` rsp. `*.h` and `*.c` +
@ -77,12 +82,13 @@ General Code Arrangement and Layout
the +CamelCaseWords+ of this type are translated into +camel-case-words.hpp+ the +CamelCaseWords+ of this type are translated into +camel-case-words.hpp+
- Each file should start with the GNU licence preamble. The headline should give a one-line summary. - Each file should start with the GNU licence preamble. The headline should give a one-line summary.
The primary author(s) and the year of the initial copyright claim should be mentioned. The primary author(s) and the year of the initial copyright claim should be mentioned.
- Each header should be focussed on a specific purpose. Preferably it starts with a file-level - Each header should be focused on a specific purpose. Preferably it starts with a file-level
doxygen comment explaining the intention and anything not obvious from reading the code. doxygen comment explaining the intention and anything not obvious from reading the code.
- when arranging headers and compilation units, please take care of the compilation times and the - when arranging headers and compilation units, please take care of the compilation times and the
code size. Avoid unnecessary includes. Use forward declarations where applicable. code size. Avoid unnecessary includes. Use forward declarations where applicable.
Yet still, _all immediately required includes should be mentioned_ (even if already included by Yet still, _all immediately required direct dependencies should be mentioned_, even if already
another dependency) included by another dependency. See the extensive discussion of these
link:{ldoc}/technical/code/linkingStructure.html#_imports_and_import_order[issues of code organisation]
- The include block starts with our own dependencies, followed by a second block with the library - The include block starts with our own dependencies, followed by a second block with the library
dependencies. After that, optionally some symbols may be brought into scope (through +using+ clauses). dependencies. After that, optionally some symbols may be brought into scope (through +using+ clauses).
Avoid cluttering top-level namespaces. Never import full namespaces (no +using namespace boost;+ please!) Avoid cluttering top-level namespaces. Never import full namespaces (no +using namespace boost;+ please!)

View file

@ -3,15 +3,16 @@ Linking and Application Structure
:Date: Autumn 2014 :Date: Autumn 2014
:Author: Ichthyostega :Author: Ichthyostega
:toc: :toc:
:toclevels: 3
This page focusses on some quite intricate aspects of the code structure, This page focusses on some rather intricate aspects of the code structure,
the build system organisation and the interplay of application parts on the build system organisation and the interplay of application parts on
a rather technical level. a technical level.
Arrangement of code Arrangement of code
------------------- -------------------
Since ``code'' may denote several different entities, the place ``where'' Since the term ``code'' may denote several different kinds of entities, the place
some piece of code is located differs according to the context in question. _where_ some piece of code is located differs according to the context in question.
Visibility vs Timing: the translation unit Visibility vs Timing: the translation unit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -19,14 +20,14 @@ To start with, when it comes to building code in C/C++, the fundamental entity
is _a single translation unit_. Assembler code is emitted while the compiler is _a single translation unit_. Assembler code is emitted while the compiler
progresses through a translation unit. Each translation unit is self contained progresses through a translation unit. Each translation unit is self contained
and represents a path of definition and understanding. Each translation unit and represents a path of definition and understanding. Each translation unit
starts anew at a state of complete ignorance, at the end leading to a fully starts out anew at a state of complete ignorance, at the end leading to a fully
specified, coherent operational structure. specified, coherent operational structure.
Within this _definition of a coded structure_, there is an inherent tension Within this _definition of a coded structure_, there is an inherent tension
between the _absoluteness_ of a definition (a definition in mathematical sense between the _absoluteness_ of a definition (a definition in mathematical sense
can not be changed, once given) and the _order of spelling out_ this definition. can not be changed, once given) and the _order of spelling out_ this definition.
When described in such an abstract way, these observations might be deemed self evident When described in such an abstract way, this kind of observation might be deemed
and trivial, but let's just consider the following complications in practice... self evident and trivial, but let's just consider the following complications in practice...
- Headers are included into multiple translation units. Which means, they appear - Headers are included into multiple translation units. Which means, they appear
in several disjoint contexts, and must be written in a way independent of the in several disjoint contexts, and must be written in a way independent of the
@ -59,19 +60,126 @@ and trivial, but let's just consider the following complications in practice...
Now the quest is to make _good use_ of these various ways of defining things. Now the quest is to make _good use_ of these various ways of defining things.
We want to write code which clearly conveys its meaning, without boring the We want to write code which clearly conveys its meaning, without boring the
reader with tedious details not necessary to understand the main point in reader with tedious details not necessary to understand the main point in
question. And at the same time we want to write code which is easy to question. And at the same time, we want to write code which is easy to
understand, easy to write and can be altered, extended and maintained. understand, easy to write and can be altered, extended and maintained.footnote:[to put
footnote:[Put blatantly, a ``simple clean language'' without any means of expression it blatantly, a ``simple clean language'' without any means of expression
would not be of much help. All the complexities of reality would creep into the usage would not be of much help. All the complexities of reality would creep into the usage
of our ``ideal'' language, and, even worse, be mixed up there with the entropy of of our »ideal« language, and, even worse, be mixed up there with the all the entropy
doing the same things several times in a different way.] produced by doing the same things several times a different way.]
Since it is really hard to reconcile all these conflicting goals, we are bound Since it is really hard to reconcile all these conflicting goals, we are bound
to rely on *patterns of construction*, which are known to work out well in to rely on *patterns of construction*, which are known to work out well in
this regard. this regard.
[yellow-background]#to be written# Imports and import order
Import order, forward decls, placement of ctors, wrappers, PImpl ^^^^^^^^^^^^^^^^^^^^^^^^
When we refer to other definitions by importing headers, these imports should be
spelled out precisely to the point. Every relevant facility used in a piece of code
must be reflected by the corresponding `#import` statement, yet there should not be any
spurious imports. Ideally, just by reading the prologue of a source file, the reader should
gain a clear understanding about the dependencies of this code. The standards are somewhat
different for header files, since every user of this header gets these imports too. Each
import incurs cost for the user -- so the _header_ should mention only those imports
- which are really necessary to spell out our definition
- which are likely to be useful for the _typical standard use_ of our definition
Imports are to be listed in a strict order: *always start with our own references*,
preferably starting with the facility most ``on topic''. Besides, for rather fundamental
library headers, it is a good idea to start with a very fundamental header, like e.g. 'lib/error.hpp'.
Of course, these widely used fundamental headers need to be carefully crafted, since the leverage
of any other include pulled in through these headers is high.
Any imports regarding *external or system libraries are given in a second block*, after our
own headers. This discipline opens the possibility for our own headers to configure or modify
some system facilities, in case the need arises. It is desirable for headers to be written
in a way independent of the include order. But in some, rare cases we need to rely on a
specific order of include. In such cases, it is a good idea to encode this specific order
right into some very fundamental header, so it gets fixed and settled early in the include
processing chain. Our 'gui/gtk-base.hpp', as used by 'gui/gtk-lumiera.hpp' is a good example.
Forward declarations
^^^^^^^^^^^^^^^^^^^^
We need the full definition of an entity whenever we need to know its precise memory layout,
be it to allocate space, to pass an argument by-value, or to point into some filed within
a struct, array or object. The full definition may be preceded by an arbitrary number of
redundant, equivalent declarations. We _do not actually need_ a full definition for any
use _not dealing with the space or memory layout_ of an entity. Especially, handling
some element by pointer or reference, or spelling out a function signature to take
this entity other than by-value, does _not require a full definition_.
Exploiting this fact allows us largely to reduce the load of dependencies, especially
when it comes to ``subsystem'' or ``package'' headers, which define the access
point to some central facility. Such headers should start with a list of the relevant
core entities of this subsystem, but only in the form of ``lightweight'' forward declarations.
Because, anyone actually to use _one of these_ participants, is bound to include the specific
header of this element anyway; all other users may safely skip the efforts and transitive
dependencies necessary to spell out the full definition of stuff not actually used and needed.
In a similar vein, a façade interface does not actually need to pull in definitions for all
the entities it is able to orchestrate. In most cases, it is sufficient to supply suitable
and compatible `typedef`s in the public part of the interface, just to the point that we're
able to spell out the bare API function signatures without compilation error.
Placement of constructors
^^^^^^^^^^^^^^^^^^^^^^^^^
At the point, where a ctor is actually invoked, we require the full definition of the element
about to be created. Consequently, at the place, where the ctor itself is _defined_ (not just
declared), the full definition of _all the members_ of a class plus the full definition of
all base classes is required. The impact of moving this point down into a single implementation
translation unit can be huge, compared to incurring the same cost in each and every other
translation unit just _using_ an entity.
Yet there is a flip side of the coin: Whenever the compiler sees the full definition of an
entity, it is able to inline operations. And the C\++ compiler uses elaborate metrics
to judge the feasibility of inlining. Especially when almost all ctor implementations are
trivial (which is the case when writing good C++ style code), the runtime impact can be
huge, basically boiling down a whole pile of calls and recursive invocations into precisely
zero assembler code to be generated. This way, abstraction barriers can evaporate
to nothingness. So we're really dealing with a run time vs. development time
and code size tradeoff here.
On a related note: care has to be taken whenever a templated class defines virtual methods.
Each instantiation of the template will cause the compiler to emit a function which generates
the VTable, together with code for each of the virtual functions. This effect is known as
``template code bloat''.
The PImpl pattern
^^^^^^^^^^^^^^^^^
It is is the very nature of a good design pattern, the reason why it is remembered and applied
over and over again: to allow otherwise destructive forces to move past each other in a
seemingly ``friction-less'' way. In our case, there is a design pattern known to resolve
the high tension and potential conflict inherent to the situations and issues described above.
And, in addition, it circumvents the lack of a real interface definition construct in C++ elegantly:
Whenever a facility has to offer an outward façade for the client, while at the same time engaging
into heavy weight implementation activities, then you may split this entity into an interface shell
and a private implementation delegate.footnote:[the common name for this pattern, »PImpl« means
``point-to-implementation''] The interface part is defined in the header, fully eligible
for inlining. It might even be generic -- templated to adapt to a wide array of parameter types.
The implementation of the API functions is also given inline, and just performs the necessary
administrative steps to accept the given parameters, before passing on the calls to the
private implementation delegate. This implementation object is managed by (smart) pointer,
so all of the dependencies and complexities of the implementation is moved into a single
dedicated translation unit, which may even be reshaped and reworked without the need to
recompile the usage site.
Wrappers and opaque holders
^^^^^^^^^^^^^^^^^^^^^^^^^^^
These constructs serve a similar purpose: To segregate concerns, together with the related
dependencies and overhead. They, too, represent some trade-off: a typically very intricate
library construct is traded for a lean and flexible construction at usage site.
A wrapper (smart-pointer or smart handle), based on the ability of C++ to invoke ctors and
dtors of stack-allocated values and object members automatically, can be used so push some
cross-cutting concern into a separate code location, together with all the accompanying
management facilities and dependencies, so the actual ``business code'' remains untainted.
In a related, but somewhat different style, an opaque holder allows to ``piggyback'' a value
without revealing the actual implementation type. When hooked this way behind a strategy interface,
extended compounds of implementation facilities can be secluded into a dedicated facility, without
incurring dependency overhead or tight coupling or even in-depth knowledge onto the client, yet
typesafe and with automatic tracking for clean-up and failure management.
Code size and Code Bloat Code size and Code Bloat
@ -90,9 +198,9 @@ Each piece of code incurs cost of various kinds
produces debug information in each and every translation unit referring it. produces debug information in each and every translation unit referring it.
Thus, for every piece of code we must ask ourselves how much _visible_ this Thus, for every piece of code we must ask ourselves how much _visible_ this
code is. And we must consider the dependencies the code incurs. It pays off to code is, need to be. And we must consider the dependencies the code incurs.
turn something into a detail and ``push it into the backyard''. This explains It pays off to turn something into a detail and ``push it into the backyard''.
why we're using the frontend - backend split so frequently. This explains why we're using the frontend - backend split so frequently.
Source and binary dependencies Source and binary dependencies
@ -150,12 +258,12 @@ layer operative, standalone, without the upper layer(s). The key is to introduce
and then to _segregate_ along the realm of this abstraction, which needs to be chosen large enough and then to _segregate_ along the realm of this abstraction, which needs to be chosen large enough
in scope to cast the service and its contract entirely in terms of this abstraction, but at the same in scope to cast the service and its contract entirely in terms of this abstraction, but at the same
time it needs to be kept tight enough to prevent details of the client to leak into the abstraction. time it needs to be kept tight enough to prevent details of the client to leak into the abstraction.
When this is achieved (which is the hard part), then any operations dealing with the abstraction solely When this is achieved (which is the hard part), then any operations dealing with the abstraction _solely_
can be migrated into the entity offering the service, while the client hides the extended knowledge about can be migrated into the entity offering the service, while the client hides the extended knowledge about
the nature of the manipulated data behind a builder function footnote:[frequently this leads to the the nature of the manipulated data behind a builder function.footnote:[frequently this leads to the
``type erasure'' pattern, where specific knowledge about the nature of the fabricated entities -- thus ``type erasure'' pattern, where specific knowledge about the nature of the fabricated entities -- thus
a specific type -- is relinquished and dropped once fabrication is complete], but retains ownership a specific type -- is relinquished and dropped once fabrication is complete] This way, the client retains
on these entities, passing just a reference to the service implementation. This move ties the binary ownership on these entities, passing just a reference to the service implementation. This move ties the binary
dependency on the client implementation to this factory function -- as long as _this factory_ remains dependency on the client implementation to this factory function -- as long as _this factory_ remains
within the client, the decoupling works and eliminates binary cross dependencies. within the client, the decoupling works and eliminates binary cross dependencies.
@ -164,9 +272,204 @@ strict dependency checking (Link flag `--no-undefined`), so every violation of t
hierarchical dependency order of our shared modules is spotted immediately during build. hierarchical dependency order of our shared modules is spotted immediately during build.
Finding dependencies at start-up Locating dependencies at start-up
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[yellow-background]#to be written# We hope for Lumiera to be not only installed on desktop systems, but also used in a studio
or production context, where you'll use a given system just for the duration of one project.
This might even be specific hardware booted with a Live-System, or it might be a ``headless''
render-farm node. For this reason, we impose the explicit requirement that Lumiera must be
fully *usable without installation*. Unzip the application into some folder, launch,
start working. There might be some problems with required media handling libraries,
but the basic idea is to use a self-contained bundle or sub-tree, and the application
needs to locate all the further required resources actively on start-up.
On the other hand, we want Lumiera to be a good citizen, packaged in the usual way,
compliant to the Unix **F**ile**S**ystem **H**ierarchy standard. It turns out these two
rather conflicting goals can be reconciled by leveraging some of the advanced features
of the GNU dynamic linker: The application will figure out the whereabouts relatively,
starting from the location of the executable, and with the help of some search paths
and symlinks, the same mechanism can be made to work in the usual FSH compliant
installation into `/usr/lib/lumiera` and `/usr/share/lumiera`
This way, we end up with a rather elaborate start-up sequence, where the application
works out it's own installation location and establishes all the further resources
actively step by step
. the first challenge is posed by the parts of the application built as dynamic libraries;
effectively most of the application code resides in some shared modules. Since we
most definitively want one global link step in the build process, where unresolved
symbols will be spotted, and we do want a coherent application core, so we use
dynamic linking right at start-up and thus need a way to make the linker locate
our further modules and components relative to the executable. Fortunately, the
GNU linker supports some extended attributes in the `.dynamic` section of ELF
executables, known as the ``new style d-tags'' -- see the extensive description
in the next section below
* any executable may define an extended search path through the `RUNPATH` tag,
which is searched to locate dynamic libraries and modules before looking
into the standard directories
footnote:[the linker also supports the old-style `RPATH` tag, which is deprecated.
In the age of multi-arch installation and virtual machines, the practice of baking
in the installation location of each library into the `RPATH` is no longer adequate.
For the time being, our build system sets both `RPATH` and the new-style, more
secure `RUNPATH` to the same value relative to the executable. We will cease
using `RPATH` at some point in the future]
* and this search patch may contain _relative_ entries, using the special
magic token `$ORIGIN` to point at the directory holding the executable
+
By convention, the Lumiera buildsystem bakes in the search location `$ORIGIN/modules`
-- so this subdirectory below the location of the executable is where all the dynamic
modules of the application will be placed by default
. after the core application has been loaded and all direct dependencies are resolved,
but still before entering `main()`, the class `lumiera::AppState` will be initialised,
which in turn holds a member of type `lumiera::BasicSetup`. The latter will figure out
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.
. from there, the _search paths_ are retrieved to locate the extended resources of the
application. All these search paths are a colon separated list; the entries may
optionally also use the token `$ORIGIN` to refer to the location of the main executable.
The default version of 'setup.ini' is outfitted with search paths to cover both the
situation of a self-contained bundle, but also the situation of a FSH compliant
installation.
Lumiera.modulepath:: this is where the plugin loader looks for additional extensions and
plug-ins, most notably the *GUI plugin*
Lumiera.gui:: defines the name of this GUI plugin, which is loaded and activated from
`main()` -- unless Lumiera starts in ``headless'' mode
Lumiera.configpath:: all the extended application configuration will be picked up from
these directories (_not yet implemented as of 2015_)
Gui.iconpath:: root of the folder structure used to load icons and similar graphical
elements for the GTK-UI. Below, several subdirectories for various icon sizes are
recognised. Actually, most of our icons are defined as SVG and rendered using
libCairo during the build process.
Gui.resourcepath:: the place where the GTK-UI looks for further resources, most notably...
Gui.stylesheet:: the name of the CSS-stylesheet for GTK-3, which defines the
application specific look, link:{ldoc}/technical/gui/guiTheme.html[skinning and theme].
While the first two steps, the relative locations `$ORIGIN/modules` and `$ORIGIN/setup.ini`
are hard-wired, the further resolution steps rely on the contents of 'setup.ini' and are
open for adjustments and reconfiguration, both for the packager or the advanced user.
Any failure or mismatch during this start-up sequence will be considered fatal and abort
the application execution.
About RPATH, RUNPATH
^^^^^^^^^^^^^^^^^^^^
Management of library dependencies can be a tricky subject, both obscure and contentious.
There is a natural tension between the application developers (»upstream«), the packagers
and distributors. Developers have a natural tendency to cut short on ``secondary'' concerns
in order to keep matters simple. As a developer, you always try to stretch to the limit,
and this very tendency _limits your ability_ to care for intricate issues faced by just a
few users, or to care for compatibility or even for extended tutorial documentation. So,
as an upstream developer, if you know that the stuff you've built works just fine with
a specific library version -- be it bleeding edge or be it outdated and obsoleted since
years -- the most pragmatic and adequate answer is to demand from your users just to
``come along with you'' -- frankly, the active developer has zero inclination to look
back to past issues already overcome in the course of development, nor has he much interest
to engage in other fields of ongoing debate not conductive to his own concerns right now.
So the best solution for the developer would be just to wrap-up his own system and ship
it as a huge bundle to the users. Every other solution seems inferior, just adding weight,
efforts and pain without tangible benefit.
Obviously, a distributor can not agree to that stance. To create a coherent and reliable whole
out of the thousand individual variations the upstream developers breed, is in itself a
herculean task and would simply be impossible without forcing some degree of standardisation
onto the developers. In fact, the distributor's task becomes feasible _only_ by offloading some
efforts for compatibility in small portions onto the shoulders of the individual upstream
projects. A preference for using a common set of shared libraries is even built into
the toolchain, and there is a distinct tendency to discourage and even hide away the
mechanisms otherwise available to deal with a self contained bundle of libraries.
Speaking in terms of history, explicit mechanisms to support packaging and distribution management
are a rather new phenomenon and tend to conflict with the _glorious »Unix Way«_ of doing things,
they are cross-cutting, global and invasive. On Unix systems, traditionally there used to be two
_overriding mechanisms_ for library resolution, one for the user, one for the developer:
- the `LD_LIBRARY_PATH` environment variable allows the _user_ on invocation to manipulate
the search location for loading dynamic libraries; it takes precedence over all default
configured system wide installation locations and over the contents of the linker cache.
In the past, astute users frequently configured an elaborate `LD_LIBRARY_PATH` into their
login profile and managed an extended set of private installation locations with custom
compiled libraries. Obviously this caused an avalanche of problems at the point where
significant functionality of a system started to be just ``provided'' and no single
person was able to manage all of the everyday functionality alone on their own.
Basically, the advent of graphical desktop systems marked this breaking point.
- the `RPATH` tag, which is the other override mechanism available for _the builder of software_,
was made to defeat and overrule the effect of `LD_LIBRARY_PATH`. Search locations baked
in as `DT_RPATH` take absolute precedence and can not be altered with any other means besides
recompiling the executable (or at least rewriting the `.dynamic` section in the ELF binary).
Over time, it became »best practice« to bake in the installation location into each and
every binary, which kind-of helped the upstream developers to re-gain control over the
libraries actually being used to execute their code. But unfortunately, the distributors
were left with zero options to manage large-scale library dependency transitions, beyond
patching the build system of each and every package.
Based on this situation, the _new-style d-tags_ were designed to implement a different
precedence hierarchy. Whenever the new d-tags are enabled,footnote:[the `--enable-new-dtags`
linker flag is default in many current distributions, and especially with the »gold« linker.]
the presence of a `DT_RUNPATH` tag in the `.dynamic` section of an ELF binary completely disables
the effect of any `DT_RPATH`. Moreover, the `LD_LIBRARY_PATH` is automatically disabled, whenever
a binary is installed as _set-user-ID_ or _set-group-ID_ -- which closes a blatant security loophole.
The use of both `RPATH` and `LD_LIBRARY_PATH` is strongly discouraged. Debian policy for example
does not explicitly rule out the use of `RPATH` / `RUNPATH`, but it is considered bad practice
footnote:[a good summary of the situation can be found on
https://wiki.debian.org/RpathIssue[this Debian page] ] -- with the exception of using a _relative_
`RUNPATH` with `$ORIGIN` to add non-standard library search locations to libraries that are only
intended for usage by the given executable or other libraries within the same source package.
In the new system, the precedence order is as follows footnote:[see
http://linux.die.net/man/8/ld.so[ld.so manpage on die.net] or
http://manpages.ubuntu.com/manpages/lucid/man8/ld.so.8.html[ld.so manpage ubuntu.com (more recent)] ]
. `LD_LIBRARY_PATH` entries, unless the executable is `setuid`/`setgid`
. `DT_RUNPATH` from the `.dynamic` section of that ELF binary, library or executable
_causing_ the actual library lookup.
. '/etc/ld.so.cache' entries, unless the `-z nodeflib` linker flaw was given at link time
. '/lib', '/usr/lib' (and the platform-decorated variants) unless `-z nodeflib` was given at link time
. otherwise linking fails (``not found'').
All the ``search paths'' mentioned here are colon separated lists of directories.
NOTE: The new-style `DT_RUNPATH` is not extended recursively when resolving transitive dependencies,
as was the case with `RPATH`. That is, if we `dlopen()` 'libA.so', which in turn marks 'libB.so'
as `DT_NEEDED`, which in turn requires a 'libC.so' -- then the resolution for 'libC.so' will
visit _only_ the `RUNPATH` given in 'libB.so', but _not_ the `RUNPATH` given in 'libA.so'
(to the contrary, the old `RPATH` used to visit all these locations). +
This behaviour was chosen deliberately, in compliance with the ELF spec, as can be seen in this
link:https://sourceware.org/bugzilla/show_bug.cgi?id=13945[glibc bug #13945] and the
developer comment by
link:https://sourceware.org/ml/libc-hacker/2002-11/msg00011.html[Roland McGrath from 2002]
mentioned therein.
the $ORIGIN token
^^^^^^^^^^^^^^^^^
To support flexible `RUNPATH` (and `RPATH`) settings, the GNU `ld.so` (also the SUN and Irix linkers)
allow the usage of some ``magic'' tokens in the `.dynamic` section of ELF binaries (both libraries
and executables):
$ORIGIN:: the directory containing the executable or library _actually triggering_
the current (innermost) resolution step. Not to be confused with the entity
causing the whole linking procedure (an executable to be executed or a `dlopen()` call)
$PLATFORM:: expands to the architecture/platform tag as provided by the OS kernel
$LIB:: the system libraries directory, which is /lib for the native architecture
on FHS compliant GNU/Linux systems.
Since the new-style `RUNPATH` is not extended for resolving transitive dependencies, each library,
when relying on relative locations, must provide _its own_ `RUNPATH` to point at the direct
dependencies at a relative location. This solution is a bit more tricky to set up, but in fact
more logical and scalable on the long run. Incidentally, it can be quite a challenge to escape
the `$ORIGIN` properly from any shell script or even build system -- it is crucial that the
linker itself, not the compiler driver, actually gets to ``see'' the dollar sign, plain,
without spurious escapes.
Transitive binary dependencies Transitive binary dependencies
@ -181,8 +484,8 @@ in the software package definition, so users can install them through the packag
There is a natural tendency to define those installation requirements too wide. For one, it is better There is a natural tendency to define those installation requirements too wide. For one, it is better
to be on the safe side, otherwise users won't be able to run the executable at all. And on top of that, to be on the safe side, otherwise users won't be able to run the executable at all. And on top of that,
there is the general tendency towards frameworks, toolkit sets and library collections -- basically there is the general tendency towards frameworks, toolkit sets and library collections -- basically
a setup which is known to work under a wide range of conditions. Using any of these typically means a setup which is known to work under a wide range of conditions. Using any of these frameworks typically
to add a _standard set of dependencies_, which is often way more than actually required to load and means to add a _standard set of dependencies_, which is often way more than actually required to load and
execute our code. One way to fight this kind of ``distribution dependency bloat'' is to link `--as-needed`. execute our code. One way to fight this kind of ``distribution dependency bloat'' is to link `--as-needed`.
In this mode, the linker silently drops any binary dependency not necessary for _this concrete piece In this mode, the linker silently drops any binary dependency not necessary for _this concrete piece
of code_ to work. This is just awesome, and indeed we set this toggle by default in our build process. of code_ to work. This is just awesome, and indeed we set this toggle by default in our build process.
@ -190,11 +493,31 @@ But there are some issues to be aware of.
Static registration magic Static registration magic
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
[yellow-background]#to be written# The linker _actually needs to see the dependency._ Indirect, conceptual dependencies, where the client
takes initiative and enrols itself actively with the server, will slip through unnoticed. Under some
additional conditions, especially with self-configuring systems, this omission might even cause a whole
dependency and subsystem to be disabled.
As a practical example, our C\++ unit-tests are organised into test-suites, where the individual test uses
a registration mechanism, providing the name of the suite and category tags. This way, the test runner
may be started to execute just some category of tests. Now, switching tests to dynamic linking causes
an insidious side effect: The registration mechanism uses static initialisation -- which is the commonly
used mechanism for this kind of tasks in C++. Place a static variable into an anonymous namespace -- it
will be initialised by the runtime system _on start-up_, causing any constructor code to run right when
it is needed to enrol itself with the global (test) service. Unfortunately, static initialisation of
shared objects is performed at load time of the library -- which never happens unless the linker has
figured out the dependency and added the library to the required set. But the linker won't be able
to see this dependency when building the test-runner, since the client, the individual test-case in
the shared library is the one to call into the test-runner, not the other way round. The registration
function resides in a common support library, picked as dependency both by the test-runner and the
individual test case, but this won't help us either. So, in this case (and similar cases), we need
either to fabricate a ``dummy'' call into the library holding the clients (tests), or we need to
link the test-runner with `--no-as-needed` -- which is the preferred solution, and in fact is
what we do.footnote:[see 'tests/SConscript']
Relative dependency location Relative dependency location
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Locating binary dependencies relative to the executable (as described above) is complicated when several Locating binary dependencies relative to the executable (as described above) gets complicated when several
of _our own dynamically linked modules_ depend on each other transitively. For example, a plug-in might of _our own dynamically linked modules_ depend on each other transitively. For example, a plug-in might
depend on `liblumierabackend.so`, which in turn depends on `liblumierasupport.so`. Now, when we link depend on `liblumierabackend.so`, which in turn depends on `liblumierasupport.so`. Now, when we link
`--as-needed`, the linker will add the direct dependency, but omit the transitive dependency on the `--as-needed`, the linker will add the direct dependency, but omit the transitive dependency on the
@ -210,7 +533,7 @@ dependency_. In our example, `liblumierabackend.so` needs an additional search p
reason, our build system by default supplies such a search hint with every Lumiera lib or dynamic reason, our build system by default supplies such a search hint with every Lumiera lib or dynamic
module -- assuming that our own shared libraries are installed into a subdirectory `modules` below module -- assuming that our own shared libraries are installed into a subdirectory `modules` below
the location of the executable; other dynamic modules (plug-ins) may be placed in sibling directories. the location of the executable; other dynamic modules (plug-ins) may be placed in sibling directories.
So, to summarise, the build defines the following `RPATH` and `RUNPATH` specs: So, to summarise, our build defines the following `RPATH` and `RUNPATH` specs:
for executables:: `$ORIGIN/modules` for executables:: `$ORIGIN/modules`
for libs and modules:: `$ORIGIN/../modules` for libs and modules:: `$ORIGIN/../modules`

View file

@ -1,5 +1,5 @@
/* /*
backend - common lumiera backend things Backend - common lumiera backend facilities
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
@ -84,7 +86,7 @@ lumiera_backend_init (void)
const char* filehandles = lumiera_tmpbuf_snprintf (SIZE_MAX, const char* filehandles = lumiera_tmpbuf_snprintf (SIZE_MAX,
"backend.file.max_handles = %d", "backend.file.max_handles = %d",
/* roughly 2/3 of all availables filehandles are managed by the backend */ /* roughly 2/3 of all available filehandles are managed by the backend */
(sysconf (_SC_OPEN_MAX)-10)*2/3); (sysconf (_SC_OPEN_MAX)-10)*2/3);
lumiera_config_setdefault (filehandles); lumiera_config_setdefault (filehandles);
@ -117,6 +119,7 @@ lumiera_backend_init (void)
return 0; return 0;
} }
void void
lumiera_backend_destroy (void) lumiera_backend_destroy (void)
{ {

View file

@ -1,5 +1,5 @@
/* /*
backend - common lumiera backend things BACKEND.h - common lumiera backend definitions
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,15 +17,18 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_BACKEND_H
#define LUMIERA_BACKEND_H
#ifndef BACKEND_BACKEND_H
#define BACKEND_BACKEND_H
#include "lib/mutex.h" #include "lib/mutex.h"
#include <nobug.h> #include <nobug.h>
//NOBUG_DECLARE_FLAG (backend);
extern size_t lumiera_backend_pagesize; extern size_t lumiera_backend_pagesize;
@ -43,4 +46,4 @@ lumiera_backend_init (void);
void void
lumiera_backend_destroy (void); lumiera_backend_destroy (void);
#endif #endif /*BACKEND_BACKEND_H*/

View file

@ -95,12 +95,12 @@ typedef int64_t FrameCnt;
/** /**
* closure representing the execution context of a job. * closure representing the execution context of a job.
* The information reachable through this closure is specific * The information reachable through this closure is specific
* for this kind of job, but static and typically shared among * for this kind of job, but static and typically shared among
* all jobs for a given feed and segment of the timeline * all jobs for a given feed and segment of the timeline
*/ */
struct lumiera_jobClosure { /* placeholder */ }; struct lumiera_jobClosure { /* placeholder */ };
typedef struct lumiera_jobClosure* LumieraJobClosure; typedef struct lumiera_jobClosure* LumieraJobClosure;
@ -279,8 +279,8 @@ namespace engine {
return this->parameter.invoKey; return this->parameter.invoKey;
} }
JobKind getKind() const; JobKind getKind() const;
bool isValid() const; bool isValid() const;
bool usesClosure (JobClosure const&) const; bool usesClosure (JobClosure const&) const;
@ -332,4 +332,4 @@ size_t lumiera_job_get_hash (LumieraJobDefinition);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif /*BACKEND_ENGINE_JOB_H*/

View file

@ -33,7 +33,7 @@
LUMIERA_ERROR_DEFINE (FILE_CHANGED, "File changed unexpected"); LUMIERA_ERROR_DEFINE (FILE_CHANGED, "File changed unexpected");
LUMIERA_ERROR_DEFINE (FILE_NOMMAPINGS, "MMapings (chunksize/bias) not initialized"); LUMIERA_ERROR_DEFINE (FILE_NOMMAPINGS, "MMapings (chunksize/bias) not initialised");

View file

@ -1,5 +1,5 @@
/* /*
file.h - interface to files by filename FILE.h - interface to files by filename
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,32 +17,33 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_FILE_H
#define LUMIERA_FILE_H /** @file file.h
** File management.
** Handling Files is split into different classes:
** 1. The 'lumiera_file' class which acts as interface to the outside for managing files.
** 'lumiera_file' is addressed by the name of the file. Since files can have more than one name (hardlinks)
** many 'lumiera_file' can point to a single 'lumiera_filedescriptor'
** 2. The 'lumiera_filedescriptor' class which does the real work managing the file in the back.
** 3. Since OS-filehandles are a limited resource we access the lazily as 'lumiera_filehandle' which are
** managed in a 'lumiera_filehandlecache'
*/
#ifndef BACKEND_FILE_H
#define BACKEND_FILE_H
#include "lib/mutex.h" #include "lib/mutex.h"
#include "lib/llist.h" #include "lib/llist.h"
#include "lib/error.h" #include "lib/error.h"
//NOBUG_DECLARE_FLAG (file);
LUMIERA_ERROR_DECLARE(FILE_CHANGED); LUMIERA_ERROR_DECLARE(FILE_CHANGED);
LUMIERA_ERROR_DECLARE(FILE_NOMMAPINGS); LUMIERA_ERROR_DECLARE(FILE_NOMMAPINGS);
/**
* @file
* File management
* Handling Files is splitted into different classes:
* 1. The 'lumiera_file' class which acts as interface to the outside for managing files.
* 'lumiera_file' is addressed by the name of the file. Since files can have more than one name (hardlinks)
* many 'lumiera_file' can point to a single 'lumiera_filedescriptor'
* 2. The 'lumiera_filedescriptor' class which does the real work managing the file in the back.
* 3. Since OS-filehandles are a limited resource we access the lazily as 'lumiera_filehandle' which are
* managed in a 'lumiera_filehandlecache'
*/
typedef struct lumiera_file_struct lumiera_file; typedef struct lumiera_file_struct lumiera_file;
typedef lumiera_file* LumieraFile; typedef lumiera_file* LumieraFile;
@ -55,17 +56,17 @@ typedef lumiera_file* LumieraFile;
/** /**
* File modes: * File modes:
* LUMIERA_FILE_READONLY existing file for reading only * - \c LUMIERA_FILE_READONLY existing file for reading only
* LUMIERA_FILE_READWRITE existing file for reading and writing * - \c LUMIERA_FILE_READWRITE existing file for reading and writing
* LUMIERA_FILE_CREATE non-existing file for reading and writing * - \c LUMIERA_FILE_CREATE non-existing file for reading and writing
* LUMIERA_FILE_RECREATE remove and recreated existing, file for reading and writing * - \c LUMIERA_FILE_RECREATE remove and recreated existing, file for reading and writing
*/ */
#define LUMIERA_FILE_READONLY (O_RDONLY | O_LARGEFILE | O_NOATIME) #define LUMIERA_FILE_READONLY (O_RDONLY | O_LARGEFILE | O_NOATIME)
#define LUMIERA_FILE_READWRITE (O_RDWR | O_LARGEFILE | O_NOATIME) #define LUMIERA_FILE_READWRITE (O_RDWR | O_LARGEFILE | O_NOATIME)
#define LUMIERA_FILE_CREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_EXCL) #define LUMIERA_FILE_CREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_EXCL)
#define LUMIERA_FILE_RECREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_TRUNC) #define LUMIERA_FILE_RECREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_TRUNC)
/* creat and excl flags will be masked out for descriptor lookup */ /* \c creat and \c excl flags will be masked out for descriptor lookup */
#define LUMIERA_FILE_MASK ~(O_CREAT | O_EXCL | O_TRUNC) #define LUMIERA_FILE_MASK ~(O_CREAT | O_EXCL | O_TRUNC)
struct lumiera_file_struct struct lumiera_file_struct
@ -78,7 +79,7 @@ struct lumiera_file_struct
/** /**
* Initialize a file structure. * Initialise a file structure.
* @param self pointer to the file structure * @param self pointer to the file structure
* @param name filename * @param name filename
* @param flags open flags * @param flags open flags
@ -90,7 +91,7 @@ lumiera_file_init (LumieraFile self, const char* name, int flags);
/** /**
* Destroy a file structure. * Destroy a file structure.
* frees all associated resources, releases the filedescriptor etc. * frees all associated resources, releases the file descriptor etc.
* @param self file structure to be destroyed * @param self file structure to be destroyed
* @param do_unlink if 1 then delete the file physically from disk (only the associated name) * @param do_unlink if 1 then delete the file physically from disk (only the associated name)
* @return self * @return self
@ -128,8 +129,8 @@ lumiera_file_delete_unlink (LumieraFile self);
/** /**
* Get a POSIX filehandle for a file. * Get a POSIX filehandle for a file.
* Filehandles are opened on demand and must be acquired for use. * Filehandles are opened on demand and must be acquired for use.
* Using filehandles is refcounted and might be nested. * The use of filehandles is refcounted and might be nested.
* After using them they must be released which puts them back into filehandlecache aging. * After using them they must be released which puts them back into filehandle cache aging.
* @param self file structure * @param self file structure
* @return POSIX filehandle or -1 on error, check lumiera_error() to retrieve the errorcode * @return POSIX filehandle or -1 on error, check lumiera_error() to retrieve the errorcode
* Currently only LUMIERA_ERROR_ERRNO will be raised but this might change in future. * Currently only LUMIERA_ERROR_ERRNO will be raised but this might change in future.
@ -169,8 +170,8 @@ lumiera_file_release_mmap (LumieraFile self, LumieraMMap map);
/** /**
* helper macro for acquireing and releasing maped regions * helper macro for acquiring and releasing maped regions
* @param nobugflag yet unused * @param nobugflag unused for now
* @param file the file from from where to acquire the mapped region * @param file the file from from where to acquire the mapped region
* @param start the start offset for the mmaped region * @param start the start offset for the mmaped region
* @param size the length of the requested block * @param size the length of the requested block
@ -210,8 +211,8 @@ lumiera_file_checkflags (LumieraFile self, int flags);
/** /**
* Set the chunksize for mapping operations * Set the chunksize for mapping operations
* can only set once for a filedescriptor, subsequent calls are no-ops * can only set once for a file descriptor, subsequent calls are no-ops
* @param chunksize allocation/mmaping granularity, must be 2's exponent of pagesize * @param chunksize allocation/mmaping granularity, must be 2's exponent of page size
* @param bias offset to shift chunks, used for stepping over a header for example. * @param bias offset to shift chunks, used for stepping over a header for example.
* @return the effective chunksize used for the file * @return the effective chunksize used for the file
*/ */
@ -237,9 +238,9 @@ lumiera_file_bias_get (LumieraFile self);
/** /**
* Place and remove locks on a file * Place and remove locks on a file.
* This locks are per thread and lock the file across multiple lumiera processes * This locks are per thread and lock the file across multiple lumiera processes
* (or any other programm which repects advisory file locking). * (or any other program which respect to advisory file locking).
* Only exclusive locks over the whole file are supported for initially accessing * Only exclusive locks over the whole file are supported for initially accessing
* a file, other locking is done somewhere else. * a file, other locking is done somewhere else.
*/ */
@ -277,12 +278,4 @@ lumiera_file_unlock (LumieraFile self);
#endif #endif /*BACKEND_FILE_H*/
/*
// Local Variables:
// mode: C
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
*/

View file

@ -1,5 +1,5 @@
/* /*
filedescriptor.c - file handling FileDescriptor - file handling
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/mutex.h" #include "lib/mutex.h"
@ -38,7 +40,7 @@
/* lookup and creation of files, initialized in backend.c */ /* lookup and creation of files, initialised in backend.c */
lumiera_mutex lumiera_filecreate_mutex; lumiera_mutex lumiera_filecreate_mutex;
@ -221,7 +223,7 @@ lumiera_filedescriptor_delete (LumieraFiledescriptor self, const char* name)
lumiera_filedescriptorregistry_remove (self); lumiera_filedescriptorregistry_remove (self);
TODO ("destruct other members (WIP)"); TODO ("destroy other members (WIP)");
lumiera_mmapings_delete (self->mmapings); lumiera_mmapings_delete (self->mmapings);

View file

@ -1,5 +1,5 @@
/* /*
filedescriptor.h - file handling FILEDESCRIPTOR.h - file handling
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -19,8 +19,14 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_FILEDESCRIPTOR_H
#define LUMIERA_FILEDESCRIPTOR_H /** @file filedescriptor.h
** File descriptors are the underlying working horse in accessing files.
** All information associated with managing a file is kept here.
*/
#ifndef BACKEND_FILEDESCRIPTOR_H
#define BACKEND_FILEDESCRIPTOR_H
#include "lib/mutex.h" #include "lib/mutex.h"
#include "lib/rwlock.h" #include "lib/rwlock.h"
@ -40,12 +46,7 @@ typedef lumiera_filedescriptor* LumieraFiledescriptor;
#include "backend/file.h" #include "backend/file.h"
#include "backend/mmapings.h" #include "backend/mmapings.h"
/**
* @file
* Filedescriptors.
* Filedescriptors are the underlying working horse in accessing files.
* All information associated with managing a file is kept here.
*/
struct lumiera_filedescriptor_struct struct lumiera_filedescriptor_struct
{ {
/** node for the lookup tree */ /** node for the lookup tree */
@ -77,6 +78,7 @@ struct lumiera_filedescriptor_struct
/** file locking, a rwlock for thread locking */ /** file locking, a rwlock for thread locking */
lumiera_rwlock filelock; lumiera_rwlock filelock;
/** readlock counter for releasing the file lock, -1 for write lock, 0 = unlocked */ /** readlock counter for releasing the file lock, -1 for write lock, 0 = unlocked */
int lock_cnt; int lock_cnt;
RESOURCE_USER (filelock_rh); RESOURCE_USER (filelock_rh);
@ -119,7 +121,7 @@ lumiera_filedescriptor_samestat (LumieraFiledescriptor self, struct stat* stat);
/** /**
* Allocate a new filedescriptor cloned from a template * Allocate a new filedescriptor cloned from a template
* @param template the source filedescriptor * @param template the source filedescriptor
* @return the constrccted filedescriptor * @return the constructed filedescriptor
*/ */
LumieraFiledescriptor LumieraFiledescriptor
lumiera_filedescriptor_new (LumieraFiledescriptor template); lumiera_filedescriptor_new (LumieraFiledescriptor template);
@ -148,11 +150,4 @@ lumiera_filedescriptor_unlock (LumieraFiledescriptor self);
#endif #endif /*BACKEND_FILEDESCRIPTOR_H*/
/*
// Local Variables:
// mode: C
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
*/

View file

@ -1,5 +1,5 @@
/* /*
filedescriptorregistry.c - register all files in use FiledescriptorRegistry - registry for tracking all files in use
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, 2010, Christian Thaeter <ct@pipapo.org> 2008, 2010, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
@ -29,10 +31,8 @@
#include "backend/filedescriptorregistry.h" #include "backend/filedescriptorregistry.h"
/* /**
Filedescriptor registry * the global registry for file descriptors.
This registry stores all acquired filedescriptors for lookup, they will be freed when not referenced anymore.
*/ */
static PSplay filedescriptorregistry = NULL; static PSplay filedescriptorregistry = NULL;
static lumiera_mutex filedescriptorregistry_mutex; static lumiera_mutex filedescriptorregistry_mutex;
@ -110,7 +110,7 @@ lumiera_filedescriptorregistry_destroy (void)
LumieraFiledescriptor LumieraFiledescriptor
lumiera_filedescriptorregistry_ensure (LumieraFiledescriptor template) lumiera_filedescriptorregistry_ensure (LumieraFiledescriptor template)
{ {
REQUIRE (filedescriptorregistry, "not initialized"); REQUIRE (filedescriptorregistry, "not initialised");
LumieraFiledescriptor ret = NULL; LumieraFiledescriptor ret = NULL;
@ -136,9 +136,6 @@ lumiera_filedescriptorregistry_ensure (LumieraFiledescriptor template)
} }
/**
* Removes a Filedescriptor from the registry.
*/
void void
lumiera_filedescriptorregistry_remove (LumieraFiledescriptor self) lumiera_filedescriptorregistry_remove (LumieraFiledescriptor self)
{ {

View file

@ -1,5 +1,5 @@
/* /*
filedescriptorregistry.h - register all files in use FILEDESCRIPTORREGISTRY.h - registry for tracking all files in use
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, 2010, Christian Thaeter <ct@pipapo.org> 2008, 2010, Christian Thaeter <ct@pipapo.org>
@ -17,24 +17,33 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_FILEDESCRIPTORREGISTRY_H
#define LUMIERA_FILEDESCRIPTORREGISTRY_H /** @file filedescriptorregistry.h
** Registry for used file descriptors.
** This registry stores all acquired file descriptors for lookup,
** they will be freed when not referenced anymore.
*/
#ifndef BACKEND_FILEDESCRIPTORREGISTRY_H
#define BACKEND_FILEDESCRIPTORREGISTRY_H
#include "backend/filedescriptor.h" #include "backend/filedescriptor.h"
/** /**
* Initialize the global filedescriptor registry. * Initialise the global file descriptor registry.
* Opening hardlinked files will be targeted to the same filedescriptor. * Opening hard linked files will be targeted to the same file descriptor.
* This function never fails but dies on error. TODO backend/subsystem failure * This function never fails but dies on error.
* @todo proper backend/subsystem failure
*/ */
void void
lumiera_filedescriptorregistry_init (void); lumiera_filedescriptorregistry_init (void);
/** /**
* Destroy and free the global filedescriptor registry. * Destroy and free the global file descriptor registry.
* Never fails. * Never fails.
*/ */
void void
@ -48,11 +57,11 @@ lumiera_filedescriptorregistry_destroy (void);
LumieraFiledescriptor LumieraFiledescriptor
lumiera_filedescriptorregistry_ensure (LumieraFiledescriptor template); lumiera_filedescriptorregistry_ensure (LumieraFiledescriptor template);
/**
* Removes a Filedescriptor from the registry. /** Removes a file descriptor from the registry. */
*/
void void
lumiera_filedescriptorregistry_remove (LumieraFiledescriptor self); lumiera_filedescriptorregistry_remove (LumieraFiledescriptor self);
#endif
#endif /*BACKEND_FILEDESCRIPTORREGISTRY_H*/

View file

@ -1,5 +1,5 @@
/* /*
filehandle - filehandle management and caching FileHandle - filehandle management and caching
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/llist.h" #include "lib/llist.h"
@ -29,6 +31,8 @@
#include <unistd.h> #include <unistd.h>
LumieraFilehandle LumieraFilehandle
lumiera_filehandle_init (LumieraFilehandle self, LumieraFiledescriptor desc) lumiera_filehandle_init (LumieraFilehandle self, LumieraFiledescriptor desc)
{ {
@ -78,7 +82,7 @@ lumiera_filehandle_handle (LumieraFilehandle self)
fd = open (lumiera_filedescriptor_name (self->descriptor), lumiera_filedescriptor_flags (self->descriptor) & LUMIERA_FILE_MASK); fd = open (lumiera_filedescriptor_name (self->descriptor), lumiera_filedescriptor_flags (self->descriptor) & LUMIERA_FILE_MASK);
if (fd == -1) if (fd == -1)
{ {
FIXME ("Handle EMFILE etc with the resourcecollector"); //////////////////////TODO Handle EMFILE etc with the resourcecollector
LUMIERA_ERROR_SET_CRITICAL (file, ERRNO, lumiera_filedescriptor_name (self->descriptor)); LUMIERA_ERROR_SET_CRITICAL (file, ERRNO, lumiera_filedescriptor_name (self->descriptor));
} }
else else

View file

@ -1,5 +1,5 @@
/* /*
filehandle - filehandle management and caching FILEHANDLE - filehandle management and caching
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,9 +17,19 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_FILEHANDLE_H
#define LUMIERA_FILEHANDLE_H
/** @file filehandle.h
** Filehandles manage the underlying POSIX filehandle for a file descriptor.
** Since we want to support handling of more files than POSIX filehandles are available
** on a common system the filehandles are opened, cached and closed on demand, see 'filehandlecache'.
** Access to filehandles is locked from elsewhere (filedescriptor, filehandlecache)
*/
#ifndef BACKEND_FILEHANDLE_H
#define BACKEND_FILEHANDLE_H
#include "lib/error.h" #include "lib/error.h"
#include "lib/llist.h" #include "lib/llist.h"
@ -31,14 +41,6 @@ typedef lumiera_filehandle* LumieraFilehandle;
//NOBUG_DECLARE_FLAG (filehandle); //NOBUG_DECLARE_FLAG (filehandle);
/**
* @file
* Filehandles.
* Filehandles manage the underlying POSIX filehandle for a filedescriptor.
* Since we want to support handling of more files than POSIX filehandles are available on a common system
* the filehandles are opened, cached and closed on demand, see 'filehandlecache'.
* Access to filehandles is locked from elsewhere (filedescriptor, filehandlecache)
*/
/** /**
@ -52,15 +54,17 @@ struct lumiera_filehandle_struct
LumieraFiledescriptor descriptor; LumieraFiledescriptor descriptor;
}; };
/** /**
* Initialize filehandle structure. * Initialise filehandle structure.
* @param self filehandle sttructure to be initialized * @param self filehandle structure to be initialised
* @param descriptor on which this filehandle will be attached * @param descriptor on which this filehandle will be attached
* @return new filehandle structure * @return new filehandle structure
*/ */
LumieraFilehandle LumieraFilehandle
lumiera_filehandle_init (LumieraFilehandle self, LumieraFiledescriptor descriptor); lumiera_filehandle_init (LumieraFilehandle self, LumieraFiledescriptor descriptor);
/** /**
* Allocate a new filehandle structure. * Allocate a new filehandle structure.
* @param descriptor on which this filehandle will be attached * @param descriptor on which this filehandle will be attached
@ -71,9 +75,9 @@ lumiera_filehandle_new (LumieraFiledescriptor descriptor);
/** /**
* destroy the resources associated eith a filehandle structure. * destroy the resources associated either a filehandle structure.
* This function is used by the filehandlecache to recycle filehandle structs. * This function is used by the filehandle cache to recycle filehandle structs.
* @param node pointer to the cachenode member of a struct filehandle * @param node pointer to the cache node member of a struct filehandle
* @return pointer to the start of the memory of the destroyed filehandle * @return pointer to the start of the memory of the destroyed filehandle
*/ */
void* void*
@ -85,7 +89,7 @@ lumiera_filehandle_handle (LumieraFilehandle self);
/** /**
* just accessor, no saftey net * just accessor, no safety net
*/ */
static inline int static inline int
lumiera_filehandle_get (LumieraFilehandle self) lumiera_filehandle_get (LumieraFilehandle self)
@ -94,4 +98,4 @@ lumiera_filehandle_get (LumieraFilehandle self)
return self->fd; return self->fd;
} }
#endif #endif /*BACKEND_FILEHANDLE_H*/

View file

@ -1,5 +1,5 @@
/* /*
filehandlecache - filehandle management and caching FileHandleCache - filehandle management and caching
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
@ -26,18 +28,21 @@
#include "backend/filehandlecache.h" #include "backend/filehandlecache.h"
/* errors */
LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available"); LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available");
/**
* the global cache for file handles.
*/
LumieraFilehandlecache lumiera_fhcache = NULL; LumieraFilehandlecache lumiera_fhcache = NULL;
void void
lumiera_filehandlecache_new (int max_entries) lumiera_filehandlecache_new (int max_entries)
{ {
REQUIRE (!lumiera_fhcache, "Filehandlecache already initialized"); REQUIRE (!lumiera_fhcache, "Filehandlecache already initialised");
lumiera_fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache)); lumiera_fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache));
lumiera_mrucache_init (&lumiera_fhcache->cache, lumiera_filehandle_destroy_node); lumiera_mrucache_init (&lumiera_fhcache->cache, lumiera_filehandle_destroy_node);

View file

@ -1,5 +1,5 @@
/* /*
filehandlecache - filehandle management and caching FILEHANDLECACHE - filehandle management and caching
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,9 +17,20 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_FILEHANDLECACHE_H
#define LUMIERA_FILEHANDLECACHE_H
/** @file filehandlecache.h
** Caching and management of filehandles.
** The number of filehandles a program can held open is usually limited, since we want to support
** using a less limited number of files and closing/opening for each operation is expensive, we
** provide a cache to keep the most frequent used files open and gracefully close/recycle unused filehandles.
** The filehandle cache defined here protects all operations on the cache with a mutex.
*/
#ifndef BACKEND_FILEHANDLECACHE_H
#define BACKEND_FILEHANDLECACHE_H
#include "lib/error.h" #include "lib/error.h"
#include "lib/mrucache.h" #include "lib/mrucache.h"
@ -30,19 +41,9 @@ typedef lumiera_filehandlecache* LumieraFilehandlecache;
#include "backend/filehandle.h" #include "backend/filehandle.h"
/**
* @file
* Filehandle management and caching
* The number of filehandles a program can held open is usually limited, since we want to support
* using a less limited number of files and closing/opening for each operation is expensive, we
* provide a cache to keep the most frequent used files open and gracefully close/recycle unused filehandles.
* The filehandlecache defined here protects all operations on the cache with a mutex.
*/
/* /** File handle cache manages file handles */
File handle cache manages file handles
*/
struct lumiera_filehandlecache_struct struct lumiera_filehandlecache_struct
{ {
lumiera_mrucache cache; lumiera_mrucache cache;
@ -52,7 +53,7 @@ struct lumiera_filehandlecache_struct
}; };
/** /**
* Initializes the filehandle cache. * Initialises the filehandle cache.
* @param max_entries number how much filehandles shall be managed * @param max_entries number how much filehandles shall be managed
* The number of elements the cache can hold is static and should be * The number of elements the cache can hold is static and should be
* determined by sysconf (_SC_OPEN_MAX) minus some (big) safety margin. * determined by sysconf (_SC_OPEN_MAX) minus some (big) safety margin.
@ -94,4 +95,6 @@ lumiera_filehandlecache_checkout (LumieraFilehandle handle);
void void
lumiera_filehandlecache_checkin (LumieraFilehandle handle); lumiera_filehandlecache_checkin (LumieraFilehandle handle);
#endif
#endif /*BACKEND_FILEHANDLECACHE_H*/

View file

@ -1,5 +1,5 @@
/* /*
fileheader.c - Definitions of generic lumiera fileheaders and identification Fileheader - Definitions of generic lumiera file headers and identification
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2010, Christian Thaeter <ct@pipapo.org> 2010, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "lib/tmpbuf.h" #include "lib/tmpbuf.h"
@ -25,24 +27,19 @@
#include "backend/file.h" #include "backend/file.h"
#include "include/logging.h" #include "include/logging.h"
//TODO: internal/static forward declarations//
#include <errno.h> #include <errno.h>
/**
* @file
*
*/
LUMIERA_ERROR_DEFINE (FILEHEADER_NOWRITE, "File is not writeable");
LUMIERA_ERROR_DEFINE (FILEHEADER_NOWRITE, "File is not writable");
LUMIERA_ERROR_DEFINE (FILEHEADER_HEADER, "Error in header"); LUMIERA_ERROR_DEFINE (FILEHEADER_HEADER, "Error in header");
LUMIERA_ERROR_DEFINE (FILEHEADER_FLAGS, "Inconsistent Flags"); LUMIERA_ERROR_DEFINE (FILEHEADER_FLAGS, "Inconsistent Flags");
LUMIERA_ERROR_DEFINE (FILEHEADER_FLAGSPACE, "No more space for flags left"); LUMIERA_ERROR_DEFINE (FILEHEADER_FLAGSPACE, "No more space for flags left");
LUMIERA_ERROR_DEFINE (FILEHEADER_ENDIANESS, "Unsupported Endianess"); LUMIERA_ERROR_DEFINE (FILEHEADER_ENDIANESS, "Unsupported Endianess");
lumiera_fileheader lumiera_fileheader
lumiera_fileheader_create (LumieraFile file, char* fourcc, int version, size_t size, const char* flags) lumiera_fileheader_create (LumieraFile file, char* fourcc, int version, size_t size, const char* flags)
{ {
@ -109,7 +106,7 @@ lumiera_fileheader_open (LumieraFile file, char* fourcc, size_t size, const char
goto err; goto err;
} }
TODO("only clear flags when file is writeable"); ////////////////////TODO only clear flags when file is writable!
lumiera_fileheader_flags_clear (&self, flags_remove); lumiera_fileheader_flags_clear (&self, flags_remove);
static uint64_t endianess_mark = LUMIERA_FILEHEADER_ENDIANMAGIC; static uint64_t endianess_mark = LUMIERA_FILEHEADER_ENDIANMAGIC;
@ -204,6 +201,7 @@ lumiera_fileheader_flags_set (LumieraFileheader self, const char* flags)
return self; return self;
} }
/** /**
* Clear flags if present * Clear flags if present
*/ */

View file

@ -1,5 +1,5 @@
/* /*
fileheader.h - Definitions of generic lumiera fileheaders and identification FILEHEADER.h - Definitions of generic lumiera file headers and identification
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2010, Christian Thaeter <ct@pipapo.org> 2010, Christian Thaeter <ct@pipapo.org>
@ -17,13 +17,28 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_FILEHEADER_H
#define LUMIERA_FILEHEADER_H /** @file fileheader.h
** Common header format to identify various kinds of files.
** Lumiera creates some files on itself, caches, indexes and so on.
** Here we define a unified header format for identifying and handling these files.
**
** Most of this files store binary data in host order for performance reasons and are not yet
** intended to be transfered between computers. While the transferability depends on the
** concrete implementation later and is not constrained here.
**
*/
#ifndef BACKEND_FILEHEADER_H
#define BACKEND_FILEHEADER_H
#include "lib/error.h" #include "lib/error.h"
LUMIERA_ERROR_DECLARE (FILEHEADER_NOWRITE); LUMIERA_ERROR_DECLARE (FILEHEADER_NOWRITE);
LUMIERA_ERROR_DECLARE (FILEHEADER_HEADER); LUMIERA_ERROR_DECLARE (FILEHEADER_HEADER);
LUMIERA_ERROR_DECLARE (FILEHEADER_FLAGS); LUMIERA_ERROR_DECLARE (FILEHEADER_FLAGS);
@ -46,17 +61,6 @@ typedef lumiera_fileheader_raw* LumieraFileheaderRaw;
#include <semaphore.h> #include <semaphore.h>
/**
* @file
*
* Lumiera creates some files on itself, caches, indexes and so on.
* Here we define a unified header format for identifying and handling these files.
*
* Most of this files store binary data in host order for performance reasons an are not yet
* intended to be transfered between computers. While the transferability depends on the
* concrete implementation later and is not contstrained here.
*
*/
#ifndef LUMIERA_PACKED #ifndef LUMIERA_PACKED
@ -64,7 +68,7 @@ typedef lumiera_fileheader_raw* LumieraFileheaderRaw;
#endif #endif
/** /**
* A basic fileheader * A basic file header
* On-Disk representation starts with 32 bytes identifying the file. * On-Disk representation starts with 32 bytes identifying the file.
* The first 32 bytes are human readable text. * The first 32 bytes are human readable text.
*/ */
@ -76,12 +80,12 @@ struct LUMIERA_PACKED lumiera_fileheader_raw_struct
char version[3]; char version[3];
/** always '\n' */ /** always '\n' */
char newline1; char newline1;
/** freeform string, comment or so on, initialized to spaces */ /** free form string, comment or so on, initialised to spaces */
char meta[15]; char meta[15];
/** always '\n' */ /** always '\n' */
char newline2; char newline2;
/** initialized to spaces, flags are single chars, unsorted */ /** Initialised to spaces, flags are single chars, unsorted */
char flags[6]; char flags[6];
/** always '\n' */ /** always '\n' */
char newline3; char newline3;
@ -93,7 +97,8 @@ struct LUMIERA_PACKED lumiera_fileheader_raw_struct
}; };
/** /**
* Fileheader flags are chars to make this easily inspectable, these add another human readable line to the header * File header flags are chars to support debugging and inspection,
* these add another human readable line to the header.
*/ */
/** file is clean */ /** file is clean */
@ -107,7 +112,7 @@ struct LUMIERA_PACKED lumiera_fileheader_raw_struct
/** /**
* A fileheader object encapsulates the underlying mmap object which keeps the * A file header object encapsulates the underlying mmap object which keeps the
* raw header data in memory and and the dereferenced thereof. * raw header data in memory and and the dereferenced thereof.
*/ */
struct lumiera_fileheader_struct struct lumiera_fileheader_struct
@ -118,15 +123,15 @@ struct lumiera_fileheader_struct
/** /**
* Create a fileheader on a file open for writing. * Create a file header on a file open for writing.
* This overwrites any existing date, take care. The created fileheader is mmaped into memory * This overwrites any existing date, take care. The created file header is mmaped into memory
* and must be closed after use. The File should be locked for operations on the fileheader. * and must be closed after use. The File should be locked for operations on the file header.
* @param file The file on which to create the header. * @param file The file on which to create the header.
* @param fourcc pointer to a string of length 4 * @param fourcc pointer to a string of length 4
* @param version version number for the header (should be incremented after changes) * @param version version number for the header (should be incremented after changes)
* the value '0' is reserved for experimental versions. * the value '0' is reserved for experimental versions.
* @param size The actual size of all header data, including following format specific data. * @param size The actual size of all header data, including following format specific data.
* @param flags initial flags which should be set (dont include CLEAN here, should be set on close) * @param flags initial flags which should be set (don't include CLEAN here, should be set on close)
* @return A lumiera_fileheader object by value, .header and .map are set to NULL on error. * @return A lumiera_fileheader object by value, .header and .map are set to NULL on error.
*/ */
lumiera_fileheader lumiera_fileheader
@ -134,9 +139,9 @@ lumiera_fileheader_create (LumieraFile file, char* fourcc, int version, size_t s
/** /**
* Open an existing fileheader. * Open an existing file header.
* The underlying file might be readonly. The opened fileheader is mmaped into memory * The underlying file might be readonly. The opened file header is mmaped into memory
* and must be closed after use. The File should be locked for operations on the fileheader. * and must be closed after use. The File should be locked for operations on the file header.
* @param file The file on which to open the header. * @param file The file on which to open the header.
* @param fourcc pointer to a string of length 4 with the expected identifier for the file * @param fourcc pointer to a string of length 4 with the expected identifier for the file
* @param size The actual size of all header data, including following format specific data * @param size The actual size of all header data, including following format specific data
@ -149,8 +154,8 @@ lumiera_fileheader_open (LumieraFile file, char* fourcc, size_t size, const char
/** /**
* Closes a previously created or opened fileheader. * Closes a previously created or opened file header.
* @param self the fileheader to close. * @param self the file header to close.
* @param flags_add set this flags if not already set * @param flags_add set this flags if not already set
* no errors, no nothing returned (yet) * no errors, no nothing returned (yet)
*/ */
@ -159,9 +164,9 @@ lumiera_fileheader_close (LumieraFileheader self, const char* flags_add);
/** /**
* Queries the version of a fileheader. * Queries the version of a file header.
* @param self the fileheader to query * @param self the file header to query
* @return the version stored in the fileheader or -1 on error. * @return the version stored in the file header or -1 on error.
*/ */
int int
lumiera_fileheader_version (LumieraFileheader self); lumiera_fileheader_version (LumieraFileheader self);
@ -187,7 +192,7 @@ LumieraFileheader
lumiera_fileheader_flags_clear (LumieraFileheader self, const char* flags); lumiera_fileheader_flags_clear (LumieraFileheader self, const char* flags);
#endif #endif /*BACKEND_FILEHEADER_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
@ -30,21 +32,13 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <errno.h> #include <errno.h>
/**
* @file
*
*/
LUMIERA_ERROR_DEFINE (MMAP_NWRITE, "Backing file not writable"); LUMIERA_ERROR_DEFINE (MMAP_NWRITE, "Backing file not writable");
LUMIERA_ERROR_DEFINE (MMAP_SPACE, "Address space exhausted"); LUMIERA_ERROR_DEFINE (MMAP_SPACE, "Address space exhausted");
/**
* global mmap registry/cache
*
*/
LumieraMMap LumieraMMap
@ -52,7 +46,7 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
{ {
TRACE (mmap_dbg); TRACE (mmap_dbg);
TODO ("enforce size instead using chunksize (rounded to pagessize) for parsing headers"); TODO ("enforce size instead using chunksize (rounded to page size) for parsing headers");
REQUIRE (self); REQUIRE (self);
REQUIRE (file); REQUIRE (file);
@ -60,9 +54,19 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
REQUIRE (size); REQUIRE (size);
/** /**
* default size for the mmapping window * default size for the mmapping window.
* 128MB on 32 bit arch * - 128MB on 32 bit arch
* 2GB on 64 bit arch * - 2GB on 64 bit arch
*
* \par
* Maintaining the right[tm] mmapping size is a bit tricky:
* - We have the default mmap_window_size which will be backed off when address space gets exhausted
* - When a bigger size is requested we have to fulfil it
* - The last mmapped chunk of a file can be as small as possible when the file is readonly
* - When the file is writable, the last chunk should be rounded up to chunksize
* - All boundaries will be aligned up/down to chunk boundaries
* - Requests beyond the file end must ftruncate and map additional pages
* - Create the 'refmap' which contains a refcounter per chunk
*/ */
TODO("move the setdefaults somewhere else, backend_defaults.c or so"); TODO("move the setdefaults somewhere else, backend_defaults.c or so");
#if SIZE_MAX <= 4294967295U #if SIZE_MAX <= 4294967295U
@ -92,16 +96,6 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
TODO ("error here? or just map as asked for?"); TODO ("error here? or just map as asked for?");
ENSURE(chunksize); ENSURE(chunksize);
/**
* Maintaining the right[tm] mmapping size is a bit tricky:
* - We have the default mmap_window_size which will be backed off when address space gets exhausted
* - When a bigger size is requested we have to fulfil it
* - The last mmapped chunk of a file can be as small as possible when the file is readonly
* - When the file is writable, the last chunk should be rounded up to chunksize
* - All boundaries will be aligned up/down to chunk boundaries
* - Requests beyond the file end must ftruncate and map additional pages
* - Create the 'refmap' which contains a refcounter per chunk
**/
/** /**
* Recovering address space strategies: * Recovering address space strategies:
@ -245,7 +239,7 @@ lumiera_mmap_init_exact (LumieraMMap self, LumieraFile file, off_t start, size_t
} }
} }
TODO ("use resourcecllector here"); /////////////////////////TODO use resourcecllector here
void* addr = mmap (NULL, void* addr = mmap (NULL,
size, size,
(descriptor->flags & O_ACCMODE) == O_RDONLY ? PROT_READ : PROT_READ|PROT_WRITE, (descriptor->flags & O_ACCMODE) == O_RDONLY ? PROT_READ : PROT_READ|PROT_WRITE,

View file

@ -1,5 +1,5 @@
/* /*
mmap.h - memory mapped access to files MMAP - memory mapped access to files
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,10 +17,17 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_MMAP_H
#define LUMIERA_MMAP_H /** @file mmap.h
** MMap objects cover a memory mapped range in a file.
** They are managed through a global mmap registry/cache.
*/
#ifndef BACKEND_MMAP_H
#define BACKEND_MMAP_H
#include "lib/llist.h" #include "lib/llist.h"
@ -36,26 +43,20 @@ typedef lumiera_mmap* LumieraMMap;
#include <nobug.h> #include <nobug.h>
#include <sys/mman.h> #include <sys/mman.h>
//NOBUG_DECLARE_FLAG (mmap);
/** /**
* @file * Descriptor of a memory mapped area
* MMap objects cover a memory maped range in a file
*/
/**
* mmaped area
*
*/ */
struct lumiera_mmap_struct struct lumiera_mmap_struct
{ {
/** used for the mrucache when checked in the cache **/ /** used for the mrucache when checked in the cache **/
llist cachenode; llist cachenode;
/** all mmaps of a filedescriptor are chained in this list, used to find ranges **/ /** all mmaps regarding a file are chained in this list, used to find ranges **/
llist searchnode; llist searchnode;
off_t start; off_t start;
@ -65,14 +66,15 @@ struct lumiera_mmap_struct
/** accumulated references, this is 0 when checked into the cache **/ /** accumulated references, this is 0 when checked into the cache **/
long refcnt; long refcnt;
/** array with refcounters per chunk **/ /** array with a refcounter per chunk **/
short* refmap; // TODO flexible array? short* refmap; ///////////////////// TODO make this a flexible array?
}; };
/** /**
* Initialize a MMap object. * Initialise a MMap object.
* The mmap objects are aligned and shifted by the chunksize and bias defined for the file * The mmap objects are aligned and shifted by the chunksize and bias defined for the file
* @param self the mmap object to be initialized * @param self the mmap object to be initialised
* @param file file from which to map * @param file file from which to map
* @param start offset in file which must be part of the mmaped region * @param start offset in file which must be part of the mmaped region
* @param size minimum size after start to map * @param size minimum size after start to map
@ -82,9 +84,9 @@ LumieraMMap
lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size); lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size);
/** /**
* Initialize a MMap object. * Initialise a MMap object.
* Maps exactly the given range * Maps exactly the given range
* @param self the mmap object to be initialized * @param self the mmap object to be initialised
* @param file file from which to map * @param file file from which to map
* @param start offset in file which must be part of the mmaped region * @param start offset in file which must be part of the mmaped region
* @param size minimum size after start to map * @param size minimum size after start to map
@ -123,7 +125,7 @@ void*
lumiera_mmap_destroy_node (LList node); lumiera_mmap_destroy_node (LList node);
#endif #endif /*BACKEND_MMAP_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
mmapcache.c - handle aging of mmap objects MMAP-Cache - handle aging of mmap objects
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,17 +17,15 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
#include "backend/mmapcache.h" #include "backend/mmapcache.h"
/**
* @file
*
*/
LumieraMMapcache lumiera_mcache = NULL; LumieraMMapcache lumiera_mcache = NULL;
@ -82,7 +80,7 @@ lumiera_mmapcache_mmap_acquire (void)
} }
else else
{ {
TRACE (mmapcache_dbg, "poped mmap from cache"); TRACE (mmapcache_dbg, "Popped mmap from cache");
} }
return map; return map;
@ -125,7 +123,7 @@ lumiera_mmapcache_age (void)
LUMIERA_MUTEX_SECTION (mmapcache, &lumiera_mcache->lock) LUMIERA_MUTEX_SECTION (mmapcache, &lumiera_mcache->lock)
{ {
ret = lumiera_mrucache_age (&lumiera_mcache->cache, 10); TODO ("age nelem == 20%(configureable) of the cache"); ret = lumiera_mrucache_age (&lumiera_mcache->cache, 10); TODO ("age nelem == 20%(configurable) of the cache");
} }
return ret; return ret;
@ -140,7 +138,7 @@ lumiera_mmapcache_checkout (LumieraMMap handle)
LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_mcache->lock) LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_mcache->lock)
{ {
TODO ("cached stats"); ////////////////////TODO cached stats
lumiera_mrucache_checkout (&lumiera_mcache->cache, &handle->cachenode); lumiera_mrucache_checkout (&lumiera_mcache->cache, &handle->cachenode);
} }
@ -156,7 +154,7 @@ lumiera_mmapcache_checkin (LumieraMMap handle)
LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_mcache->lock) LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_mcache->lock)
{ {
TODO ("cached stats"); ////////////////////TODO cached stats
lumiera_mrucache_checkin (&lumiera_mcache->cache, &handle->cachenode); lumiera_mrucache_checkin (&lumiera_mcache->cache, &handle->cachenode);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
mmapcache.h - handle aging of mmap objects MMAPCACHE.h - handle aging of mmap objects
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,10 +17,17 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_MMAPCACHE_H
#define LUMIERA_MMAPCACHE_H /** @file mmapcache.h
** Lumiera's Mmapcache stores a MRU cache of all established mmaped memory regions which are currently not in use.
** The mmapcache also manages the upper limit about how much memory can be mmaped.
*/
#ifndef BACKEND_MMAPCACHE_H
#define BACKEND_MMAPCACHE_H
#include "lib/error.h" #include "lib/error.h"
#include "lib/mrucache.h" #include "lib/mrucache.h"
@ -34,11 +41,8 @@ typedef lumiera_mmapcache* LumieraMMapcache;
#include <nobug.h> #include <nobug.h>
/**
* @file
* Mmapcache stores a MRU cache of all established mmaped memory regions which are currently not in use.
* The mmapcache also manages the upper limit about how much memory can be mmaped.
*/
struct lumiera_mmapcache_struct struct lumiera_mmapcache_struct
{ {
@ -51,8 +55,8 @@ struct lumiera_mmapcache_struct
/** /**
* Initializes the mmapcache. * Initialises the mmapcache.
* @param limit the mmapcache will drop elements when the sum of all mmapings gives over limit * @param limit the mmapcache will drop elements when the sum of all mmappings gives over limit
*/ */
void void
lumiera_mmapcache_new (size_t limit); lumiera_mmapcache_new (size_t limit);
@ -67,9 +71,9 @@ lumiera_mmapcache_delete (void);
/** /**
* Get a fresh mmap object. * Get a fresh mmap object.
* when mmaped_limit is reached, the oldest mmap object gets dropped else a new allocated object * when mmaped_limit is reached, the oldest mmap object gets dropped else
* is returned * a new allocated object is returned
* @return the new uninitialized mmap (void* because this is uninitialized) * @return the new uninitialised mmap (void* because this is uninitialised)
*/ */
void* void*
lumiera_mmapcache_mmap_acquire (void); lumiera_mmapcache_mmap_acquire (void);
@ -95,7 +99,7 @@ lumiera_mmapcache_forget (LumieraMMap map);
/** /**
* Destroy and free the nelem oldest elements. * Destroy and free the nelem oldest elements.
* Used to free up resources and memory. * Used to free up resources and memory.
* @return nelem-(numer of elements which got freed), that is 0 if all requested elements got freed * @return nelem-(number of elements which got freed), that is 0 if all requested elements got freed
*/ */
int int
lumiera_mmapcache_age (void); lumiera_mmapcache_age (void);
@ -116,7 +120,8 @@ lumiera_mmapcache_checkout (LumieraMMap handle);
void void
lumiera_mmapcache_checkin (LumieraMMap handle); lumiera_mmapcache_checkin (LumieraMMap handle);
#endif
#endif /*BACKEND_MMAPCACHE_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
mmapings.c - manage ranges of mmaped areas on a filedescriptor MMapings - manage ranges of mmaped areas on a file descriptor
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/mutex.h" #include "lib/mutex.h"
@ -28,11 +30,6 @@
#include "backend/mmapcache.h" #include "backend/mmapcache.h"
/**
* @file
*
*/
LumieraMMapings LumieraMMapings
lumiera_mmapings_init (LumieraMMapings self, LumieraFile file, size_t chunksize, size_t bias) lumiera_mmapings_init (LumieraMMapings self, LumieraFile file, size_t chunksize, size_t bias)
@ -102,7 +99,7 @@ lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, off_t sta
/* find first matching mmap, crude way */ /* find first matching mmap, crude way */
LLIST_FOREACH (&self->mmaps, node) LLIST_FOREACH (&self->mmaps, node)
{ {
TODO ("improve this selection algorithm, choose mmaps by size, move mfu to head etc"); ////////////TODO improve the algorithm used here: choose mmaps by size, move mfu to head etc...
LumieraMMap mmap = LLIST_TO_STRUCTP (node, lumiera_mmap, searchnode); LumieraMMap mmap = LLIST_TO_STRUCTP (node, lumiera_mmap, searchnode);

View file

@ -1,5 +1,5 @@
/* /*
mmapings.h - manage ranges of mmaped areas on a filedescriptor MMAPINGS.h - manage ranges of mmaped areas on a file descriptor
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,10 +17,16 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_MMAPINGS_H
#define LUMIERA_MMAPINGS_H /** @file mmapings.h
** Manage the mmap objects of a file.
*/
#ifndef BACKEND_MMAPINGS_H
#define BACKEND_MMAPINGS_H
#include "lib/mutex.h" #include "lib/mutex.h"
#include "lib/llist.h" #include "lib/llist.h"
@ -34,13 +40,8 @@ typedef lumiera_mmapings* LumieraMMapings;
#include <nobug.h> #include <nobug.h>
//NOBUG_DECLARE_FLAG (mmapings);
/**
* @file
* Manage the mmap objects of a file
*
*/
struct lumiera_mmapings_struct struct lumiera_mmapings_struct
{ {
@ -48,7 +49,7 @@ struct lumiera_mmapings_struct
llist mmaps; llist mmaps;
/** /**
* chunkssize is the smallest granularity which is used for mmapping files, it * chunksize is the smallest granularity which is used for mmapping files, it
* should reflect the intended file usage, that is 'pagesize' for small or non growing * should reflect the intended file usage, that is 'pagesize' for small or non growing
* files and some MB for media files. Must be a 2's exponent of pagesize. * files and some MB for media files. Must be a 2's exponent of pagesize.
**/ **/
@ -63,31 +64,24 @@ struct lumiera_mmapings_struct
lumiera_mutex lock; lumiera_mutex lock;
}; };
/**
* initialize mmapings container
* /** initialise mmapings container */
*/
LumieraMMapings LumieraMMapings
lumiera_mmapings_init (LumieraMMapings self, LumieraFile file, size_t chunksize, size_t bias); lumiera_mmapings_init (LumieraMMapings self, LumieraFile file, size_t chunksize, size_t bias);
/**
* destroy mmapings container and free all resources. /** destroy mmapings container and free all resources. */
*
*/
LumieraMMapings LumieraMMapings
lumiera_mmapings_destroy (LumieraMMapings self); lumiera_mmapings_destroy (LumieraMMapings self);
/**
* allocate and initialize new mmapings container /** allocate and initialise new mmapings container */
*
*/
LumieraMMapings LumieraMMapings
lumiera_mmapings_new (LumieraFile file, size_t chunksize, size_t bias); lumiera_mmapings_new (LumieraFile file, size_t chunksize, size_t bias);
/**
* destroy and free mmapings container and all its resources /** destroy and free mmapings container and all its resources */
*
*/
void void
lumiera_mmapings_delete (LumieraMMapings self); lumiera_mmapings_delete (LumieraMMapings self);
@ -106,7 +100,6 @@ lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, off_t sta
/** /**
* release a previously acquired MMap object * release a previously acquired MMap object
* @param self mmapings to which the map belongs * @param self mmapings to which the map belongs
* @param acquirer holding node
* @param map object to be released * @param map object to be released
*/ */
void void
@ -115,7 +108,7 @@ lumiera_mmapings_release_mmap (LumieraMMapings self, LumieraMMap map);
#endif #endif /*BACKEND_MMAPINGS_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
resourcecollector.c - manage/collect resources when they get short ResourceCollector - manage/collect resources when they get short
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,18 +17,21 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/llist.h" #include "lib/llist.h"
#include "lib/mutex.h" #include "lib/mutex.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
#include "resourcecollector.h" #include "backend/resourcecollector.h"
#include <unistd.h> #include <unistd.h>
//NOBUG_DEFINE_FLAG (resourcecollector); /* TODO: make this a hierachy, derrive from PARENT (library) ? */
llist lumiera_resourcecollector_registry[LUMIERA_RESOURCE_END]; llist lumiera_resourcecollector_registry[LUMIERA_RESOURCE_END];
lumiera_mutex lumiera_resourcecollector_lock; lumiera_mutex lumiera_resourcecollector_lock;

View file

@ -1,5 +1,5 @@
/* /*
resourcecollector.h - manage/collect resources when they get short RESOURCECOLLECTOR.h - manage/collect resources when they get short
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,13 +17,16 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_RESOURCECOLLECTOR_H
#define LUMIERA_RESOURCECOLLECTOR_H
#ifndef BACKEND_RESOURCECOLLECTOR_H
#define BACKEND_RESOURCECOLLECTOR_H
#include <nobug.h> #include <nobug.h>
//NOBUG_DECLARE_FLAG (resourcecollector);
/** /**
* Resources known to the resource collector * Resources known to the resource collector
@ -72,13 +75,13 @@ enum lumiera_resource_try
LUMIERA_RESOURCE_ONE, LUMIERA_RESOURCE_ONE,
/** try to free a small reasonable implementation defined amount of resources **/ /** try to free a small reasonable implementation defined amount of resources **/
LUMIERA_RESOURCE_SOME, LUMIERA_RESOURCE_SOME,
/** try to free a biggier implementation defined amount of resources **/ /** try to free a bigger implementation defined amount of resources **/
LUMIERA_RESOURCE_MANY, LUMIERA_RESOURCE_MANY,
/** free as much as possible **/ /** free as much as possible **/
LUMIERA_RESOURCE_ALL, LUMIERA_RESOURCE_ALL,
/** die! **/ /** die! **/
LUMIERA_RESOURCE_PANIC, LUMIERA_RESOURCE_PANIC,
/** When a handler gets unregistered it wull be called with this value to give it a chance to clean up the user 'data' **/ /** When a handler gets unregistered it will be called with this value to give it a chance to clean up the user 'data' **/
LUMIERA_RESOURCE_UNREGISTER LUMIERA_RESOURCE_UNREGISTER
}; };
@ -86,7 +89,7 @@ enum lumiera_resource_try
/** /**
* The type for the resource collector handler functions. * The type for the resource collector handler functions.
* Handlers are always run with a global resourcecollector mutex locked, the user does not need to * Handlers are always run with a global resourcecollector mutex locked, the user does not need to
* care about syncronization. * care about synchronisation.
* @param itr the current iteration try in freeing resources * @param itr the current iteration try in freeing resources
* @param data user supplied data at registration time for the handler * @param data user supplied data at registration time for the handler
* @param context context pointer for this collection run, might be NULL (at least for UNREGISTER and PANIC) * @param context context pointer for this collection run, might be NULL (at least for UNREGISTER and PANIC)
@ -100,8 +103,8 @@ typedef lumiera_resourcehandler* LumieraResourcehandler;
/** /**
* Initialize the Resourcecollector. * Initialise the Resourcecollector.
* The resourcecollector is singleton and can be used after initialized once. * The Resourcecollector is singleton and can be used after initialised once.
*/ */
void void
lumiera_resourcecollector_init (void); lumiera_resourcecollector_init (void);
@ -119,7 +122,7 @@ lumiera_resourcecollector_destroy (void);
* Try to free resources. * Try to free resources.
* *
* @param which The kind of resource to be acquired * @param which The kind of resource to be acquired
* @param iteration a pointer to a local iterator, initialized with the start * @param iteration a pointer to a local iterator, initialised with the start
* value for the loop * value for the loop
* @param context NULL or some context dependent data for the needed resource * @param context NULL or some context dependent data for the needed resource
* this is a pointer to a size_t for MEMORY and a pointer to a filename * this is a pointer to a size_t for MEMORY and a pointer to a filename
@ -161,7 +164,7 @@ lumiera_resourcehandler_unregister (LumieraResourcehandler self);
/** /**
* Looks up a handler. * Looks up a handler.
* Used to find a registered handler when the return value of register_handler() was unpractical to store. * Used to find a registered handler when the return value of register_handler() was not practical to store.
* @param resource resource for which this handler was registered * @param resource resource for which this handler was registered
* @param handler pointer to the handler function, same as used for registering * @param handler pointer to the handler function, same as used for registering
* @param data opaque user-data pointer, same as used for registering * @param data opaque user-data pointer, same as used for registering
@ -170,7 +173,9 @@ lumiera_resourcehandler_unregister (LumieraResourcehandler self);
LumieraResourcehandler LumieraResourcehandler
lumiera_resourcecollector_handler_find (enum lumiera_resource resource, lumiera_resource_handler_fn handler, void* data); lumiera_resourcecollector_handler_find (enum lumiera_resource resource, lumiera_resource_handler_fn handler, void* data);
#endif
#endif /*BACKEND_RESOURCECOLLECTOR_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
threadpool.c - Manage pools of threads Threadpool - Manage pools of threads
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2009, Michael Ploujnikov <ploujj@gmail.com> 2009, Michael Ploujnikov <ploujj@gmail.com>
@ -17,30 +17,24 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//TODO: Support library includes// * *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
//TODO: Lumiera header includes//
#include "backend/threadpool.h" #include "backend/threadpool.h"
//TODO: internal/static forward declarations//
static lumiera_threadpool threadpool;
//TODO: System includes//
#include <pthread.h> #include <pthread.h>
/**
* @file
*
*/
LUMIERA_ERROR_DEFINE(THREADPOOL_OFFLINE, "tried to acquire thread while threadpool is not available"); LUMIERA_ERROR_DEFINE(THREADPOOL_OFFLINE, "tried to acquire thread while threadpool is not available");
//code goes here//
static lumiera_threadpool threadpool;
void void
lumiera_threadpool_init(void) lumiera_threadpool_init(void)
@ -71,7 +65,7 @@ lumiera_threadpool_destroy(void)
LUMIERA_CONDITION_SECTION (cond_sync, &threadpool.pool[i].sync) LUMIERA_CONDITION_SECTION (cond_sync, &threadpool.pool[i].sync)
threadpool.pool[i].status = LUMIERA_THREADPOOL_OFFLINE; threadpool.pool[i].status = LUMIERA_THREADPOOL_OFFLINE;
/* wait that all theads have finished */ /* wait that all threads have finished */
for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i)
{ {
LUMIERA_CONDITION_SECTION (cond_sync, &threadpool.pool[i].sync) LUMIERA_CONDITION_SECTION (cond_sync, &threadpool.pool[i].sync)
@ -104,7 +98,6 @@ lumiera_threadpool_destroy(void)
} }
/** /**
*
* @return thread handle or NULL on error (lumiera error will be set) * @return thread handle or NULL on error (lumiera error will be set)
*/ */
LumieraThread LumieraThread
@ -130,7 +123,7 @@ lumiera_threadpool_acquire_thread (enum lumiera_thread_class kind,
TRACE (threadpool, "created thread %p", ret); TRACE (threadpool, "created thread %p", ret);
/* /*
a newly created thread flows somewhere in the airm it isnt released yet into the idle list, a newly created thread flows somewhere in the air; it is not yet released into the idle list,
nor in the working list, While we are holding this CONDITION_SECION we can safely put it on the working list, nor in the working list, While we are holding this CONDITION_SECION we can safely put it on the working list,
this removes a small race. this removes a small race.
*/ */

View file

@ -1,5 +1,5 @@
/* /*
threadpool.h - Manage pools of threads THREADPOOL.h - Manage pools of threads
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2009, Michael Ploujnikov <ploujj@gmail.com> 2009, Michael Ploujnikov <ploujj@gmail.com>
@ -17,31 +17,21 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_THREADPOOL_H
#define LUMIERA_THREADPOOL_H
//TODO: Support library includes// #ifndef BACKEND_THREADPOOL_H
#define BACKEND_THREADPOOL_H
#include "lib/condition.h" #include "lib/condition.h"
#include "lib/llist.h" #include "lib/llist.h"
//TODO: Forward declarations//
//TODO: Lumiera header includes//
#include "threads.h" #include "threads.h"
//TODO: System includes//
#include <nobug.h> #include <nobug.h>
/**
* @file
*
*/
//TODO: declarations go here//
/** /**
* Acquire a thread from a threadpool. * Acquire a thread from a threadpool.
@ -81,16 +71,16 @@ struct lumiera_threadpool_struct
} pool[LUMIERA_THREADCLASS_COUNT]; } pool[LUMIERA_THREADCLASS_COUNT];
}; };
/**
* Initialize the thread pool. /** Initialise the thread pool. */
*/
void void
lumiera_threadpool_init(void); lumiera_threadpool_init(void);
void void
lumiera_threadpool_destroy(void); lumiera_threadpool_destroy(void);
#endif
#endif /*BACKEND_THREADPOOL_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
threads.c - Manage threads Threads - Helper for managing threads
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,36 +17,27 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//TODO: Support library includes// * *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
#include "backend/threads.h"
//TODO: Lumiera header includes//
#include "threads.h"
//TODO: internal/static forward declarations//
//TODO: System includes//
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
/**
* @file threads.c LUMIERA_ERROR_DEFINE(THREAD, "fatal threads initialisation error");
*
*/
//code goes here// /** Macro for enum string trick: expands as an array of thread class name strings */
#define LUMIERA_THREAD_CLASS(name) #name, #define LUMIERA_THREAD_CLASS(name) #name,
// enum string trick: expands as an array of thread class name strings
const char* lumiera_threadclass_names[] = { const char* lumiera_threadclass_names[] = {
LUMIERA_THREAD_CLASSES LUMIERA_THREAD_CLASSES
}; };
@ -59,11 +50,11 @@ const char* lumiera_threadstate_names[] = {
}; };
#undef LUMIERA_THREAD_STATE #undef LUMIERA_THREAD_STATE
LUMIERA_ERROR_DEFINE(THREAD, "fatal threads initialization error");
/* thread local storage pointing back to the thread structure of each thread */ /** thread local storage pointing back to the thread structure of each thread */
static pthread_key_t lumiera_thread_tls; static pthread_key_t lumiera_thread_tls;
static pthread_once_t lumiera_thread_initialized = PTHREAD_ONCE_INIT; static pthread_once_t lumiera_thread_initialised = PTHREAD_ONCE_INIT;
static void static void
lumiera_thread_tls_init (void) lumiera_thread_tls_init (void)
@ -124,8 +115,11 @@ thread_loop (void* thread)
return 0; return 0;
} }
// when this is called it should have already been decided that the function
// shall run in parallel, as a thread /**
* @remarks when this is called it should have already been decided
* that the function shall run in parallel, as a thread.
*/
LumieraThread LumieraThread
lumiera_thread_run (int kind, lumiera_thread_run (int kind,
void (*function)(void *), void (*function)(void *),
@ -165,7 +159,7 @@ lumiera_thread_new (enum lumiera_thread_class kind,
struct nobug_flag* flag, struct nobug_flag* flag,
pthread_attr_t* attrs) pthread_attr_t* attrs)
{ {
pthread_once (&lumiera_thread_initialized, lumiera_thread_tls_init); pthread_once (&lumiera_thread_initialised, lumiera_thread_tls_init);
// TODO: do something with this string: // TODO: do something with this string:
(void) purpose; (void) purpose;
@ -189,6 +183,7 @@ lumiera_thread_new (enum lumiera_thread_class kind,
return self; return self;
} }
LumieraThread LumieraThread
lumiera_thread_destroy (LumieraThread self) lumiera_thread_destroy (LumieraThread self)
{ {
@ -218,6 +213,7 @@ lumiera_thread_destroy (LumieraThread self)
return self; return self;
} }
void void
lumiera_thread_delete (LumieraThread self) lumiera_thread_delete (LumieraThread self)
{ {
@ -229,16 +225,12 @@ lumiera_thread_delete (LumieraThread self)
LumieraThread LumieraThread
lumiera_thread_self (void) lumiera_thread_self (void)
{ {
pthread_once (&lumiera_thread_initialized, lumiera_thread_tls_init); pthread_once (&lumiera_thread_initialised, lumiera_thread_tls_init);
return pthread_getspecific (lumiera_thread_tls); return pthread_getspecific (lumiera_thread_tls);
} }
/**
* Set a threads deadline
* A thread must finish before its deadline is hit. Otherwise it counts as stalled
* which is a fatal error which might pull the application down.
*/
LumieraThread LumieraThread
lumiera_thread_deadline_set (struct timespec deadline) lumiera_thread_deadline_set (struct timespec deadline)
{ {
@ -250,10 +242,7 @@ lumiera_thread_deadline_set (struct timespec deadline)
} }
/**
* Extend a threads deadline
* sets the deadline to now+ms in future. This can be used to implement a heartbeat.
*/
LumieraThread LumieraThread
lumiera_thread_deadline_extend (unsigned ms) lumiera_thread_deadline_extend (unsigned ms)
{ {
@ -277,10 +266,7 @@ lumiera_thread_deadline_extend (unsigned ms)
} }
/**
* Clear a threads deadline
* Threads without deadline will not be checked against deadlocks (this is the default)
*/
LumieraThread LumieraThread
lumiera_thread_deadline_clear (void) lumiera_thread_deadline_clear (void)
{ {

View file

@ -1,5 +1,5 @@
/* /*
threads.h - Manage threads THREADS.h - Helper for managing threads
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,36 +17,23 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_THREADS_H
#define LUMIERA_THREADS_H
//TODO: Support library includes// #ifndef BACKEND_THREADS_H
#define BACKEND_THREADS_H
#include "lib/condition.h" #include "lib/condition.h"
//TODO: Forward declarations//
//TODO: Lumiera header includes//
//TODO: System includes//
#include <nobug.h> #include <nobug.h>
/**
* @file threads.h
*
*/
//TODO: declarations go here//
typedef struct lumiera_thread_struct lumiera_thread; typedef struct lumiera_thread_struct lumiera_thread;
typedef lumiera_thread* LumieraThread; typedef lumiera_thread* LumieraThread;
// this is used for an enum string trick /** Helper macro used for an enum string trick */
#define LUMIERA_THREAD_CLASSES \ #define LUMIERA_THREAD_CLASSES \
/** mostly idle, low latency **/ \ /** mostly idle, low latency **/ \
LUMIERA_THREAD_CLASS(INTERACTIVE) \ LUMIERA_THREAD_CLASS(INTERACTIVE) \
@ -59,9 +46,11 @@ typedef lumiera_thread* LumieraThread;
/** Something to do when there is really nothing else to do **/ \ /** Something to do when there is really nothing else to do **/ \
LUMIERA_THREAD_CLASS(IDLE) LUMIERA_THREAD_CLASS(IDLE)
// enum string trick: expands as an enum of thread classes /** Macro for enum string trick: expands as an enum of thread classes */
#define LUMIERA_THREAD_CLASS(name) LUMIERA_THREADCLASS_##name, #define LUMIERA_THREAD_CLASS(name) LUMIERA_THREADCLASS_##name,
/** /**
* Thread classes. * Thread classes.
* We define some 'classes' of threads for different purposes to abstract * We define some 'classes' of threads for different purposes to abstract
@ -79,8 +68,8 @@ enum lumiera_thread_class
* flag to let the decision to run the function in a thread open to the backend. * flag to let the decision to run the function in a thread open to the backend.
* depending on load it might decide to run it sequentially. * depending on load it might decide to run it sequentially.
* This has some constraints: * This has some constraints:
* The Thread must be very careful with locking, better don't. * The Thread must be very careful with locking, better don't.
* TODO explain syncronization issues * @todo explain synchronisation issues
**/ **/
LUMIERA_THREAD_OR_NOT = 1<<8, LUMIERA_THREAD_OR_NOT = 1<<8,
@ -95,6 +84,7 @@ enum lumiera_thread_class
// defined in threads.c // defined in threads.c
extern const char* lumiera_threadclass_names[]; extern const char* lumiera_threadclass_names[];
// there is some confusion between the meaning of this // there is some confusion between the meaning of this
// on one hand it could be used to tell the current state of the thread // on one hand it could be used to tell the current state of the thread
// on the other, it is used to tell the thread which state to enter on next iteration // on the other, it is used to tell the thread which state to enter on next iteration
@ -128,6 +118,8 @@ extern const char* lumiera_threadstate_names[];
#include "threadpool.h" #include "threadpool.h"
/** /**
* The actual thread data * The actual thread data
*/ */
@ -136,6 +128,7 @@ struct lumiera_thread_struct
llist node; // this should be first for easy casting llist node; // this should be first for easy casting
pthread_t id; pthread_t id;
// TODO: maybe this condition variable should be renamed when we have a better understanding of how it will be used // TODO: maybe this condition variable should be renamed when we have a better understanding of how it will be used
lumiera_condition signal; // control signal, state change signal lumiera_condition signal; // control signal, state change signal
@ -154,6 +147,7 @@ struct lumiera_thread_struct
void * arguments; void * arguments;
}; };
/** /**
* Create a thread structure. * Create a thread structure.
*/ */
@ -164,7 +158,7 @@ lumiera_thread_new (enum lumiera_thread_class kind,
pthread_attr_t* attrs); pthread_attr_t* attrs);
/** /**
* Destroy and de-initialize a thread structure. * Destroy and de-initialise a thread structure.
* Memory is not freed by this function. * Memory is not freed by this function.
*/ */
LumieraThread LumieraThread
@ -179,12 +173,12 @@ lumiera_thread_delete (LumieraThread self);
/** /**
* Start a thread. * Start a thread.
* Threads are implemented as procedures which take a void* and dont return anything. * Threads are implemented as procedures which take a void* and don't return anything.
* When a thread wants to pass something back to the application it should use the void* it got for * When a thread wants to pass something back to the application it should use the void* it got for
* constructing the return. * constructing the return.
* * Threads must complete (return from their thread function) * * Threads must complete (return from their thread function)
* * They must not call any exit() function. * * They must not call any exit() function.
* * Threads are not cancelable * * Threads can not be cancelled
* * Threads shall not handle signals (all signals will be disabled for them) unless explicitly acknowledged * * Threads shall not handle signals (all signals will be disabled for them) unless explicitly acknowledged
* *
* @param kind class of the thread to start * @param kind class of the thread to start
@ -209,66 +203,62 @@ lumiera_thread_run (int kind,
LumieraThread LumieraThread
lumiera_thread_self (void); lumiera_thread_self (void);
/** /**
* Heartbeat and Deadlines * Set a thread deadline.
* A thread must finish before its deadline is hit. Otherwise it counts as stalled
* which is a fatal error which might pull the application down.
*
* \par Heartbeat and Deadlines.
* *
* Any thread can have an optional 'deadline' which must never be hit. * Any thread can have an optional 'deadline' which must never be hit.
* This deadlines are lazily checked and if hit this is a fatal error which triggers * This deadlines are lazily checked and if hit this is a fatal error which triggers
* an emergency shutdown. Thus threads are obliged to set and extend their deadlines * an emergency shutdown. Thus threads are obliged to set and extend their deadlines
* accordingly. * accordingly.
*
*/
/**
* Set a threads deadline
* A thread must finish before its deadline is hit. Otherwise it counts as stalled
* which is a fatal error which might pull the application down.
*/ */
LumieraThread LumieraThread
lumiera_thread_deadline_set (struct timespec deadline); lumiera_thread_deadline_set (struct timespec deadline);
/** /**
* Extend a threads deadline * Extend the deadline of a thread
* sets the deadline to now+ms in future. This can be used to implement a heartbeat. * sets the deadline to \c NOW+ms in future. This can be used to implement a heartbeat.
*/ */
LumieraThread LumieraThread
lumiera_thread_deadline_extend (unsigned ms); lumiera_thread_deadline_extend (unsigned ms);
/** /**
* Clear a threads deadline * Clear a thread's deadline
* Threads without deadline will not be checked against deadlocks (this is the default) * Threads without deadline will not be checked against deadlocks (this is the default)
*/ */
LumieraThread LumieraThread
lumiera_thread_deadline_clear (void); lumiera_thread_deadline_clear (void);
/**
* Thread syncronization
* The syncronization primitives act as barrier over 2 threads, any thread reaching a syncronization
* point first is blocked until the other one reaches it too.
*/
/** /**
* Syncronize with another threads state * Synchronise with another threads state.
* * This blocks until/unless the other thread reaches a synchronisation point.
* this blocks until/unless the other thread reaches a syncronization point *
* \par Thread synchronisation
* The synchronisation primitives act as barrier over 2 threads, any thread reaching
* a synchronisation point first is blocked until the other one reaches it too.
*/ */
LumieraThread LumieraThread
lumiera_thread_sync_other (LumieraThread other); lumiera_thread_sync_other (LumieraThread other);
/** /**
* Syncronize current thread * Synchronise current thread
* *
* this blocks until/unless the other thread reaches a syncronization point * this blocks until/unless the other thread reaches a synchronisation point
* @return on success pointer to self (opaque), or NULL on error * @return on success pointer to self (opaque), or NULL on error
*/ */
LumieraThread LumieraThread
lumiera_thread_sync (void); lumiera_thread_sync (void);
// TODO implement timedsync, this is bit tricky because after a timeout, syncronization points are desynced // TODO implement timedsync, this is bit tricky because after a timeout, synchronisation points are desynched
// we possibly need some way to reset/resync this // we possibly need some way to reset/resync this
//LumieraThread //LumieraThread
//lumiera_thread_timedsync (struct timespec timeout); //lumiera_thread_timedsync (struct timespec timeout);
@ -284,7 +274,7 @@ lumiera_thread_sync (void);
lumiera_err lumiera_err
lumiera_thread_join (LumieraThread thread); lumiera_thread_join (LumieraThread thread);
#endif #endif /*BACKEND_THREADS_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -27,7 +27,7 @@
#include "common/subsystem-runner.hpp" #include "common/subsystem-runner.hpp"
extern "C" { extern "C" {
#include "common/config_interface.h" #include "common/config-interface.h"
#include "common/interface.h" #include "common/interface.h"
#include "common/interfaceregistry.h" #include "common/interfaceregistry.h"

View file

@ -23,8 +23,8 @@
/** @file appstate.hpp /** @file appstate.hpp
** Registering and managing primary application-global services. ** Registering and managing primary application-global services.
** This can be considered the "main" object of the Lumiera application ** This can be considered the "main" object of the Lumiera application
** Besides encapsulating the logic for starting up the fundamental parts ** Besides encapsulating the logic to start up the fundamental parts of
** of the application, there is a mechanism for registering \em subsystems ** the application, there is a mechanism for registering \em subsystems
** to be brought up and shut down in order. AppState will issue the global ** to be brought up and shut down in order. AppState will issue the global
** application lifecycle events (where other parts may have registered ** application lifecycle events (where other parts may have registered
** callbacks) and provides the top-level catch-all error handling. ** callbacks) and provides the top-level catch-all error handling.

View file

@ -77,7 +77,7 @@ namespace lumiera {
"name of the Lumiera GUI plugin to load") "name of the Lumiera GUI plugin to load")
("Lumiera.modulepath", opt::value<string>(), ("Lumiera.modulepath", opt::value<string>(),
"search path for loadable modules. " "search path for loadable modules. "
"May us $ORIGIN to refer to the EXE location") "May use $ORIGIN to refer to the EXE location")
("Lumiera.configpath", opt::value<string>(), ("Lumiera.configpath", opt::value<string>(),
"search path for extended configuration. " "search path for extended configuration. "
"Extended Config system not yet implemented " "Extended Config system not yet implemented "

View file

@ -1,5 +1,5 @@
/* /*
config_interface.c - Lumiera configuration interface implementation Config-interface - Lumiera configuration interface implementation
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,19 +17,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//TODO: Support library includes// * *****************************************************/
//TODO: Lumiera header includes// #include "common/config-interface.h"
#include "common/config_interface.h"
#include "common/config.h" #include "common/config.h"
//TODO: internal/static forward declarations//
//TODO: System includes//
LUMIERA_EXPORT( LUMIERA_EXPORT(
@ -155,10 +149,3 @@ lumiera_config_interface_destroy (void)
#endif #endif
/*
// Local Variables:
// mode: C
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
*/

View file

@ -1,5 +1,5 @@
/* /*
config_interface.h - Lumiera configuration interface CONFIG-INTERFACE.h - Lumiera configuration interface
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,21 +17,27 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/** @file config-interface.h
** External interface to the lumiera configuration system.
** This file provides an interface descriptor for external entities
** (e.g. plug-ins) to gain access to the configuration system (as
** planned in 2008).
**
** @note this is unfinished work, development in this area stalled in 2008
** @see config.h
*/
#ifndef LUMIERA_CONFIG_INTERFACE_H #ifndef LUMIERA_CONFIG_INTERFACE_H
#define LUMIERA_CONFIG_INTERFACE_H #define LUMIERA_CONFIG_INTERFACE_H
//TODO: Support library includes//
#include "common/interface.h" #include "common/interface.h"
//TODO: Forward declarations//
/**
* @file
* Declares the interface for the lumiera configuration system
*/
void void
lumiera_config_interface_init (void); lumiera_config_interface_init (void);

View file

@ -1,5 +1,5 @@
/* /*
config_lookup.c - Lookup functions for the config subsystem Config-lookup - Lookup functions for the config subsystem
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,14 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
/** @file config-lookup.c
** Implementation of the lookup of configuration keys
*/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
@ -29,9 +36,10 @@
/* we only use one fatal error for now, when allocation in the config system fail, something else is pretty wrong */ /* 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"); LUMIERA_ERROR_DEFINE (CONFIG_LOOKUP, "config lookup failure");
/*
support functions for the splay tree
*/ /* === support functions for the splay tree === */
static int static int
cmp_fn (const void* a, const void* b); cmp_fn (const void* a, const void* b);
@ -42,10 +50,6 @@ static const void*
key_fn (const PSplaynode node); key_fn (const PSplaynode node);
/**
* @file
* Implementation of the lookup of configuration keys
*/
LumieraConfigLookup LumieraConfigLookup
@ -173,9 +177,7 @@ lumiera_config_lookup_item_tail_find (LumieraConfigLookup self, const char* key)
/* /* === Lookup of entries === */
Lookup entries
*/
LumieraConfigLookupentry LumieraConfigLookupentry
lumiera_config_lookupentry_init (LumieraConfigLookupentry self, const char* key) lumiera_config_lookupentry_init (LumieraConfigLookupentry self, const char* key)

View file

@ -17,10 +17,12 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_CONFIG_LOOKUP_H
#define LUMIERA_CONFIG_LOOKUP_H #ifndef COMMON_CONFIG_LOOKUP_H
#define COMMON_CONFIG_LOOKUP_H
#include "lib/psplay.h" #include "lib/psplay.h"
#include "lib/llist.h" #include "lib/llist.h"
@ -44,7 +46,7 @@ typedef lumiera_config_lookupentry* LumieraConfigLookupentry;
* Lookup of configuration keys. Configuration keys are dynamically stored in a splay tree. * Lookup of configuration keys. Configuration keys are dynamically stored in a splay tree.
* This happens for defaults, loaded config files and entries which are set explicitly. * This happens for defaults, loaded config files and entries which are set explicitly.
* The system maintains no central registry of all possible keys. * The system maintains no central registry of all possible keys.
* We store here the full keys of configentries as well as the keys of section prefixes. * We store here the full keys of config entries as well as the keys of section prefixes.
* Section prefixes are stored with a trailing dot to disambiguate them from entry keys. * Section prefixes are stored with a trailing dot to disambiguate them from entry keys.
*/ */
@ -52,7 +54,7 @@ typedef lumiera_config_lookupentry* LumieraConfigLookupentry;
LUMIERA_ERROR_DECLARE (CONFIG_LOOKUP); LUMIERA_ERROR_DECLARE (CONFIG_LOOKUP);
/** /**
* Just contains a hashtable to give sufficent abstraction. * Just contains a hashtable to give sufficient abstraction.
*/ */
struct lumiera_config_lookup_struct struct lumiera_config_lookup_struct
{ {
@ -60,16 +62,16 @@ struct lumiera_config_lookup_struct
}; };
/** /**
* Initialize a lookup structure. * Initialise a lookup structure.
* @param self lookup structure to be initialized * @param self lookup structure to be initialised
* @return self on success else NULL * @return self on success else NULL
*/ */
LumieraConfigLookup LumieraConfigLookup
lumiera_config_lookup_init (LumieraConfigLookup self); lumiera_config_lookup_init (LumieraConfigLookup self);
/** /**
* Destruct a lookup structure. * Destroy a lookup structure.
* @param self lookup structure to be destructed * @param self lookup structure to be destroyed
* @return self * @return self
*/ */
LumieraConfigLookup LumieraConfigLookup
@ -87,9 +89,7 @@ lumiera_config_lookup_insert (LumieraConfigLookup self, LumieraConfigitem item);
/** /**
* Add a default config item to a lookup structure. * @internal Add a default config item to a lookup structure.
* @internal
* This function is used internal.
* The item must contain a full key and not part of any 'section' * The item must contain a full key and not part of any 'section'
* and is inserted as tail of the lookup list. * and is inserted as tail of the lookup list.
* @param self lookup structure where the item shall be added * @param self lookup structure where the item shall be added
@ -132,37 +132,33 @@ LumieraConfigitem
lumiera_config_lookup_item_find (LumieraConfigLookup self, const char* key); lumiera_config_lookup_item_find (LumieraConfigLookup self, const char* key);
/** /**
* Find a the bottommost config item stored to a given key. * Find a the bottom most config item stored to a given key.
* defaults sits at the bottom if exists * defaults sits at the bottom if exists
* @param self lookup structure where the key shall be searched * @param self lookup structure where the key shall be searched
* @param key string to be looked up * @param key string to be looked up
* @return TODO
*/ */
LumieraConfigitem LumieraConfigitem
lumiera_config_lookup_item_tail_find (LumieraConfigLookup self, const char* key); lumiera_config_lookup_item_tail_find (LumieraConfigLookup self, const char* key);
/* /* Lookup hash entries for the cuckoo hash */
Lookup hash entries for the cuckoo hash
*/
/**
* Structure defining single hash table entries. /** @internal Structure defining single hash table entries.*/
* @internal
*/
struct lumiera_config_lookupentry_struct struct lumiera_config_lookupentry_struct
{ {
psplaynode node; psplaynode node;
/* stack of all configitems stored under this key */
/** stack of all configitems stored under this key */
llist configitems; llist configitems;
/* /**
we store a copy of the full key here * we store a copy of the full key here
configentry keys are complete as expected * configentry keys are complete as expected
section keys are the prefix stored with a trailing dot, * section keys are the prefix stored with a trailing dot,
suffixes will be found by iterative search * suffixes will be found by iterative search
*/ */
char* full_key; char* full_key;
}; };
@ -182,7 +178,8 @@ lumiera_config_lookupentry_destroy (LumieraConfigLookupentry self);
void void
lumiera_config_lookupentry_delete (LumieraConfigLookupentry self); lumiera_config_lookupentry_delete (LumieraConfigLookupentry self);
#endif
#endif /*COMMON_CONFIG_LOOKUP_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
config_typed.c - Lumiera configuration highlevel interface Config-typed - Lumiera configuration high-level interface
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,27 +17,27 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//TODO: Support library includes// * *****************************************************/
/** @file config-type.d
** Implementation: high level typed configuration interfaces.
** @note unfinished draft from 2008
*/
#include "include/logging.h" #include "include/logging.h"
#include "lib/tmpbuf.h" #include "lib/tmpbuf.h"
//TODO: Lumiera header includes//
#include "common/config.h" #include "common/config.h"
//TODO: internal/static forward declarations// #include <stdint.h>
extern LumieraConfig lumiera_global_config; extern LumieraConfig lumiera_global_config;
//TODO: System includes//
#include <stdint.h>
/**
* @file
* Here are the high level typed configuration interfaces defined.
*/
const char* const char*
lumiera_config_link_get (const char* key, const char** value) lumiera_config_link_get (const char* key, const char** value)
@ -176,7 +176,7 @@ scan_string (const char* in)
*wpos = '\0'; *wpos = '\0';
} }
else else
/* quotes doesnt match */ /* quotes doesn't match */
LUMIERA_ERROR_SET (config, CONFIG_SYNTAX_VALUE, "unmatched quotes"); LUMIERA_ERROR_SET (config, CONFIG_SYNTAX_VALUE, "unmatched quotes");
} }
else else
@ -281,13 +281,10 @@ lumiera_config_wordlist_set (const char* key, const char** value)
} }
/**
* Word
* A single word, no quotes, chopped
*/
/** /**
* helper function, takes a raw input string and give a tmpbuf with the word parsed back. * helper function, takes a raw input string and give a tmpbuf with the word parsed back.
* @remarks 'Word' is a single word, no quotes, chopped
*/ */
static char* static char*
scan_word (const char* in) scan_word (const char* in)

View file

@ -1,5 +1,5 @@
/* /*
config_wordlist.c - Lumiera wordlist access functions Config-wordlist - Lumiera wordlist access functions
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/error.h" #include "lib/error.h"

View file

@ -1,5 +1,5 @@
/* /*
config.c - Lumiera configuration system Config - Lumiera configuration system
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,30 +17,19 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//TODO: Support library includes// * *****************************************************/
#include "include/logging.h" #include "include/logging.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
#include "lib/tmpbuf.h" #include "lib/tmpbuf.h"
#include "common/config.h" #include "common/config.h"
//TODO: Lumiera header includes//
//TODO: internal/static forward declarations//
//TODO: System includes//
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
/**
* @file
*
*/
LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX, "syntax error in configfile"); LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX, "syntax error in configfile");
LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX_KEY, "syntax error in key"); LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX_KEY, "syntax error in key");
@ -90,7 +79,7 @@ int
lumiera_config_init (const char* path) lumiera_config_init (const char* path)
{ {
TRACE (config_dbg); TRACE (config_dbg);
REQUIRE (!lumiera_global_config, "Configuration subsystem already initialized"); REQUIRE (!lumiera_global_config, "Configuration subsystem already initialised");
REQUIRE (path); REQUIRE (path);
@ -240,7 +229,7 @@ lumiera_config_set (const char* key, const char* delim_value)
LumieraConfigitem item = lumiera_config_lookup_item_find (&lumiera_global_config->keys, key); LumieraConfigitem item = lumiera_config_lookup_item_find (&lumiera_global_config->keys, key);
if (item && item->parent != &lumiera_global_config->defaults) if (item && item->parent != &lumiera_global_config->defaults)
{ {
TODO ("is a user writeable file?"); TODO ("is a user writable file?");
TODO (" replace delim_value"); TODO (" replace delim_value");
lumiera_configitem_set_value (item, delim_value); lumiera_configitem_set_value (item, delim_value);
} }
@ -262,7 +251,7 @@ lumiera_config_set (const char* key, const char* delim_value)
ENSURE (*item->delim == '=' || *item->delim == '<', "syntax error,"); ENSURE (*item->delim == '=' || *item->delim == '<', "syntax error,");
TODO ("insert in proper parent (file)"); TODO ("insert in proper parent (file)");
llist_insert_tail (&lumiera_global_config->TODO_unknown.childs, &item->link); llist_insert_tail (&lumiera_global_config->TODO_unknown.children, &item->link);
item->parent = &lumiera_global_config->TODO_unknown; item->parent = &lumiera_global_config->TODO_unknown;
lumiera_config_lookup_insert (&lumiera_global_config->keys, item); lumiera_config_lookup_insert (&lumiera_global_config->keys, item);
@ -300,7 +289,7 @@ lumiera_config_setdefault (const char* line)
ENSURE (*item->delim == '=' || *item->delim == '<', "default must be a configentry with key=value or key<delegate syntax"); ENSURE (*item->delim == '=' || *item->delim == '<', "default must be a configentry with key=value or key<delegate syntax");
TRACE (config_dbg, "registering default: '%s'", item->line); TRACE (config_dbg, "registering default: '%s'", item->line);
llist_insert_head (&lumiera_global_config->defaults.childs, &item->link); llist_insert_head (&lumiera_global_config->defaults.children, &item->link);
item->parent = &lumiera_global_config->defaults; item->parent = &lumiera_global_config->defaults;
lumiera_config_lookup_insert (&lumiera_global_config->keys, item); lumiera_config_lookup_insert (&lumiera_global_config->keys, item);
@ -317,7 +306,7 @@ lumiera_config_dump (FILE* out)
{ {
fprintf (out, "# registered defaults:\n"); fprintf (out, "# registered defaults:\n");
LLIST_FOREACH (&lumiera_global_config->defaults.childs, node) LLIST_FOREACH (&lumiera_global_config->defaults.children, node)
fprintf (out, "%s\n", ((LumieraConfigitem) node)->line); fprintf (out, "%s\n", ((LumieraConfigitem) node)->line);
fprintf (out, "# end of defaults\n\n"); fprintf (out, "# end of defaults\n\n");

View file

@ -1,5 +1,5 @@
/* /*
config.h - Lumiera configuration system CONFIG.h - Lumiera configuration system
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,31 +17,36 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_CONFIG_H
#define LUMIERA_CONFIG_H
//TODO: Support library includes// /** @file config.h
** Interface for a lumiera configuration system (draft).
** This configuration uses ini-style configuration files and supports some
** simple types. A mechanism for overlay / cascading was planned. After some
** debate it turned out that we had no clear vision regarding the scope of
** that effort: should this system also manage (layered) defaults? should
** it also be able to save user preferences? Anyway, development in that
** area stalled and never reached the level of just loading and parsing
** a simple file -- yet this was not considered a roadblock and we agreed
** to revisit the topic when we've gained a better understanding of
** session storage and management of default values and user preferences.
**
** @see lumiera::BasicSetup simple start-up configuration
** @see http://lumiera.org/documentation/technical/backend/ConfigLoader.html ConfigLoader draft from 2008
*/
#ifndef COMMON_CONFIG_H
#define COMMON_CONFIG_H
#include "lib/error.h" #include "lib/error.h"
#include "lib/mutex.h" #include "lib/mutex.h"
#include "common/config-lookup.h"
#include "common/configitem.h"
//TODO: Forward declarations// #include <nobug.h>
struct lumiera_config_struct; #include <stdio.h>
/* master config subsystem debug flag */
//NOBUG_DECLARE_FLAG (config_all);
/* config subsystem internals */
//NOBUG_DECLARE_FLAG (configsys);
/* high level typed interface operations */
//NOBUG_DECLARE_FLAG (config_typed);
/* file operations */
//NOBUG_DECLARE_FLAG (config_file);
/* single config items */
//NOBUG_DECLARE_FLAG (config_item);
/* lookup config keys */
//NOBUG_DECLARE_FLAG (config_lookup);
LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX);
@ -49,23 +54,11 @@ LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX_KEY);
LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX_VALUE); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX_VALUE);
LUMIERA_ERROR_DECLARE (CONFIG_NO_ENTRY); LUMIERA_ERROR_DECLARE (CONFIG_NO_ENTRY);
//TODO: Lumiera header includes//
#include "common/config-lookup.h"
#include "common/configitem.h"
//TODO: System includes//
#include <nobug.h>
#include <stdio.h>
/**
* @file
* TODO documentation, http://www.pipapo.org/pipawiki/Lumiera/ConfigLoader
*/
#define LUMIERA_CONFIG_KEY_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_." #define LUMIERA_CONFIG_KEY_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_."
#define LUMIERA_CONFIG_ENV_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789__" #define LUMIERA_CONFIG_ENV_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789__"
struct lumiera_config_struct struct lumiera_config_struct
{ {
lumiera_config_lookup keys; lumiera_config_lookup keys;
@ -198,12 +191,12 @@ lumiera_config_setdefault (const char* line);
// * {{{int lumiera_config_TYPE_get(const char* key, TYPE* value, const char* default) }}} // * {{{int lumiera_config_TYPE_get(const char* key, TYPE* value, const char* default) }}}
// High level config interface for different types. // High level config interface for different types.
// if default is given (!NULL) then value is set to default in case key was not found or any other error occured. // if default is given (!NULL) then value is set to default in case key was not found or any other error occurred.
// error code is still set and -1 (fail) is returned in case of an error, but it might be cleared with no ill effects. // error code is still set and -1 (fail) is returned in case of an error, but it might be cleared with no ill effects.
// NOTE: errors are persistent in our error handler, they must still be cleared, even when ignored. // NOTE: errors are persistent in our error handler, they must still be cleared, even when ignored.
// if default is given then 'KEY_NOT_FOUND' is not a error here, if default is NULL then it is // if default is given then 'KEY_NOT_FOUND' is not a error here, if default is NULL then it is
// NOTE2: default values are given as strings, the config loader remembers a given default value and checks if it got changed // NOTE2: default values are given as strings, the config loader remembers a given default value and checks if it got changed
// when it is _set(). Thus a default value can be supressed when set/written // when it is _set(). Thus a default value can be suppressed when set/written
/** /**
* *
*/ */
@ -260,7 +253,7 @@ lumiera_config_wordlist_replace (const char* key, const char* value, const char*
/** /**
* Add a word to the end of a wordlist if it doesnt exist already * Add a word to the end of a wordlist if it doesn't exist already
* @param key key under which this wordlist is stored * @param key key under which this wordlist is stored
* @param value new word to add * @param value new word to add
* @param delims a string literal listing all characters which are treated as delimiters * @param delims a string literal listing all characters which are treated as delimiters
@ -298,7 +291,7 @@ lumiera_config_reset (const char* key);
int int
lumiera_config_info (const char* key, const char** filename, unsigned* line); lumiera_config_info (const char* key, const char** filename, unsigned* line);
#endif #endif /*COMMON_CONFIG_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
configentry.c - single entries from configfiles Configentry - single entries from configfiles
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,26 +17,15 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//TODO: Support library includes// * *****************************************************/
#include "lib/safeclib.h" #include "lib/safeclib.h"
//TODO: Lumiera header includes//
#include "common/configentry.h" #include "common/configentry.h"
//TODO: internal/static forward declarations//
//TODO: System includes//
/**
* @file
*
*/
//code goes here//
LumieraConfigitem LumieraConfigitem
lumiera_configentry_new (LumieraConfigitem tmp) lumiera_configentry_new (LumieraConfigitem tmp)
{ {
@ -65,10 +54,3 @@ struct lumiera_configitem_vtable lumiera_configentry_funcs =
/*
// Local Variables:
// mode: C
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
*/

View file

@ -1,5 +1,5 @@
/* /*
configentry.h - single entries from configfiles CONFIGENTRY.h - single entries from configfiles
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,31 +17,23 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_CONFIGENTRY_H
#define LUMIERA_CONFIGENTRY_H
//TODO: Support library includes// #ifndef COMMON_CONFIGENTRY_H
#define COMMON_CONFIGENTRY_H
#include "common/configitem.h"
#include <nobug.h>
//TODO: Forward declarations//
typedef struct lumiera_configentry_struct lumiera_configentry; typedef struct lumiera_configentry_struct lumiera_configentry;
typedef lumiera_configentry* LumieraConfigentry; typedef lumiera_configentry* LumieraConfigentry;
//TODO: Lumiera header includes//
#include "common/configitem.h"
//TODO: System includes//
#include <nobug.h>
/**
* @file
*/
//TODO: declarations go here//
struct lumiera_configentry_struct struct lumiera_configentry_struct
{ {
lumiera_configitem entry; lumiera_configitem entry;
@ -57,7 +49,7 @@ lumiera_configentry_new (LumieraConfigitem tmp);
LumieraConfigitem LumieraConfigitem
lumiera_configentry_destroy (LumieraConfigitem self); lumiera_configentry_destroy (LumieraConfigitem self);
#endif #endif /*COMMON_CONFIGENTRY_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
configitem.c - generalized hierachy of configuration items Configitem - generalised hierarchy of configuration items
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -22,8 +22,7 @@
/** @file configitem.c /** @file configitem.c
** create a configitem out of a single line. ** Implementation: create a configitem from a single line of the config file.
**
*/ */
@ -32,12 +31,13 @@
#include "lib/safeclib.h" #include "lib/safeclib.h"
#include "lib/tmpbuf.h" #include "lib/tmpbuf.h"
//TODO: Lumiera header includes//
#include "common/config.h" #include "common/config.h"
#include "common/configitem.h" #include "common/configitem.h"
#include "common/configentry.h" #include "common/configentry.h"
#include <ctype.h>
#include <stdint.h>
static LumieraConfigitem parse_directive (LumieraConfigitem self, char* itr); static LumieraConfigitem parse_directive (LumieraConfigitem self, char* itr);
@ -46,8 +46,6 @@ static LumieraConfigitem parse_section (LumieraConfigitem self, char* itr);
static LumieraConfigitem parse_configentry (LumieraConfigitem self, char* itr); static LumieraConfigitem parse_configentry (LumieraConfigitem self, char* itr);
#include <ctype.h>
#include <stdint.h>
@ -59,7 +57,7 @@ lumiera_configitem_init (LumieraConfigitem self)
llist_init (&self->link); llist_init (&self->link);
self->parent = NULL; self->parent = NULL;
llist_init (&self->childs); llist_init (&self->children);
llist_init (&self->lookup); llist_init (&self->lookup);
@ -81,10 +79,10 @@ lumiera_configitem_destroy (LumieraConfigitem self, LumieraConfigLookup lookup)
if (self) if (self)
{ {
LLIST_WHILE_HEAD (&self->childs, node) LLIST_WHILE_HEAD (&self->children, node)
lumiera_configitem_delete ((LumieraConfigitem) node, lookup); lumiera_configitem_delete ((LumieraConfigitem) node, lookup);
ENSURE (llist_is_empty (&self->childs), "destructor didn't remove childs"); ENSURE (llist_is_empty (&self->children), "destructor didn't remove children");
if (self->vtable && self->vtable->destroy) if (self->vtable && self->vtable->destroy)
self->vtable->destroy (self); self->vtable->destroy (self);
@ -151,8 +149,8 @@ lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem source)
self->parent = source->parent; self->parent = source->parent;
llist_init (&self->childs); llist_init (&self->children);
llist_insertlist_next (&self->childs, &source->childs); llist_insertlist_next (&self->children, &source->children);
llist_init (&self->lookup); llist_init (&self->lookup);
llist_insertlist_next (&self->lookup, &source->lookup); llist_insertlist_next (&self->lookup, &source->lookup);

View file

@ -1,5 +1,5 @@
/* /*
configitem.h - generalized hierarchy of configuration items CONFIGITEM.h - generalised hierarchy of configuration items
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,76 +17,53 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_CONFIGITEM_H
#define LUMIERA_CONFIGITEM_H
//TODO: Support library includes// /** @file configitem.h
** Hierarchy of configuration items.
** configitems form a 3 level hierarchy:
**
** \verbatim
** 1. file:
** contain sections
**
** 2. section:
** [prefix suffix]
** contain lines
**
** 3. lines are
** comment:
** empty line or line only containing spaces and tabs
** line starting with spaces and tabs followed by a #
** directive:
** '@include name' or '@readonly'
** directives are only valid at the toplevel section []
** configurationentry:
** 'key = value' or 'key < redirect'
** erroneous:
** any line which can't be parsed
** \endverbatim
*/
#ifndef COMMON_CONFIGITEM_H
#define COMMON_CONFIGITEM_H
#include "lib/llist.h" #include "lib/llist.h"
/* Forward declarations */
//TODO: Forward declarations//
typedef struct lumiera_configitem_struct lumiera_configitem; typedef struct lumiera_configitem_struct lumiera_configitem;
typedef lumiera_configitem* LumieraConfigitem; typedef lumiera_configitem* LumieraConfigitem;
struct lumiera_configitem_vtable; struct lumiera_configitem_vtable;
//TODO: Lumiera header includes//
#include "common/config-lookup.h" #include "common/config-lookup.h"
//TODO: System includes//
#include <nobug.h> #include <nobug.h>
/**
* @file
* configitems build a 3 level hierarchy:
*
* 1. file:
* contain sections
*
* 2. section:
* [prefix suffix]
* contain lines
*
* 3. lines are
* comment:
* empty line or line only containing spaces and tabs
* line starting with spaces and tabs followed by a #
* directive:
* '@include name' or '@readonly'
* directives are only valid at the toplevel section []
* configurationentry:
* 'key = value' or 'key < redirect'
*/
//TODO: declarations go here//
/**
* @file
* configitems build a 3 level hierarchy:
*
* 1. file:
* contain sections
*
* 2. section:
* [prefix suffix]
* contain lines
*
* 3. lines are
* comment:
* empty line or line only containing spaces and tabs
* line starting with spaces and tabs followed by a #
* directive:
* '@include name' or '@readonly'
* directives are only valid at the toplevel section []
* configurationentry:
* 'key = value' or 'key < redirect'
* erroneous:
* any line which cant be parsed
*/
struct lumiera_configitem_vtable struct lumiera_configitem_vtable
{ {
@ -96,9 +73,9 @@ struct lumiera_configitem_vtable
struct lumiera_configitem_struct struct lumiera_configitem_struct
{ {
llist link; // all lines on the same hierarchy level are linked here (see childs) llist link; // all lines on the same hierarchy level are linked here (see children)
LumieraConfigitem parent; // parent section LumieraConfigitem parent; // parent section
llist childs; // root node for all lines below this hierarchy llist children; // root node for all lines below this hierarchy
llist lookup; // all lines with the same key are stacked up on the lookup llist lookup; // all lines with the same key are stacked up on the lookup
@ -109,6 +86,7 @@ struct lumiera_configitem_struct
struct lumiera_configitem_vtable* vtable; // functiontable for subclassing struct lumiera_configitem_vtable* vtable; // functiontable for subclassing
}; };
LumieraConfigitem LumieraConfigitem
lumiera_configitem_init (LumieraConfigitem self); lumiera_configitem_init (LumieraConfigitem self);
@ -130,7 +108,8 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line);
LumieraConfigitem LumieraConfigitem
lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem dest); lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem dest);
#endif
#endif /*COMMON_CONFIGITEM_H*/
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
interfacedescriptor.h - Metadata interface for Lumiera interfaces INTERFACE-DESCRIPTOR.h - Metadata interface for Lumiera interfaces
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,16 +17,19 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_INTERFACEDESCRIPTOR_H
#define LUMIERA_INTERFACEDESCRIPTOR_H
#ifndef COMMON_INTERFACEDESCRIPTOR_H
#define COMMON_INTERFACEDESCRIPTOR_H
#include "common/interface.h" #include "common/interface.h"
/** /**
* Release state of an interface implementation. * Release state of an interface implementation.
* The interface subsystem must be able to categorize implementations to present possible * The interface subsystem must be able to categorise implementations to present possible
* upgrade paths to the user. This is done by the tagging it to a certain state in concert * upgrade paths to the user. This is done by the tagging it to a certain state in concert
* with the version and the user supplied version compare function. The respective numbers * with the version and the user supplied version compare function. The respective numbers
* are chosen in a way that a higher value indicates precedence when selecting an implementation. * are chosen in a way that a higher value indicates precedence when selecting an implementation.
@ -73,7 +76,7 @@ LUMIERA_INTERFACE_DECLARE (lumieraorg_interfacedescriptor, 0,
#if 0 #if 0
/** /**
* For convenience, a copy'n'paste descriptor * For convenience: a copy'n'paste descriptor
*/ */
LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0, LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0,
/*IDENTIFIER*/, /*IDENTIFIER*/,
@ -131,7 +134,7 @@ LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0,
#endif #endif
#endif /* LUMIERA_INTERFACEDESCRIPTORS_H */ #endif /* COMMON_INTERFACEDESCRIPTOR_H */
/* /*
// Local Variables: // Local Variables:
// mode: C // mode: C

View file

@ -1,5 +1,5 @@
/* /*
interface.c - Lumiera interface api Interface - Lumiera interface handling
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,18 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
/** @file interface.c
** Implementation: handling of interfaces (extension points).
** From a programmers perspective interfaces only need to be opened when needed and closed
** when finished with them. There is no difference if the interface is internally provided
** by the core or provided by an external plugin.
** Interfaces can be opened multiple times and cross reference each other.
*/
#include "include/logging.h" #include "include/logging.h"
@ -31,15 +42,9 @@
#include <nobug.h> #include <nobug.h>
/**
* @file
* From a programmers perspective interfaces only need to be opened when needed and closed
* when finished with them. There is no difference if the interface is internally provided
* by the core or provided by an external plugin.
* Interfaces can be opened multiple times and cross reference each other.
*/
/* the mother of all interfaces */
/** the mother of all interfaces */
LumieraInterface lumiera_interface_interface; LumieraInterface lumiera_interface_interface;
static LumieraInterfacenode static LumieraInterfacenode
@ -85,10 +90,10 @@ lumiera_interface_open (const char* interface, unsigned version, size_t minminor
static void static void
push_dependency (LumieraInterfacenode parent, LumieraInterfacenode child) push_dependency (LumieraInterfacenode parent, LumieraInterfacenode child)
{ {
/* push a dependency on the dependency array, allcoate or resize it on demand */ /* push a dependency on the dependency array, allocate or resize it on demand */
TRACE (interface_dbg, "%s %s", parent->interface->name, child->interface->name); TRACE (interface_dbg, "%s %s", parent->interface->name, child->interface->name);
/* no dependencies recorded yet, alloc a first block for 4 pointers */ /* no dependencies recorded yet, allocate a first block for 4 pointers */
if (!parent->deps_size) if (!parent->deps_size)
parent->deps = lumiera_calloc (parent->deps_size = 4, sizeof (LumieraInterfacenode)); parent->deps = lumiera_calloc (parent->deps_size = 4, sizeof (LumieraInterfacenode));
@ -161,7 +166,7 @@ lumiera_interface_open_interfacenode (LumieraInterfacenode self)
static LumieraInterfacenode stack = NULL; static LumieraInterfacenode stack = NULL;
/* /*
Ok, this got little more complicated than it should be, OK, this got little more complicated than it should be,
but finally it handles any kind of cross dependencies between interfaces gracefully but finally it handles any kind of cross dependencies between interfaces gracefully
*/ */
@ -306,7 +311,7 @@ lumiera_interfacenode_close (LumieraInterfacenode self)
} }
/** /**
* Definitinon of 'the mother of all interfaces' * Definition of 'the mother of all interfaces'
* since this interface is singleton and required for any component to open any other * since this interface is singleton and required for any component to open any other
* interface this should get a very stable interface and likely never change. * interface this should get a very stable interface and likely never change.
*/ */

View file

@ -1,5 +1,5 @@
/* /*
interface.h - Lumiera interface macros and structures INTERFACE.h - Lumiera interface macros and structures
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,89 +17,81 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/** @file interface.h
** @brief Lumiera interface macros and structures.
**
** Lumiera uses a system of versioned interfaces as external extension points
** and for defining plug-ins. The interfaces defined here are C compatible and,
** thus, can be used by any language able to bind to C. The interfaces are
** versioned to provide forward and backward compatibility for both source and
** binary deployment of modules.
**
** \par Overview
**
** To make an interface available to code so that the code can use the
** interface, the interface needs to be declared and then defined. We provide a
** number of macros here which ease this process.
**
** The interface is declared by placing the following macro in a
** header file:
** \code
** LUMIERA_INTERFACE_DECLARE(name, version,
** LUMIERA_INTERFACE_SLOT(ret, name, params),
** ...
** )
**
** \endcode
** Any code that wants to use this interface must then include the header file.
**
** The interface is defined by mapping interface functions to slots, or
** providing inline definitions for slot functions. Defining the interface has
** the following form:
** \code
** LUMIERA_INTERFACE_INSTANCE(iname, version, name, descriptor, acquire, release,
** LUMIERA_INTERFACE_MAP (slot, function),
** LUMIERA_INTERFACE_INLINE (slot, ret, params, {body}),
** ...
** )
** \endcode
**
** A collection of interfaces can be defined in 2 different ways depending on
** where whether the interface is exported by the core, or by a plugin:
** \code
** LUMIERA_EXPORT(queryfunc,
** LUMIERA_INTERFACE_DEFINE(...),
** ...
** ) // Exporting from the core
**
** LUMIERA_PLUGIN(descriptor, acquire, release,
** LUMIERA_INTERFACE_DEFINE(...),
** ...
** ) // Exporting from an interface
** \endcode
**
** \par Naming and Versioning
**
** Interfaces have unique names and a major and minor version. The name and the major version
** is used to construct a C identifier for the interface, the minor version is implicitly defined
** by the number of functions in the interface. Interface instances are not versioned by the
** interface system, versioning these will be defined somewhere else.
**
** Slot names are normal C identifiers, how these shall be versioned has to be defined somewhere
** else and is not the subject of the interface system. Each function can have its own unique UUID.
*/
#ifndef LUMIERA_INTERFACE_H #ifndef LUMIERA_INTERFACE_H
#define LUMIERA_INTERFACE_H #define LUMIERA_INTERFACE_H
#include "lib/ppmpl.h" #include "lib/ppmpl.h"
#include "lib/psplay.h" #include "lib/psplay.h"
/* TODO better doxygen formating */
/**
* @file interface.h
* @brief Lumiera interface macros and structures.
*
* Lumiera uses a system of versioned interfaces instead of just employing a
* simple library (containg the functions and data) and header file strategy.
* The interfaces defined here are C compatible and, thus, can be used by any
* language able to bind to C. The interfaces are versioned to provide forward
* and backward compatibility for both source and binary deployment of
* modules. The interfaces play a central role in the Lumiera architecture.
* Other facilities, such as serializing sessions and distributed computing
* will use them extensively.
*
* Overview
*
* Interfaces are used for 2 reasons in Lumiera:
* -# The Lumiera core system uses them internally and exports its functionality though them.
* -# Plugins (effects, ...) extend Lumiera by providing interfaces
*
* To make an interface available to code so that the code can use the
* interface, the interface needs to be declared and then defined. We provide a
* number of macros here which ease this process.
*
* The interface is declared by placing the following macro in a
* header file:
* \code
* LUMIERA_INTERFACE_DECLARE(name, version,
* LUMIERA_INTERFACE_SLOT(ret, name, params),
* ...
* )
*
* \endcode
* Any code that wants to use this interface must then include the header file.
*
* The interface is defined by mapping interface functions to slots, or
* providing inline definitions for slot functions. Defining the interface has
* the following form:
* \code
* LUMIERA_INTERFACE_INSTANCE(iname, version, name, descriptor, acquire, release,
* LUMIERA_INTERFACE_MAP (slot, function),
* LUMIERA_INTERFACE_INLINE (slot, ret, params, {body}),
* ...
* )
* \endcode
*
* A collection of interfaces can be defined in 2 different ways depending on
* where whether the interface is exported by the core, or by a plugin:
* \code
* LUMIERA_EXPORT(queryfunc,
* LUMIERA_INTERFACE_DEFINE(...),
* ...
* ) // Exporting from the core
*
* LUMIERA_PLUGIN(descriptor, acquire, release,
* LUMIERA_INTERFACE_DEFINE(...),
* ...
* ) // Exporting from an interface
* \endcode
*
* Naming and Versioning
*
* Interfaces have unique names and a major and minor version. The name and the major version
* is used to construct a C identifier for the interface, the minor version is implicitly defined
* by the number of functions in the interface. Interface instances are not versioned by the
* interface system, versioning these wii be defined somewhere else.
*
* Slot names are normal C identifiers, how these shall be versioned has to be defined somewhere
* else and is not the subject of the interface system. Each function can have its own unique uuid.
*/
/* /* ==== Macros to Declare an Interface */
Macros to Declare an Interface
*/
/** /**
* *
@ -179,7 +171,7 @@ LUMIERA_INTERFACE_TYPE(name, version) \
* Declare a function slot inside an interface. * Declare a function slot inside an interface.
* @param ret return type of the function * @param ret return type of the function
* @param name name of this slot * @param name name of this slot
* @param params parentized list of parameters for the function * @param params parenthesised list of parameters for the function
*/ */
#define PPMPL_FOREACH_LUMIERA_INTERFACE_SLOT(ret, name, params) \ #define PPMPL_FOREACH_LUMIERA_INTERFACE_SLOT(ret, name, params) \
ret (*name) params; \ ret (*name) params; \
@ -240,7 +232,7 @@ PPMPL_FOREACH(_P2_, __VA_ARGS__)
* Map a inline defined function to a interface slot * Map a inline defined function to a interface slot
* @param slot name of the slot to be mapped * @param slot name of the slot to be mapped
* @param ret return type of the inline function * @param ret return type of the inline function
* @param params parentized list of parameters given to the function * @param params parenthesised list of parameters given to the function
* @param ... braced function body * @param ... braced function body
* *
* @note C++ requires that all mappings are in the same order than defined in the interface declaration, * @note C++ requires that all mappings are in the same order than defined in the interface declaration,

View file

@ -1,5 +1,5 @@
/* /*
interfaceregistry.c - Lumiera interface registry InterfaceRegistry - registry for extension points
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,27 +17,26 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
/** @file interfaceregistry.c
** Interface instances are published and activated by registering them
** into a global registry, which is defined here. This instances are identified
** by their name and major version.
*/
#include "include/logging.h" #include "include/logging.h"
#include "lib/error.h" #include "lib/error.h"
#include "lib/psplay.h" #include "lib/psplay.h"
#include "lib/safeclib.h" #include "lib/safeclib.h"
#include <nobug.h> #include <nobug.h>
#include "common/plugin.h" #include "common/plugin.h"
#include "common/interfaceregistry.h" #include "common/interfaceregistry.h"
/**
* @file
* Interface instances are published and activated by registering them
* into a global registry, which is defined here. This instances are identified
* by their name and major version.
*/
PSplay lumiera_interfaceregistry; PSplay lumiera_interfaceregistry;
@ -81,9 +80,7 @@ lumiera_interfacenode_delete (LumieraInterfacenode self)
} }
/** /** Initialise the interface registry */
* Initialize the interface registry
*/
void void
lumiera_interfaceregistry_init (void) lumiera_interfaceregistry_init (void)
{ {

View file

@ -1,5 +1,5 @@
/* /*
interfaceregistry.h - Lumiera interface registry INTERFACEREGISTRY.h - Lumiera interface registry
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,17 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/** @file interfaceregistry.h
** Global registry for interfaces (extension points).
** Interface instances are published and activated by registering them
** into a global registry, which is defined here. This instances are identified
** by their name and major version.
*/
#ifndef LUMIERA_INTERFACEREGISTRY_H #ifndef LUMIERA_INTERFACEREGISTRY_H
#define LUMIERA_INTERFACEREGISTRY_H #define LUMIERA_INTERFACEREGISTRY_H
@ -31,17 +41,6 @@
#include <nobug.h> #include <nobug.h>
/**
* @file
* Interface instances are published and activated by registering them
* into a global registry, which is defined here. This instances are identified
* by their name and major version.
*/
//NOBUG_DECLARE_FLAG (interface_all);
//NOBUG_DECLARE_FLAG (interfaceregistry);
//NOBUG_DECLARE_FLAG (interface);
extern PSplay lumiera_interfaceregistry; extern PSplay lumiera_interfaceregistry;
extern lumiera_recmutex lumiera_interface_mutex; extern lumiera_recmutex lumiera_interface_mutex;
@ -70,15 +69,17 @@ struct lumiera_interfacenode_struct
/** temporary used to stack interfaces when recursively opening/closing them */ /** temporary used to stack interfaces when recursively opening/closing them */
LumieraInterfacenode lnk; LumieraInterfacenode lnk;
/** allocated size of the following deps table */
/** allocated size of the following dependency table */
size_t deps_size; size_t deps_size;
/** NULL terminated table of all dependencies (interfaces opened on initialization) */
/** NULL terminated table of all dependencies (interfaces opened on initialisation) */
LumieraInterfacenode* deps; LumieraInterfacenode* deps;
}; };
/** /**
* Initialize the interface registry * Initialise the interface registry
*/ */
void void
lumiera_interfaceregistry_init (void); lumiera_interfaceregistry_init (void);

View file

@ -1,5 +1,5 @@
/* /*
plugin_dynlib.c - Lumiera Plugin loader for dynamic libraries PluginDynlib - Lumiera Plugin loader for dynamic libraries
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
/** @file plugin-dynlib.c
** Implementation of plugin loader for dynamic libraries.
*/
#include "include/logging.h" #include "include/logging.h"
#include "lib/tmpbuf.h" #include "lib/tmpbuf.h"
@ -26,10 +32,6 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <nobug.h> #include <nobug.h>
/**
* @file
* Plugin loader for dynamic libraries.
*/
LumieraPlugin LumieraPlugin
lumiera_plugin_load_DYNLIB (const char* name) lumiera_plugin_load_DYNLIB (const char* name)

View file

@ -1,5 +1,5 @@
/* /*
plugin.c - Lumiera Plugin loader Plugin - Lumiera Plugin loader implementation
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,7 +17,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
* *****************************************************/
/** @file plugin.c /** @file plugin.c
@ -250,7 +251,7 @@ lumiera_plugin_load (const char* plugin)
{ {
TRACE (pluginloader_dbg, "plugin=%s", plugin); TRACE (pluginloader_dbg, "plugin=%s", plugin);
/* dispatch on ext, call the registered function */ /* dispatch on extension, call the registered function */
const char* ext = strrchr (plugin, '.'); const char* ext = strrchr (plugin, '.');
LumieraPlugintype itr = lumiera_plugin_types; LumieraPlugintype itr = lumiera_plugin_types;
@ -312,7 +313,7 @@ lumiera_plugin_unload (LumieraPlugin self)
if (self->refcnt) if (self->refcnt)
return self->refcnt; return self->refcnt;
/* dispatch on ext, call the registered function */ /* dispatch on extension, call the registered function */
const char* ext = strrchr (self->name, '.'); const char* ext = strrchr (self->name, '.');
LumieraPlugintype itr = lumiera_plugin_types; LumieraPlugintype itr = lumiera_plugin_types;

View file

@ -1,5 +1,5 @@
/* /*
plugin.h - Plugin loader PLUGIN.h - Plugin loader
Copyright (C) Lumiera.org Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -17,9 +17,38 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef LUMIERA_PLUGIN_H
#define LUMIERA_PLUGIN_H
/** @file plugin.h
** Lumiera plugins define 'interfaces' as shown in interface.h, the plugin system handles the loading
** of all kinds of plugins under the hood, invoked from the interface system. Most things defined here
** are called internally and should not be used by other parts of the application.
**
** \par Plugin discovery
** The #lumiera_plugin_discover() function offers a automatic way to load and register new plugins. It
** traverses all configured plugin directories. It takes to function for loading and registering plugins
** as parameter, by now this only uses the here defined \c plugin_load() and \c plugin_register() functions
** which lets it load any newly found plugin unconditionally. Later these callbacks will be replaced by
** a smarter system (plugindb) which makes it possible to load plugins on-demand and select proper
** plugins based on their version and capabilities.
**
** \par Plugin loading
** Plugins are loaded and initialised in a sequence of steps:
** plugin_load() dispatches to a specific loader function depending on the type (extension) of a plugin.
** This loader allocates a new plugin structure with plugin_new() and then does it work and eventually
** finalising the plugin structure initialisation with plugin_init() by providing a handle to a
** \c lumieraorg__plugin interface. plugin_init() also stores the current error state (which might be clean)
** into the plugin. After that the plugin can be registered which records it in the plugin registry and if
** its error state is clean, registering all interfaces it offers in the interface registry. With that
** the plugin is ready to be used. Plugins with the error state set should still be registered to prevent
** further discovery runs to try loading them again.
**
*/
#ifndef COMMON_PLUGIN_H
#define COMMON_PLUGIN_H
#include "lib/psplay.h" #include "lib/psplay.h"
#include "lib/error.h" #include "lib/error.h"
@ -29,33 +58,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <nobug.h> #include <nobug.h>
/**
* @file
* Lumiera plugins defines 'interfaces' as shown in interface.h, the plugin system handles the loading
* of all kinds of plugins under the hood, invoked from the interface system. Most things defined here
* are called internally and should not be used by other parts of the application.
*
* Plugin discovery
* The plugin_discover() function offers a automatic way to load and register new plugins. It traverses
* all configured plugin directories. It takes to function for loading and registering plugins as
* parameter, by now this only uses the here defined plugin_load() and plugin_register() functions
* which lets it load any newly found plugin unconditionally. Later these callbacks will be replaced by
* a smarter system (plugindb) which makes it possible to load plugins on-demand and select proper
* plugins based on their version and capabilities.
*
* Plugin loading
* Plugins are loaded and initialized in a sequence of steps:
* plugin_load() dispatches to a specific loader function depending on the type (extension) of a plugin.
* This loader allocates a new plugin structure with plugin_new() and then does it work and eventually
* finalizing the plugin structure initialization with plugin_init() by providing a handle to a
* lumieraorg__plugin interface. plugin_init() also stores the current error state (which might be clean)
* into the plugin. After that the plugin can be registered which records it in the pluginregistry and if
* its error state is clean, registering all interfaces it offers in the interface registry. With that
* the plugin is ready to be used. Plugins with the error state set should still be registered to prevent
* further discovery runs to try loading them again.
*
*/
LUMIERA_ERROR_DECLARE(PLUGIN_INIT); LUMIERA_ERROR_DECLARE(PLUGIN_INIT);
LUMIERA_ERROR_DECLARE(PLUGIN_OPEN); LUMIERA_ERROR_DECLARE(PLUGIN_OPEN);
@ -64,9 +66,6 @@ LUMIERA_ERROR_DECLARE(PLUGIN_REGISTER);
LUMIERA_ERROR_DECLARE(PLUGIN_VERSION); LUMIERA_ERROR_DECLARE(PLUGIN_VERSION);
//NOBUG_DECLARE_FLAG (plugin);
/* tool macros*/
struct lumiera_plugin_struct; struct lumiera_plugin_struct;
@ -75,22 +74,21 @@ typedef lumiera_plugin* LumieraPlugin;
/** /**
* Allocates an preinitializes a plugin structure * Allocates an preinitialises a plugin structure
* @internal * @internal
* @param name path/filename of the plugin * @param name path/filename of the plugin
* @return new allocated/preinitialized plugin structure with its error state set to LUMIERA_ERROR_PLUGIN_INIT * @return new allocated/preinitialised plugin structure with its error state set to \c LUMIERA_ERROR_PLUGIN_INIT
*/ */
LumieraPlugin LumieraPlugin
lumiera_plugin_new (const char* name); lumiera_plugin_new (const char* name);
/** /**
* Complete plugin initialization * @internal Complete plugin initialisation
* @internal
* Stores any pending error (from loading) in self which clears out the LUMIERA_ERROR_PLUGIN_INIT error state * Stores any pending error (from loading) in self which clears out the LUMIERA_ERROR_PLUGIN_INIT error state
* which was initialized by lumiera_plugin_new(), stores the handle and plugin pointers in the plugin struct. * which was initialised by lumiera_plugin_new(), stores the handle and plugin pointers in the plugin struct.
* @param self pointer to the plugin struct * @param self pointer to the plugin struct
* @param handle opaque handle referring to some plugin type specific data * @param handle opaque handle referring to some plugin type specific data
* @param plugin a lumieraorg__plugin interface which will be used to initialize this plugin * @param plugin a lumieraorg__plugin interface which will be used to initialise this plugin
*/ */
LumieraPlugin LumieraPlugin
lumiera_plugin_init (LumieraPlugin self, void* handle, LumieraInterface plugin); lumiera_plugin_init (LumieraPlugin self, void* handle, LumieraInterface plugin);
@ -98,7 +96,7 @@ lumiera_plugin_init (LumieraPlugin self, void* handle, LumieraInterface plugin);
/** /**
* Tries to load a plugin * Tries to load a plugin
* Creates a new plugin structure and tries to load and initialize the plugin. * Creates a new plugin structure and tries to load and initialise the plugin.
* The plugins error state may be set on any problem which should be queried later. * The plugins error state may be set on any problem which should be queried later.
* @param plugin path/filename of the plugin to load * @param plugin path/filename of the plugin to load
* @return pointer to the new plugin structure (always, never NULL, check error state) * @return pointer to the new plugin structure (always, never NULL, check error state)
@ -109,12 +107,12 @@ lumiera_plugin_load (const char* plugin);
/** /**
* Register a plugin and its interfaces. * Register a plugin and its interfaces.
* Registers the plugin (unconditionally) at the pluginregistry. * Registers the plugin (unconditionally) at the plugin registry.
* When the error state of the plugin is NULL then use its lumieraorg__plugin interface * When the error state of the plugin is NULL then use its lumieraorg__plugin interface
* to register all interfaces offered by the plugin at the interface registry. * to register all interfaces offered by the plugin at the interface registry.
* Registered plugins will be automatic unloaded at application end. * Registered plugins will be automatic unloaded at application end.
* @param self the plugin to be registered (calling with NULL is a no-op) * @param self the plugin to be registered (calling with NULL is a no-op)
* @return 1 on success (including calling with NULL) and 0 when a error occured * @return 1 on success (including calling with NULL) and 0 when a error occurred
*/ */
int int
lumiera_plugin_register (LumieraPlugin self); lumiera_plugin_register (LumieraPlugin self);
@ -139,7 +137,7 @@ lumiera_plugin_handle (LumieraPlugin self);
/** /**
* Query the plugin name * Query the plugin name
* The name is the path and filname under which it was loaded * The name is the path and filename under which it was loaded
* @param self plugin to query * @param self plugin to query
* @return pointer to the name string * @return pointer to the name string
*/ */
@ -148,8 +146,7 @@ lumiera_plugin_name (LumieraPlugin self);
/** /**
* Increment refcount * @internal Increment refcount
* @internal
* @param self plugin which refcount to increment * @param self plugin which refcount to increment
*/ */
void void
@ -157,8 +154,7 @@ lumiera_plugin_refinc (LumieraPlugin self);
/** /**
* Decrement refcount * @internal Decrement refcount
* @internal
* @param self plugin which refcount to decrement * @param self plugin which refcount to decrement
*/ */
void void
@ -195,7 +191,8 @@ lumiera_plugin_discover (LumieraPlugin (*callback_load)(const char* plugin),
int (*callback_register) (LumieraPlugin)); int (*callback_register) (LumieraPlugin));
/* psplay support functions */ /* === psplay support functions === */
int int
lumiera_plugin_cmp_fn (const void* keya, const void* keyb); lumiera_plugin_cmp_fn (const void* keya, const void* keyb);
@ -205,4 +202,6 @@ lumiera_plugin_key_fn (const PSplaynode node);
void void
lumiera_plugin_delete_fn (PSplaynode node); lumiera_plugin_delete_fn (PSplaynode node);
#endif /* LUMIERA_PLUGIN_H */
#endif /*COMMON_PLUGIN_H*/

View file

@ -24,7 +24,7 @@
#include "gui/display-service.hpp" #include "gui/display-service.hpp"
extern "C" { extern "C" {
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
} }

View file

@ -62,7 +62,7 @@
extern "C" { extern "C" {
#include "common/interface.h" #include "common/interface.h"
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
} }
#include <functional> #include <functional>

View file

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

View file

@ -165,7 +165,7 @@ typedef lumiera_condition* LumieraCondition;
/** /**
* Initialize a condition variable * Initialize a condition variable
* @param self is a pointer to the condition variable to be initialized * @param self is a pointer to the condition variable to be initialised
* @return self as given * @return self as given
*/ */
LumieraCondition LumieraCondition

View file

@ -75,7 +75,7 @@ typedef void (*cuckoo_movfunc)(void* dest, void* src, size_t size);
/** /**
* Function table used to specialize various funtions used by the hash. * Function table used to specialise various functions used by the hash.
* TODO some elements might be NULL, then defaults are used * TODO some elements might be NULL, then defaults are used
*/ */
struct cuckoo_vtable struct cuckoo_vtable
@ -90,11 +90,11 @@ struct cuckoo_vtable
/** /**
* Initialize a cuckoo hash. * Initialise a cuckoo hash.
* @param self pointer to a uninitialized cuckoo datastructure * @param self pointer to a uninitialised cuckoo datastructure
* @param itemsize size for a single hash entry, will be rounded up to align CUCKOO_GRANULARITY * @param itemsize size for a single hash entry, will be rounded up to align CUCKOO_GRANULARITY
* @param vtable initialized vtable * @param vtable initialised vtable
* @return The initialized hashtable or NULL at allocation failure * @return The initialised hashtable or NULL at allocation failure
*/ */
Cuckoo Cuckoo
cuckoo_init (Cuckoo self, size_t itemsize, struct cuckoo_vtable* vtable); cuckoo_init (Cuckoo self, size_t itemsize, struct cuckoo_vtable* vtable);
@ -103,8 +103,8 @@ cuckoo_init (Cuckoo self, size_t itemsize, struct cuckoo_vtable* vtable);
* Allocate a new cuckoo hash. * Allocate a new cuckoo hash.
* @param itemsize size for a single hash entry, will be rounded up to align CUCKOO_GRANULARITY * @param itemsize size for a single hash entry, will be rounded up to align CUCKOO_GRANULARITY
* @param startsize initial size of table t3, as 2's exponent * @param startsize initial size of table t3, as 2's exponent
* @param vtable initialized vtable * @param vtable initialised vtable
* @return The initialized hashtable or NULL at allocation failure * @return The initialised hashtable or NULL at allocation failure
*/ */
Cuckoo Cuckoo
cuckoo_new (size_t itemsize, struct cuckoo_vtable* vtable); cuckoo_new (size_t itemsize, struct cuckoo_vtable* vtable);
@ -114,7 +114,7 @@ cuckoo_new (size_t itemsize, struct cuckoo_vtable* vtable);
* Destroy a cuckoo hash. * Destroy a cuckoo hash.
* Frees internal used resources. * Frees internal used resources.
* @param self cuckoo hash to destroy * @param self cuckoo hash to destroy
* @return The now uninitialized hashtable * @return The now uninitialised hashtable
*/ */
Cuckoo Cuckoo
cuckoo_destroy (Cuckoo self); cuckoo_destroy (Cuckoo self);

View file

@ -29,7 +29,7 @@
/** /**
* @file * @file
* Intrusive cyclic double linked list * Intrusive cyclic double linked list
* There is only one node type which contains a forward and a backward pointer. In a empty initialized node, * There is only one node type which contains a forward and a backward pointer. In a empty initialised node,
* this pointers point to the node itself. Note that these pointers can never ever become NULL. * this pointers point to the node itself. Note that these pointers can never ever become NULL.
* This lists are used by using one node as 'root' node where its both pointers are the head/tail pointer to the actual list. * This lists are used by using one node as 'root' node where its both pointers are the head/tail pointer to the actual list.
* Care needs to be taken to ensure not to apply any operations meant to be applied to data nodes to the root node. * Care needs to be taken to ensure not to apply any operations meant to be applied to data nodes to the root node.
@ -44,7 +44,7 @@
* #define LLIST_IMPLEMENTATION before including this header yields in definitions * #define LLIST_IMPLEMENTATION before including this header yields in definitions
* this can be used to generate a library. This is currently untested and not recommended. * this can be used to generate a library. This is currently untested and not recommended.
* The rationale for using inlined functions is that most functions are very small and likely to be used in performance critical parts. * The rationale for using inlined functions is that most functions are very small and likely to be used in performance critical parts.
* Inlining can give a huge performance and optimization improvement here. * Inlining can give a huge performance and optimisation improvement here.
* The few functions which are slightly larger are expected to be the less common used ones, so inlining them too shouldn't be a problem either * The few functions which are slightly larger are expected to be the less common used ones, so inlining them too shouldn't be a problem either
*/ */
@ -188,10 +188,10 @@ typedef llist ** LList_ref;
tail = llist_tail (list)) tail = llist_tail (list))
/** /**
* Initialize a new llist. * Initialise a new llist.
* Must not be applied to a list node which is not empty! Lists need to be initialized * Must not be applied to a list node which is not empty! Lists need to be initialised
* before any other operation on them is called. * before any other operation on them is called.
* @param self node to be initialized * @param self node to be initialised
*/ */
LLIST_FUNC (LList llist_init (LList self), LLIST_FUNC (LList llist_init (LList self),
return self->next = self->prev = self; return self->next = self->prev = self;

View file

@ -60,8 +60,8 @@
/* /*
C++ can't initialize arrays from string literals with the trailing \0 cropped C++ can't initialise arrays from string literals with the trailing \0 cropped
C can't initialize non constant members, C can't initialise non constant members,
there we go there we go
////////////////////////////////TODO 3/2014 possibly not used anymore, after removing LUIDs from the Interface descriptors (see #925) ////////////////////////////////TODO 3/2014 possibly not used anymore, after removing LUIDs from the Interface descriptors (see #925)
*/ */

View file

@ -43,7 +43,7 @@
void *(*mpool_malloc_hook)(size_t size) = malloc; void *(*mpool_malloc_hook)(size_t size) = malloc;
void (*mpool_free_hook)(void *ptr) = free; void (*mpool_free_hook)(void *ptr) = free;
/** called after a mpool got initialized */ /** called after a mpool got initialised */
void (*mpool_init_hook) (MPool self) = NULL; void (*mpool_init_hook) (MPool self) = NULL;
/** called before a mpool gets destroyed */ /** called before a mpool gets destroyed */
void (*mpool_destroy_hook) (MPool self) = NULL; void (*mpool_destroy_hook) (MPool self) = NULL;
@ -196,7 +196,7 @@ mpool_cluster_alloc_ (MPool self)
/* clear the bitmap */ /* clear the bitmap */
memset (&cluster->data, 0, MPOOL_BITMAP_SIZE (self->elements_per_cluster)); memset (&cluster->data, 0, MPOOL_BITMAP_SIZE (self->elements_per_cluster));
/* initialize freelist */ /* initialise freelist */
for (unsigned i = 0; i < self->elements_per_cluster; ++i) for (unsigned i = 0; i < self->elements_per_cluster; ++i)
{ {
MPoolnode node = cluster_element_get (cluster, self, i); MPoolnode node = cluster_element_get (cluster, self, i);

View file

@ -86,23 +86,23 @@ struct mpool_struct
extern void *(*mpool_malloc_hook)(size_t size); extern void *(*mpool_malloc_hook)(size_t size);
extern void (*mpool_free_hook)(void *ptr); extern void (*mpool_free_hook)(void *ptr);
/** called after a mpool got initialized */ /** called after a mpool got initialised */
extern void (*mpool_init_hook) (MPool self); extern void (*mpool_init_hook) (MPool self);
/** called before a mpool gets destroyed */ /** called before a mpool gets destroyed */
extern void (*mpool_destroy_hook) (MPool self); extern void (*mpool_destroy_hook) (MPool self);
/* /*
//index.mpool_init xref:mpool_init[mpool_init()]:: initialize a new memory pool //index.mpool_init xref:mpool_init[mpool_init()]:: Initialise a new memory pool
//mpool [[mpool_init]] //mpool [[mpool_init]]
//mpool .mpool_init //mpool .mpool_init
//mpool Initialize a memory pool, memory pools must be initialized before being used. One can supply //mpool Initialise a memory pool, memory pools must be initialised before being used. One can supply
//mpool an optional destructor function for elements, this will be used to destroy elements which are still //mpool an optional destructor function for elements, this will be used to destroy elements which are still
//mpool in the pool when it gets destroyed itself. The destructor is _NOT_ called when elemented are freed. //mpool in the pool when it gets destroyed itself. The destructor is _NOT_ called when elements are freed.
//mpool //mpool
//mpool MPool mpool_init (MPool self, size_t elem_size, unsigned elements_per_cluster, mpool_move_fn mv, mpool_destroy_fn dtor) //mpool MPool mpool_init (MPool self, size_t elem_size, unsigned elements_per_cluster, mpool_move_fn mv, mpool_destroy_fn dtor)
//mpool //mpool
//mpool `self`:: //mpool `self`::
//mpool pointer to the memory pool structure to be initialized //mpool pointer to the memory pool structure to be initialised
//mpool `elem_size`:: //mpool `elem_size`::
//mpool size for a single element //mpool size for a single element
//mpool `elements_per_cluster`:: //mpool `elements_per_cluster`::
@ -124,13 +124,13 @@ mpool_init (MPool self, size_t elem_size, unsigned elements_per_cluster, mpool_d
//mpool A memory pool is not used anymore it should be destroyed. This frees all memory allocated with it. //mpool A memory pool is not used anymore it should be destroyed. This frees all memory allocated with it.
//mpool When a destructor was provided at construction time, then this destructor is used on all non free elements //mpool When a destructor was provided at construction time, then this destructor is used on all non free elements
//mpool before before the clusters are freed. If no destructor was given then the clusters are just freed. //mpool before before the clusters are freed. If no destructor was given then the clusters are just freed.
//mpool The destroyed memory pool behaves as if it was freshly initialized and can be used again, this is some kindof //mpool The destroyed memory pool behaves as if it was freshly initialised and can be used again, this is some kindof
//mpool exceptional behaviour. //mpool exceptional behaviour.
//mpool //mpool
//mpool MPool mpool_destroy (MPool self) //mpool MPool mpool_destroy (MPool self)
//mpool //mpool
//mpool `self`:: //mpool `self`::
//mpool pointer to an initialized memory pool to be destroyed. //mpool pointer to an initialised memory pool to be destroyed.
//mpool return:: //mpool return::
//mpool self //mpool self
//mpool //mpool

View file

@ -35,7 +35,7 @@
*/ */
/** /**
* Callback function used to destruct/cleanup aged elements. * Callback function used to destroy/cleanup aged elements.
* shall clean the element sufficiently up to be ready for being freed or reused, * shall clean the element sufficiently up to be ready for being freed or reused,
* this callback function must be reentrant and prepared to be called twice. * this callback function must be reentrant and prepared to be called twice.
* @param node the llist node used to link cache elements (will be empty at call) * @param node the llist node used to link cache elements (will be empty at call)
@ -53,9 +53,9 @@ typedef struct lumiera_mrucache_struct lumiera_mrucache;
typedef lumiera_mrucache* LumieraMruCache; typedef lumiera_mrucache* LumieraMruCache;
/** /**
* Initialize a cache. * Initialise a cache.
* @param self cache to be initialized * @param self cache to be initialised
* @param destructor_cb function for destructing a cache node, preparing for reuse. * @param destructor_cb function for destroying a cache node, preparing for reuse.
* @return self * @return self
*/ */
LumieraMruCache LumieraMruCache
@ -145,7 +145,7 @@ lumiera_mrucache_checkout (LumieraMruCache self, LList node)
* This function is used to get a new element by deleting the oldest least used one from the cache. * This function is used to get a new element by deleting the oldest least used one from the cache.
* The cache must be locked for this operation. * The cache must be locked for this operation.
* @param self cache * @param self cache
* @return pointer to the uninitialized memory ready for being reused or NULL when no element was available * @return pointer to the uninitialised memory ready for being reused or NULL when no element was available
*/ */
static inline void* static inline void*
lumiera_mrucache_pop (LumieraMruCache self) lumiera_mrucache_pop (LumieraMruCache self)

View file

@ -101,9 +101,9 @@ typedef lumiera_mutex* LumieraMutex;
/** /**
* Initialize a mutex variable * Initialise a mutex variable
* This initializes a 'fast' default mutex which must not be locked recursively from one thread. * This initialises a 'fast' default mutex which must not be locked recursively from one thread.
* @param self is a pointer to the mutex to be initialized * @param self is a pointer to the mutex to be initialised
* @param purpose textual hint for the nobug resourcetracker * @param purpose textual hint for the nobug resourcetracker
* @param flag nobug logging target * @param flag nobug logging target
* @return self as given * @return self as given

View file

@ -155,10 +155,10 @@ psplay_delete (PSplay self);
/** /**
* Initialize a splay tree node * Initialise a splay tree node
* The user has to place this nodes within his datastructure and must * The user has to place this nodes within his datastructure and must
* initialize them before using them. * Initialise them before using them.
* @param self pointer to the node to be initialized * @param self pointer to the node to be initialised
* @return self * @return self
*/ */
PSplaynode PSplaynode
@ -195,7 +195,7 @@ psplay_find (PSplay self, const void* key, int splayfactor);
* @param self pointer to the splay tree * @param self pointer to the splay tree
* @param node node to be removed * @param node node to be removed
* @return pointer to the removed node * @return pointer to the removed node
* removal is optimized for the case where one call it immediately after one did a * removal is optimised for the case where one call it immediately after one did a
* psplay_find() as last operation on that tree * psplay_find() as last operation on that tree
*/ */
PSplaynode PSplaynode

View file

@ -165,8 +165,8 @@ typedef lumiera_reccondition* LumieraReccondition;
/** /**
* Initialize a condition variable * Initialise a condition variable
* @param self is a pointer to the condition variable to be initialized * @param self is a pointer to the condition variable to be initialised
* @return self as given * @return self as given
*/ */
LumieraReccondition LumieraReccondition

View file

@ -94,9 +94,9 @@ typedef struct lumiera_recmutex_struct lumiera_recmutex;
typedef lumiera_recmutex* LumieraRecmutex; typedef lumiera_recmutex* LumieraRecmutex;
/** /**
* Initialize a recursive mutex variable * Initialise a recursive mutex variable
* Initializes a 'recursive' mutex which might be locked by the same thread multiple times. * Initialises a 'recursive' mutex which might be locked by the same thread multiple times.
* @param self is a pointer to the mutex to be initialized * @param self is a pointer to the mutex to be initialised
* @return self as given * @return self as given
*/ */
LumieraRecmutex LumieraRecmutex

View file

@ -142,7 +142,7 @@ typedef lumiera_rwlock* LumieraRWLock;
/** /**
* Initialize a rwlock * Initialize a rwlock
* @param self is a pointer to the rwlock to be initialized * @param self is a pointer to the rwlock to be initialised
* @return self as given * @return self as given
*/ */
LumieraRWLock LumieraRWLock
@ -153,7 +153,7 @@ lumiera_rwlock_init (LumieraRWLock self,
/** /**
* destroy a rwlock * destroy a rwlock
* @param self is a pointer to the rwlock to be initialized * @param self is a pointer to the rwlock to be initialised
* @return self on success or NULL at error * @return self on success or NULL at error
*/ */
LumieraRWLock LumieraRWLock

View file

@ -1,5 +1,5 @@
/* /*
safe_clib.h - Portable and safe wrapers around some clib functions and some tools safe_clib.h - Portable and safe wrappers around some clib functions and some tools
Copyright (C) CinelerraCV Copyright (C) CinelerraCV
2008, Christian Thaeter <ct@pipapo.org> 2008, Christian Thaeter <ct@pipapo.org>
@ -32,10 +32,10 @@ LUMIERA_ERROR_DECLARE(NO_MEMORY);
/** /**
* Install the resourcecollector run hook. * Install the resourcecollector run hook.
* The resourcecollectr must be hooked into the safeclib at bootup after it got * The resourcecollectr must be hooked into the safeclib at bootup after it got
* initialized and removed from it before shut down. Without resourcecollector * initialised and removed from it before shut down. Without resourcecollector
* failed allocations will abort(). * failed allocations will abort().
* @param hook pointer to the resourcecollector_run function, must be of type * @param hook pointer to the resourcecollector_run function, must be of type
* lumiera_resourcecollector_run_fn but we dont want a dependency on backend in this header * lumiera_resourcecollector_run_fn but we don't want a dependency on backend in this header
*/ */
void void
lumiera_safeclib_set_resourcecollector (void* hook); lumiera_safeclib_set_resourcecollector (void* hook);

View file

@ -61,13 +61,13 @@ namespace lib {
/** /**
* Helper: Access a path Specification as a sequence of filesystem Paths. * Helper: Access a path Specification as a sequence of filesystem Paths.
* This iterator class dissects a ':'-separated path list. The individual * This iterator class dissects a ':'-separated path list. The individual
* components may use the symbol \c $ORIGIN to denote the directory holding * components may use the symbol \c $ORIGIN to refer to the directory
* the current executable. * holding the current executable.
* @note #next picks the current component and advances the iteration. * @note #next picks the current component and advances the iteration.
*/ */
class SearchPathSplitter class SearchPathSplitter
: public BoolCheckable<SearchPathSplitter : public BoolCheckable<SearchPathSplitter
, boost::noncopyable> , boost::noncopyable>
{ {
string pathSpec_; string pathSpec_;
sregex_iterator pos_, sregex_iterator pos_,

View file

@ -30,13 +30,13 @@
* *
* List node is a structure, which consists only of a forward pointer. This is * List node is a structure, which consists only of a forward pointer. This is
* much easier and makes code much cleaner, than to have forward pointer as is. * much easier and makes code much cleaner, than to have forward pointer as is.
* In a empty initialized node, this pointer points to the node itself. Note * In a empty initialised node, this pointer points to the node itself. Note
* that this pointer can never ever become NULL. * that this pointer can never ever become NULL.
* *
* This lists are used by using one node as 'root' node where it's pointer is * This lists are used by using one node as 'root' node where it's pointer is
* the head pointer to the actual list. Care needs to be taken to ensure not to * the head pointer to the actual list. Care needs to be taken to ensure not to
* apply any operations meant to be applied to data nodes to the root node. * apply any operations meant to be applied to data nodes to the root node.
* This way is the prefered way to use this lists. * This way is the preferred way to use this lists.
* *
* Alternatively one can store only a chain of data nodes and use a SList * Alternatively one can store only a chain of data nodes and use a SList
* pointer to point to the first item (which might be NULL in case no data is * pointer to point to the first item (which might be NULL in case no data is
@ -52,7 +52,7 @@
* 1 <= C <= N-1 nodes, and, thus, speed up search. * 1 <= C <= N-1 nodes, and, thus, speed up search.
* *
* This header can be used in 2 different ways: * This header can be used in 2 different ways:
* 1) (prerefered) just including it provides all functions as static inlined * 1) (preferred) just including it provides all functions as static inlined
* functions. This is the default * functions. This is the default
* 2) #define LLIST_INTERFACE before including this header gives only the declarations * 2) #define LLIST_INTERFACE before including this header gives only the declarations
* #define LLIST_IMPLEMENTATION before including this header yields in definitions * #define LLIST_IMPLEMENTATION before including this header yields in definitions
@ -60,7 +60,7 @@
* recommended. * recommended.
* The rationale for using inlined functions is that most functions are very * The rationale for using inlined functions is that most functions are very
* small and likely to be used in performance critical parts. Inlining can give * small and likely to be used in performance critical parts. Inlining can give
* a hughe performance and optimization improvement here. The few functions * a huge performance and optimisation improvement here. The few functions
* which are slightly larger are expected to be the less common used ones, so * which are slightly larger are expected to be the less common used ones, so
* inlining them too shouldn't be a problem either. * inlining them too shouldn't be a problem either.
*/ */
@ -184,11 +184,11 @@ typedef slist** SList_ref;
for ( SList head = slist_head( list ); ! slist_is_empty( list ); head = slist_head( list ) ) for ( SList head = slist_head( list ); ! slist_is_empty( list ); head = slist_head( list ) )
/** /**
* Initialize a new llist. * Initialise a new llist.
* Must not be applied to a list node which is not empty! Lists need to be initialized * Must not be applied to a list node which is not empty! Lists need to be initialised
* before any other operation on them is called. * before any other operation on them is called.
* *
* @param list node to be initialized * @param list node to be initialised
*/ */
SLIST_FUNC ( SLIST_FUNC (

View file

@ -27,7 +27,7 @@
#include "lib/depend.hpp" #include "lib/depend.hpp"
extern "C" { extern "C" {
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
} }
#include <string> #include <string>

View file

@ -35,7 +35,7 @@ static snd_pcm_sframes_t delay = 0;
static unsigned int rate = 44100; static unsigned int rate = 44100;
static int audio_initialized = 0; static int audio_initialised = 0;
size_t size_t
audio_offset() audio_offset()
@ -52,10 +52,10 @@ audio_init()
const char* device; const char* device;
int err; int err;
if(audio_initialized) if(audio_initialised)
return; return;
audio_initialized = 1; audio_initialised = 1;
device = getenv("ALSA_DEVICE"); device = getenv("ALSA_DEVICE");
@ -104,7 +104,7 @@ audio_init()
fprintf(stderr, "Buffer time is %.3f seconds\n", buffer_time / 1.0e6); fprintf(stderr, "Buffer time is %.3f seconds\n", buffer_time / 1.0e6);
if(0 > (err = snd_pcm_sw_params_current(playback_handle, sw_params))) if(0 > (err = snd_pcm_sw_params_current(playback_handle, sw_params)))
errx(EXIT_FAILURE, "Audio: Could not initialize software parameters: %s", errx(EXIT_FAILURE, "Audio: Could not initialise software parameters: %s",
snd_strerror(err)); snd_strerror(err));
snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params, 0); snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params, 0);

View file

@ -1,7 +1,7 @@
TESTING "Memory pool tests" ./test-mpool TESTING "Memory pool tests" ./test-mpool
TEST "init/destroy" basic <<END TEST "init/destroy" basic <<END
err: initialized err: initialised
err: allocated err: allocated
err: DUMP err: DUMP
err: freed err: freed

View file

@ -1,7 +1,7 @@
TESTING "test configuration system" ./test-configloader TESTING "test configuration system" ./test-configloader
TEST "initializing config system" init <<END TEST "initialising config system" init <<END
out: initialized out: initialised
out: destroyed out: destroyed
END END

View file

@ -1,7 +1,7 @@
TESTING "File mmaping" ./test-filemmap TESTING "File mmaping" ./test-filemmap
TEST "chunksize not initialized" mmap_missing_chunksize <<END TEST "chunksize not initialised" mmap_missing_chunksize <<END
return: 0 return: 0
END END

View file

@ -36,7 +36,7 @@ TEST (init)
/* Note: lumiera_config_init and lumiera_config_destroy are /* Note: lumiera_config_init and lumiera_config_destroy are
* invoked automatically from ConfigFacade * invoked automatically from ConfigFacade
*/ */
printf ("initialized\n"); printf ("initialised\n");
lumiera_config_destroy (); lumiera_config_destroy ();
printf ("destroyed\n"); printf ("destroyed\n");
/* there will be a warning about destroying the already /* there will be a warning about destroying the already

View file

@ -23,9 +23,9 @@
#include "common/interface.h" #include "common/interface.h"
#include "common/interfaceregistry.h" #include "common/interfaceregistry.h"
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
#include "common/config.h" #include "common/config.h"
#include "common/config_interface.h" #include "common/config-interface.h"
#include "lib/test/test.h" #include "lib/test/test.h"
#include "interface/say_hello.h" #include "interface/say_hello.h"

View file

@ -51,7 +51,7 @@ TEST (basic)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(void*), 10, dtor); mpool_init (&mypool, sizeof(void*), 10, dtor);
ECHO ("initialized"); ECHO ("initialised");
void* element; void* element;
element = mpool_alloc (&mypool); element = mpool_alloc (&mypool);
@ -74,7 +74,7 @@ TEST (destroy)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(void*), 10, dtor); mpool_init (&mypool, sizeof(void*), 10, dtor);
ECHO ("initialized"); ECHO ("initialised");
void* element; void* element;
element = mpool_alloc (&mypool); element = mpool_alloc (&mypool);
@ -92,7 +92,7 @@ TEST (clusters)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(void*), 2, dtor); mpool_init (&mypool, sizeof(void*), 2, dtor);
ECHO ("initialized"); ECHO ("initialised");
for (int i = 1; i <= 5; ++i) for (int i = 1; i <= 5; ++i)
{ {
@ -113,7 +113,7 @@ TEST (clusters_big)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(void*), 200, dtor); mpool_init (&mypool, sizeof(void*), 200, dtor);
ECHO ("initialized"); ECHO ("initialised");
for (int i = 1; i <= 700; ++i) for (int i = 1; i <= 700; ++i)
{ {
@ -134,7 +134,7 @@ TEST (alloc_free)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, 24, 4, dtor); mpool_init (&mypool, 24, 4, dtor);
ECHO ("initialized"); ECHO ("initialised");
void* elem[32]; void* elem[32];
@ -161,7 +161,7 @@ TEST (alloc_free_big)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, 24, 4, dtor); mpool_init (&mypool, 24, 4, dtor);
ECHO ("initialized"); ECHO ("initialised");
void* elem[2000]; void* elem[2000];
@ -199,7 +199,7 @@ TEST (bench_mpool)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(struct teststruct), 2000, NULL); mpool_init (&mypool, sizeof(struct teststruct), 2000, NULL);
ECHO ("initialized"); ECHO ("initialised");
llist list; llist list;
llist_init (&list); llist_init (&list);
@ -228,7 +228,7 @@ TEST (bench_malloc)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(llist), 2000, NULL); mpool_init (&mypool, sizeof(llist), 2000, NULL);
ECHO ("initialized"); ECHO ("initialised");
llist list; llist list;
llist_init (&list); llist_init (&list);
@ -262,7 +262,7 @@ TEST (bench_mpool_sim)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(struct teststruct), 2000, NULL); mpool_init (&mypool, sizeof(struct teststruct), 2000, NULL);
ECHO ("initialized"); ECHO ("initialised");
llist list; llist list;
llist_init (&list); llist_init (&list);
@ -304,7 +304,7 @@ TEST (bench_malloc_sim)
{ {
mpool mypool; mpool mypool;
mpool_init (&mypool, sizeof(llist), 2000, NULL); mpool_init (&mypool, sizeof(llist), 2000, NULL);
ECHO ("initialized"); ECHO ("initialised");
llist list; llist list;
llist_init (&list); llist_init (&list);

View file

@ -23,8 +23,8 @@
#include <stdio.h> #include <stdio.h>
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
#include "common/config_interface.h" #include "common/config-interface.h"
#include "interface/say_hello.h" #include "interface/say_hello.h"

View file

@ -23,13 +23,13 @@
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
#include "common/config_interface.h" #include "common/config-interface.h"
#include "lib/format-string.hpp" #include "lib/format-string.hpp"
extern "C" { extern "C" {
#include "common/interface.h" #include "common/interface.h"
#include "common/interfacedescriptor.h" #include "common/interface-descriptor.h"
#include "interface/say_hello.h" #include "interface/say_hello.h"
} }

View file

@ -0,0 +1,753 @@
<map version="freeplane 1.3.0">
<!--To view this file, download free mind mapping software Freeplane from http://freeplane.sourceforge.net -->
<node TEXT="Operating System" ID="ID_1631706542" CREATED="1421688431835" MODIFIED="1421875739706" VGAP="1">
<edge STYLE="sharp_bezier" WIDTH="4"/>
<font NAME="SansSerif" SIZE="12"/>
<hook NAME="MapStyle" zoom="0.75">
<properties show_icon_for_attributes="true" show_note_icons="true"/>
<map_styles>
<stylenode LOCALIZED_TEXT="styles.root_node">
<stylenode LOCALIZED_TEXT="styles.predefined" POSITION="right">
<stylenode LOCALIZED_TEXT="default" MAX_WIDTH="600" COLOR="#000000" STYLE="as_parent">
<font NAME="SansSerif" SIZE="10" BOLD="false" ITALIC="false"/>
</stylenode>
<stylenode LOCALIZED_TEXT="defaultstyle.details"/>
<stylenode LOCALIZED_TEXT="defaultstyle.note"/>
<stylenode LOCALIZED_TEXT="defaultstyle.floating">
<edge STYLE="hide_edge"/>
<cloud COLOR="#f0f0f0" SHAPE="ROUND_RECT"/>
</stylenode>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.user-defined" POSITION="right">
<stylenode LOCALIZED_TEXT="styles.topic" COLOR="#18898b" STYLE="fork">
<font NAME="Liberation Sans" SIZE="10" BOLD="true"/>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.subtopic" COLOR="#cc3300" STYLE="fork">
<font NAME="Liberation Sans" SIZE="10" BOLD="true"/>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.subsubtopic" COLOR="#669900">
<font NAME="Liberation Sans" SIZE="10" BOLD="true"/>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.important">
<icon BUILTIN="yes"/>
</stylenode>
<stylenode TEXT="note">
<icon BUILTIN="info"/>
<icon BUILTIN="pencil"/>
<edge COLOR="#ff9999"/>
<font NAME="SansSerif" SIZE="12" ITALIC="true"/>
</stylenode>
</stylenode>
<stylenode LOCALIZED_TEXT="styles.AutomaticLayout" POSITION="right">
<stylenode LOCALIZED_TEXT="AutomaticLayout.level.root" COLOR="#000000">
<font SIZE="18"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,1" COLOR="#0033ff">
<font SIZE="16"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,2" COLOR="#00b439">
<font SIZE="14"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,3" COLOR="#990000">
<font SIZE="12"/>
</stylenode>
<stylenode LOCALIZED_TEXT="AutomaticLayout.level,4" COLOR="#111111">
<font SIZE="10"/>
</stylenode>
</stylenode>
</stylenode>
</map_styles>
</hook>
<node TEXT="Workboards" POSITION="left" ID="ID_957022120" CREATED="1421689856157" MODIFIED="1428008690853" HGAP="12" VSHIFT="796">
<edge STYLE="sharp_bezier"/>
<font NAME="SansSerif" SIZE="12"/>
<linktarget COLOR="#b0b0b0" DESTINATION="ID_957022120" ENDARROW="None" ENDINCLINATION="-471;88;" ID="Arrow_ID_1910682021" SOURCE="ID_21270584" STARTARROW="Default" STARTINCLINATION="-215;12;"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#00cccc" WIDTH="2" TRANSPARENCY="60" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1355866027" STARTINCLINATION="-94;205;" ENDINCLINATION="-146;-5;" STARTARROW="DEFAULT" ENDARROW="DEFAULT"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="5" TRANSPARENCY="40" DASH="3 3" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_377209301" MIDDLE_LABEL="data links" STARTINCLINATION="-19;45;" ENDINCLINATION="-100;-8;" STARTARROW="NONE" ENDARROW="NONE"/>
<node TEXT="2D space where you can place all data which is dedicated to one project for exchange between apps and for organizing them. &#xa;Things like files, notes, link to disks, link to all the apps you need, .. And also there should be a clipboard where files can be stored temporarily for exchange between different apps.&#xa;Depending on what file the user is clicking it leads directly to one of the &apos;Stages&apos; within Lumiera." ID="ID_903148200" CREATED="1421690272218" MODIFIED="1428008690848" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="Applications" POSITION="left" ID="ID_308197395" CREATED="1421689994974" MODIFIED="1421869020366" HGAP="13" VSHIFT="-728">
<edge STYLE="sharp_bezier"/>
<font NAME="SansSerif" SIZE="12"/>
<node TEXT="Lumiera GUI" ID="ID_799374750" CREATED="1421688581377" MODIFIED="1424562055463" HGAP="28" VSHIFT="96" BACKGROUND_COLOR="#c9ebff">
<font NAME="SansSerif" SIZE="14" BOLD="true"/>
<edge STYLE="sharp_bezier" COLOR="#6699ff" WIDTH="8"/>
<arrowlink SHAPE="LINE" COLOR="#82a8c4" WIDTH="32" TRANSPARENCY="40" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1631706542" STARTINCLINATION="351;0;" ENDINCLINATION="351;0;" STARTARROW="NONE" ENDARROW="NONE"/>
<node TEXT="status bar" ID="ID_941913456" CREATED="1425492130071" MODIFIED="1425492135387">
<node ID="ID_993005912" CREATED="1425492152287" MODIFIED="1425492273346" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
which <font color="#ff0000">stage</font>&#160;is open, which <font color="#ff0000">deck</font>&#160;active and which <font color="#ff0000">layer</font>&#160; is on. you can also adjust this per mouse click.
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="Monitors" ID="ID_169098805" CREATED="1424538476932" MODIFIED="1424545227930" BACKGROUND_COLOR="#c9ebff">
<font BOLD="true"/>
<node ID="ID_1028303235" CREATED="1421869132696" MODIFIED="1424543504244" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
part of the screen flexible in size. shows all <font color="#ff0000">active</font>&#160;&#160;media.
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="screens" ID="ID_882314282" CREATED="1427133734376" MODIFIED="1427133738660">
<node TEXT="screen #1 (entrance)" ID="ID_273506288" CREATED="1427133153442" MODIFIED="1427133767141">
<node TEXT="background tasks" ID="ID_439609503" CREATED="1425491207680" MODIFIED="1425491213220"/>
<node TEXT="system set-up" ID="ID_436437505" CREATED="1424550898115" MODIFIED="1425491350051">
<node TEXT="all settings" ID="ID_1546835283" CREATED="1424551354023" MODIFIED="1424551897351">
<node TEXT="all configurations summary page" ID="ID_1123100252" CREATED="1424551784043" MODIFIED="1424551805558"/>
<node TEXT="user settings" ID="ID_232216436" CREATED="1424551388774" MODIFIED="1424551397482">
<node TEXT="manage stages" ID="ID_438538782" CREATED="1424545942126" MODIFIED="1424559886387">
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="40" DASH="3 3" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1010179755" STARTINCLINATION="206;0;" ENDINCLINATION="206;0;" STARTARROW="DEFAULT" ENDARROW="NONE"/>
</node>
</node>
<node TEXT="project settings" ID="ID_850353925" CREATED="1424551856033" MODIFIED="1424551863789">
<node TEXT="manage stages" ID="ID_484864958" CREATED="1424545942126" MODIFIED="1424559877487">
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="40" DASH="3 3" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1010179755" STARTINCLINATION="183;0;" ENDINCLINATION="183;0;" STARTARROW="DEFAULT" ENDARROW="NONE"/>
</node>
</node>
<node TEXT="commands setting" ID="ID_1570765503" CREATED="1424552395634" MODIFIED="1424552404270"/>
</node>
<node TEXT="system set-up physical location A" ID="ID_1134489156" CREATED="1424549822335" MODIFIED="1425491384221">
<node ID="ID_1951575539" CREATED="1424549843366" MODIFIED="1424562277752" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
users have their own <font color="#ff0000">settings</font>, they can overrule <font color="#ff0000">system set-up</font>'s and vice versa. it have to be clearly displyed whose <font color="#ff0000">settings</font>&#160;are the actual active ones.
</p>
<p>
</p>
<p>
<font color="#ff0000">set-up'</font>s are devided by <font color="#ff0000">locations</font>, the system should automatically add a new <font color="#ff0000">set-up</font>&#160;when other displays are connected. you can set it also to not switch and just ignore different hardware
</p>
<p>
</p>
<p>
how audio plays back..
</p>
<p>
the clips and all the media have a <font color="#ff0000">position in 3D space</font>, when it comes to playing here int the <font color="#ff0000">set-up</font>&#160;it is choosen how it mixes to the specific hardware
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
<node TEXT="hardware" ID="ID_1481095521" CREATED="1424550893892" MODIFIED="1424550896574">
<node TEXT="monitors" ID="ID_344403385" CREATED="1424550814869" MODIFIED="1424550820536"/>
<node TEXT="input devices" ID="ID_271294297" CREATED="1424548949046" MODIFIED="1424548966881">
<node ID="ID_1839031989" CREATED="1424548984901" MODIFIED="1424549225647" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
(most of the time) invisible
</p>
<p>
to translate human moves or a serie of moves into '<font color="#ff0000">gestures</font>'. depending an what is active on the '<font color="#ff0000">ground layer</font>' this will performe modification on the '<font color="#ff0000">material</font>'
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
<node TEXT="gestures" ID="ID_90605865" CREATED="1424549230463" MODIFIED="1424549237170"/>
<node TEXT="menue and meta data control" ID="ID_1185962130" CREATED="1424549237830" MODIFIED="1424549365763">
<node TEXT="cursor controll on a 2d surface" ID="ID_1273301047" CREATED="1424549299381" MODIFIED="1424549302432"/>
<node TEXT="going through a menue in a linear way, a chain of subpoints" ID="ID_56058976" CREATED="1424549303701" MODIFIED="1424549354167"/>
</node>
</node>
<node TEXT="output devices/ interfaces" ID="ID_404832506" CREATED="1424550821236" MODIFIED="1424550848247"/>
<node TEXT="disk control" ID="ID_995914206" CREATED="1424550849004" MODIFIED="1424550861303"/>
<node TEXT="manage stages" ID="ID_1010179755" CREATED="1424545942126" MODIFIED="1424545946082"/>
</node>
</node>
<node TEXT="system set-up physical location XY" ID="ID_769065294" CREATED="1424559383809" MODIFIED="1425491389873"/>
</node>
<node TEXT="users" ID="ID_1685488414" CREATED="1424549774217" MODIFIED="1427134110222" BACKGROUND_COLOR="#b7e7ff">
<node TEXT="(linkto: user settings in &apos;set-up&apos;)" ID="ID_163709331" CREATED="1424549944596" MODIFIED="1427133915947"/>
<node TEXT="select one user" ID="ID_822583798" CREATED="1427133512038" MODIFIED="1427133515857"/>
</node>
<node TEXT="projects" ID="ID_377209301" CREATED="1424550024193" MODIFIED="1427134110218" BACKGROUND_COLOR="#b7e7ff">
<node TEXT="locations in host system file structure" ID="ID_1725583550" CREATED="1424550032634" MODIFIED="1424550079844"/>
<node TEXT="select/ create one project" ID="ID_639407254" CREATED="1427133522485" MODIFIED="1427133535440"/>
<node TEXT="project settings" ID="ID_1846219353" CREATED="1427133543398" MODIFIED="1427133656574"/>
</node>
<node TEXT="button: first run/ expert" ID="ID_236205142" CREATED="1427133963875" MODIFIED="1427134110224" BACKGROUND_COLOR="#b7e7ff"/>
</node>
<node TEXT="screen #2 (media and project management)" ID="ID_89437962" CREATED="1427133404183" MODIFIED="1427133771651">
<node TEXT="RAW importer (open cine)" ID="ID_1655373824" CREATED="1427135813095" MODIFIED="1427135825846"/>
<node TEXT="Media Manager (source)" ID="ID_1350811385" CREATED="1421688933520" MODIFIED="1421877281459">
<edge STYLE="sharp_bezier" COLOR="#3399ff" WIDTH="8"/>
</node>
<node TEXT="Project Organizer" ID="ID_1355866027" CREATED="1421688988255" MODIFIED="1424552709945" BACKGROUND_COLOR="#c9ebff">
<font BOLD="true"/>
<node ID="ID_1309625965" CREATED="1421693452494" MODIFIED="1424545013325" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
automatic or manual group <font color="#ff0000">objects</font>&#160;with a few different render options for the <font color="#ff0000">groups/bins</font>. bins are universal <font color="#ff0000">objects</font>&#160;which can transform to finished <font color="#ff0000">timelines</font>&#160;and can be viewed in all the '<font color="#ff0000">Views</font>' provided in the '<font color="#ff0000">Editor</font>' <font color="#ff0000">stage</font>. '<font color="#ff0000">Views</font>' are <font color="#ff0000">sub stages</font>.
</p>
<p>
In '<font color="#ff0000">Project Organizer'</font>&#160;you have to define <font color="#ff0000">settings</font>&#160;for each <font color="#ff0000">project</font>&#160;such as how many <font color="#ff0000">sub-stages</font>&#160;you will see, which hardware interfaces, how detailed options you want to see when exporting,... there should be some <font color="#ff0000">pre-configured scenarios</font>&#160;five or so which covers all your needs. one of them should be '<font color="#ff0000">easy setup</font>' for beginners, online production,... and pro users can make their own.
</p>
<p>
this <font color="#ff0000">settings</font>&#160;can be easily modified during the editing process but the aim is to have as less things around as possible.
</p>
<p>
maybe it's good to select a <font color="#ff0000">user</font>&#160;here so that every project can include one ore more <font color="#ff0000">users</font>&#160;and they can have their <font color="#ff0000">configurations</font>&#160; (environment).
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
</node>
<node TEXT="screen #3 (stage)" ID="ID_985340493" CREATED="1427135656363" MODIFIED="1427135675766">
<node TEXT="Deck B" ID="ID_159099011" CREATED="1424538460669" MODIFIED="1424550638176" BACKGROUND_COLOR="#c9ebff">
<font BOLD="false"/>
<node TEXT="same subpoints as A. &apos;Deck B&apos; is not visible by default to provide a simple first experience for new users." ID="ID_210143166" CREATED="1424543017772" MODIFIED="1424543225828" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
<node TEXT="a second deck which is situated left from A. The user can swich between A and B totally or show them in differen proportion. You can use one as in other NLE&apos;s to view the source media and the other for a sequence or have two parts of the same sequence open for comparison or easy coping clips around.&#xa;there is always one deck/ viewer active so that our navigation input by any interface always adresses one.&#xa;&#xa;Deck B has two different loads, the manual loaded material and a second temporarely show clip board with clip history. at the moment i don&apos;t know how and when to switch between this two. there have to be something like a &apos;clear&apos; button which get rid of the clipboard content." ID="ID_1788168808" CREATED="1421869204062" MODIFIED="1428008682966" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="Deck A" ID="ID_1199676605" CREATED="1424538435622" MODIFIED="1424545234000" BACKGROUND_COLOR="#c9ebff">
<font BOLD="true"/>
<node TEXT="dummy substage" ID="ID_1095221684" CREATED="1424548758939" MODIFIED="1424548774863">
<node ID="ID_1883657315" CREATED="1421834595396" MODIFIED="1427209377979" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<icon BUILTIN="info"/>
<icon BUILTIN="pencil"/>
<richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
all the<font color="#ff0000">&#160;stages</font>&#160;should be available in a mouse/touch and keyboard/'lumiera hardware interface' only version. so that there are different environments without compromises
</p>
<p>
</p>
<p>
every <font color="#ff0000">user</font>&#160;should have the possibility to show only his/her most important <font color="#ff0000">stages</font>.
</p>
<p>
</p>
<p>
<font color="#ff0000">stages</font>&#160;can have many view options, this are the '<font color="#ff0000">views</font>'. views are pre-configured by the system <font color="#ff0000">set-up</font>&#160;or by the <font color="#ff0000">user</font>. for example: show waveform, detailed zoom, ..
</p>
<p>
every view should be as intuitive and clear as possible. this small fragments of the system should really try to do 'one thing at a time'. it should allow an emotional link to what is going on.
</p>
<p>
</p>
<p>
there should be the possibility to <font color="#ff0000">save/mark/create 'subviews'</font>&#160;&#160;or '<font color="#ff0000">presentation state</font>' which stores specific position, selections, active commands, active clips, small details.. during one working scession to come by another time. this can be called '<font color="#ff0000">worksite</font>' (idea by hermann).
</p>
<p>
another thing inside <font color="#ff0000">views</font>&#160;are '<font color="#ff0000">commands</font>' which are the modifying tools. they are also '<font color="#ff0000">subviews</font>' with some minor graphical changes to the actual <font color="#ff0000">view</font>&#160;to show that the <font color="#ff0000">command</font>&#160;is on and to let you intuetivly know what to modify. the command is performed by '<font color="#ff0000">gestures</font>' this are a set of human inputs through various devices (<font color="#ff0000">input devices</font>). <font color="#ff0000">gestures</font>&#160;define how the <font color="#ff0000">command</font>&#160; is performed.
</p>
<p>
and for some <font color="#ff0000">views</font>&#160;in some <font color="#ff0000">substages</font>&#160;e.g. in the '<font color="#ff0000">title text tool</font>' there can be the possibility to save <font color="#ff0000">templates</font>&#160;as one possible <font color="#ff0000">subview</font>. so that the user can manage to be very efficient when he/she has a repitative task by setting presets and hiding features.
</p>
<p>
</p>
<p>
also note that a change of input device (mouse to keyboard or 'lumiera interface') should happen when you switch between views, and stages only! for continuety in the workflow.
</p>
<p>
</p>
<p>
why the '<font color="#ff0000">screens</font>' and '<font color="#ff0000">stages</font>' together are such a long list: <b>A</b>. to have less buttons and distracting things around when you want to focus on one task. (one thing at a time vs. multitasking and windows) <b>B</b>. because the main input tool should be a wheel which makes it easy to switch around in a linear way (thats what we have to do anyways while editing movies)
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" BOLD="false" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
<node TEXT="view" ID="ID_401678398" CREATED="1424548805785" MODIFIED="1424548812805">
<node TEXT="subviews" ID="ID_602492544" CREATED="1424548813353" MODIFIED="1424560342324">
<node TEXT="command" ID="ID_456573634" CREATED="1424548828842" MODIFIED="1424548832141"/>
<node TEXT="worksite" ID="ID_888035005" CREATED="1424548832658" MODIFIED="1424548835229"/>
<node TEXT="templates" ID="ID_566682118" CREATED="1424561571873" MODIFIED="1424561575339"/>
</node>
</node>
</node>
<node TEXT="folder/file structure" ID="ID_1044571034" CREATED="1427135870662" MODIFIED="1427136542050" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="watch, mark, tag" ID="ID_813068038" CREATED="1421693200606" MODIFIED="1424560485096" BACKGROUND_COLOR="#c9ebff">
<node ID="ID_1478131109" CREATED="1421693353769" MODIFIED="1424560418554" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
magazine (newspaper) view, where you can explore your shooting. with description and tagging clips inside this <font color="#ff0000">bin/sequence/group </font>
</p>
<p>
or have jsut one <font color="#ff0000">clip</font>&#160;open
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="arrange, set relations between objects" ID="ID_35799295" CREATED="1421693288323" MODIFIED="1427210863422" BACKGROUND_COLOR="#c9ebff">
<node ID="ID_251653884" CREATED="1421833724647" MODIFIED="1424560255068" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
Loose arrangement and clip connecting in 2D space. object based montage.
</p>
<p>
'<font color="#ff0000">Relation Spyder</font>' tool which sets the relations throught a static wall of clips, this produces a fexible line which is/become a new object (sequence) --&gt; define time as a flexible line object
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="quick arrange editor" ID="ID_1712184626" CREATED="1421693293897" MODIFIED="1424560522767" BACKGROUND_COLOR="#c9ebff">
<node TEXT="arrange clips according to the &apos;time ray&apos; or line, so now the time goes continually forward " ID="ID_1791626974" CREATED="1421833865857" MODIFIED="1424546603557" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="precision editor" ID="ID_440912401" CREATED="1421693300930" MODIFIED="1424560554398" BACKGROUND_COLOR="#c9ebff">
<node TEXT="in a track based linear manner (very classical)" ID="ID_1081334440" CREATED="1421834029165" MODIFIED="1424546742689" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
<node ID="ID_653643155" CREATED="1423697628289" MODIFIED="1424548709712" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
<font color="#ff0000">subview/command</font>: Trim
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
<node ID="ID_1059757556" CREATED="1423697642450" MODIFIED="1424548737117" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
<font color="#ff0000">subview/command</font>: Slip/Slide
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
</node>
<node TEXT="Video D" ID="ID_64799033" CREATED="1421693297131" MODIFIED="1424544629272" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="Effects" ID="ID_1784867392" CREATED="1421836863882" MODIFIED="1424544629326" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="Audio" ID="ID_1789129602" CREATED="1421693239244" MODIFIED="1424544629333" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="title text tool" ID="ID_1019385943" CREATED="1421836883496" MODIFIED="1424560721562" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="subtitle" ID="ID_1750288910" CREATED="1424560666128" MODIFIED="1424560682535" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="Color grading" ID="ID_1384014116" CREATED="1421693243796" MODIFIED="1424544629346" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="Video F" ID="ID_170073817" CREATED="1421693304747" MODIFIED="1424544629296" BACKGROUND_COLOR="#c9ebff">
<node TEXT="flow chart, nodes, meta organizer" ID="ID_1897507803" CREATED="1421836743045" MODIFIED="1424546603550" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
<node TEXT="its possible to create relations between objects e.g. Master-Slave for undertitle positions, effects, clip X on a specific point in time is linked to clip Y on a specific point in time, clip Z is linked to a &apos;track&apos; object on time 0,0 (which is a normal track based timline);&#xa;..........." ID="ID_724972898" CREATED="1421877384276" MODIFIED="1424546663727" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
</node>
<node TEXT="storyboard" ID="ID_1504447149" CREATED="1421693316538" MODIFIED="1424560660891" BACKGROUND_COLOR="#c9ebff">
<node TEXT="storyboard (stills)" ID="ID_570194982" CREATED="1421837217853" MODIFIED="1424546603545" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="skript editor" ID="ID_1167933863" CREATED="1424548590856" MODIFIED="1424548633249" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="(VFX external)" ID="ID_994646344" CREATED="1421693248963" MODIFIED="1425490435306">
<edge COLOR="#009999"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#00cacc" WIDTH="2" TRANSPARENCY="20" DASH="2 7" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_1382218680" STARTINCLINATION="-282;0;" ENDINCLINATION="89;0;" STARTARROW="DEFAULT" ENDARROW="DEFAULT"/>
</node>
<node TEXT="(Audio external)" ID="ID_139552117" CREATED="1421833310388" MODIFIED="1424543923924">
<edge COLOR="#009999"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#00cacc" WIDTH="2" TRANSPARENCY="80" DASH="2 7" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_981858212" STARTINCLINATION="-139;17;" ENDINCLINATION="49;-109;" STARTARROW="DEFAULT" ENDARROW="DEFAULT"/>
</node>
<node TEXT="(Color grading external)" ID="ID_1170018192" CREATED="1421833355530" MODIFIED="1424561892851">
<edge COLOR="#009999"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#00cacc" WIDTH="2" TRANSPARENCY="20" DASH="2 7" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_21270584" STARTINCLINATION="-100;-115;" ENDINCLINATION="63;144;" STARTARROW="DEFAULT" ENDARROW="DEFAULT"/>
</node>
<node TEXT="presentation mode" ID="ID_1954213973" CREATED="1422010227433" MODIFIED="1424544629317" BACKGROUND_COLOR="#c9ebff"/>
<node ID="ID_278613962" CREATED="1424545342206" MODIFIED="1427136482358" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
playhead
</p>
<p>
This is for time based views only. Each deck have one playhead. Playheads are static in the middle of the viewer and the media is transported through. (so we don't have the situation that the playhead is moving through the window and the timeline have to jump afterwards.)
</p>
<p>
</p>
<p>
curtains
</p>
<p>
each <font color="#ff0000">sub-stage</font>&#160;can offer up to three different levels of details. form very simplistic to all&#160;&#160;information available. like curtains on a stage and each one opens more depth showing more of the stage.
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="layers (supervisor view?)" ID="ID_1734175285" CREATED="1427136034562" MODIFIED="1427136124578">
<node TEXT="configuration" ID="ID_1371867622" CREATED="1424538638924" MODIFIED="1424558657595">
<arrowlink SHAPE="LINE" COLOR="#b981d5" WIDTH="9" TRANSPARENCY="40" DASH="2 7" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_436437505" STARTINCLINATION="390;0;" ENDINCLINATION="-94;125;" STARTARROW="NONE" ENDARROW="NONE"/>
<node ID="ID_740976869" CREATED="1421869758888" MODIFIED="1424546349238" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
<font color="#ff0000">configuration</font>&#160;as a <font color="#ff0000">layer</font>&#160;should show only <font color="#ff0000">options</font>&#160; which are relevant to what we see now, underneath this <font color="#ff0000">layer</font>. so to say every <font color="#ff0000">stage</font>, <font color="#ff0000">view</font>, ... have their own <font color="#ff0000">meta page</font>&#160;where all the <font color="#ff0000">options</font>&#160;are stored. also if some <font color="#ff0000">options</font>&#160;are relative or overruled by more general <font color="#ff0000">configurations</font>&#160;or the <font color="#ff0000">system set-up</font>, it is shown here and greyed out
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="info and metainfo" ID="ID_1319186312" CREATED="1424538693567" MODIFIED="1424538719699">
<node ID="ID_693210573" CREATED="1421869573267" MODIFIED="1424546412639" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
this layer puts detailed information over everything actual on the screen and should act as a quick lookup. there can also be <font color="#ff0000">git-tickets</font>&#160; on the <font color="#ff0000">elements</font>&#160;for easy <font color="#ff0000">user-feedback</font>.
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="community help" ID="ID_665638406" CREATED="1424539495593" MODIFIED="1424539505128"/>
<node TEXT="feedback, report, discuss" ID="ID_1371256061" CREATED="1424539506560" MODIFIED="1425398140870"/>
</node>
<node TEXT="Working Environments" ID="ID_1243081809" CREATED="1424539420339" MODIFIED="1424543225835" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="screen #4 (export)" ID="ID_590390406" CREATED="1427136607861" MODIFIED="1427136623823">
<node TEXT="Export/Delivery" ID="ID_1335679422" CREATED="1421691750314" MODIFIED="1424560857471" BACKGROUND_COLOR="#c9ebff">
<node TEXT="disk authoring" ID="ID_383021832" CREATED="1424560797348" MODIFIED="1424560823065" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="DCP authoring" ID="ID_1039511040" CREATED="1424560811419" MODIFIED="1424560823058" BACKGROUND_COLOR="#c9ebff"/>
<node TEXT="online upload" ID="ID_112117702" CREATED="1427138051155" MODIFIED="1427138058470"/>
<node TEXT="file export" ID="ID_955811778" CREATED="1427138061754" MODIFIED="1427138064677"/>
<node TEXT="archive" ID="ID_854916224" CREATED="1427138067002" MODIFIED="1427138070413"/>
</node>
</node>
</node>
<node TEXT="commands" ID="ID_524039080" CREATED="1424552344268" MODIFIED="1424552347816">
<node TEXT="toggle" ID="ID_1134625982" CREATED="1424553233277" MODIFIED="1424553482663">
<node ID="ID_1248307175" CREATED="1424553483662" MODIFIED="1424553500640" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
&#160;between two or more <font color="#ff0000">options</font>
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="function" ID="ID_954374090" CREATED="1424553284835" MODIFIED="1424553305670">
<node ID="ID_936013660" CREATED="1424553318698" MODIFIED="1424553386274" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
one time <font color="#ff0000">action</font>
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="tool" ID="ID_998579174" CREATED="1424553309530" MODIFIED="1424553315206">
<node ID="ID_1358609391" CREATED="1424553333425" MODIFIED="1424553378344" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
have a subset of <font color="#ff0000">functions</font>&#160;which are controlled by '<font color="#ff0000">gestures</font>'
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node ID="ID_483591724" CREATED="1424553724323" MODIFIED="1424554236699" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
to use with <font color="#ff0000">mouse</font>: since we have no buttons in this concept all the available commands (case sensitive) will be shown e.g. on right button click. then there is a graphical representation of each command arround the mouse in circles and sorted by topic. some <font color="#ff0000">modulation keys</font>&#160;are available to.
</p>
<p>
it would be great if that could evolve to a standard in all open source creative media applications so that's easy to switch over to a application which you use seldom and start right away. a kind of a fallback or standarized interface. not the functions have to be the same but how they are arranged and how they are accesd and maybe how they are performed (gestures).
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="gestures" ID="ID_1346965909" CREATED="1424553547844" MODIFIED="1424553551833">
<node TEXT="for mouse+keyboard" ID="ID_1939982340" CREATED="1424553567484" MODIFIED="1424553580375"/>
<node TEXT="for keyboard only" ID="ID_82059654" CREATED="1424553582475" MODIFIED="1424553589199"/>
<node TEXT="for graphic pen + modulations keys" ID="ID_1171750706" CREATED="1424553590419" MODIFIED="1424553610214"/>
<node TEXT="for lumiera &apos;console&apos;" ID="ID_1162501041" CREATED="1424553611163" MODIFIED="1424553622558">
<node TEXT="i am planning to make a hardware interface optimized for this concept and somehow usable for other nle&apos;s" ID="ID_1912685880" CREATED="1424554265505" MODIFIED="1424554327543" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node ID="ID_1462754876" CREATED="1424554355807" MODIFIED="1424555101898" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0"><richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
?? not really a serious idea
</p>
<p>
</p>
<p>
kind of gestures:
</p>
<p>
</p>
<p>
<font color="#ff0000">cut </font>
</p>
<p>
</p>
<p>
<font color="#ff0000">modify edits </font>
</p>
<p>
<font color="#000000">drag </font>
</p>
<p>
<font color="#000000">*affecting the overall length (splice in, ripple) </font>
</p>
<p>
<font color="#000000">*overwriting</font>
</p>
<p>
</p>
<p>
<font color="#ff0000">take</font>
</p>
<p>
*affecting the overall length (splice in, ripple)
</p>
<p>
*overwriting
</p>
<p>
</p>
<p>
<font color="#ff0000">place</font>
</p>
<p>
*affecting the overall length (splice in, ripple)
</p>
<p>
*overwriting
</p>
<p>
</p>
<p>
<font color="#ff0000">handle clips</font>
</p>
<p>
move
</p>
<p>
slip/slide
</p>
<p>
</p>
<p>
</p>
<p>
<font color="#ff0000">change the view and stage</font>&#160;(program navigation)
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
</node>
<node TEXT="Lumiera Automation" ID="ID_398881700" CREATED="1424544334552" MODIFIED="1424544552600" BACKGROUND_COLOR="#c9ebff">
<font NAME="SansSerif" SIZE="12" BOLD="false"/>
<edge STYLE="sharp_bezier" COLOR="#6699ff" WIDTH="4"/>
<node TEXT="pro users can config their own funktion set to do some steps of processing within the OS file browser or in the &apos;workboards&apos;. e.g. process footage for import, archive footage, archive projects, make online version of an project (this only works if the sequences are available as singular files)" ID="ID_1447355109" CREATED="1424544363160" MODIFIED="1424544537727" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
<node TEXT="Color grading tool" ID="ID_21270584" CREATED="1421833449694" MODIFIED="1424561913571">
<linktarget COLOR="#b0b0b0" DESTINATION="ID_21270584" ENDARROW="Default" ENDINCLINATION="63;144;" ID="Arrow_ID_299541508" SOURCE="ID_1170018192" STARTARROW="Default" STARTINCLINATION="-100;-115;"/>
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="40" DASH="2 7" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_957022120" STARTINCLINATION="-73;-21;" ENDINCLINATION="-199;116;" STARTARROW="NONE" ENDARROW="NONE"/>
</node>
<node TEXT="Audio tool" ID="ID_981858212" CREATED="1421833473622" MODIFIED="1421833665013">
<linktarget COLOR="#b0b0b0" DESTINATION="ID_981858212" ENDARROW="Default" ENDINCLINATION="49;-109;" ID="Arrow_ID_1916075795" SOURCE="ID_139552117" STARTARROW="Default" STARTINCLINATION="-139;17;"/>
</node>
<node TEXT="VFX tool" ID="ID_1382218680" CREATED="1421833506781" MODIFIED="1421833631238">
<linktarget COLOR="#b0b0b0" DESTINATION="ID_1382218680" ENDARROW="Default" ENDINCLINATION="89;0;" ID="Arrow_ID_1748651927" SOURCE="ID_994646344" STARTARROW="Default" STARTINCLINATION="-282;0;"/>
</node>
</node>
<node POSITION="right" ID="ID_1132874300" CREATED="1423698898394" MODIFIED="1425491152491" COLOR="#333333" BACKGROUND_COLOR="#f0f0f0">
<icon BUILTIN="info"/>
<icon BUILTIN="pencil"/>
<richcontent TYPE="NODE">
<html>
<head>
</head>
<body>
<p>
however the relation to the OS looks like, at some point it will be interesting how we can trip arrount between lumiera and other software. so the interaction i think should be very well implemented in the concept.
</p>
<p>
here i suggest '<font color="#ff0000">workboards</font>' which contain project files on a 2d space like a desktop and a clipboard to hand them from one program to anoter. files can also be grouped freely or by software they belong to. there can be some alternative views like in a magazine view. they contain a whole project. you can open them in lumiera (see: stage/project organizer) or as a stand alone full screen app. in case of 'elementaryOS' as a host system there are options like 'D-bus' or 'contractor' which can be used i guess.
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10" ITALIC="true"/>
<edge COLOR="#ff9999"/>
</node>
</node>
</map>