Lumiera  0.pre.03
»edityourfreedom«
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) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
32 #include "lib/depend-inject.hpp"
33 #include "lib/depend.hpp"
34 
35 extern "C" {
37 }
38 
39 #include <functional>
40 #include <memory>
41 #include <string>
42 
43 
44 
45 namespace proc {
46  namespace play{
47 
48  using std::string;
49  using lumiera::Subsys;
50  using std::unique_ptr;
51  using std::bind;
52 
53 
54 
55  namespace { // hidden local details of the service implementation....
56 
59  class DummyPlayerSubsysDescriptor
60  : public Subsys
61  {
63 
66 
67 
68  operator string () const { return "Dummy-Player"; }
69 
70 
71  bool
72  shouldStart (lumiera::Option&) override
73  {
74  return false; // for now the DummyPlayerService only comes "up" as dependency,
75  } // but doesn't start as a subsystem on it's own.
76 
77  bool
78  start (lumiera::Option&, Subsys::SigTerm terminationHandle) override
79  {
80  ASSERT (!thePlayer_);
81 
82  thePlayer_.createInstance (terminationHandle);
83  return true;
84  }
85 
86  void
87  triggerShutdown () noexcept override
88  {
89  thePlayer_.shutdown();
90  // note: shutdown of the DummyPlayerService instance may block
91  // for a short period, until termination of all tick services
92  }
93 
94  bool
95  checkRunningState () noexcept override
96  {
97  return bool(thePlayer_);
98  }
99  };
100 
101  lib::Depend<DummyPlayerSubsysDescriptor> theDummyPlayerDescriptor;
102 
103 
104 
105 
106 
107  /* ================== define an lumieraorg_DummyPlayer instance ======================= */
108 
109  LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
110  ,lumieraorg_DummyPlayerFacade_descriptor
111  , NULL, NULL, NULL
112  , LUMIERA_INTERFACE_INLINE (name,
113  const char*, (LumieraInterface ifa),
114  { (void)ifa; return "DummyPlayer"; }
115  )
116  , LUMIERA_INTERFACE_INLINE (brief,
117  const char*, (LumieraInterface ifa),
118  { (void)ifa; return "Proc Interface: dummy player to test integration with the GUI"; }
119  )
120  , LUMIERA_INTERFACE_INLINE (homepage,
121  const char*, (LumieraInterface ifa),
122  { (void)ifa; return "http://www.lumiera.org/develompent.html" ;}
123  )
124  , LUMIERA_INTERFACE_INLINE (version,
125  const char*, (LumieraInterface ifa),
126  { (void)ifa; return "0.1~pre"; }
127  )
128  , LUMIERA_INTERFACE_INLINE (author,
129  const char*, (LumieraInterface ifa),
130  { (void)ifa; return "Hermann Vosseler"; }
131  )
132  , LUMIERA_INTERFACE_INLINE (email,
133  const char*, (LumieraInterface ifa),
134  { (void)ifa; return "Ichthyostega@web.de"; }
135  )
136  , LUMIERA_INTERFACE_INLINE (copyright,
137  const char*, (LumieraInterface ifa),
138  {
139  (void)ifa;
140  return
141  "Copyright (C) Lumiera.org\n"
142  " 2009 Hermann Vosseler <Ichthyostega@web.de>";
143  }
144  )
145  , LUMIERA_INTERFACE_INLINE (license,
146  const char*, (LumieraInterface ifa),
147  {
148  (void)ifa;
149  return
150  "This program is free software; you can redistribute it and/or modify\n"
151  "it under the terms of the GNU General Public License as published by\n"
152  "the Free Software Foundation; either version 2 of the License, or\n"
153  "(at your option) any later version.\n"
154  "\n"
155  "This program is distributed in the hope that it will be useful,\n"
156  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
157  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
158  "GNU General Public License for more details.\n"
159  "\n"
160  "You should have received a copy of the GNU General Public License\n"
161  "along with this program; if not, write to the Free Software\n"
162  "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA";
163  }
164  )
165  , LUMIERA_INTERFACE_INLINE (state,
166  int, (LumieraInterface ifa),
167  {(void)ifa; return LUMIERA_INTERFACE_EXPERIMENTAL; }
168  )
169  , LUMIERA_INTERFACE_INLINE (versioncmp,
170  int, (const char* a, const char* b),
171  {(void)a;(void)b; return 0;}
172  )
173  );
174 
175 
176 
177 
178 
179  using lumiera::error::LERR_(LIFECYCLE);
181 
182  typedef ProcessImpl* ProcP;
183 
184 
185  LUMIERA_INTERFACE_INSTANCE (lumieraorg_DummyPlayer, 0
186  ,lumieraorg_DummyPlayerService
187  , LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_DummyPlayerFacade_descriptor)
188  , NULL /* on open */
189  , NULL /* on close */
190  , LUMIERA_INTERFACE_INLINE (startPlay,
191  LumieraPlayProcess, (LumieraDisplaySlot viewerHandle),
192  {
193  if (!_instance)
194  {
195  lumiera_error_set (LUMIERA_ERROR_LIFECYCLE, 0);
196  return 0;
197  }
198 
199  return static_cast<LumieraPlayProcess> (_instance().start(viewerHandle));
200  }
201  )
202  , LUMIERA_INTERFACE_INLINE (togglePlay,
203  void, (LumieraPlayProcess handle, bool doPlay),
204  {
205  if (!_instance)
206  {
207  lumiera_error_set(LUMIERA_ERROR_LIFECYCLE, 0);
208  return;
209  }
210 
211  REQUIRE (handle);
212  ProcP proc = static_cast<ProcP> (handle);
213 
214  proc->doPlay(doPlay);
215  }
216  )
217  , LUMIERA_INTERFACE_INLINE (terminate,
218  void, (LumieraPlayProcess handle),
219  {
220  if (!_instance)
221  {
222  lumiera_error_set(LUMIERA_ERROR_LIFECYCLE, 0);
223  return;
224  }
225 
226  REQUIRE (handle);
227  ProcP proc = static_cast<ProcP> (handle);
228 
229  ProcessImpl::terminate (proc);
230  }
231  )
232  );
233 
234 
235 
236 
237  } // (End) hidden service impl details
238 
239 
240 
241 
243  : error_("")
244  , notifyTermination_(terminationHandle)
245  , serviceInstance_( LUMIERA_INTERFACE_REF (lumieraorg_DummyPlayer, 0, lumieraorg_DummyPlayerService))
246  {
247  INFO (progress, "DummyPlayer Facade opened.");
248  }
249 
250 
251 
252 
263  ProcessImpl*
265  {
266  unique_ptr<ProcessImpl> newProcess (new ProcessImpl (viewerHandle));
267 
268  REQUIRE (!newProcess->isActive());
269  newProcess->setRate(25);
270 
271  return newProcess.release();
272  }
273 
274 
275 
276 
277 
278 
279  /* === Process Implementation === */
280 
281 
283  : fps_{0}
284  , play_{false}
285  , display_{Display::facade().getHandle (viewerHandle)}
286  , imageGen_{}
287  , tick_{new TickService (bind (&ProcessImpl::doFrame, this))}
288  { }
289 
290 
292  {
293  INFO (proc_dbg, "Playback process halted...");
294  }
295 
296 
298  void
300  {
301  if (process)
302  delete process;
303  }
304 
305 
315  {
316  DummyPlayer::Process handle;
317  DummyPlayer::ProcessImplementationLink *const implementationLink = this;
318  handle.activate(implementationLink, &terminate);
319  return handle; // note the deleter function...
320  }
321 
322 
323 
324  void
326  {
327  REQUIRE (fps==0 || fps_==0 );
328  REQUIRE (fps==0 || !play_ );
329  REQUIRE (tick_);
330 
331  fps_ = fps;
332  play_ = (fps != 0);
333 
334  if (play_)
335  imageGen_.reset(new DummyImageGenerator(fps));
336 
337  // callbacks with given frequency, starting now
338  tick_->activate(fps);
339  }
340 
341 
342 
343  void
345  {
346  REQUIRE (isActive());
347  tick_->activate (yes? fps_:0);
348  play_ = yes;
349  }
350 
351 
352 
353  void
355  {
356  REQUIRE (isActive());
357  ASSERT (imageGen_);
358 
359  if (play_)
360  display_(imageGen_->next());
361  else
362  display_(imageGen_->current());
363  }
364 
365 
366 
367  } // namespace play
368 
369 } // namespace proc
370 
371 
372 
373 
374 
375 namespace lumiera {
376 
380  {
381  return proc::play::theDummyPlayerDescriptor();
382  }
383 
384 
385 } // namespace lumiera
DummyPlayerService(Subsys::SigTerm terminationHandle)
void setRate(uint fps)
activate a playback process with given specification
Dependencies and lifecycle of a partially independent Subsystem of the Application.
Definition: subsys.hpp:70
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
lumiera_playprocess * LumieraPlayProcess
Playback process, front-end to be used by client code.
lumiera_displaySlot * LumieraDisplaySlot
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.
Per type specific configuration of instances created as service dependencies.
A public service provided by the Proc-Layer, implementing a dummy/mockup playback process...
Frontend for handling the Lumiera application commandline arguments.
Definition: option.hpp:76
static lumiera::Subsys & getDescriptor()
provide a descriptor for lumiera::AppState, wired accordingly to allow main to deal with the dummy pl...
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:289
Not finished development code.
#define LUMIERA_INTERFACE_INSTANCE(iname, version, name, descriptor, acquire, release,...)
Define an interface instance.
Definition: interface.h:194
void doPlay(bool yes)
forward the play/pause toggle to the play process implementation
#define LERR_(_NAME_)
Definition: error.hpp:58
return NULL
Definition: llist.h:596
#define LUMIERA_INTERFACE_REF(iname, version, dname)
Return a reference (pointer) to an interface implementation.
Definition: interface.h:128
std::unique_ptr< TickService > tick_
void doFrame()
periodically invoked while playing
ProcessImpl(LumieraDisplaySlot)
typename lib::DependInject< FA >::template ServiceInstance< Proxy< InstanceHandle< I, FA > >> ServiceHandle
The ServiceHandle automatically creates and manages the Proxy instance.
static void terminate(DummyPlayer::ProcessImplementationLink *)
deleter function for lib::Handle
ProcessImpl * start(LumieraDisplaySlot viewerHandle)
conceptually, this serves as implementation of the DummyPlayer::start() function. ...
Tick generating service for a periodic callback, with adjustable frequency.
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:105
function< void(string *)> SigTerm
Definition: subsys.hpp:74
Handle & activate(IMP *impl, DEL whenDead)
Activation of the handle by the managing service.
Definition: handle.hpp:115
A data record to describe interface, interface instances and plug-in instances.
Lumiera public interface.
std::unique_ptr< DummyImageGenerator > imageGen_
Proc-Layer implementation namespace root.
Definition: id-scheme.hpp:63
lumiera_interface * LumieraInterface
Definition: interface.h:364
A timer service invoking a given callback periodically.
Actual implementation of a single (dummy) playback process.