WIP factor out all signal dispatching from playback-controller into DisplayService and DisplayerSlot

DisplayService is intended to implement the Display facade and additionally
manage N display output sinks (DisplayerSlot). Now the playback-controller
contains just the bare controller logic, all services like tick generation
or signal dispatching have been factored out...  makes me feel better :-)
This commit is contained in:
Fischlurch 2009-02-02 05:25:49 +01:00
parent 06272c2e4b
commit 7de661f4c9
7 changed files with 85 additions and 62 deletions

View file

@ -20,13 +20,18 @@
* *****************************************************/
#include "gui/controller/playback-controller.hpp"
#include "gui/display-service.hpp"
#include "lib/error.hpp"
#include <nobug.h>
namespace gui {
namespace controller {
PlaybackController::PlaybackController() :
playing(false)
{ }
@ -75,45 +80,18 @@ PlaybackController::is_playing()
return playing;
}
//dispatcher.connect(sigc::mem_fun(this, &PlaybackController::on_frame));
void
PlaybackController::attach_viewer(
const sigc::slot<void, void*>& on_frame)
PlaybackController::attach_viewer (FrameDestination const& outputDestination)
{
frame_signal.connect(on_frame);
}
/*
void
PlaybackController::pull_frame()
{
REQUIRE (is_playing());
REQUIRE (playHandle);
/////////////////////TODO: unsolved problem: how to access the display-service from /within/ the GUI??
DisplayService& displayService = do_something_magic();
unsigned char * newBuffer = reinterpret_cast<unsigned char*> (playHandle.getFrame());
if (newBuffer != currentBuffer)
{
currentBuffer = newBuffer;
dispatcher.emit();
}
else
{
TRACE (render, "frame dropped?");
}
viewerHandle_ = displayService.setUp (outputDestination);
}
*/
void
PlaybackController::on_frame()
{
frame_signal.emit(currentBuffer);
}
} // namespace controller
} // namespace gui

View file

@ -27,8 +27,8 @@
#define PLAYBACK_CONTROLLER_HPP
#include "include/dummy-player-facade.h"
#include "include/display-facade.h"
#include <sigc++/sigc++.h>
#include <glibmm.h>
#include <boost/noncopyable.hpp>
@ -63,13 +63,10 @@ private:
volatile bool playing;
Glib::Dispatcher dispatcher;
proc::play::DummyPlayer::Process playHandle;
unsigned char * currentBuffer;
LumieraDisplaySlot viewerHandle_;
sigc::signal<void, void*> frame_signal;
};
} // namespace controller

View file

@ -234,12 +234,22 @@ namespace gui {
/* === Process Implementation === */
/* === DisplayerSlot Implementation === */
ProcessImpl::ProcessImpl()
: fps_(0), play_(false), imageGen_(0)
{ }
DisplayerSlot::DisplayerSlot (FrameDestination const& outputDestination)
: currBuffer_(0)
{
hasFrame_.connect (outputDestination);
dispatcher_.connect (sigc::mem_fun (this, &DisplayerSlot::displayCurrentFrame));
}
void
DisplayerSlot::displayCurrentFrame()
{
hasFrame_.emit (currentBuffer_);
}
DummyPlayer::Process

View file

@ -43,37 +43,60 @@
#include "common/instancehandle.hpp"
#include "lib/singleton-ref.hpp"
#include <sigc++/sigc++.h>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <string>
#include <vector>
namespace gui {
using std::string;
using std::vector;
using boost::scoped_ptr;
using lumiera::Display;
using Glib::Dispatcher;
// class DummyImageGenerator;
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 to output frames
* to a viewer widget executing within the GTK event thread.
* 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 Display::Displayer,
boost::noncopyable
: boost::noncopyable
{
Dispatcher dispatcher_;
FrameSignal hasFrame_;
LumieraDisplayFrame currBuffer_;
public:
DisplayerSlot() ;
DisplayerSlot (FrameDestination const&) ;
/* Implementation-level API to be used by DisplayService */
/** receive a frame to be displayed */
inline void put (LumieraDisplayFrame);
private:
/** internal: activated via Dispatcher
* and running in GTK main thread */
void displayCurrentFrame();
};
typedef vector<scoped_ptr<DisplayerSlot> > DisplayerTab;
/******************************************************
@ -95,6 +118,7 @@ namespace gui {
{
string error_;
DisplayerTab slots_;
/* === Interface Lifecycle === */
@ -106,20 +130,35 @@ namespace gui {
lib::SingletonRef<DisplayService> implInstance_;
ServiceInstanceHandle serviceInstance_;
public:
DisplayService();
~DummyPlayerService() { } ///TODO
/** allocate and lock the given display slot */
Display::Displayer getHandle(LumieraDisplaySlot) =0;
LumieraDisplaySlot setUp (FrameDestination const&);
};
void
DisplayerSlot::put(LumieraDisplayFrame newFrame)
{
if (newFrame != currBuffer_)
{
currBuffer_ = newFrame;
dispatcher_.emit();
}
else
{
TRACE (render, "frame dropped?");
}
}
} // namespace gui
#endif

View file

@ -48,7 +48,7 @@
#include <locale> // need to include this to prevent errors when libintl.h defines textdomain (because gtk-lumiera removes the def when ENABLE_NLS isn't defined)
#include "gui/gtk-lumiera.hpp" // need to include this before nobugcfg.h, because types.h from GTK tries to shaddow the ERROR macro from windows, which kills nobug's ERROR macro
// TODO not needed? #include "include/logging.h"
#include "lib/error.hpp"
#include "gui/guifacade.hpp"
#include "gui/notification-service.hpp"
@ -110,7 +110,7 @@ namespace gui {
gui::application().main(argc, argv); // execute the GTK Event Loop
if (!lumiera_error_peek())
return;
return; // all went well, normal shutdown
}
catch (lumiera::Error& problem)
{
@ -149,7 +149,7 @@ namespace gui {
if (!lumiera_error_peek())
LUMIERA_ERROR_SET (gui, STATE, "unexpected error when starting the GUI thread");
return false;
}
} // note: lumiera_error state remains set
}
} // namespace gui

View file

@ -47,11 +47,7 @@ struct lumiera_displaySlot_struct
typedef struct lumiera_displaySlot_struct LumieraDisplaySlot; ///< value semantics
struct lumiera_displayFrame_struct
{
void* const buff_;
};
typedef struct lumiera_displayFrame_struct LumieraDisplayFrame;
typedef unsigned char * LumieraDisplayFrame;
@ -105,15 +101,15 @@ namespace lumiera {
/**
* Functor for pushing frames to the display
*/
typedef function<void(Frame*)> Displayer;
typedef function<void(LumieraDisplayFrame)> Sink;
/** allocate an already existing display/viewer for output
* @return a functor representing the frame sink */
virtual Displayer getHandle(LumieraDisplaySlot) =0;
virtual Sink getHandle(LumieraDisplaySlot) =0;
virtual ~DummyPlayer();
virtual ~Display();
};

View file

@ -296,7 +296,10 @@ namespace proc {
ProcessImpl::ProcessImpl()
: fps_(0), play_(false), imageGen_(0), tick_(new TickService (bind (ProcessImpl::doFrame, this)))
: fps_(0)
, play_(false)
, imageGen_(0)
, tick_(new TickService (bind (ProcessImpl::doFrame, this)))
{ }