resolve the remaining liblumieracommon.so dependency problems
now this library doesn't refer to any symbols from Proc-Layer anymore. Resolving these problems highlighted IMHO a serious shortcomming of our interface system, which hinders the building of abstractions at interface level
This commit is contained in:
parent
ef9a6e6f11
commit
4ede0453be
6 changed files with 85 additions and 28 deletions
|
|
@ -25,7 +25,6 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "common/query.hpp"
|
||||
#include "common/config-rules.hpp"
|
||||
#include "proc/mobject/session/query/fake-configrules.hpp"
|
||||
|
||||
using lumiera::QueryKey;
|
||||
|
||||
|
|
|
|||
|
|
@ -74,10 +74,12 @@ namespace lumiera {
|
|||
/** get an implementation instance of this service */
|
||||
static lumiera::facade::Accessor<DummyPlayer> facade;
|
||||
|
||||
class ProcessImplementationLink;
|
||||
|
||||
/**
|
||||
* Continuous playback process, which has been started with a specific
|
||||
* output size, format and framerate. It is a handle to a calculation process,
|
||||
* 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.
|
||||
*
|
||||
|
|
@ -89,14 +91,33 @@ namespace lumiera {
|
|||
* @see dummy-player-service.cpp implementation
|
||||
*/
|
||||
class Process
|
||||
: public lib::Handle<proc::play::ProcessImpl>
|
||||
: 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 Proc-Layer without this indirection
|
||||
* through a VTable, since a direct call would require
|
||||
* us to link against liblumieraproc.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
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////TODO: define some dummy negotiation about size and framerate....
|
||||
|
||||
/** create a new playback process outputting to the given viewer/display */
|
||||
virtual Process start(LumieraDisplaySlot viewerHandle) =0;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
** a callback can be registered to be executed on a specific application lifecycle
|
||||
** event. Examples being #ON_BASIC_INIT, #ON_GLOBAL_INIT. Other subsystems may
|
||||
** register additional events for more specific purpose.
|
||||
**
|
||||
**
|
||||
** @note the implementation resides in lib/lifecycle.cpp and gets linked into liblumiera.so
|
||||
** @see lumiera::AppState
|
||||
** @see main.cpp
|
||||
*/
|
||||
|
|
@ -48,6 +49,7 @@ namespace lumiera {
|
|||
|
||||
using lib::Symbol;
|
||||
|
||||
//defined in liblumiera.so
|
||||
extern const char * ON_BASIC_INIT; ///< automatic static init. treated specially
|
||||
extern const char * ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic!
|
||||
extern const char * ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic!
|
||||
|
|
@ -95,6 +97,7 @@ namespace lumiera {
|
|||
#else /* =========== C interface ====================== */
|
||||
|
||||
|
||||
//defined in liblumiera.so
|
||||
extern const char * lumiera_ON_BASIC_INIT;
|
||||
extern const char * lumiera_ON_GLOBAL_INIT;
|
||||
extern const char * lumiera_ON_GLOBAL_SHUTDOWN;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,20 @@
|
|||
**
|
||||
** 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 Proc-Layer
|
||||
*/
|
||||
|
|
@ -39,7 +52,8 @@
|
|||
|
||||
/* ==================== DummyPlayer ======================================= */
|
||||
|
||||
#include "proc/play/dummy-player-service.hpp"
|
||||
//#include "proc/play/dummy-player-service.hpp"
|
||||
#include "include/dummy-player-facade.h"
|
||||
|
||||
namespace lumiera {
|
||||
|
||||
|
|
@ -56,7 +70,7 @@ namespace lumiera {
|
|||
namespace facade {
|
||||
|
||||
typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0)
|
||||
, proc::play::DummyPlayer
|
||||
, lumiera::DummyPlayer
|
||||
> IHandle_DummyPlayer;
|
||||
|
||||
|
||||
|
|
@ -65,7 +79,7 @@ namespace lumiera {
|
|||
: public Holder<IHandle_DummyPlayer>
|
||||
{
|
||||
//----Proxy-Implementation-of-DummyPlayer--------
|
||||
typedef proc::play::DummyPlayer::Process Process;
|
||||
typedef lumiera::DummyPlayer::Process Process;
|
||||
typedef proc::play::ProcessImpl ProcessImpl;
|
||||
|
||||
/** @note as an optimisation we hand out a direct reference
|
||||
|
|
@ -74,17 +88,19 @@ namespace lumiera {
|
|||
* 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
|
||||
* @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)
|
||||
{
|
||||
ProcessImpl* pP = static_cast<ProcessImpl*> (_i_.startPlay (viewerHandle));
|
||||
ProcessImplementationLink* pP = static_cast<ProcessImplementationLink*> (_i_.startPlay (viewerHandle));
|
||||
|
||||
if (!pP)
|
||||
throw lumiera::error::State("failed to start DummyPlayer", lumiera_error());
|
||||
|
||||
return pP->createHandle();
|
||||
} //////////////////TODO here we get library linking problems: createHandle is implemented in liblumieraproc.so and this is necessarily so.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -99,4 +115,19 @@ namespace lumiera {
|
|||
|
||||
} // namespace facade
|
||||
|
||||
|
||||
/* === Forwarding function(s) on the Process handle === */
|
||||
|
||||
void
|
||||
DummyPlayer::Process::play (bool yes)
|
||||
{
|
||||
// access the implementation via smart-Handle
|
||||
impl().doPlay(yes);
|
||||
}
|
||||
|
||||
// emit the VTable and typeinfo for this interface here (in liblumieracommon.so)
|
||||
DummyPlayer::ProcessImplementationLink::~ProcessImplementationLink() { };
|
||||
|
||||
|
||||
|
||||
} // namespace lumiera
|
||||
|
|
|
|||
|
|
@ -291,21 +291,29 @@ namespace proc {
|
|||
}
|
||||
|
||||
|
||||
/** deleter function for lib::Handle */
|
||||
void
|
||||
ProcessImpl::terminate (ProcessImpl* process) ///< deleter function for lib::Handle
|
||||
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;
|
||||
handle.activate(this, &terminate); // note the deleter function...
|
||||
return handle;
|
||||
DummyPlayer::ProcessImplementationLink *const implementationLink = this;
|
||||
handle.activate(implementationLink, &terminate);
|
||||
return handle; // note the deleter function...
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -344,7 +352,7 @@ namespace proc {
|
|||
{
|
||||
REQUIRE (isActive());
|
||||
ASSERT (imageGen_);
|
||||
|
||||
|
||||
if (play_)
|
||||
display_(imageGen_->next());
|
||||
else
|
||||
|
|
@ -361,13 +369,7 @@ namespace proc {
|
|||
|
||||
|
||||
|
||||
namespace lumiera { /* === Forwarding function(s) on the Process handle === */
|
||||
|
||||
void DummyPlayer::Process::play(bool yes) { impl().doPlay(yes); }
|
||||
|
||||
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
|
||||
/** @internal intended for use by main(). */
|
||||
lumiera::Subsys&
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
** 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 lumiera::DummyPlayer
|
||||
** @see gui::PlaybackController usage example
|
||||
*/
|
||||
|
|
@ -78,7 +78,7 @@ namespace proc {
|
|||
* ProcessImpl instance and have to manage the lifecycle manually.
|
||||
*/
|
||||
class ProcessImpl
|
||||
: public lumiera_playprocess,
|
||||
: public lumiera::DummyPlayer::ProcessImplementationLink,
|
||||
boost::noncopyable
|
||||
{
|
||||
uint fps_;
|
||||
|
|
@ -109,7 +109,7 @@ namespace proc {
|
|||
/* Lifecycle */
|
||||
|
||||
DummyPlayer::Process createHandle();
|
||||
static void terminate(ProcessImpl* process);
|
||||
static void terminate(DummyPlayer::ProcessImplementationLink*);
|
||||
|
||||
private:
|
||||
void doFrame (); ///< periodically invoked while playing
|
||||
|
|
@ -164,3 +164,4 @@ namespace proc {
|
|||
|
||||
} // namespace proc
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue