Clean-up: remove dummy-player services and interfaces (see #1342)

For the [ticket:1221 »Playback Vertical Slice«] one of the next steps
will be to define a way to pass buffers from the core to the UI.

The `DisplayService` and the `DummyPlayerService` where parts of an
early architecture study to see how such a flexible connection between
components in different layers can be accomplished.

The findings from this prototyping work helped to shape the design
of the actual `PlayService`...
This commit is contained in:
Fischlurch 2025-05-14 01:32:21 +02:00
parent 8abeb02397
commit 017ba5f160
29 changed files with 55 additions and 2035 deletions

View file

@ -1,84 +0,0 @@
/*
Display(Proxy) - service providing access to a display for outputting frames
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file display-interface-proxy.cpp
** Interface-Proxy for the lumiera::Display facade (experimental/deprecated).
** The purpose is to define a proxy implementation of lumiera::Display, in order to
** redirect any calls through the associated C Language Interface "lumieraorg_Display"
**
** @see display-facade.hpp
** @see display-service.hpp actual implementation within the GUI
** @deprecated obsolete early design draft from 2009;
** as of 2018 only kept in source to compile some likewise obsolete UI widgets.
*/
#include "include/display-facade.h"
#include "include/interfaceproxy.hpp"
namespace lumiera {
/// emit the vtable here into this translation unit within liblumieracommon.so...
Display::~Display() { }
/** static storage for the facade access front-end */
lib::Depend<Display> Display::facade;
} // namespace lumiera
namespace lumiera {
namespace facade {
/* ==================== stage::Display ====================================== */
using Interface = LUMIERA_INTERFACE_INAME(lumieraorg_Display, 0);
using Facade = lumiera::Display;
using IHandle = InstanceHandle<Interface, Facade>;
template<>
class Proxy<IHandle>
: public Binding<IHandle>
{
//----Proxy-Implementation-of-lumiera::Display--------
Display::Sink
getHandle (LumieraDisplaySlot display) override
{
_i_.allocate (display);
Sink sinkHandle;
sinkHandle.activate (display, _i_.release);
if (lumiera_error_peek() || !sinkHandle)
throw lumiera::error::State("failed to allocate output DisplayerSlot",
lumiera_error());
return sinkHandle;
}
public:
using Binding<IHandle>::Binding;
};
/** emit proxy code here... */
template
class Link<Interface,Facade>;
}} //namespace facade::lumiera

View file

@ -1,138 +0,0 @@
/*
DISPLAY-FACADE.h - accessing a display for outputting frames
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file display-facade.h
** Experimental Interface, allowing the Dummy-Player to access the
** video display widget in the GUI. While, generally speaking, the GUI
** controls the application and thus acts on its own, it might expose some
** services to the lower layers.
**
** In the Dummy-Player design study, the lumiera::Display interface serves
** to hand over calculated frames to the GUI for displaying them in a viewer.
**
** @deprecated This is a first draft as of 1/2009, and likely to be superseded
** by a better design, where rather the \em provider of an output facility
** registers with the OutputManager in the core.
**
** @see [corresponding implementation](\ref display-service.hpp)
** @see stage::GuiFacade
** @see dummy-player-facade.h
**
*/
#ifndef STAGE_INTERFACE_DISPLAY_H
#define STAGE_INTERFACE_DISPLAY_H
#include "include/display-handles.h"
#ifdef __cplusplus /* ============== C++ Interface ================= */
#include "lib/depend.hpp"
#include "lib/handle.hpp"
namespace lumiera {
/**************************************************************//**
* Interface for outputting frames to an (already allocated) viewer
* or display. The viewer is addressed by an "slot" handle, which the
* client receives from some other public interface. This reflects
* the fact that is's not up to the client to create an display or
* viewer; rather they are provided by some internal facility and
* the client code is handed out an display handle in the course
* of a larger interaction, like starting a player. This way,
* when the client code actually is about to produce output,
* he can allocate the slot and obtain a Displayer (functor)
* for pushing the frames out. (Users of the C Language Interface
* have to carry out these steps manually and also have to care
* for cleaning up and deallocating the slot).
*
* @note This is a first draft version of a rather important interface.
* The current version as of 1/2009 just serves a mockup player
* implementation. You can expect this interface to change
* considerably if we get at devising the real player.
*
* @see dummy-player-facade.hpp
* @see stage::PlaybackController
*
*/
class Display
{
public:
/** get an implementation instance of this service */
static lib::Depend<Display> facade;
/**
* Functor for pushing frames to the display.
* While one client is holding such a Sink handle,
* the corresponding DisplayerSlot is locked for
* exclusive use by this client.
*/
class Sink
: public lib::Handle<lumiera_displaySlot>
{
public:
/** push a frame up to the display, calling
* through the CL Interface.
* @see DisplayService::allocate */
inline void
operator() (DummyFrame frame)
{
impl().put_ (&impl(),frame);
}
};
/** allocate an already existing display/viewer for output
* @return a functor representing the frame sink */
virtual Sink getHandle(LumieraDisplaySlot) =0;
virtual ~Display(); ///< this is an interface
};
} // namespace lumiera
extern "C" {
#endif /* =========================== CL Interface ===================== */
#include "common/interface.h"
LUMIERA_INTERFACE_DECLARE (lumieraorg_Display, 0
, LUMIERA_INTERFACE_SLOT (void, allocate,(LumieraDisplaySlot) )
, LUMIERA_INTERFACE_SLOT (void, release,(LumieraDisplaySlot) )
, LUMIERA_INTERFACE_SLOT (void, put,(LumieraDisplaySlot, DummyFrame))
);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,5 +1,5 @@
/*
DISPLAY-HANDLES.h - opaque handle types for playback and display
DISPLAY-HANDLES.hpp - opaque handle types for playback and display
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
@ -32,21 +32,11 @@
using DummyFrame = std::byte *;
struct lumiera_displaySlot_struct
{
void (*put_)(lumiera_displaySlot_struct*, DummyFrame);
};
typedef struct lumiera_displaySlot_struct lumiera_displaySlot;
typedef lumiera_displaySlot* LumieraDisplaySlot;
struct lumiera_playprocess_struct { };
typedef struct lumiera_playprocess_struct lumiera_playprocess;
typedef lumiera_playprocess* LumieraPlayProcess;
#ifdef __cplusplus
namespace lumiera {
/** Supported Displayer formats */
@ -59,5 +49,4 @@ namespace lumiera {
DISPLAY_RGB16
};
} // namespace lumiera
#endif /*__cplusplus*/
#endif /*LUMIERA_DISPLAY_HANDLES_H*/

View file

@ -1,150 +0,0 @@
/*
DUMMY-PLAYER-FACADE.h - access point to a dummy test player
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file dummy-player-facade.h
* @deprecated left-over from an early design draft (2009)
*/
#ifndef STEAM_INTERFACE_DUMMYPLAYER_H
#define STEAM_INTERFACE_DUMMYPLAYER_H
#include "include/display-facade.h"
#include "include/display-handles.h"
#ifdef __cplusplus /* ============== C++ Interface ================= */
#include "common/subsys.hpp"
#include "lib/depend.hpp"
#include "lib/handle.hpp"
namespace steam {
namespace play {
class ProcessImpl;
} }
namespace lumiera {
/**************************************************************//**
* Experimental Interface Steam-Layer (or maybe the vault?):
* Global access point for starting a dummy playback, generating
* some test image data for the GUI to display in a viewer window.
*
* This is a mockup service we created 1/2009 to collect some
* experiences regarding integration of the application layers.
* Lumiera is not yet able actually to deliver rendered video data.
*
* In hindsight, this design study highlighted some relevant problems
* with our interface layout and the way we create bindings to the
* implementation. The moment we attempt to use other abstractions
* within an interface (as we do here with the Process interface),
* we're running into serious maintenance and library dependency problems.
* @deprecated obsoleted design from 2009 and not operative anymore (2018)
*/
class DummyPlayer
{
public:
/** provide a descriptor for lumiera::AppState,
* wired accordingly to allow main to deal with
* the dummy player as independent subsystem. */
static lumiera::Subsys& getDescriptor();
/** get an implementation instance of this service */
static lib::Depend<DummyPlayer> facade;
class ProcessImplementationLink;
/**
* Playback process, front-end to be used by client code.
* This handle represents a continuous playback process, which has been started
* with a specific output size, format and framerate. It is a handle to a calculation process,
* which is about to produce a stream of frames and push them to the viewer widget,
* specified by a LumieraDisplaySlot when starting this process.
*
* The Lifecycle of the referred playback process is managed automatically
* through this handle (by ref count). Client code is supposed to use the
* API on this handle to control the playback mode.
*
* @see handle.hpp
* @see dummy-player-service.cpp implementation
*/
class Process
: public lib::Handle<ProcessImplementationLink>
{
public:
void play(bool); ///< play/pause toggle
};
/**
* Mediator to allow the client to communicate with
* the Process implementation via the Process handle,
* without having to map each implementation-level function
* into the dummy player interface. We can't access the
* implementation in Steam-Layer without this indirection
* through a VTable, since a direct call would require
* us to link against liblumierasteam.so
*/
class ProcessImplementationLink
: public lumiera_playprocess
{
public:
virtual ~ProcessImplementationLink(); ///< this is an interface
virtual Process createHandle() =0; ///< activate the Process-frontend and link it to the process implementation
virtual void doPlay(bool yes) =0; ///< forward the play/pause toggle to the play process implementation
};
/** create a new playback process outputting to the given viewer/display */
virtual Process start(LumieraDisplaySlot viewerHandle) =0;
protected:
virtual ~DummyPlayer();
friend class lib::DependencyFactory<DummyPlayer>;
};
} // namespace lumiera
extern "C" {
#endif /* =========================== CL Interface ===================== */
#include "common/interface.h"
LUMIERA_INTERFACE_DECLARE (lumieraorg_DummyPlayer, 0
, LUMIERA_INTERFACE_SLOT (LumieraPlayProcess, startPlay, (LumieraDisplaySlot) )
, LUMIERA_INTERFACE_SLOT (void, togglePlay,(LumieraPlayProcess, bool))
, LUMIERA_INTERFACE_SLOT (void, terminate, (LumieraPlayProcess) )
);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -26,7 +26,6 @@
#include "vault/enginefacade.hpp"
#include "vault/netnodefacade.hpp"
#include "vault/scriptrunnerfacade.hpp"
#include "include/dummy-player-facade.h"
#include "steam/facade.hpp"
#include "stage/guifacade.hpp"
@ -38,7 +37,6 @@ namespace {
Subsys& engine = vault::EngineFacade::getDescriptor();
Subsys& netNode = vault::NetNodeFacade::getDescriptor();
Subsys& script = vault::ScriptRunnerFacade::getDescriptor();
Subsys& player = lumiera::DummyPlayer::getDescriptor(); ///////TODO: just a dummy, until we're able to render
Subsys& session = steam::Facade::getSessionDescriptor();
Subsys& playOut = steam::Facade::getPlayOutDescriptor();
Subsys& lumigui = stage::GuiFacade::getDescriptor();
@ -60,12 +58,10 @@ main (int argc, const char* argv[])
netNode.depends (session);
netNode.depends (engine);
// playOut.depends (engine);
// playOut.depends (engine); ///////////////////////////////////////TICKET #1149 actually start an »Engine subsystem«
playOut.depends (session);
lumigui.depends (session);
// lumigui.depends (engine);
player.depends (playOut); //////TODO dummy player, until we're able to render
lumigui.depends (player);
script.depends (session);
script.depends (engine);

View file

@ -20,7 +20,7 @@
#include "stage/ctrl/demo-controller.hpp"
#include "steam/engine/worker/tick-service.hpp"
#include "steam/engine/worker/dummy-tick-service.hpp"
#include "steam/engine/worker/dummy-image-generator.hpp"
#include <utility>
@ -35,7 +35,7 @@ namespace ctrl {
}
using std::make_unique;
using steam::node::TickService;
using steam::node::DummyTickService;
using steam::node::DummyImageGenerator;
using lumiera::DisplayerInput;
@ -77,7 +77,7 @@ namespace ctrl {
DemoController::play()
{
if (not tick_)
tick_.reset (new TickService{[this]{ processFrame(); }});
tick_.reset (new DummyTickService{[this]{ processFrame(); }});
ASSERT (tick_);
tick_->activate (FPS);
playing_ = true;

View file

@ -32,7 +32,7 @@
#define DEMO_CONTROLLER_H
#include "stage/gtk-base.hpp"
#include "include/display-handles.h"
#include "include/display-handles.hpp"
#include "lib/nocopy.hpp"
#include <memory>
@ -40,7 +40,7 @@
namespace steam {
namespace node {
class TickService;
class DummyTickService;
class DummyImageGenerator;
}}
@ -56,7 +56,7 @@ namespace ctrl {
, public sigc::trackable
{
unique_ptr<steam::node::DummyImageGenerator> imageGen_;
unique_ptr<steam::node::TickService> tick_;
unique_ptr<steam::node::DummyTickService> tick_;
public:
~DemoController();

View file

@ -34,7 +34,6 @@
#define STAGE_CTRL_FACADE_H
#include "stage/notification-service.hpp"
#include "stage/display-service.hpp"
#include "lib/depend-inject.hpp"
#include "lib/nocopy.hpp"
@ -55,10 +54,8 @@ namespace ctrl {
: util::NonCopyable
{
using Instance_Notification = lib::DependInject<NotificationService>::ServiceInstance<>;
using Instance_DisplayService = lib::DependInject<DisplayService>::ServiceInstance<>;
Instance_Notification notificationService_;
Instance_DisplayService displayService_; ///////////////////////////////////////////////////////TICKET #82 obsolete and will go away once we have a real OutputSlot offered by the UI
public:
@ -67,7 +64,6 @@ namespace ctrl {
*/
Facade (UiBus& bus, UiManager& manager)
: notificationService_{bus.getAccessPoint(), manager} // opens the GuiNotificationService instance
, displayService_{} // opens the DisplayService instance ////////TICKET #82 obsolete
{
INFO (stage, "UI-Facade Interfaces activated.");
}

View file

@ -1,114 +0,0 @@
/*
PlaybackController - playback controller object
Copyright (C)
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file playback-controller.cpp
** Implementation parts of PlaybackController.
** @warning this is preliminary code and will be reworked, once
** we're able to connect to actual playback processes
** performed by the render engine.
*/
#include "stage/ctrl/player-controller.hpp"
#include "stage/display-service.hpp"
#include "lib/error.hpp"
#include "include/logging.h"
namespace stage {
namespace ctrl {
namespace error = lumiera::error;
PlayerController::PlayerController()
: playing_(false)
, viewerHandle_(0)
{
instance = this; ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
}
PlayerController::~PlayerController()
{
instance = nullptr; ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
}
PlayerController* PlayerController::instance; ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
PlayerController&
PlayerController::get() ////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
{
if (not instance)
throw error::Logic ("GTK UI is not in running state"
, LERR_(LIFECYCLE));
return *instance;
}
void
PlayerController::play()
{
if (playHandle_)
{
playHandle_.play(true);
playing_ = true;
}
else if (viewerHandle_)
try
{
playHandle_ = lumiera::DummyPlayer::facade().start (viewerHandle_);
playing_ = true;
}
catch (lumiera::error::State& err)
{
WARN (stage, "failed to start playback: %s" ,err.what());
lumiera_error();
playing_ = false;
}
}
void
PlayerController::pause()
{
if (playHandle_)
playHandle_.play(false);
playing_ = false;
}
void
PlayerController::stop()
{
playHandle_.close();
playing_ = false;
}
bool
PlayerController::is_playing()
{
return playing_;
}
void
PlayerController::useDisplay (LumieraDisplaySlot display)
{
viewerHandle_ = display;
}
}} // namespace stage::ctrl

View file

@ -1,83 +0,0 @@
/*
PLAYBACK-CONTROLLER.hpp - playback controller object
Copyright (C)
2009, Joel Holdsworth <joel@airwebreathe.org.uk>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file playback-controller.hpp
** This file contains the definition of the playback controller object.
**
** @deprecated this represents an early design of playback and will be reworked
** @remarks what we actually need is a PlaybackController as a shell or proxy
** to maintain a flexible link to ongoing processes in the core. But note,
** this is also related to the Displayer service, which needs to be offered
** by the UI, so we create a mutual dependency here, and there is not much
** that can be done about this.
** @todo as a temporary solution, 1/2017 the playback controller was moved
** into the viewer panel. Of course it can not work that way....
** @todo 5/2025 now pushed aside in preparation for the »Playback Vertical Slice« //////////////////////TICKET #1273 : develop a Viewer-Connection concept
** @todo create a durable PlaybacController design //////////////////////////////////////////////////////TICKET #1072
*/
#ifndef PLAYER_CONTROLLER_H
#define PLAYER_CONTROLLER_H
#include "stage/gtk-base.hpp"
#include "include/dummy-player-facade.h"
#include "include/display-facade.h"
#include "lib/nocopy.hpp"
namespace stage {
namespace ctrl {
/** @deprecated we need a durable design for the playback process */
class PlayerController
: util::NonCopyable
{
volatile bool playing_;
lumiera::DummyPlayer::Process playHandle_;
LumieraDisplaySlot viewerHandle_;
static PlayerController* instance; ///////////////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
public:
PlayerController();
~PlayerController();
static PlayerController& get(); ///////////////////////////////////////////////////////////////////TICKET #1067 shitty workaround to allow disentangling of top-level
void play();
void pause();
void stop();
bool is_playing();
void useDisplay (LumieraDisplaySlot display);
private:
void on_frame();
};
}} // namespace stage::ctrl
#endif /*PLAYER_CONTROLLER_H*/

View file

@ -1,245 +0,0 @@
/*
DisplayService - service providing access to a display for outputting frames
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file display-service.cpp
** Implementation of _Displayer Service,_ exposed as a public interface.
** This service allows to set up _display slots,_ which can be handed over
** to client code in the course of the play process for outputting frames.
**
** @deprecated This is a first draft as of 1/2009, and likely to be superseded
** by a better design, where rather the \em provider of an output facility
** registers with the OutputManager in the core.
*/
#include "stage/display-service.hpp"
#include "lib/depend.hpp"
extern "C" {
#include "common/interface-descriptor.h"
}
namespace stage {
namespace { // hidden local details of the service implementation....
/* ================== define an lumieraorg_Display instance ======================= */
LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
,lumieraorg_DisplayFacade_descriptor
, NULL, NULL, NULL
, LUMIERA_INTERFACE_INLINE (name,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "Display"; }
)
, LUMIERA_INTERFACE_INLINE (brief,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "UI Interface: service for outputting frames to a viewer or display"; }
)
, LUMIERA_INTERFACE_INLINE (homepage,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "http://www.lumiera.org/develompent.html" ;}
)
, LUMIERA_INTERFACE_INLINE (version,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "0.1~pre"; }
)
, LUMIERA_INTERFACE_INLINE (author,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "Hermann Vosseler"; }
)
, LUMIERA_INTERFACE_INLINE (email,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "Ichthyostega@web.de"; }
)
, LUMIERA_INTERFACE_INLINE (copyright,
const char*, (LumieraInterface ifa),
{
(void)ifa;
return
"Copyright (C)\n"
" 2009, Hermann Vosseler <Ichthyostega@web.de>";
}
)
, LUMIERA_INTERFACE_INLINE (license,
const char*, (LumieraInterface ifa),
{
(void)ifa;
return
"**Lumiera** is free software; you can redistribute it and/or modify it\n"
"under the terms of the GNU General Public License as published by the\n"
"Free Software Foundation; either version 2 of the License, or (at your\n"
"option) any later version. See the file COPYING for further details."
;
}
)
, LUMIERA_INTERFACE_INLINE (state,
int, (LumieraInterface ifa),
{(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; }
)
, LUMIERA_INTERFACE_INLINE (versioncmp,
int, (const char* a, const char* b),
{(void)a;(void)b; return 0;} ////////////////////////////////////////////TODO define version ordering
)
);
using LERR_(LIFECYCLE);
lib::Depend<DisplayService> _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation...
LUMIERA_INTERFACE_INSTANCE (lumieraorg_Display, 0
,lumieraorg_DisplayService
, LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DisplayFacade_descriptor)
, NULL /* on open */
, NULL /* on close */
, LUMIERA_INTERFACE_INLINE (allocate,
void, (LumieraDisplaySlot slotHandle),
{
if (!_instance)
{
lumiera_error_set (LUMIERA_ERROR_LIFECYCLE, 0);
return;
}
REQUIRE (slotHandle);
try
{
_instance().allocate (slotHandle,true);
}
catch (lumiera::Error&){ /* error state remains set */ }
}
)
, LUMIERA_INTERFACE_INLINE (release,
void, (LumieraDisplaySlot slotHandle),
{
if (!_instance)
{
lumiera_error_set (LUMIERA_ERROR_LIFECYCLE, 0);
return;
}
REQUIRE (slotHandle);
_instance().allocate (slotHandle,false);
}
)
, LUMIERA_INTERFACE_INLINE (put,
void, (LumieraDisplaySlot slotHandle, DummyFrame frame),
{
//skipping full checks for performance reasons
REQUIRE (_instance && !lumiera_error_peek());
REQUIRE (slotHandle);
DisplayerSlot& slot = _instance().resolve (slotHandle);
slot.put (frame);
}
)
);
} // (End) hidden service impl details
DisplayService::DisplayService()
: error_{}
, serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_Display, 0, lumieraorg_DisplayService))
{
INFO (progress, "Display Facade opened.");
}
LumieraDisplaySlot
DisplayService::setUp (FrameDestination const& outputDestination)
{
DisplayerTab& slots (_instance().slots_);
return &slots.manage (new DisplayerSlot (outputDestination));
}
void
DisplayService::allocate (LumieraDisplaySlot handle, bool doAllocate)
{
REQUIRE (handle);
if (doAllocate)
{
if (handle->put_)
throw lumiera::error::Logic("slot already allocated for output");
else
// Mark the handle as "allocated" and ready for output:
// Place the function pointer from the C interface into the handle struct.
// calling it will invoke the implementing instance's "put" function
// (see the LUMIERA_INTERFACE_INLINE above in this file!)
handle->put_ = serviceInstance_.get().put;
}
else
handle->put_ = 0;
}
DisplayerSlot&
DisplayService::resolve (LumieraDisplaySlot handle)
{
REQUIRE (handle);
REQUIRE (handle->put_, "accessing a DisplayerSlot, which hasn't been locked for output");
return *static_cast<DisplayerSlot*> (handle);
}
/* === DisplayerSlot Implementation === */
DisplayerSlot::DisplayerSlot (FrameDestination const& outputDestination)
: currBuffer_(0)
{
put_ = 0; // mark as not allocated
hasFrame_.connect (outputDestination);
dispatcher_.connect (sigc::mem_fun (this, &DisplayerSlot::displayCurrentFrame));
}
DisplayerSlot::~DisplayerSlot()
{
TRACE (gui_dbg, "Displayer Slot closing...");
}
void
DisplayerSlot::displayCurrentFrame()
{
hasFrame_.emit (currBuffer_);
}
} // namespace stage

View file

@ -1,180 +0,0 @@
/*
DISPLAY-SERVICE.hpp - service providing access to a display for outputting frames
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file display-service.hpp
** A public service provided by the GUI, implementing the lumiera::Display facade interface.
** It serves two purposes:
** - It maintains a collection of DisplayerSlot objects, which are the actual connection points
** and allow to receive frames and dispatch them to the GTK main event loop thread.
** Conceptually, creating such a slot means providing a possible display for output.
** - It provides the actual implementation of the Display facade interface, i.e. the function
** which is to invoked periodically by the playback processes to dispose a new frame into
** the display.
**
** This service is the implementation of a layer separation facade interface. This header defines
** the interface used to \em provide this service, not to access it. Clients get a specific
** LumieraDisplaySlot passed as parameter when initiating a playback process from the GUI. Using
** this LumieraDisplaySlot handle, clients should then use lumiera::DummyPlayer#facade to access
** an implementation instance of this service in order to push actual frames up.
**
** @deprecated This is a first draft as of 1/2009, and likely to be superseded
** by a better design, where rather the \em provider of an output facility
** registers with the OutputManager in the core.
**
** @see lumiera::Display
** @see lumiera::DummyPlayer
** @see stage::PlaybackController usage example
*/
#ifndef STAGE_DISPLAY_SERVICE_H
#define STAGE_DISPLAY_SERVICE_H
#include "include/display-facade.h"
#include "common/instancehandle.hpp"
#include "lib/scoped-ptrvect.hpp"
#include "include/logging.h"
#include "lib/nocopy.hpp"
#include <glibmm.h>
#include <sigc++/sigc++.h>
#include <string>
#include <vector>
namespace stage {
using std::string;
using std::vector;
using lumiera::Display;
using Glib::Dispatcher;
typedef sigc::slot<void, void*> FrameDestination;
typedef sigc::signal<void, void*> FrameSignal;
/****************************************************************//**
* Actual implementation of a single displayer slot. Internally,
* it is connected via the Glib::Dispatcher for outputting frames
* to a viewer widget, which executes within the GTK event thread.
* @note must be created from the GTK event thread.
*/
class DisplayerSlot
: public lumiera_displaySlot,
util::NonCopyable
{
Dispatcher dispatcher_;
FrameSignal hasFrame_;
DummyFrame currBuffer_;
public:
DisplayerSlot (FrameDestination const&) ;
~DisplayerSlot () ;
/* Implementation-level API to be used by DisplayService */
/** receive a frame to be displayed */
inline void put (DummyFrame);
private:
/** internal: activated via Dispatcher
* and running in GTK main thread */
void displayCurrentFrame();
};
typedef lib::ScopedPtrVect<DisplayerSlot> DisplayerTab;
/**************************************************//**
* Actual implementation of the DisplayService.
* Creating an instance of this class automatically
* registers the interface lumieraorg_Display with
* the Lumiera Interface/Plugin system and creates
* a forwarding proxy within the application core to
* route calls through this interface.
*
* In addition to the Display interface, this class
* implements an additional service for the GUI,
* allowing actually to set up display slots, which
* then can be handed out to client code in the
* course of the play process for outputting frames.
*/
class DisplayService
: util::NonCopyable
{
string error_;
DisplayerTab slots_;
/* === Interface Lifecycle === */
typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_Display, 0)
, lumiera::Display
> ServiceInstanceHandle;
ServiceInstanceHandle serviceInstance_;
public:
DisplayService();
~DisplayService() { INFO (proc_dbg, "Display service dying..."); }
/** open a new display, sending frames to the given output destination
* @return handle for this slot, can be used to start a play process.
* NULL handle in case of any error. */
static LumieraDisplaySlot setUp (FrameDestination const&);
/** prepare and the given slot for output
* @param doAllocate allocate when true, else release it
* @throw lumiera::error::Logic when already in use */
void allocate (LumieraDisplaySlot, bool doAllocate);
/** resolve the given display slot handle to yield a ref
* to an actual implementation object. In order to be resolvable,
* the DisplayerSlot needs to be locked (=allocated) for output use. */
DisplayerSlot& resolve (LumieraDisplaySlot);
};
void
DisplayerSlot::put(DummyFrame newFrame)
{
if (newFrame != currBuffer_)
{
currBuffer_ = newFrame;
dispatcher_.emit();
}
else
{
TRACE (render, "frame dropped?");
}
}
} // namespace stage
#endif

View file

@ -28,7 +28,7 @@
#include "lib/nocopy.hpp"
#include "include/display-handles.h"
#include "include/display-handles.hpp"
namespace stage {
namespace output {

View file

@ -27,7 +27,6 @@
#include "stage/workspace/workspace-window.hpp"
#include "stage/ui-bus.hpp" ///////////////////////////////////TODO why are we forced to include this after workspace-window.hpp ?? Ambiguity between std::ref and boost::reference_wrapper
#include "stage/display-service.hpp"
namespace stage {

View file

@ -22,7 +22,6 @@
#include "stage/workspace/workspace-window.hpp"
#include "stage/ui-bus.hpp" ///////////////////////////////////TODO why are we forced to include this after workspace-window.hpp ?? Ambiguity between std::ref and boost::reference_wrapper
#include "stage/display-service.hpp"
namespace stage {

View file

@ -32,23 +32,6 @@
namespace stage {
///////////////////////////////////////////////////////////////////////////////////TICKET #959 : scheduled for termination....
namespace controller {
Controller::Controller (model::Project& modelProject)
: project_(modelProject)
, playback_()
{ }
ctrl::PlayerController& Controller::get_playback_controller()
{
return playback_;
}
}// namespace stage::controller
///////////////////////////////////////////////////////////////////////////////////TICKET #959 : scheduled for termination....
UiBus::UiBus()

View file

@ -84,9 +84,6 @@
** @see ctrl/core-service.hpp
**
** [MVC-Pattern]: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
**
** @todo as of 1/2015, this header needs to be reshaped ////////////////////TICKET #959
**
*/
@ -95,7 +92,6 @@
#include "stage/gtk-base.hpp" //////////////////////////////////////////////////////TODO remove any GTK dependency if possible
#include "stage/ctrl/player-controller.hpp"
#include "lib/nocopy.hpp"
#include <memory>
@ -106,30 +102,6 @@ using std::unique_ptr;
namespace stage {
///////////////////////////////////////////////////////////////////////////////////TICKET #959 : scheduled for termination....
namespace model {
class Project;
} // namespace model
namespace controller {
/**
* @todo needs to be reshaped for communication with Steam-Layer ////////////////TICKET #959
*/
class Controller
{
model::Project& project_;
ctrl::PlayerController playback_;
public:
Controller (model::Project&);
ctrl::PlayerController& get_playback_controller();
};
}// namespace stage::controller
///////////////////////////////////////////////////////////////////////////////////TICKET #959 : scheduled for termination....
namespace ctrl {
class StateManager;
class CoreService;

View file

@ -21,8 +21,7 @@
*/
//#include "stage/widget/timeline-widget.hpp" /////////////////////////////////////////////////////////////TODO old GTK-2 UI is defunct (3/23)
#include "stage/widget/timeline/timeline-zoom-scale.hpp"
#include "stage/widget/timeline-zoom-scale.hpp"
using namespace Gtk; ///////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please!

View file

@ -29,7 +29,6 @@
#include "stage/gtk-base.hpp"
#include "stage/widget/mini-button.hpp"
//#include "stage/widget/timeline-widget.hpp" //////////////////////////////////////////////////////////////TODO old GTK-2 UI is defunct (3/23)
#include "stage/widget/timeline/timeline-state.hpp"
using namespace Gtk; ////////////////////////////////////////////////////////////////////////////////TICKET #1071 no wildcard includes please!

View file

@ -1,71 +0,0 @@
/*
EngineServiceMock - dummy render engine implementation for test/development
Copyright (C)
2012, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file engine-service-mock.cpp
** Implementation translation unit for a mock render engine for unit testing.
** @todo draft from 2012, and, while stalled, still relevant as of 2016
*/
#include "steam/engine/engine-service-mock.hpp"
#include "steam/engine/worker/dummy-tick.hpp"
//#include <string>
//#include <memory>
//#include <functional>
namespace steam {
namespace engine{
// using std::string;
// using lumiera::Subsys;
// using std::bind;
namespace { // hidden local details of the service implementation....
} // (End) hidden service impl details
/**
* Initialise a mock render engine.
* This dummy implementation manages a collection of
* "Processors", each running in a separate thread.
*/
EngineServiceMock::EngineServiceMock()
: processors_()
{ }
/** special engine configuration for mock/testing operation.
*/
RenderEnvironment&
EngineServiceMock::configureCalculation (ModelPort,Timings,Quality)
{
UNIMPLEMENTED ("represent *this as RenderEnvironment Closure)");
RenderEnvironment* todo_fake(0); ////KABOOOM
return *todo_fake;
}
}} // namespace steam::engine

View file

@ -1,92 +0,0 @@
/*
ENGINE-SERVICE-MOCK.hpp - dummy render engine implementation for test/development
Copyright (C)
2012, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file engine-service-mock.hpp
** Placeholder implementation of the render engine for test and diagnostics.
** This implementation can be used as a drop-in replacement of the real engine.
** Of course, it is lacking most of the functionality; it is just usable to detect
** and verify the actual engine setup and invocation that \em would happen.
**
** @todo 1/2012 until the real render engine is usable, this mock implementation
** will stand-in, allowing us to develop the other parts of the play/render subsystem.
**
** @see steam::engine::EngineService "the real thing"
** @see render-configurator.cpp (activating the mock or the real engine)
** @see DummyPlayConnection
** @see EngineInterface_test
** @see CalcStream_test
*/
#ifndef STEAM_ENGINE_ENGINE_SERVICE_MOCK_H
#define STEAM_ENGINE_ENGINE_SERVICE_MOCK_H
#include "lib/error.hpp"
//#include "include/dummy-player-facade.h"
//#include "include/display-facade.h"
#include "steam/engine/calc-stream.hpp"
#include "steam/mobject/model-port.hpp"
#include "steam/play/timings.hpp"
#include "steam/play/output-slot.hpp"
//#include "common/instancehandle.hpp"
//#include "lib/singleton-ref.hpp"
#include "steam/engine/engine-service.hpp"
#include "lib/scoped-ptrvect.hpp"
namespace steam {
namespace node { class DummyTick; }
namespace engine{
// using std::string;
// using lumiera::Subsys;
// using lumiera::Display;
// using lumiera::DummyPlayer;
using mobject::ModelPort;
using steam::play::Timings;
typedef EngineService::Quality Quality;
/************************************************************//**
* Variant of the render engine, reconfigured for mock operation.
* Especially, this setup leaves out most of the actual Lumiera
* engine's implementation facilities. There is no scheduler
* and no frame cache; rather we perform simple dependent
* calculations which might block.
*/
class EngineServiceMock
: public EngineService
{
lib::ScopedPtrVect<node::DummyTick> processors_;
public:
EngineServiceMock();
protected:
virtual RenderEnvironment& configureCalculation (ModelPort,Timings,Quality);
};
}} // namespace steam::engine
#endif

View file

@ -32,8 +32,7 @@
#include "lib/error.hpp"
#include "include/display-facade.h"
#include "include/display-handles.h"
#include "include/display-handles.hpp"
#include <array>

View file

@ -1,5 +1,5 @@
/*
TICK-SERVICE.hpp - issuing timed callbacks
DUMMY-TICK-SERVICE.hpp - issuing timed callbacks
Copyright (C)
2009, Joel Holdsworth <joel@airwebreathe.org.uk>,
@ -12,7 +12,7 @@
*/
/** @file tick-service.hpp
/** @file dummy-tick-service.hpp
** A timer service invoking a given callback periodically.
** This is a rough preliminary implementation as of 1/2009. We use it to
** drive the frame "creation" of a player dummy (the render engine is not
@ -25,8 +25,8 @@
*/
#ifndef STEAM_PLAY_TICKSERVICE_H
#define STEAM_PLAY_TICKSERVICE_H
#ifndef STEAM_PLAY_DUMMY_TICK_SERVICE_H
#define STEAM_PLAY_DUMMY_TICK_SERVICE_H
#include "lib/error.hpp"
@ -51,7 +51,7 @@ namespace node {
* Tick generating service for a periodic callback,
* with adjustable frequency. Quick'n dirty implementation!
*/
class TickService
class DummyTickService
: lib::ThreadJoinable<>
{
typedef function<void(void)> Tick;
@ -61,23 +61,23 @@ namespace node {
static const uint POLL_TIMEOUT = 10000;
public:
TickService (Tick callback)
DummyTickService (Tick callback)
: ThreadJoinable("Tick generator (dummy)"
, bind (&TickService::timerLoop, this, callback)
, bind (&DummyTickService::timerLoop, this, callback)
)
, timespan_{POLL_TIMEOUT}
{
INFO (steam, "TickService started.");
INFO (steam, "DummyTickService started.");
}
~TickService ()
~DummyTickService ()
{
timespan_ = 0;
if (not this->join())
WARN (steam, "Failure in TickService");
WARN (steam, "Failure in DummyTickService");
usleep (200000); // additional delay allowing GTK to dispatch the last output
INFO (steam, "TickService shutdown.");
INFO (steam, "DummyTickService shutdown.");
}
@ -117,7 +117,6 @@ namespace node {
}} // namespace steam::node
#endif
#endif /*STEAM_PLAY_DUMMY_TICK_SERVICE_H*/

View file

@ -1,117 +0,0 @@
/*
DUMMY-TICK.hpp - issuing timed callbacks
Copyright (C)
2009, Joel Holdsworth <joel@airwebreathe.org.uk>,
Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file dummy-tick.hpp
** A timer service invoking a given callback periodically.
** This is a rough preliminary implementation as of 1/2009. We use it to
** drive the frame "creation" of a player dummy (the render engine is not
** ready yet). The intention is to use this service as part of a mock engine
** setup, used to verify the construction of engine components. As an integration
** test, we build a "dummy player", delivering some test data frames to the GUI.
**
** @see steam::play::DummyPlayerService
**
*/
#ifndef STEAM_ENGINE_WORKER_DUMMY_TICK_H
#define STEAM_ENGINE_WORKER_DUMMY_TICK_H
#include "lib/error.hpp"
#include "lib/thread.hpp"
#include <functional>
#include <limits>
namespace steam {
namespace node {
using std::function;
using std::bind;
/********************************************************//**
* Tick generating service for a periodic callback,
* with adjustable frequency. Quick'n dirty implementation!
*/
class DummyTick
: lib::ThreadJoinable<>
{
typedef function<void(void)> Tick;
volatile uint timespan_;
/** poll interval for new settings in wait state */
static const uint POLL_TIMEOUT = 1000;
public:
DummyTick (Tick callback)
: ThreadJoinable("Tick generator (dummy)"
, bind (&DummyTick::timerLoop, this, callback)
)
{
INFO (steam, "TickService started.");
}
~DummyTick ()
{
timespan_ = 0;
this->join();
usleep (200000); // additional delay allowing GTK to dispatch the last output
INFO (steam, "TickService shutdown.");
}
/** set the periodic timer to run with a given frequency,
* starting \em now. Well, not actually now, but at the next
* opportunity. It should be \em now, but this implementation
* is sloppy! setting fps==0 halts (pauses) the timer.
*/
void activate (uint fps)
{
REQUIRE ( 0==fps
||( 1000000/fps < std::numeric_limits<uint>::max()
&& 1000000/fps > POLL_TIMEOUT));
if (fps)
timespan_ = 1000000/fps; // microseconds per tick
else
timespan_ = POLL_TIMEOUT;
}
private:
void timerLoop(Tick periodicFun)
{
timespan_ = POLL_TIMEOUT;
while (0 < timespan_)
{
if (timespan_ > POLL_TIMEOUT)
periodicFun();
usleep (timespan_);
}
TRACE (proc_dbg, "Tick Thread timer loop exiting...");
}
};
}} // namespace steam::node
#endif

View file

@ -1,121 +0,0 @@
/*
DummyPlayer(Proxy) - access point and service implementing a dummy test player
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file dummy-player-interface-proxy.cpp
** Interface-Proxy for the lumiera::DummyPlayer facade (experimental/obsolete).
** The purpose is to define a proxy implementation of lumiera::DummyPlayer, in order to
** redirect any calls through the associated C Language Interface "lumieraorg_DummyPlayer"
**
** @remarks the implementation of this interface proxy for the DummyPlayer highlighted
** some interesting design issues. The way we're defining our interfaces and
** bindings seems to have some shortcomings when attempting to express an
** interface (here DummyPlayer) in terms of another abstraction
** (here the DummyPlayer::Process), since the implementation of this
** abstraction has to be mapped and indirected via the interface-system
** as well. This forces us to duplicate all of these secondary interface
** functions several times, and incurs a further forwarding through the
** smart-Handle, since our interface system doesn't support suitable
** lifecycle support out of the box and instead places this burden
** onto the client code (or, as in this case here, the intermediary
** proxy used by the client code to access the interface).
**
** @see dummy-player-facade.hpp
** @see dummy-player-service.hpp actual implementation within the Steam-Layer
** @deprecated obsolete early design draft from 2009;
** as of 2018 only kept in source to compile some likewise obsolete UI widgets.
*/
#include "include/dummy-player-facade.h"
#include "include/interfaceproxy.hpp"
namespace lumiera {
// emit the vtable here into this translation unit within liblumieracommon.so ...
DummyPlayer::~DummyPlayer() { }
DummyPlayer::ProcessImplementationLink::~ProcessImplementationLink() { };
/** static storage for the facade access front-end */
lib::Depend<DummyPlayer> DummyPlayer::facade;
namespace facade {
/* ==================== DummyPlayer ======================================= */
using Interface = LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0);
using Facade = lumiera::DummyPlayer;
using IHandle = InstanceHandle<Interface, Facade>;
template<>
class Proxy<IHandle>
: public Binding<IHandle>
{
//----Proxy-Implementation-of-DummyPlayer--------
typedef lumiera::DummyPlayer::Process Process;
typedef steam::play::ProcessImpl ProcessImpl;
/** @note as an optimisation we hand out a direct reference
* to the implementing process object. While this ref could
* still be passed as handle to the C Language interface, using
* it directly within the client (=GUI) bypasses the C interface
* and thus leaves us only with one level of indirection,
* irrespective if using the C or C++ interface.
* @note in hindsight this turned out as a very bad idea,
* since it complicated the definition of the facade proxy
* and created quite involved library dependency problems.
*/
Process start(LumieraDisplaySlot viewerHandle) override
{
ProcessImplementationLink* pP = static_cast<ProcessImplementationLink*> (_i_.startPlay (viewerHandle));
if (!pP)
throw lumiera::error::State("failed to start DummyPlayer", lumiera_error());
return pP->createHandle();
}
public:
using Binding<IHandle>::Binding;
};
/** emit proxy code here... */
template
class Link<Interface,Facade>;
} // namespace facade
/* === Forwarding function(s) on the Process handle === */
void
DummyPlayer::Process::play (bool yes)
{
// access the implementation via smart-Handle
impl().doPlay(yes);
}
} // namespace lumiera

View file

@ -1,368 +0,0 @@
/*
DummyPlayerService - access point and service implementing a dummy test player
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file dummy-player-service.cpp
** Implementation of a service for mock render output to support testing.
*/
#include "steam/play/dummy-player-service.hpp"
#include "steam/engine/worker/dummy-image-generator.hpp"
#include "steam/engine/worker/tick-service.hpp"
#include "lib/depend-inject.hpp"
#include "lib/depend.hpp"
extern "C" {
#include "common/interface-descriptor.h"
}
#include <functional>
#include <memory>
#include <string>
namespace steam {
namespace play{
using std::string;
using lumiera::Subsys;
using std::unique_ptr;
using std::bind;
namespace { // hidden local details of the service implementation....
/** details of how the DummyPlayer service can be started
* and used as independent "subsystem" within main() */
class DummyPlayerSubsysDescriptor
: public Subsys
{
using ServiceHandle = lib::DependInject<DummyPlayerService>::ServiceInstance<>;
/** manages the actual (single) instance of the player service impl */
ServiceHandle thePlayer_{ServiceHandle::NOT_YET_STARTED};
operator string () const { return "Dummy-Player"; }
bool
shouldStart (lumiera::Option&) override
{
return false; // for now the DummyPlayerService only comes "up" as dependency,
} // but doesn't start as a subsystem on it's own.
bool
start (lumiera::Option&, Subsys::SigTerm terminationHandle) override
{
ASSERT (!thePlayer_);
thePlayer_.createInstance (terminationHandle);
return true;
}
void
triggerShutdown () noexcept override
{
thePlayer_.shutdown();
// note: shutdown of the DummyPlayerService instance may block
// for a short period, until termination of all tick services
}
bool
checkRunningState () noexcept override
{
return bool(thePlayer_);
}
};
lib::Depend<DummyPlayerSubsysDescriptor> theDummyPlayerDescriptor;
/* ================== define an lumieraorg_DummyPlayer instance ======================= */
LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
,lumieraorg_DummyPlayerFacade_descriptor
, NULL, NULL, NULL
, LUMIERA_INTERFACE_INLINE (name,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "DummyPlayer"; }
)
, LUMIERA_INTERFACE_INLINE (brief,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "Steam Interface: dummy player to test integration with the GUI"; }
)
, LUMIERA_INTERFACE_INLINE (homepage,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "http://www.lumiera.org/develompent.html" ;}
)
, LUMIERA_INTERFACE_INLINE (version,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "0.1~pre"; }
)
, LUMIERA_INTERFACE_INLINE (author,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "Hermann Vosseler"; }
)
, LUMIERA_INTERFACE_INLINE (email,
const char*, (LumieraInterface ifa),
{ (void)ifa; return "Ichthyostega@web.de"; }
)
, LUMIERA_INTERFACE_INLINE (copyright,
const char*, (LumieraInterface ifa),
{
(void)ifa;
return
"Copyright (C)\n"
" 2009, Hermann Vosseler <Ichthyostega@web.de>";
}
)
, LUMIERA_INTERFACE_INLINE (license,
const char*, (LumieraInterface ifa),
{
(void)ifa;
return
"**Lumiera** is free software; you can redistribute it and/or modify it\n"
"under the terms of the GNU General Public License as published by the\n"
"Free Software Foundation; either version 2 of the License, or (at your\n"
"option) any later version. See the file COPYING for further details."
;
}
)
, LUMIERA_INTERFACE_INLINE (state,
int, (LumieraInterface ifa),
{(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; }
)
, LUMIERA_INTERFACE_INLINE (versioncmp,
int, (const char* a, const char* b),
{(void)a;(void)b; return 0;} ////////////////////////////////////////////TODO define version ordering
)
);
using LERR_(LIFECYCLE);
lib::Depend<DummyPlayerService> _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation...
typedef ProcessImpl* ProcP;
LUMIERA_INTERFACE_INSTANCE (lumieraorg_DummyPlayer, 0
,lumieraorg_DummyPlayerService
, LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DummyPlayerFacade_descriptor)
, NULL /* on open */
, NULL /* on close */
, LUMIERA_INTERFACE_INLINE (startPlay,
LumieraPlayProcess, (LumieraDisplaySlot viewerHandle),
{
if (!_instance)
{
lumiera_error_set (LUMIERA_ERROR_LIFECYCLE, 0);
return 0;
}
return static_cast<LumieraPlayProcess> (_instance().start(viewerHandle));
}
)
, LUMIERA_INTERFACE_INLINE (togglePlay,
void, (LumieraPlayProcess handle, bool doPlay),
{
if (!_instance)
{
lumiera_error_set(LUMIERA_ERROR_LIFECYCLE, 0);
return;
}
REQUIRE (handle);
ProcP proc = static_cast<ProcP> (handle);
proc->doPlay(doPlay);
}
)
, LUMIERA_INTERFACE_INLINE (terminate,
void, (LumieraPlayProcess handle),
{
if (!_instance)
{
lumiera_error_set(LUMIERA_ERROR_LIFECYCLE, 0);
return;
}
REQUIRE (handle);
ProcP proc = static_cast<ProcP> (handle);
ProcessImpl::terminate (proc);
}
)
);
} // (End) hidden service impl details
DummyPlayerService::DummyPlayerService (Subsys::SigTerm terminationHandle)
: error_("")
, notifyTermination_(terminationHandle)
, serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerService))
{
INFO (progress, "DummyPlayer Facade opened.");
}
/** @par implementation note
* A new process (implementation) is created, configured
* and started here. This may include spawning a thread or
* allocating a timer. The newly created process is self-contained
* and will be just handed out, without caring for its lifecycle.
* If client code accesses this function via the plain C interface,
* the client is responsible for terminating this process, whereas
* when using the C++ interface, you'll get a Handle object which
* manages the lifecycle automatically.
*/
ProcessImpl*
DummyPlayerService::start (LumieraDisplaySlot viewerHandle)
{
unique_ptr<ProcessImpl> newProcess (new ProcessImpl (viewerHandle));
REQUIRE (!newProcess->isActive());
newProcess->setRate(25);
return newProcess.release();
}
/* === Process Implementation === */
ProcessImpl::ProcessImpl(LumieraDisplaySlot viewerHandle)
: fps_{0}
, play_{false}
, display_{Display::facade().getHandle (viewerHandle)}
, imageGen_{}
, tick_{new TickService (bind (&ProcessImpl::doFrame, this))}
{ }
ProcessImpl::~ProcessImpl()
{
INFO (proc_dbg, "Playback process halted...");
}
/** deleter function for lib::Handle */
void
ProcessImpl::terminate (DummyPlayer::ProcessImplementationLink* process)
{
if (process)
delete process;
}
/**
* activate a forwarding smart-Handle
* to be used by client code for communication with the play process implementation.
* The handle manages the lifecycle of the interface / play process connection.
* This virtual function is used by the interface proxy to connect the client side
* and the actual play process, after creating the latter through the interface system.
*/
DummyPlayer::Process
ProcessImpl::createHandle()
{
DummyPlayer::Process handle;
DummyPlayer::ProcessImplementationLink *const implementationLink = this;
handle.activate(implementationLink, &terminate);
return handle; // note the deleter function...
}
void
ProcessImpl::setRate (uint fps)
{
REQUIRE (fps==0 || fps_==0 );
REQUIRE (fps==0 || !play_ );
REQUIRE (tick_);
fps_ = fps;
play_ = (fps != 0);
if (play_)
imageGen_.reset(new DummyImageGenerator(fps));
// callbacks with given frequency, starting now
tick_->activate(fps);
}
void
ProcessImpl::doPlay(bool yes)
{
REQUIRE (isActive());
tick_->activate (yes? fps_:0);
play_ = yes;
}
void
ProcessImpl::doFrame()
{
REQUIRE (isActive());
ASSERT (imageGen_);
if (play_)
display_(imageGen_->next());
else
display_(imageGen_->current());
}
} // namespace play
} // namespace steam
namespace lumiera {
/** @internal intended for use by main(). */
lumiera::Subsys&
DummyPlayer::getDescriptor()
{
return steam::play::theDummyPlayerDescriptor();
}
} // namespace lumiera

View file

@ -1,154 +0,0 @@
/*
DUMMY-PLAYER-SERVICE.hpp - service implementing a dummy test player
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file dummy-player-service.hpp
** A public service provided by the Steam-Layer, implementing a dummy/mockup playback process.
** This is a design sketch; Lumiera isn't able to generate rendered output as of 2/2009. The
** idea is, that for each ongoing calculation process, there is a ProcessImpl instance holding
** the necessary handles and allocations and providing an uniform API to the client side.
** Especially, this ProcessImpl holds a TickService, which generates periodic callbacks, and
** it uses an output handle (functor) to push the generated frames up.
**
** This service is the implementation of a layer separation facade interface. Clients should use
** steam::play::DummyPlayer#facade to access this service. This header defines the interface used
** to \em provide this service, not to access it.
**
** @see lumiera::DummyPlayer
** @see stage::PlaybackController usage example
*/
#ifndef STEAM_DUMMYPLAYER_SERVICE_H
#define STEAM_DUMMYPLAYER_SERVICE_H
#include "include/dummy-player-facade.h"
#include "include/display-facade.h"
#include "common/instancehandle.hpp"
#include "lib/nocopy.hpp"
#include <memory>
#include <string>
namespace steam {
namespace node {
class DummyImageGenerator;
class TickService;
}
namespace play {
using std::string;
using lumiera::Subsys;
using lumiera::Display;
using lumiera::DummyPlayer;
using steam::node::DummyImageGenerator;
using steam::node::TickService;
/****************************************************************//**
* Actual implementation of a single (dummy) playback process.
* The DummyPlayerService (see below) maintains a collection of such
* actively running playback processes, while the client code gets
* DummyPlayer::Process handles to track any ongoing use. Users of
* the plain C interface get a direct bare pointer to the respective
* ProcessImpl instance and have to manage the lifecycle manually.
*/
class ProcessImpl
: public lumiera::DummyPlayer::ProcessImplementationLink,
util::NonCopyable
{
uint fps_;
bool play_;
Display::Sink display_;
std::unique_ptr<DummyImageGenerator> imageGen_;
std::unique_ptr<TickService> tick_;
public:
ProcessImpl(LumieraDisplaySlot) ;
~ProcessImpl() ;
/* Implementation-level API */
/** activate a playback process
* with given specification */
void setRate (uint fps);
bool isActive () { return fps_ != 0; }
bool isPlaying() { return play_; }
void doPlay(bool yes);
/* Lifecycle */
DummyPlayer::Process createHandle();
static void terminate(DummyPlayer::ProcessImplementationLink*);
private:
void doFrame (); ///< periodically invoked while playing
};
/**************************************************//**
* Actual implementation of the DummyPlayer service.
* Creating an instance of this class automatically
* registers the interface lumieraorg_DummyPlayer with
* the Lumiera Interface/Plugin system and creates
* a forwarding proxy within the application core to
* route calls through this interface.
*/
class DummyPlayerService
: util::NonCopyable
{
string error_;
Subsys::SigTerm notifyTermination_;
/* === Interface Lifecycle === */
typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0)
, DummyPlayer
> ServiceInstanceHandle;
ServiceInstanceHandle serviceInstance_;
public:
DummyPlayerService(Subsys::SigTerm terminationHandle);
~DummyPlayerService() { notifyTermination_(&error_); }
/** conceptually, this serves as implementation
* of the DummyPlayer#start() function. But because
* this function sits \em behind the interface, it
* just returns an impl pointer. */
ProcessImpl* start (LumieraDisplaySlot viewerHandle);
};
} // namespace play
} // namespace steam
#endif

View file

@ -71,7 +71,7 @@ namespace play {
// class DummyImageGenerator;
// class TickService;
// class DummyTickService;
class ProcessTable;
class RenderConfigurator;

View file

@ -130098,8 +130098,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
beziehe mich hier per Ged&#228;chtnis auf Sachverhalte, die ich irgenwann irgendwo mal gelesen habe; demnach kann XV mit irgend einer Art von &#187;Compositor&#171; zusammenarbeiten, notfalls aber seine sichtbare (clipping)-Region auch per Colour-Key herausfinden; dabei geht es um die Frage, welcher Teil des Videobildes tats&#228;chlich auf dem Desktop zu sehen ist, denn das Fenster k&#246;nnte partiell verdeckt sein
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#dda58c" COLOR="#5b280f" CREATED="1746756832085" ID="ID_853235588" MODIFIED="1747012941631" TEXT="&#x27f9; in den Grenzen dieses Demo-Codes nicht reparierbar">
<arrowlink COLOR="#db2739" DESTINATION="ID_682377255" ENDARROW="Default" ENDINCLINATION="179;8;" ID="Arrow_ID_438825790" STARTARROW="None" STARTINCLINATION="-4;66;"/>
@ -130142,8 +130141,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
...und geh&#246;rt in einen dedizierten OutputManager
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1747012862178" ID="ID_1494657487" MODIFIED="1747012907629" TEXT="kurzfristig mu&#xdf; ich den DemoImageGenerator umschaltbar machen">
<richcontent TYPE="NOTE"><html>
@ -130153,8 +130151,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
er rechnet ja ohnehin zun&#228;chst in RGB, und macht dann eine YUV-Konvertierung
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
</node>
@ -130171,8 +130168,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
Tip: suche nach &quot;image data&quot;
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1746896115704" ID="ID_830630093" MODIFIED="1746896127222" TEXT="Beschreibung nicht ganz klar wegen Alpha"/>
<node CREATED="1746896128024" ID="ID_1425663830" MODIFIED="1746896136962" TEXT="deute es so: es gibt zwei Varianten">
@ -130236,8 +130232,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
sieht zwar nach nitpicking aus, aber da wir dann explizit per structured-Binding auf die Komponenten zugreifen, k&#246;nnte der Code etwas klarer werden
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1746929669548" ID="ID_485365336" MODIFIED="1746936730029" TEXT="tja... compiliert aber das Ausgabeformat stimmt nicht">
@ -130255,8 +130250,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
...sonst ist es nicht m&#246;glich, das als virtuellen Zugriff f&#252;r Input und Output zu verwenden
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1746936646298" ID="ID_86296092" MODIFIED="1746936667952" TEXT="die 2-Pixel-Schritte hab ich bereits in die Schleifenvariable genommen"/>
</node>
@ -130301,8 +130295,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
...was jetzt einfach an dem Test-Setup liegt, in dem die Komponenten nochmal gewrapped sind
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1747006403724" ID="ID_160039328" MODIFIED="1747006427854" TEXT="Arrrgh &#x2014; es will einfach nicht passen">
@ -130362,8 +130355,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
...denn sonst endet man doch wieder mit z.B. einem Debian-Paket, das <i>build-depends on the world of media processing</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1746893907208" ID="ID_273417317" MODIFIED="1746893913676" TEXT="Initialisierung des Playback">
@ -130383,8 +130375,7 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
sie k&#246;nnte zwar im System installiert und vorhanden sein, aber nicht richtig konfiguriert, vielleicht &#252;berhaupt nie nutzbar sein, oder aber derzeit grade nicht nutzbar (weil eine externe Verbindung oder Ressource fehlt)
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1746895729204" ID="ID_677582239" MODIFIED="1746895739484" TEXT="Caching und Abk&#xfc;rzungen"/>
@ -162395,7 +162386,8 @@ Since then others have made contributions, see the log for the history.</font></
<icon BUILTIN="idea"/>
</node>
<node CREATED="1742175967881" ID="ID_1117969598" MODIFIED="1742175981193" TEXT="Recherche: Basis-Infos zu XV"/>
<node CREATED="1746053053337" ID="ID_385901530" MODIFIED="1746053077036" TEXT="Reste vom alten Video-Widget beurteilen">
<node COLOR="#435e98" CREATED="1746053053337" FOLDED="true" ID="ID_385901530" MODIFIED="1747179141231" TEXT="Reste vom alten Video-Widget beurteilen">
<icon BUILTIN="info"/>
<node CREATED="1742175946044" ID="ID_114770740" MODIFIED="1746053104281" TEXT="Lib-Dependencies">
<node CREATED="1746053105247" ID="ID_1243539235" MODIFIED="1746053166039" TEXT="der eigentliche XV-Code ist vollst&#xe4;ndig">
<richcontent TYPE="NOTE"><html>
@ -162549,12 +162541,12 @@ Since then others have made contributions, see the log for the history.</font></
</body>
</html></richcontent>
</node>
<node CREATED="1746059010720" ID="ID_431781822" MODIFIED="1746059029328" TEXT="es m&#xfc;&#xdf;ten nur wenige Teile (einfach) nach GTK-3 portiert werden">
<node COLOR="#435e98" CREATED="1746059010720" ID="ID_431781822" MODIFIED="1747179152638" TEXT="es m&#xfc;&#xdf;ten nur wenige Teile (einfach) nach GTK-3 portiert werden">
<node CREATED="1746059031084" ID="ID_752582525" MODIFIED="1746059039703" TEXT="das VideoDisplayWidget"/>
<node CREATED="1746059048115" ID="ID_269648070" MODIFIED="1746059068296" TEXT="das ViewerPannel m&#xfc;&#xdf;te man wieder reparieren"/>
<node CREATED="1746059563342" ID="ID_1477952429" MODIFIED="1746059586582" TEXT="eigentlich einfach neu implementieren, nach GTK-Tutorial"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1746059132520" ID="ID_1219347509" MODIFIED="1746226359001" TEXT="Hilfsprojekt: Funktionsf&#xe4;higkeit validieren">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1746059132520" ID="ID_1219347509" MODIFIED="1747179061138" TEXT="Hilfsprojekt: Funktionsf&#xe4;higkeit validieren">
<arrowlink COLOR="#fefeb4" DESTINATION="ID_1819581335" ENDARROW="Default" ENDINCLINATION="-2783;152;" ID="Arrow_ID_1160980366" STARTARROW="None" STARTINCLINATION="-4870;297;"/>
<icon BUILTIN="yes"/>
<node COLOR="#5b280f" CREATED="1746059159380" ID="ID_56657133" MODIFIED="1746059884614" TEXT="es g&#xe4;be noch den DummyPlayer">
@ -162573,7 +162565,7 @@ Since then others have made contributions, see the log for the history.</font></
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1746059388997" ID="ID_1757013848" MODIFIED="1746059905577">
<node BACKGROUND_COLOR="#dcd3ac" COLOR="#435e98" CREATED="1746059388997" ID="ID_1757013848" MODIFIED="1747179047215">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -162593,8 +162585,20 @@ Since then others have made contributions, see the log for the history.</font></
</node>
</node>
<node CREATED="1746059640388" ID="ID_1149968188" MODIFIED="1746059644047" TEXT="danach...">
<node CREATED="1746059645095" ID="ID_1095537094" MODIFIED="1746059662007" TEXT="steht fest: wir k&#xf6;nnen / k&#xf6;nnen nicht Video anzeigen"/>
<node CREATED="1746059663185" ID="ID_473345546" MODIFIED="1746059697070" TEXT="kann der ganze DummyPlayer entfernt werden"/>
<node COLOR="#435e98" CREATED="1746059645095" ID="ID_1095537094" MODIFIED="1747179092024">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
steht fest: <i>wir k&#246;nnen Video anzeigen</i>
</p>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1746059663185" ID="ID_473345546" MODIFIED="1747182536693" TEXT="kann der ganze DummyPlayer entfernt werden">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1746059700212" ID="ID_191158269" MODIFIED="1746059710934" TEXT="k&#xf6;nnte auch gleich die alte Timeline mit entfernt werden"/>
</node>
</node>
@ -162640,6 +162644,9 @@ Since then others have made contributions, see the log for the history.</font></
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1744756270441" ID="ID_831819953" LINK="https://issues.lumiera.org/ticket/473" MODIFIED="1746059845274" TEXT="RefArray und ScopedHolder m&#xfc;ssen jetzt wirklich mal weg">
<arrowlink COLOR="#fd26d0" DESTINATION="ID_1135941103" ENDARROW="Default" ENDINCLINATION="-1048;89;" ID="Arrow_ID_1050531240" STARTARROW="None" STARTINCLINATION="-1120;-23;"/>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1747180091430" ID="ID_202566672" MODIFIED="1747180099934" TEXT="was ist mit ScopedPtrvect?">
<icon BUILTIN="help"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1742175299968" ID="ID_1393531242" MODIFIED="1742175305316" TEXT="C++20">