WIP continue with the skeleton of a DisplayService within the GUI

This commit is contained in:
Fischlurch 2009-02-01 00:43:21 +01:00
parent cc585dd0d6
commit e78383b044
6 changed files with 503 additions and 19 deletions

View file

@ -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
View 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
View 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

View file

@ -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.");
}

View file

@ -98,6 +98,8 @@ namespace lumiera {
class Display
{
public:
/** get an implementation instance of this service */
static lumiera::facade::Accessor<Display> facade;
/**

View file

@ -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.");
}