WIP continue with the skeleton of a DisplayService within the GUI
This commit is contained in:
parent
cc585dd0d6
commit
e78383b044
6 changed files with 503 additions and 19 deletions
|
|
@ -30,10 +30,10 @@ using util::cStr;
|
|||
|
||||
namespace lumiera {
|
||||
namespace facade {
|
||||
|
||||
|
||||
|
||||
|
||||
LUMIERA_ERROR_DEFINE (FACADE_LIFECYCLE, "facade interface currently not accessible");
|
||||
|
||||
|
||||
|
||||
template<class IHA>
|
||||
class Holder;
|
||||
|
|
@ -95,11 +95,11 @@ namespace lumiera {
|
|||
} // namespace facade
|
||||
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ==================== GuiNotification =================================== */
|
||||
|
||||
#include "include/guinotification-facade.h"
|
||||
|
|
@ -115,7 +115,7 @@ namespace gui {
|
|||
|
||||
namespace lumiera {
|
||||
namespace facade {
|
||||
|
||||
|
||||
typedef InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_GuiNotification, 0)
|
||||
, gui::GuiNotification
|
||||
> Handle_GuiNotification;
|
||||
|
|
@ -132,7 +132,7 @@ namespace lumiera {
|
|||
|
||||
|
||||
public:
|
||||
Proxy (IHandle const& iha) : THolder(iha) {}
|
||||
Proxy (IHandle const& iha) : THolder(iha) {}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -142,12 +142,59 @@ namespace lumiera {
|
|||
} // namespace facade
|
||||
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ==================== gui::Display ====================================== */
|
||||
|
||||
#include "include/display-facade.h"
|
||||
|
||||
namespace lumiera {
|
||||
|
||||
/** storage for the facade proxy factory used by client code to invoke through the interface */
|
||||
lumiera::facade::Accessor<Display> Display::facade;
|
||||
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace facade {
|
||||
|
||||
typedef InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_Display, 0)
|
||||
, lumiera::Display
|
||||
> Handle_Display;
|
||||
|
||||
|
||||
template<>
|
||||
class Proxy<Handle_Display>
|
||||
: public Holder<Handle_Display>
|
||||
{
|
||||
//----Proxy-Implementation-of-lumiera::Display--------
|
||||
|
||||
void displayInfo (string const& text) { _i_.displayInfo (cStr(text)); }
|
||||
void triggerGuiShutdown (string const& cause) { _i_.triggerGuiShutdown (cStr(cause)); }
|
||||
|
||||
|
||||
public:
|
||||
Proxy (IHandle const& iha) : THolder(iha) {}
|
||||
};
|
||||
|
||||
|
||||
template void openProxy<Handle_Display> (Handle_Display const&);
|
||||
template void closeProxy<Handle_Display> (void);
|
||||
|
||||
} // namespace facade
|
||||
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ==================== DummyPlayer ======================================= */
|
||||
|
||||
#include "proc/play/dummy-player-service.hpp"
|
||||
|
|
@ -163,7 +210,7 @@ namespace proc {
|
|||
|
||||
namespace lumiera {
|
||||
namespace facade {
|
||||
|
||||
|
||||
typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0)
|
||||
, proc::play::DummyPlayer
|
||||
> Handle_DummyPlayer;
|
||||
|
|
@ -184,8 +231,8 @@ namespace lumiera {
|
|||
* and thus leaves us only with one level of indirection,
|
||||
* irrespective if using the C or C++ interface.
|
||||
*/
|
||||
Process start()
|
||||
{
|
||||
Process start()
|
||||
{
|
||||
ProcessImpl* pP = static_cast<ProcessImpl*> (_i_.startPlay());
|
||||
|
||||
if (!pP)
|
||||
|
|
@ -197,7 +244,7 @@ namespace lumiera {
|
|||
|
||||
|
||||
public:
|
||||
Proxy (IHandle const& iha) : THolder(iha) {}
|
||||
Proxy (IHandle const& iha) : THolder(iha) {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
310
src/gui/display-service.cpp
Normal file
310
src/gui/display-service.cpp
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
DisplayService - service providing access to a display for outputting frames
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "gui/display-service.hpp"
|
||||
//#include "lib/singleton.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "common/interfacedescriptor.h"
|
||||
}
|
||||
|
||||
#include <string>
|
||||
//#include <memory>
|
||||
//#include <boost/scoped_ptr.hpp>
|
||||
|
||||
|
||||
namespace gui {
|
||||
|
||||
using std::string;
|
||||
// using boost::scoped_ptr;
|
||||
|
||||
|
||||
namespace { // hidden local details of the service implementation....
|
||||
|
||||
|
||||
|
||||
/* ================== define an lumieraorg_GuiNotification instance ======================= */
|
||||
|
||||
LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
|
||||
,lumieraorg_DisplayFacade_descriptor
|
||||
, NULL, NULL, NULL
|
||||
, LUMIERA_INTERFACE_INLINE (name, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{ (void)ifa; return "Display"; }
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (brief, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{ (void)ifa; return "UI Interface: service for outputting frames to a viewer or display"; }
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (homepage, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{ (void)ifa; return "http://www.lumiera.org/develompent.html" ;}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (version, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{ (void)ifa; return "0.1~pre"; }
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (author, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{ (void)ifa; return "Hermann Vosseler"; }
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (email, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{ (void)ifa; return "Ichthyostega@web.de"; }
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (copyright, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{
|
||||
(void)ifa;
|
||||
return
|
||||
"Copyright (C) Lumiera.org\n"
|
||||
" 2009 Hermann Vosseler <Ichthyostega@web.de>";
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (license, LUIDGEN,
|
||||
const char*, (LumieraInterface ifa),
|
||||
{
|
||||
(void)ifa;
|
||||
return
|
||||
"This program is free software; you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation; either version 2 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"This program is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with this program; if not, write to the Free Software\n"
|
||||
"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA";
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (state, LUIDGEN,
|
||||
int, (LumieraInterface ifa),
|
||||
{(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; }
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (versioncmp, LUIDGEN,
|
||||
int, (const char* a, const char* b),
|
||||
{return 0;} ////////////////////////////////////////////TODO define version ordering
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using lumiera::facade::LUMIERA_ERROR_FACADE_LIFECYCLE;
|
||||
typedef lib::SingletonRef<DisplayService>::Accessor InstanceRef;
|
||||
|
||||
InstanceRef _instance; ///< a backdoor for the C Language impl to access the actual DummyPlayer implementation...
|
||||
|
||||
typedef ProcessImpl* ProcP; ///////////////TODO
|
||||
|
||||
|
||||
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 (startPlay, LUIDGEN,
|
||||
LumieraPlayProcess, (void),
|
||||
{
|
||||
if (!_instance)
|
||||
{
|
||||
lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<LumieraPlayProcess> (_instance->start());
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (togglePlay, LUIDGEN,
|
||||
void, (LumieraPlayProcess handle, bool doPlay),
|
||||
{
|
||||
if (!_instance)
|
||||
{
|
||||
lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
REQUIRE (handle);
|
||||
ProcP proc = static_cast<ProcP> (handle);
|
||||
|
||||
proc->doPlay(doPlay);
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (terminate, LUIDGEN,
|
||||
void, (LumieraPlayProcess handle),
|
||||
{
|
||||
if (!_instance)
|
||||
{
|
||||
lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
REQUIRE (handle);
|
||||
ProcP proc = static_cast<ProcP> (handle);
|
||||
|
||||
ProcessImpl::terminate (proc);
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (getFrame, LUIDGEN,
|
||||
void *, (LumieraPlayProcess handle),
|
||||
{
|
||||
//skipping full checks for performance reasons
|
||||
REQUIRE (_instance && !lumiera_error_peek());
|
||||
|
||||
REQUIRE (handle);
|
||||
ProcP proc = static_cast<ProcP> (handle);
|
||||
|
||||
return const_cast<void*> (proc->getFrame());
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
} // (End) hidden service impl details
|
||||
|
||||
|
||||
|
||||
|
||||
DisplayService::DisplayService()
|
||||
: error_("")
|
||||
, implInstance_(this,_instance)
|
||||
, serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_Display, 0, lumieraorg_DisplayService))
|
||||
{
|
||||
INFO (progress, "Display 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*
|
||||
DisplayService::start()
|
||||
{
|
||||
auto_ptr<ProcessImpl> newProcess (new ProcessImpl);
|
||||
|
||||
REQUIRE (!newProcess->isActive());
|
||||
newProcess->setRate(25);
|
||||
|
||||
return newProcess.release();
|
||||
}
|
||||
|
||||
|
||||
/* === Forwarding functions on the Process handle === */
|
||||
|
||||
void DummyPlayer::Process::play(bool yes) { impl().doPlay(yes); }
|
||||
void* const DummyPlayer::Process::getFrame() { return impl().getFrame(); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* === Process Implementation === */
|
||||
|
||||
|
||||
ProcessImpl::ProcessImpl()
|
||||
: fps_(0), play_(false), imageGen_(0)
|
||||
{ }
|
||||
|
||||
|
||||
DummyPlayer::Process
|
||||
ProcessImpl::createHandle()
|
||||
{
|
||||
DummyPlayer::Process handle;
|
||||
handle.activate(this, &terminate);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProcessImpl::terminate (ProcessImpl* process)
|
||||
{
|
||||
if (process)
|
||||
delete process;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ProcessImpl::setRate (uint fps)
|
||||
{
|
||||
REQUIRE (fps==0 || fps_==0 );
|
||||
REQUIRE (fps==0 || !play_ );
|
||||
|
||||
fps_ = fps;
|
||||
play_ = (fps != 0);
|
||||
|
||||
if (play_)
|
||||
imageGen_.reset(new DummyImageGenerator(fps));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ProcessImpl::doPlay(bool yes)
|
||||
{
|
||||
REQUIRE (isActive());
|
||||
play_ = yes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void* const
|
||||
ProcessImpl::getFrame()
|
||||
{
|
||||
REQUIRE (isActive());
|
||||
ASSERT (imageGen_);
|
||||
|
||||
if (play_)
|
||||
return imageGen_->next();
|
||||
else
|
||||
return imageGen_->current();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// emit the vtable here into this translation unit within liblumieraproc.so ...
|
||||
DummyPlayer::~DummyPlayer() { }
|
||||
|
||||
|
||||
|
||||
} // namespace proc
|
||||
125
src/gui/display-service.hpp
Normal file
125
src/gui/display-service.hpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
DISPLAY-SERVICE.hpp - service providing access to a display for outputting frames
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
/** @file display-service.hpp
|
||||
** A public service provided by the GUI, implementing the gui::GuiNotification facade interface.
|
||||
** The purpose of this service is to push state update and notification of events from the lower
|
||||
** layers into the Lumiera GUI. Typically, this happens asynchronously and triggered by events
|
||||
** within the lower layers.
|
||||
**
|
||||
** This service is the implementation of a layer separation facade interface. Clients should use
|
||||
** proc::play::DummyPlayer#facade to access this service. This header defines the interface used
|
||||
** to \em provide this service, not to access it.
|
||||
**
|
||||
** @see gui::GuiFacade
|
||||
** @see guifacade.cpp starting this service
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GUI_DISPLAY_SERVICE_H
|
||||
#define GUI_DISPLAY_SERVICE_H
|
||||
|
||||
|
||||
#include "include/display-facade.h"
|
||||
#include "common/instancehandle.hpp"
|
||||
#include "lib/singleton-ref.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace gui {
|
||||
|
||||
using std::string;
|
||||
using lumiera::Display;
|
||||
|
||||
|
||||
// class DummyImageGenerator;
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* 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.
|
||||
*/
|
||||
class DisplayerSlot
|
||||
: public Display::Displayer,
|
||||
boost::noncopyable
|
||||
{
|
||||
|
||||
public:
|
||||
DisplayerSlot() ;
|
||||
|
||||
/* Implementation-level API to be used by DisplayService */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************
|
||||
* 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.
|
||||
* \par
|
||||
* 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
|
||||
: boost::noncopyable
|
||||
{
|
||||
|
||||
string error_;
|
||||
|
||||
|
||||
/* === Interface Lifecycle === */
|
||||
|
||||
typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_Display, 0)
|
||||
, lumiera::Display
|
||||
> ServiceInstanceHandle;
|
||||
|
||||
lib::SingletonRef<DisplayService> implInstance_;
|
||||
ServiceInstanceHandle serviceInstance_;
|
||||
|
||||
public:
|
||||
DisplayService();
|
||||
|
||||
~DummyPlayerService() { } ///TODO
|
||||
|
||||
|
||||
|
||||
/** allocate and lock the given display slot */
|
||||
Display::Displayer getHandle(LumieraDisplaySlot) =0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace gui
|
||||
#endif
|
||||
|
|
@ -140,7 +140,7 @@ namespace gui {
|
|||
|
||||
|
||||
LUMIERA_INTERFACE_INSTANCE (lumieraorg_GuiNotification, 0
|
||||
,lumieraorg_GuiNotificationFacade
|
||||
,lumieraorg_GuiNotificationService
|
||||
, LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_GuiNotificationFacade_descriptor)
|
||||
, NULL /* on open */
|
||||
, NULL /* on close */
|
||||
|
|
@ -171,7 +171,7 @@ namespace gui {
|
|||
|
||||
NotificationService::NotificationService ()
|
||||
: implInstance_(this,_instance),
|
||||
serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_GuiNotification, 0,lumieraorg_GuiNotificationFacade))
|
||||
serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_GuiNotification, 0,lumieraorg_GuiNotificationService))
|
||||
{
|
||||
INFO (gui, "GuiNotification Facade opened.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ namespace lumiera {
|
|||
class Display
|
||||
{
|
||||
public:
|
||||
/** get an implementation instance of this service */
|
||||
static lumiera::facade::Accessor<Display> facade;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ namespace proc {
|
|||
|
||||
|
||||
LUMIERA_INTERFACE_INSTANCE (lumieraorg_DummyPlayer, 0
|
||||
,lumieraorg_DummyPlayerFacade
|
||||
,lumieraorg_DummyPlayerService
|
||||
, LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DummyPlayerFacade_descriptor)
|
||||
, NULL /* on open */
|
||||
, NULL /* on close */
|
||||
|
|
@ -249,7 +249,7 @@ namespace proc {
|
|||
: error_("")
|
||||
, notifyTermination_(terminationHandle)
|
||||
, implInstance_(this,_instance)
|
||||
, serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerFacade))
|
||||
, serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerService))
|
||||
{
|
||||
INFO (progress, "DummyPlayer Facade opened.");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue