Lumiera  0.pre.03
»edit your freedom«
dummy-player-service.cpp
Go to the documentation of this file.
1 /*
2  DummyPlayerService - access point and service implementing a dummy test player
3 
4  Copyright (C)
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
14 
23 #include "lib/depend-inject.hpp"
24 #include "lib/depend.hpp"
25 
26 extern "C" {
28 }
29 
30 #include <functional>
31 #include <memory>
32 #include <string>
33 
34 
35 
36 namespace steam {
37  namespace play{
38 
39  using std::string;
40  using lumiera::Subsys;
41  using std::unique_ptr;
42  using std::bind;
43 
44 
45 
46  namespace { // hidden local details of the service implementation....
47 
51  : public Subsys
52  {
54 
56  ServiceHandle thePlayer_{ServiceHandle::NOT_YET_STARTED};
57 
58 
59  operator string () const { return "Dummy-Player"; }
60 
61 
62  bool
64  {
65  return false; // for now the DummyPlayerService only comes "up" as dependency,
66  } // but doesn't start as a subsystem on it's own.
67 
68  bool
69  start (lumiera::Option&, Subsys::SigTerm terminationHandle) override
70  {
71  ASSERT (!thePlayer_);
72 
73  thePlayer_.createInstance (terminationHandle);
74  return true;
75  }
76 
77  void
78  triggerShutdown () noexcept override
79  {
80  thePlayer_.shutdown();
81  // note: shutdown of the DummyPlayerService instance may block
82  // for a short period, until termination of all tick services
83  }
84 
85  bool
86  checkRunningState () noexcept override
87  {
88  return bool(thePlayer_);
89  }
90  };
91 
92  lib::Depend<DummyPlayerSubsysDescriptor> theDummyPlayerDescriptor;
93 
94 
95 
96 
97 
98  /* ================== define an lumieraorg_DummyPlayer instance ======================= */
99 
100  LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
101  ,lumieraorg_DummyPlayerFacade_descriptor
102  , NULL, NULL, NULL
103  , LUMIERA_INTERFACE_INLINE (name,
104  const char*, (LumieraInterface ifa),
105  { (void)ifa; return "DummyPlayer"; }
106  )
107  , LUMIERA_INTERFACE_INLINE (brief,
108  const char*, (LumieraInterface ifa),
109  { (void)ifa; return "Steam Interface: dummy player to test integration with the GUI"; }
110  )
111  , LUMIERA_INTERFACE_INLINE (homepage,
112  const char*, (LumieraInterface ifa),
113  { (void)ifa; return "http://www.lumiera.org/develompent.html" ;}
114  )
115  , LUMIERA_INTERFACE_INLINE (version,
116  const char*, (LumieraInterface ifa),
117  { (void)ifa; return "0.1~pre"; }
118  )
119  , LUMIERA_INTERFACE_INLINE (author,
120  const char*, (LumieraInterface ifa),
121  { (void)ifa; return "Hermann Vosseler"; }
122  )
123  , LUMIERA_INTERFACE_INLINE (email,
124  const char*, (LumieraInterface ifa),
125  { (void)ifa; return "Ichthyostega@web.de"; }
126  )
127  , LUMIERA_INTERFACE_INLINE (copyright,
128  const char*, (LumieraInterface ifa),
129  {
130  (void)ifa;
131  return
132  "Copyright (C)\n"
133  " 2009, Hermann Vosseler <Ichthyostega@web.de>";
134  }
135  )
136  , LUMIERA_INTERFACE_INLINE (license,
137  const char*, (LumieraInterface ifa),
138  {
139  (void)ifa;
140  return
141  "**Lumiera** is free software; you can redistribute it and/or modify it\n"
142  "under the terms of the GNU General Public License as published by the\n"
143  "Free Software Foundation; either version 2 of the License, or (at your\n"
144  "option) any later version. See the file COPYING for further details."
145  ;
146  }
147  )
148  , LUMIERA_INTERFACE_INLINE (state,
149  int, (LumieraInterface ifa),
150  {(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; }
151  )
152  , LUMIERA_INTERFACE_INLINE (versioncmp,
153  int, (const char* a, const char* b),
154  {(void)a;(void)b; return 0;}
155  )
156  );
157 
158 
159 
160 
161 
162  using LERR_(LIFECYCLE);
164 
165  typedef ProcessImpl* ProcP;
166 
167 
168  LUMIERA_INTERFACE_INSTANCE (lumieraorg_DummyPlayer, 0
169  ,lumieraorg_DummyPlayerService
170  , LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DummyPlayerFacade_descriptor)
171  , NULL /* on open */
172  , NULL /* on close */
173  , LUMIERA_INTERFACE_INLINE (startPlay,
174  LumieraPlayProcess, (LumieraDisplaySlot viewerHandle),
175  {
176  if (!_instance)
177  {
178  lumiera_error_set (LUMIERA_ERROR_LIFECYCLE, 0);
179  return 0;
180  }
181 
182  return static_cast<LumieraPlayProcess> (_instance().start(viewerHandle));
183  }
184  )
185  , LUMIERA_INTERFACE_INLINE (togglePlay,
186  void, (LumieraPlayProcess handle, bool doPlay),
187  {
188  if (!_instance)
189  {
190  lumiera_error_set(LUMIERA_ERROR_LIFECYCLE, 0);
191  return;
192  }
193 
194  REQUIRE (handle);
195  ProcP proc = static_cast<ProcP> (handle);
196 
197  proc->doPlay(doPlay);
198  }
199  )
200  , LUMIERA_INTERFACE_INLINE (terminate,
201  void, (LumieraPlayProcess handle),
202  {
203  if (!_instance)
204  {
205  lumiera_error_set(LUMIERA_ERROR_LIFECYCLE, 0);
206  return;
207  }
208 
209  REQUIRE (handle);
210  ProcP proc = static_cast<ProcP> (handle);
211 
212  ProcessImpl::terminate (proc);
213  }
214  )
215  );
216 
217 
218 
219 
220  } // (End) hidden service impl details
221 
222 
223 
224 
225  DummyPlayerService::DummyPlayerService (Subsys::SigTerm terminationHandle)
226  : error_("")
227  , notifyTermination_(terminationHandle)
228  , serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerService))
229  {
230  INFO (progress, "DummyPlayer Facade opened.");
231  }
232 
233 
234 
235 
246  ProcessImpl*
247  DummyPlayerService::start (LumieraDisplaySlot viewerHandle)
248  {
249  unique_ptr<ProcessImpl> newProcess (new ProcessImpl (viewerHandle));
250 
251  REQUIRE (!newProcess->isActive());
252  newProcess->setRate(25);
253 
254  return newProcess.release();
255  }
256 
257 
258 
259 
260 
261 
262  /* === Process Implementation === */
263 
264 
265  ProcessImpl::ProcessImpl(LumieraDisplaySlot viewerHandle)
266  : fps_{0}
267  , play_{false}
268  , display_{Display::facade().getHandle (viewerHandle)}
269  , imageGen_{}
270  , tick_{new TickService (bind (&ProcessImpl::doFrame, this))}
271  { }
272 
273 
274  ProcessImpl::~ProcessImpl()
275  {
276  INFO (proc_dbg, "Playback process halted...");
277  }
278 
279 
281  void
283  {
284  if (process)
285  delete process;
286  }
287 
288 
298  {
299  DummyPlayer::Process handle;
300  DummyPlayer::ProcessImplementationLink *const implementationLink = this;
301  handle.activate(implementationLink, &terminate);
302  return handle; // note the deleter function...
303  }
304 
305 
306 
307  void
309  {
310  REQUIRE (fps==0 || fps_==0 );
311  REQUIRE (fps==0 || !play_ );
312  REQUIRE (tick_);
313 
314  fps_ = fps;
315  play_ = (fps != 0);
316 
317  if (play_)
318  imageGen_.reset(new DummyImageGenerator(fps));
319 
320  // callbacks with given frequency, starting now
321  tick_->activate(fps);
322  }
323 
324 
325 
326  void
328  {
329  REQUIRE (isActive());
330  tick_->activate (yes? fps_:0);
331  play_ = yes;
332  }
333 
334 
335 
336  void
338  {
339  REQUIRE (isActive());
340  ASSERT (imageGen_);
341 
342  if (play_)
343  display_(imageGen_->next());
344  else
345  display_(imageGen_->current());
346  }
347 
348 
349 
350  } // namespace play
351 
352 } // namespace steam
353 
354 
355 
356 
357 
358 namespace lumiera {
359 
363  {
364  return steam::play::theDummyPlayerDescriptor();
365  }
366 
367 
368 } // namespace lumiera
Dependencies and lifecycle of a partially independent Subsystem of the Application.
Definition: subsys.hpp:61
DummyPlayer::Process createHandle()
activate a forwarding smart-Handle to be used by client code for communication with the play process ...
static lib::Depend< Display > facade
get an implementation instance of this service
Playback process, front-end to be used by client code.
void doPlay(bool yes)
forward the play/pause toggle to the play process implementation
lib::Depend< DummyPlayerService > _instance
a backdoor for the C Language impl to access the actual SessionCommand implementation...
Configuration handle to expose a service implementation through the Depend<SRV> front-end.
Generator for test dummy video frames to simulate playback of rendered output.
ProcessImpl * start(LumieraDisplaySlot viewerHandle)
conceptually, this serves as implementation of the DummyPlayer::start() function. ...
Per type specific configuration of instances created as service dependencies.
A public service provided by the Steam-Layer, implementing a dummy/mockup playback process...
bool checkRunningState() noexcept override
whether this subsystem is actually operational.
Frontend for handling the Lumiera application commandline arguments.
Definition: option.hpp:68
static lumiera::Subsys & getDescriptor()
provide a descriptor for lumiera::AppState, wired accordingly to allow main to deal with the dummy pl...
Steam-Layer implementation namespace root.
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:280
Not finished development code.
bool start(lumiera::Option &, Subsys::SigTerm terminationHandle) override
attempt to bring up this subsystem up.
#define LUMIERA_INTERFACE_INSTANCE(iname, version, name, descriptor, acquire, release,...)
Define an interface instance.
Definition: interface.h:185
bool shouldStart(lumiera::Option &) override
query application option state to determine if this subsystem should be activated.
#define LUMIERA_INTERFACE_REF(iname, version, dname)
Return a reference (pointer) to an interface implementation.
Definition: interface.h:119
void setRate(uint fps)
activate a playback process with given specification
void triggerShutdown() noexcept override
initiate termination of this subsystem.
void doFrame()
periodically invoked while playing
details of how the DummyPlayer service can be started and used as independent "subsystem" within main...
static void terminate(DummyPlayer::ProcessImplementationLink *)
deleter function for lib::Handle
Tick generating service for a periodic callback, with adjustable frequency.
Actual implementation of a single (dummy) playback process.
Singleton services and Dependency Injection.
lumiera_err lumiera_error_set(lumiera_err nerr, const char *extra)
Set error state for the current thread.
Definition: error-state.c:96
Handle & activate(IMP *impl, DEL whenDead)
Activation of the handle by the managing service.
Definition: handle.hpp:112
A data record to describe interface, interface instances and plug-in instances.
Lumiera public interface.
Definition: advice.cpp:104
A timer service invoking a given callback periodically.
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption