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) 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 steam {
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 
60  : public Subsys
61  {
63 
65  ServiceHandle thePlayer_{ServiceHandle::NOT_YET_STARTED};
66 
67 
68  operator string () const { return "Dummy-Player"; }
69 
70 
71  bool
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 "Steam 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 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 
242  DummyPlayerService::DummyPlayerService (Subsys::SigTerm terminationHandle)
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*
264  DummyPlayerService::start (LumieraDisplaySlot viewerHandle)
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 
282  ProcessImpl::ProcessImpl(LumieraDisplaySlot viewerHandle)
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 
291  ProcessImpl::~ProcessImpl()
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 steam
370 
371 
372 
373 
374 
375 namespace lumiera {
376 
380  {
381  return steam::play::theDummyPlayerDescriptor();
382  }
383 
384 
385 } // namespace lumiera
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
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:77
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:289
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:194
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:128
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:105
Handle & activate(IMP *impl, DEL whenDead)
Activation of the handle by the managing service.
Definition: handle.hpp:121
A data record to describe interface, interface instances and plug-in instances.
Lumiera public interface.
Definition: advice.cpp:113
A timer service invoking a given callback periodically.
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption