sync with Lumiera master

This commit is contained in:
Fischlurch 2011-02-13 20:32:26 +01:00
commit 0983ba8db8
63 changed files with 536 additions and 171 deletions

View file

@ -316,7 +316,7 @@ function change_state()
local state="$2"
local nl=$'\n'
local comment="$state$nl//add reason$nl $(date +%c) $(git config --get user.name) <$(git config --get user.email)>$nl"
local comment=".State -> $state$nl//add reason$nl $(date +%c) $(git config --get user.name) <$(git config --get user.email)>$nl"
edit_state "$name" "$state" "$comment"
edit "$name" -4 "endof_comments"
process "$name"

View file

@ -0,0 +1,225 @@
ApplicationInstall
==================
// please don't remove the //word: comments
[grid="all"]
`------------`-----------------------
*State* _Draft_
*Date* _Di 11 Jan 2011 17:00:55 CET_
*Proposed by* Ichthyostega <prg@ichthyostega.de>
-------------------------------------
[abstract]
*********************************************************************************
Lumiera should be a _freely relocatable_ application bundle.
Relying only on the relative folder structure within this bundle, the application
will be fully functional at any location, provided that the external library
dependencies are resolvable using the standard mechanisms of the platform.
The setup mechanism must be obvious, self-explanatory and must not rely
on compiled in magic or buildsystem trickery. Yet packaging into a FSH conforming
installation location should be supported by the same mechanisms.
*********************************************************************************
Description
-----------
//description: add a detailed description:
Lumiera is planned to become a large professional application bundle, relying
on several external resources for proper operation. An installed Lumiera
application will be more like Gimp, Blender, OpenOffice or Eclipse,
not like bash, autotools or emcas.
Besides that, it can be expected that Lumiera frequently will be used in a
project or studio like setup, where the application isn't installed, but just
unZIPped / unTARed and used as-is. Thus, it should be sufficient to unpack
the application bundle and point it to the session file and maybe the
media storage.
The Eclipse platform can serve as a model for the setup of an modern
application of that style: It can be just unpacked, and when looking
into the folder structure, the meaning of the parts is obvious, and the
basic bootstrap is controlled by two short text based INI files.
While Lumiera presumably won't get _that_ heavyweight and is clearly
not intended to become a general business application platform like OSGi --
the underlying principles can serve as a point of reference for modern
development standards.
This leads to the following conclusions:
- we need to define a standard folder layout for the bundle
- the application must not rely on any compiled-in absolute paths
- the executable should fetch the directly accompanying shared modules
- all other lib dependencies should be handled by the system mechanisms
- the bootstrap configuration likewise must not be compiled-in
- this configuration must be human readable and clearly exhibit its purpose
- the same system must be able to adapt to a FSH conforming installation layout
Judging from our current planning and the existing codebase, Lumiera
is on a good way in that direction, yet some cleanup needs to be done,
especially removing convenience shortcuts from the early days of development
and catching up with the repair of some traits of sloppyness here and there.
Library resolution
~~~~~~~~~~~~~~~~~~
In former days, it was common habit to compile-in a hard wired absolute
+RPATH+. This can be considered obsolete practice; for example, the Debian
policy forbids doing so. This is the result from numerous maintainability
problems in the past. On the other hand, the GNU linker and other modern
linkers support a relative resolution of shared modules directly accompanying
an specific executable. The Debian policy allows this, if and only if these
shared modules are installed with the same binary package and only used by
this specific executable(s). Together, this is exactly what we need to
solve our requirement.
Thus, the build process enables the new-style DT-tags in the Elf binary
and sets the +DT_RUNPATH+ with an value relative to +$ORIGIN+, which resolves
to the path of the currently executing binary. Moreover, it is _sufficient_
to set this on the initial executable _only,_ because this creates a common
searchpath for all lib resolution events in the scope of that loaded executable.
Besides that, we need to care that our private libraries have a unique +SONAME+,
in this case all starting with the prefix +liblumiera*+. Note moreover that this
new-style +DT_RUNPATH+ indeed _can_ be overridden by an +LD_LIBRARY_PATH+ in the
environment, should there be the need for very special experiments.
Bootstrap location
~~~~~~~~~~~~~~~~~~
Thus, a single relative library folder becomes the only hard wired start
configuration. In our case, the folder +$ORIGIN/modules+ was chosen. The
root of the package then holds all the binaries depending on these common
internal libraries, that is the +lumiera+ executable and any accompanying
special tools. As usual with such large application bundles, these get
only _symlinked_ into the +/usr/bin+ folder on installation.
For sake of clarity, after starting the executable, the _same location_
is used to load the bootstrap configuration. This configuration in turn
defines all further locations like the extended configuration, project
templates, plugin search path, the GUI module to load, the search path
for icons and GUI resources, project templates and similar basics.
Relative paths and the location of the executable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
According to the general requirements outlined above, most paths should
be given in a relative fashion. Unfortunately there is no portable solution
for self-discovering the currently running executable. But at least there
is a solution for all current major platforms. Under Linux, this information
can be retrieved from the kernel through the +/proc+ filesystem.
Again for sake of clarity, the same token +$ORIGIN+ was chosen to denote
this executable location (note: this is _not_ the current working directory).
Moreover, due to the folder layout detailed above, this coincides with the
root of the application bundle, thus making for a self-explanatory convention.
Besides +$ORIGIN+, these search paths later on likely will contain locations
below the user's home directory, e.g. +~/.lumiera/themes+
Tasks
~~~~~
// List what needs to be done to implement this Proposal:
* identify what impedes such a modern setup procedure ([green]#✔ done#)
* rectify the folder structure created in the build target
directory ([green]#✔ done#)
* build the executables in a way to allow relative resolution of the
internal shared modules ([green]#✔ done#)
* replace the compiled-in path definitions for plugin loading by a
configurable bootstrap ([green]#✔#)
* add an working library implementation for a config loader ([green]#✔ done#)
* add a mechanism for establishing the path of the current execubable. +
This is _non-portable_ ([green]#✔ done#)
* wire the prepared API in the GUI to use this working config loader
for resolving GUI resources ([green]#✔ done#)
* try to extract the path search code from the existing config loader,
or build a new solution based on standard libraries ([green]#✔ done#)
* introduce an output root directory into the buildsystem, allowing
for package builds ([green]#✔#)
* define a _Debian packaging_ as proof-of-concept ([green]#✔ done#)
Discussion
~~~~~~~~~~
Pros
^^^^
* self-contained
* self-explanatory
* based on _best practices_
* conforming with FSH and Debian policy
Cons
^^^^
* requires work
* raises the bar at the implementation side
* requires an bootstrap sequence to be explicitly performed
on application startup
* breaks with some beloved habits of the Unix community
Alternatives
^^^^^^^^^^^^
//alternatives: explain alternatives and tell why they are not viable:
I can think of two alternatives
. dealing with all those problems _later_
. not making an concept, rather sticking to UNIX habits
The first alternative is indeed worth considering, because we're settling
some things to be really implemented way later, which bears some dangers.
But, on the other hand, it is a common practice known from extreme programming
to deliver early and regularly, which effectively means to set up the deploy
path of an application really early in the development cycle. The rationale
is that -- according to general experience -- the deployment always turns
up some very specific problems and constraints, which can be a serious
threat when discovered late in the development process.
The second alternative isn't really applicable IMHO. The original UNIX philosophy
breeds on an academic setup and really excels with small nifty commandline utils
combined by pipes, each specialised to do a single thing very well. These utils
are more like the objects within our implementation. The concept of large
application software bundles and desktop software was always a bit alien
within the classic UNIX environment.
Rationale
---------
//rationale: Give a concise summary why it should be done *this* way:
This RfC can be seen as an commitment to an professional approach and as
clarification: Traditionally, the Unix community hailed a lot of _black magic_
practices like compiled-in installation paths, macro magic, +sed+ and +awk+
trickery, inline code compiled on-the-fly, relying on very specific and
un-obvious behaviour of some build script, configuration via environment
variables and a lot of similar idioms. These practices might be adequate
in a quickly moving Research & Development setup, but turned out to be
not so helpful when it comes to industrial strength development,
as they are known to lead to maintenance problems.
//Conclusion
//----------
//conclusion: When approbate (this proposal becomes a Final)
// write some conclusions about its process:
Comments
--------
//comments: append below
.State -> Draft
There is now a complete implementation of this concept on my ``proc'' branch. +
Moreover, I was able to define an initial Debian packaging for Lumiera on top
of that implementation.
During that work, I had opportunity to visit various areas of the existing codebase,
which reminded me of several small issues, which seem to become unhealthy when lying
around unfixed for such a long time. Probably I'll start a clean-up initiative and
try to bring these points to discussion separately.
So 13 Feb 2011 20:04:00 CET Ichthyostega <prg@ichthyostega.de>
//endof_comments:

View file

@ -20,7 +20,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "name-chooser.hpp"
#include "dialog.hpp"

View file

@ -27,7 +27,7 @@
#ifndef NAME_CHOOSER_H
#define NAME_CHOOSER_H
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace dialogs {

View file

@ -20,7 +20,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "preferences-dialog.hpp"
#include "dialog.hpp"

View file

@ -27,7 +27,7 @@
#ifndef PREFERENCES_DIALOG_HPP
#define PREFERENCES_DIALOG_HPP
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace dialogs {

View file

@ -20,7 +20,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "render.hpp"
#include "dialog.hpp"

View file

@ -27,7 +27,7 @@
#ifndef RENDER_HPP
#define RENDER_HPP
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace dialogs {

View file

@ -24,7 +24,7 @@
** represents a track, and wraps proc layer data
*/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#ifndef TRACK_HPP
#define TRACK_HPP

View file

@ -22,7 +22,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "displayer.hpp"
#include "xvdisplayer.hpp"
#include "gdkdisplayer.hpp"

View file

@ -22,7 +22,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include <gdk/gdkx.h>
#include <iostream>

View file

@ -22,7 +22,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include <gdk/gdkx.h>

View file

@ -20,7 +20,7 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "assets-panel.hpp"
namespace gui {

View file

@ -20,12 +20,14 @@
* *****************************************************/
#include "panel.hpp"
#include "../gtk-lumiera.hpp"
#include "../workspace/panel-manager.hpp"
#include "../workspace/workspace-window.hpp"
#include <gdl/gdl-dock-item-grip.h>
#include "gui/gtk-lumiera.hpp"
#include "gui/workspace/panel-manager.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "panel.hpp"
using namespace Gtk;
namespace gui {

View file

@ -27,10 +27,10 @@
#ifndef PANEL_HPP
#define PANEL_HPP
#include "../gtk-lumiera.hpp"
#include <gdl/gdl-dock-item.h>
#include "../widgets/panel-bar.hpp"
#include "gui/gtk-lumiera.hpp"
#include "gui/widgets/panel-bar.hpp"
namespace gui {

View file

@ -22,15 +22,15 @@
#include <boost/foreach.hpp>
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "timeline-panel.hpp"
#include "../workspace/workspace-window.hpp"
#include "../model/project.hpp"
#include "../controller/controller.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "gui/model/project.hpp"
#include "gui/controller/controller.hpp"
extern "C" {
#include "../../lib/time.h"
#include "lib/time.h"
}
using namespace Gtk;

View file

@ -27,8 +27,8 @@
#define TIMELINE_PANEL_HPP
#include "panel.hpp"
#include "../widgets/timecode-widget.hpp"
#include "../widgets/timeline-widget.hpp"
#include "gui/widgets/timecode-widget.hpp"
#include "gui/widgets/timeline-widget.hpp"
using namespace gui::widgets;

View file

@ -20,14 +20,14 @@
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "viewer-panel.hpp"
#include "../workspace/workspace-window.hpp"
#include "../controller/controller.hpp"
#include "../controller/playback-controller.hpp"
#include "gui/gtk-lumiera.hpp"
#include "gui/controller/controller.hpp"
#include "gui/controller/playback-controller.hpp"
#include "gui/display-service.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "viewer-panel.hpp"
using namespace Gtk;
using namespace gui::widgets;

View file

@ -29,7 +29,7 @@
#include <gtkmm.h>
#include "panel.hpp"
#include "../widgets/video-display-widget.hpp"
#include "gui/widgets/video-display-widget.hpp"
namespace gui {
namespace panels {

View file

@ -27,7 +27,7 @@
#ifndef RECTANGLE_HPP
#define RECTANGLE_HPP
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace util {

View file

@ -21,10 +21,10 @@
* *****************************************************/
#include "panel-bar.hpp"
#include "../workspace/workspace-window.hpp"
#include "../workspace/panel-manager.hpp"
#include "../panels/panel.hpp"
#include "../util/rectangle.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "gui/workspace/panel-manager.hpp"
#include "gui/panels/panel.hpp"
#include "gui/util/rectangle.hpp"
#include <nobug.h>
#include <algorithm>

View file

@ -31,7 +31,7 @@
#include <sigc++/bind.h>
#include "timecode-widget.hpp"
#include "../util/convert.hpp"
#include "gui/util/convert.hpp"
using namespace sigc;
using namespace Gtk;

View file

@ -37,7 +37,7 @@
#include "timeline/timeline-clip-track.hpp"
#include "timeline/timeline-layout-helper.hpp"
#include "../model/sequence.hpp"
#include "gui/model/sequence.hpp"
namespace gui {
namespace widgets {

View file

@ -24,9 +24,9 @@
#include <boost/foreach.hpp>
#include "timeline-body.hpp"
#include "../timeline-widget.hpp"
#include "../../window-manager.hpp"
#include "../../util/cairo-util.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/window-manager.hpp"
#include "gui/util/cairo-util.hpp"
#include "timeline-arrow-tool.hpp"
#include "timeline-ibeam-tool.hpp"

View file

@ -26,7 +26,7 @@
#ifndef TIMELINE_BODY_HPP
#define TIMELINE_BODY_HPP
#include "../../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "timeline-tool.hpp"
namespace gui {

View file

@ -31,7 +31,7 @@
#include <vector>
#include "timeline-track.hpp"
#include "../../model/clip-track.hpp"
#include "gui/model/clip-track.hpp"
namespace gui {
namespace widgets {

View file

@ -24,8 +24,8 @@
*/
#include "../../gtk-lumiera.hpp"
#include "../../model/clip.hpp"
#include "gui/gtk-lumiera.hpp"
#include "gui/model/clip.hpp"
#include "timeline-view-window.hpp"
#include "include/logging.h"

View file

@ -21,7 +21,7 @@
* *****************************************************/
#include "timeline-group-track.hpp"
#include "../timeline-widget.hpp"
#include "gui/widgets/timeline-widget.hpp"
using namespace Gtk;
using namespace boost;

View file

@ -27,7 +27,7 @@
#define TIMELINE_GROUP_TRACK_HPP
#include "timeline-track.hpp"
#include "../../model/group-track.hpp"
#include "gui/model/group-track.hpp"
namespace gui {
namespace widgets {

View file

@ -25,8 +25,8 @@
#include "timeline-header-container.hpp"
#include "timeline-track.hpp"
#include "../timeline-widget.hpp"
#include "../../util/rectangle.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/util/rectangle.hpp"
using namespace Gtk;
using namespace std;

View file

@ -28,7 +28,7 @@
#ifndef HEADER_CONTAINER_HPP
#define HEADER_CONTAINER_HPP
#include "../../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "timeline-layout-helper.hpp"
namespace gui {

View file

@ -23,8 +23,8 @@
#include <boost/foreach.hpp>
#include "../timeline-widget.hpp"
#include "../../util/rectangle.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/util/rectangle.hpp"
using namespace Gtk;
using namespace std;

View file

@ -27,7 +27,7 @@
#ifndef HEADER_WIDGET_HPP
#define HEADER_WIDGET_HPP
#include "../../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace widgets {

View file

@ -21,7 +21,7 @@
* *****************************************************/
#include "timeline-ibeam-tool.hpp"
#include "../timeline-widget.hpp"
#include "gui/widgets/timeline-widget.hpp"
using namespace boost;
using namespace gui::widgets;

View file

@ -24,9 +24,9 @@
#include <boost/foreach.hpp>
#include "timeline-layout-helper.hpp"
#include "../timeline-widget.hpp"
#include "../../model/sequence.hpp"
#include "../../util/rectangle.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/model/sequence.hpp"
#include "gui/util/rectangle.hpp"
using namespace Gtk;
using namespace std;

View file

@ -27,8 +27,8 @@
#ifndef TIMELINE_LAYOUT_HELPER_HPP
#define TIMELINE_LAYOUT_HELPER_HPP
#include "../../gtk-lumiera.hpp"
#include "../../../lib/tree.hpp"
#include "gui/gtk-lumiera.hpp"
#include "lib/tree.hpp"
namespace gui {

View file

@ -23,12 +23,12 @@
#include <cairomm-1.0/cairomm/cairomm.h>
#include "timeline-ruler.hpp"
#include "../timeline-widget.hpp"
#include "../../window-manager.hpp"
#include "../../util/cairo-util.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/window-manager.hpp"
#include "gui/util/cairo-util.hpp"
extern "C" {
#include "../../../lib/time.h"
#include "lib/time.h"
}
using namespace Gtk;

View file

@ -27,7 +27,7 @@
#ifndef TIMELINE_RULER_HPP
#define TIMELINE_RULER_HPP
#include "../../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace widgets {

View file

@ -21,7 +21,7 @@
* *****************************************************/
#include "timeline-tool.hpp"
#include "../timeline-widget.hpp"
#include "gui/widgets/timeline-widget.hpp"
using namespace Gdk;
using namespace boost;

View file

@ -27,7 +27,7 @@
#ifndef TIMELINE_TOOL_HPP
#define TIMELINE_TOOL_HPP
#include "../../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace widgets {

View file

@ -21,9 +21,9 @@
* *****************************************************/
#include "timeline-track.hpp"
#include "../timeline-widget.hpp"
#include "../../window-manager.hpp"
#include "../../dialogs/name-chooser.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/window-manager.hpp"
#include "gui/dialogs/name-chooser.hpp"
#include "include/logging.h"
using namespace boost;

View file

@ -23,11 +23,11 @@
** This file contains the definition of timeline track object
*/
#include "../../gtk-lumiera.hpp"
#include "../../model/track.hpp"
#include "../menu-button.hpp"
#include "../mini-button.hpp"
#include "../button-bar.hpp"
#include "gui/gtk-lumiera.hpp"
#include "gui/model/track.hpp"
#include "gui/widgets/menu-button.hpp"
#include "gui/widgets/mini-button.hpp"
#include "gui/widgets/button-bar.hpp"
#include "timeline-header-container.hpp"
#include "timeline-header-widget.hpp"

View file

@ -21,7 +21,7 @@
* *****************************************************/
#include "timeline-view-window.hpp"
#include "../timeline-widget.hpp"
#include "gui/widgets/timeline-widget.hpp"
using namespace Gtk;
using namespace gui::widgets;

View file

@ -27,7 +27,7 @@
#ifndef TIMELINE_VIEW_WINDOW_HPP
#define TIMELINE_VIEW_WINDOW_HPP
#include "../../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace widgets {

View file

@ -24,10 +24,9 @@
#include <gdkmm/general.h>
#include <cairomm-1.0/cairomm/cairomm.h>
#include "../gtk-lumiera.hpp"
#include "../output/xvdisplayer.hpp"
#include "../output/gdkdisplayer.hpp"
#include "gui/gtk-lumiera.hpp"
#include "gui/output/xvdisplayer.hpp"
#include "gui/output/gdkdisplayer.hpp"
#include "video-display-widget.hpp"

View file

@ -28,7 +28,7 @@
#include <gtkmm.h>
#include "../output/displayer.hpp"
#include "gui/output/displayer.hpp"
using namespace gui::output;

View file

@ -23,13 +23,13 @@
#include "actions.hpp"
#include "workspace-window.hpp"
#include "../window-manager.hpp"
#include "gui/window-manager.hpp"
#include "../dialogs/render.hpp"
#include "../dialogs/preferences-dialog.hpp"
#include "../dialogs/name-chooser.hpp"
#include "gui/dialogs/render.hpp"
#include "gui/dialogs/preferences-dialog.hpp"
#include "gui/dialogs/name-chooser.hpp"
#include "../model/project.hpp"
#include "gui/model/project.hpp"
#include "include/logging.h"

View file

@ -29,7 +29,7 @@
#ifndef ACTIONS_HPP
#define ACTIONS_HPP
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
namespace gui {
namespace workspace {

View file

@ -22,9 +22,9 @@
#include "panel-manager.hpp"
#include "../panels/assets-panel.hpp"
#include "../panels/viewer-panel.hpp"
#include "../panels/timeline-panel.hpp"
#include "gui/panels/assets-panel.hpp"
#include "gui/panels/viewer-panel.hpp"
#include "gui/panels/timeline-panel.hpp"
#include "include/logging.h"

View file

@ -31,7 +31,7 @@
#include <gdl/gdl.h>
#include <typeinfo>
#include "../panels/panel.hpp"
#include "gui/panels/panel.hpp"
using namespace gui::panels;

View file

@ -32,7 +32,7 @@
#include <gdl/gdl-dock-item.h>
#include <gdl/gdl-dock-placeholder.h>
#include "../gtk-lumiera.hpp"
#include "gui/gtk-lumiera.hpp"
#include "workspace-window.hpp"
#include "include/logging.h"

View file

@ -34,9 +34,9 @@
#include "actions.hpp"
#include "panel-manager.hpp"
#include "../panels/assets-panel.hpp"
#include "../panels/viewer-panel.hpp"
#include "../panels/timeline-panel.hpp"
#include "gui/panels/assets-panel.hpp"
#include "gui/panels/viewer-panel.hpp"
#include "gui/panels/timeline-panel.hpp"
using namespace gui::panels;

View file

@ -34,6 +34,16 @@ extern "C" {
using std::string;
namespace lib {
namespace time {
const Time Time::MAX ( TimeValue (+std::numeric_limits<gavl_time_t>::max()) );
const Time Time::MIN ( TimeValue (-std::numeric_limits<gavl_time_t>::max()) );
}} // namespace lib::Time
///////////////////////////////////////////////////////////////////////////TODO leftover of the existing/initial lumitime-Implementation
namespace lumiera {

View file

@ -24,6 +24,8 @@
#ifndef LIB_TIME_QUANTISER_H
#define LIB_TIME_QUANTISER_H
#include "lib/time/timevalue.hpp"
//#include <boost/operators.hpp>
#include <string>

View file

@ -24,6 +24,8 @@
#ifndef LIB_TIME_TIMECODE_H
#define LIB_TIME_TIMECODE_H
#include "lib/time/timevalue.hpp"
//#include <boost/operators.hpp>
#include <string>

View file

@ -36,33 +36,48 @@ extern "C" {
namespace lib {
namespace time {
using lumiera::Time;
/**
* fixed format time specification.
*
* @todo WIP-WIP-WIP
* basic constant internal time value.
* These time values provide the implementation base
* for all further time types. They can be created by
* wrapping up a raw micro tick value (gavl_time_t),
* are totally ordered, but besides that,
* they are opaque and non-mutable.
* @note clients should prefer to use Time instances,
* which explicitly denote an Lumiera internal
* time value and are easier to use.
* @see TimeVar when full arithmetics are required
*/
class TimeValue
: boost::totally_ordered<Time,
boost::totally_ordered<Time, gavl_time_t> >
: boost::totally_ordered<TimeValue,
boost::totally_ordered<TimeValue, gavl_time_t> >
{
protected:
/** the raw (internal) time value
* used to implement the time types */
gavl_time_t t_;
public:
static const Time MAX ;
static const Time MIN ;
/** Assigning of time values is not allowed,
* but derived classed might allow that */
TimeValue&
operator= (TimeValue const& o)
{
t_ = o.t_;
return *this;
}
public:
explicit
TimeValue (gavl_time_t val=0)
: t_(val)
{ }
// using standard copy operations
operator gavl_time_t () const { return t_; }
/** copy initialisation allowed */
TimeValue (TimeValue const& o)
: t_(o.t_)
{ }
// Supporting totally_ordered
friend bool operator< (TimeValue const& t1, TimeValue const& t2) { return t1.t_ < t2.t_; }
@ -73,48 +88,74 @@ namespace time {
};
/** a mutable time value,
* behaving like a plain number,
* allowing copy and re-accessing
*/
class TimeVar
: public TimeValue
, boost::additive<TimeVar>
, boost::additive<TimeVar,
boost::additive<TimeVar, TimeValue,
boost::multipliable<TimeVar, int>
> >
{
public:
TimeVar (TimeValue time)
TimeVar (TimeValue time = TimeValue())
: TimeValue(time)
{ }
// Allowing copy and assignment
TimeVar (TimeVar const& o)
: TimeValue(o)
{ }
TimeVar&
operator= (TimeValue const& o)
{
t_ = TimeVar(o);
return *this;
}
// Supporting mixing with plain long int arithmetics
operator gavl_time_t () const { return t_; }
// Supporting additive
TimeVar& operator+= (TimeVar const& tx) { t_ += tx.t_; return *this; }
TimeVar& operator-= (TimeVar const& tx) { t_ -= tx.t_; return *this; }
// Supporting multiplication with integral factor
TimeVar& operator*= (int64_t fact) { t_ *= fact; return *this; }
TimeVar& operator*= (int fact) { t_ *= fact; return *this; }
// baseclass TimeValue is already totally_ordered
};
class Offset;
class Offset;
/**
* Lumiera's internal time value datatype
*/
//class Time
// : public TimeValue
// {
// public:
// explicit
// Time (TimeValue val=0)
// : TimeValue(val)
// { }
//
// Time ( long millis
// , uint secs
// , uint mins =0
// , uint hours=0
// );
// };
class Time
: public TimeValue
{
public:
static const Time MAX ;
static const Time MIN ;
explicit
Time (TimeValue val= TimeValue(0))
: TimeValue(val)
{ }
Time ( long millis
, uint secs
, uint mins =0
, uint hours=0
);
};
class Offset
@ -123,18 +164,21 @@ namespace time {
public:
explicit
Offset (TimeValue distance)
Offset (TimeValue const& distance)
: TimeValue(distance)
{ }
};
inline Offset
operator- (Time const& end, Time const& start)
{
//////////////////////////////////////////////////////////////TODO this seems rather like a bad idea,
// because it opens a lot of implicit conversions which we don't want!
//inline Offset
//operator- (TimeValue const& end, TimeValue const& start)
//{
// TimeVar distance(end);
// distance -= start;
// return Offset(distance);
}
//}
typedef const Offset TimeDistance;

View file

@ -27,18 +27,22 @@
** doesn't deal with alignment issues and is <b>not threadsafe</b>.
**
** Values can be stored using \c operator= . In order to access the value
** stored in lumiera::Variant, you additionally need to define a "functor"
** <ul><li>with a typedef "Ret" for the return type</li>
** <li>providing a <tt>static Ret access(ELM&)</tt> function
** for each of the types used in the Variant</li>
** </ul>
** stored in lib::Variant, you additionally need to define a "functor"
** - with a typedef "Ret" for the return type
** - providing a \code static Ret access(ELM&) \endcode function
** for each of the types used in the Variant</li>
**
** @todo the instance handling for the accessor seems somewhat
** misaligned: why do we create another accessor as static var
** within the access() function?? Why not putting that into the
** Holder::Storage instance created by the client code?
** @todo write an unit test ///////////////////////////////////////TICKET #141
** @see wrapperptr.hpp usage example
*/
#ifndef LUMIERA_VARIANT_H
#define LUMIERA_VARIANT_H
#ifndef LIB_VARIANT_H
#define LIB_VARIANT_H
#include "lib/meta/typelist-util.hpp"
@ -48,7 +52,7 @@
namespace lumiera {
namespace lib {
namespace variant {
@ -100,13 +104,13 @@ namespace lumiera {
put (T const& toStore)
{
BASE::deleteCurrent(); // remove old content, if any
//
T& storedObj = *new(BASE::buffer_) T (toStore);
BASE::which_ = idx; // remember the actual type selected
return storedObj;
}
using BASE::put;
using BASE::put; // inherited alternate put() for other types T
};
typedef InstantiateWithIndex< TYPES
@ -122,9 +126,9 @@ namespace lumiera {
struct CaseSelect
{
typedef typename FUNCTOR::Ret Ret;
typedef Ret (*Func)(Buffer&);
typedef Ret (Func)(Buffer&);
Func table_[TYPECNT];
Func* table_[TYPECNT];
CaseSelect ()
{
@ -146,11 +150,16 @@ namespace lumiera {
if (TYPECNT <= storage.which_)
return FUNCTOR::ifEmpty ();
else
return (*table_[storage.which_]) (storage);
{
Func& access = *table_[storage.which_];
return access (storage);
}
}
};
/** initialise the dispatcher (trampoline)
* for the case of accessing type T */
template< class T, class BASE, uint i >
struct CasePrepare
: BASE
@ -161,7 +170,14 @@ namespace lumiera {
}
};
/** access the variant's inline buffer,
* using the configured access functor.
* @note the actual accessor instance
* is created on demand (static)
* @todo shouldn't this rather be located within
* the Holder::Storage created by clients??
*/
template<class FUNCTOR>
static typename FUNCTOR::Ret
access (Buffer& buf)
@ -205,7 +221,7 @@ namespace lumiera {
/**
/**
* A variant wrapper (typesafe union) capable of holding a value of any
* of a bounded collection of types. The value is stored in a local buffer
* directly within the object and may be accessed by a typesafe visitation.
@ -273,5 +289,5 @@ namespace lumiera {
}
};
} // namespace lumiera
} // namespace lib
#endif

View file

@ -55,7 +55,7 @@ namespace lumiera {
* error reporting is similar to the behaviour of dynamic_cast<T>: when retrieving
* a pointer, NULL is returned in case of mismatch.
*/
typedef lumiera::Variant<WrapperTypes, util::AccessCasted> WrapperPtr;
typedef lib::Variant<WrapperTypes, util::AccessCasted> WrapperPtr;

View file

@ -37,8 +37,8 @@
#include <string.h>
#include <locale.h>
#include <librsvg-2/librsvg/rsvg.h>
#include <librsvg-2/librsvg/rsvg-cairo.h>
#include <librsvg/rsvg.h>
#include <librsvg/rsvg-cairo.h>
#ifdef CAIRO_HAS_PS_SURFACE
#include <cairo-ps.h>

View file

@ -633,7 +633,7 @@ return: 0
END
PLANNED "Times and time intervals" TimeValue_test <<END
TEST "Times and time intervals" TimeValue_test <<END
return: 0
END

View file

@ -40,8 +40,6 @@ namespace lib {
namespace time{
namespace test{
using lumiera::Time;
/********************************************************
* @test verify handling of grid aligned timecode values.
@ -56,7 +54,7 @@ namespace test{
{
long refval= isnil(arg)? 1 : lexical_cast<long> (arg[1]);
Time ref (refval);
TimeValue ref (refval);
checkBasics (ref);
checkComparisons (ref);
@ -65,13 +63,13 @@ namespace test{
void
checkBasics (Time const& ref)
checkBasics (TimeValue ref)
{
}
void
checkComparisons (Time const& ref)
checkComparisons (TimeValue ref)
{
}

View file

@ -40,8 +40,6 @@ namespace lib {
namespace time{
namespace test{
using lumiera::Time;
/********************************************************
* @test verify handling of time values, time intervals.
@ -56,7 +54,7 @@ namespace test{
{
long refval= isnil(arg)? 1 : lexical_cast<long> (arg[1]);
Time ref (refval);
TimeValue ref (refval);
checkBasics (ref);
checkComparisons (ref);
@ -65,13 +63,13 @@ namespace test{
void
checkBasics (Time const& ref)
checkBasics (TimeValue ref)
{
}
void
checkComparisons (Time const& ref)
checkComparisons (TimeValue ref)
{
}

View file

@ -49,27 +49,96 @@ namespace test{
*/
class TimeValue_test : public Test
{
gavl_time_t
random_or_get (Arg arg)
{
if (isnil(arg))
return (rand() % 10000);
else
return lexical_cast<gavl_time_t> (arg[1]);
}
virtual void
run (Arg arg)
{
long refval= isnil(arg)? 1 : lexical_cast<long> (arg[1]);
TimeValue ref (random_or_get(arg));
Time ref (refval);
checkBasics (ref);
checkBasicTimeValues (ref);
checkMutableTime (ref);
checkComparisons (ref);
checkComponentAccess();
}
/** @test creating some time values and performing trivial comparisons.
* @note you can't do much beyond that, because TimeValues as such
* are a "dead end": they are opaque and can't be altered.
*/
void
checkBasics (Time const& ref)
checkBasicTimeValues (TimeValue org)
{
TimeValue zero;
TimeValue one (1);
TimeValue max (Time::MAX);
TimeValue min (Time::MIN);
TimeValue val (org);
CHECK (zero == zero);
CHECK (zero <= zero);
CHECK (zero >= zero);
CHECK (zero < one);
CHECK (min < max);
CHECK (min < val);
CHECK (val < max);
// mixed comparisons with raw numeric time
gavl_time_t g2 (-2);
CHECK (zero > g2);
CHECK (one > g2);
CHECK (one >= g2);
CHECK (g2 < max);
CHECK (!(g2 > max));
CHECK (!(g2 < min));
}
void
checkComparisons (Time const& ref)
checkMutableTime (TimeValue org)
{
TimeVar zero;
TimeVar one = TimeValue(1);
TimeVar two = TimeValue(2);
TimeVar var (org);
var += two;
var *= 2;
CHECK (zero == (var - 2*(org + two)) );
// the transient vars caused no side-effects
CHECK (var == 2*two + org + org);
CHECK (two == TimeValue(2));
var = org; // assign new value
CHECK (zero == (var - org));
CHECK (zero < one);
CHECK (one < two);
CHECK (var < Time::MAX);
CHECK (var > Time::MIN);
gavl_time_t raw (var);
CHECK (raw == org);
CHECK (raw > org - two);
}
void
checkComparisons (TimeValue org)
{
}