diff --git a/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerEventListener.h b/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerEventListener.h new file mode 100644 index 000000000..1a6278080 --- /dev/null +++ b/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerEventListener.h @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport 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. + + LiveSupport 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 LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: maroy $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerEventListener.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef AudioPlayerEventListener_h +#define AudioPlayerEventListener_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include +#include + +#include "LiveSupport/Core/Ptr.h" + + +namespace LiveSupport { +namespace PlaylistExecutor { + +using namespace boost; + +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An event listener interface, for catching events of an audio player. + * + * @author $Author: maroy $ + * @version $Revision: 1.1 $ + * @see AudioPlayerInterface + */ +class AudioPlayerEventListener +{ + public: + /** + * A virtual destructor, as this class has virtual functions. + */ + virtual + ~AudioPlayerEventListener(void) throw () + { + } + + /** + * Catch the event when playing has stopped. + * This will happen probably due to the fact that the + * audio clip has been played to its end. + */ + virtual void + onStop(void) throw () = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace PlaylistExecutor +} // namespace LiveSupport + + +#endif // AudioPlayerEventListener_h + diff --git a/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h b/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h index b2f80b2fc..bf83cf430 100644 --- a/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h +++ b/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: fgerlits $ - Version : $Revision: 1.7 $ + Author : $Author: maroy $ + Version : $Revision: 1.8 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/include/LiveSupport/PlaylistExecutor/AudioPlayerInterface.h,v $ ------------------------------------------------------------------------------*/ @@ -48,6 +48,7 @@ #include "LiveSupport/Core/Ptr.h" #include "LiveSupport/Core/Playlist.h" +#include "LiveSupport/PlaylistExecutor/AudioPlayerEventListener.h" namespace LiveSupport { namespace PlaylistExecutor { @@ -67,8 +68,8 @@ using namespace LiveSupport::Core; /** * A generic interface for playing audio files. * - * @author $Author: fgerlits $ - * @version $Revision: 1.7 $ + * @author $Author: maroy $ + * @version $Revision: 1.8 $ */ class AudioPlayerInterface { @@ -96,6 +97,30 @@ class AudioPlayerInterface virtual void deInitialize(void) throw () = 0; + /** + * Attach an event listener for this audio player. + * After this call, the supplied event will recieve all events + * related to this audio player. + * + * @param eventListener the event listener to register. + * @see #detach + */ + virtual void + attachListener(Ptr::Ref eventListener) + throw () = 0; + + /** + * Detach an event listener for this audio player. + * + * @param eventListener the event listener to unregister. + * @exception std::invalid_argument if the supplied event listener + * has not been previously registered. + * @see #attach + */ + virtual void + detachListener(Ptr::Ref eventListener) + throw (std::invalid_argument) = 0; + /** * Specify which audio resource to play. * The file may be a playlist, referencing other files, which diff --git a/livesupport/modules/playlistExecutor/src/AdviseSink.cxx b/livesupport/modules/playlistExecutor/src/AdviseSink.cxx index 17e6fb635..aff14cdfd 100644 --- a/livesupport/modules/playlistExecutor/src/AdviseSink.cxx +++ b/livesupport/modules/playlistExecutor/src/AdviseSink.cxx @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: fgerlits $ - Version : $Revision: 1.3 $ + Author : $Author: maroy $ + Version : $Revision: 1.4 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/AdviseSink.cxx,v $ ------------------------------------------------------------------------------*/ @@ -255,6 +255,8 @@ AdviseSink::OnStop(void) throw () now = pScheduler->GetCurrentSchedulerTime(); ulStopTime = now.tv_sec; + helixPlayer->fireOnStopEvent(); + // TODO: maybe save the number of seconds played? // GetGlobal()->g_ulNumSecondsPlayed = ulStopTime - ulStartTime; diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx b/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx index 8bb9aef4b..afdb0382a 100644 --- a/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx +++ b/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.18 $ + Version : $Revision: 1.19 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayer.cxx,v $ ------------------------------------------------------------------------------*/ @@ -269,6 +269,55 @@ HelixPlayer :: deInitialize(void) throw () } +/*------------------------------------------------------------------------------ + * Attach an event listener. + *----------------------------------------------------------------------------*/ +void +HelixPlayer :: attachListener(Ptr::Ref eventListener) + throw () +{ + listeners.push_back(eventListener); +} + + +/*------------------------------------------------------------------------------ + * Detach an event listener. + *----------------------------------------------------------------------------*/ +void +HelixPlayer :: detachListener(Ptr::Ref eventListener) + throw (std::invalid_argument) +{ + ListenerVector::iterator it = listeners.begin(); + ListenerVector::iterator end = listeners.end(); + + while (it != end) { + if ((*it).get() == eventListener.get()) { + listeners.erase(it); + return; + } + ++it; + } + + throw std::invalid_argument("supplied event listener not found"); +} + + +/*------------------------------------------------------------------------------ + * Send the onStop event to all attached listeners. + *----------------------------------------------------------------------------*/ +void +HelixPlayer :: fireOnStopEvent(void) throw () +{ + ListenerVector::iterator it = listeners.begin(); + ListenerVector::iterator end = listeners.end(); + + while (it != end) { + (*it)->onStop(); + ++it; + } +} + + /*------------------------------------------------------------------------------ * Specify which file to play *----------------------------------------------------------------------------*/ diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayer.h b/livesupport/modules/playlistExecutor/src/HelixPlayer.h index be21c03d3..17e9999a4 100644 --- a/livesupport/modules/playlistExecutor/src/HelixPlayer.h +++ b/livesupport/modules/playlistExecutor/src/HelixPlayer.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: fgerlits $ - Version : $Revision: 1.15 $ + Author : $Author: maroy $ + Version : $Revision: 1.16 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayer.h,v $ ------------------------------------------------------------------------------*/ @@ -111,8 +111,8 @@ using namespace LiveSupport::Core; * * * - * @author $Author: fgerlits $ - * @version $Revision: 1.15 $ + * @author $Author: maroy $ + * @version $Revision: 1.16 $ */ class HelixPlayer : virtual public Configurable, virtual public AudioPlayerInterface, @@ -193,6 +193,20 @@ class HelixPlayer : virtual public Configurable, */ bool playing; + /** + * The type for the vector of listeners. + * Just a shorthand notation, to make reference to the type + * easier. + */ + typedef std::vector::Ref> + ListenerVector; + + /** + * A vector of event listeners, which are interested in events + * related to this player. + */ + ListenerVector listeners; + /** * A thread for handling helix events, on a regular basis. * Helix apperantly needs to be polled all the time to function. @@ -299,6 +313,36 @@ class HelixPlayer : virtual public Configurable, virtual void deInitialize(void) throw (); + /** + * Attach an event listener for this audio player. + * After this call, the supplied event will recieve all events + * related to this audio player. + * + * @param eventListener the event listener to register. + * @see #detach + */ + virtual void + attachListener(Ptr::Ref eventListener) + throw (); + + /** + * Detach an event listener for this audio player. + * + * @param eventListener the event listener to unregister. + * @exception std::invalid_argument if the supplied event listener + * has not been previously registered. + * @see #attach + */ + virtual void + detachListener(Ptr::Ref eventListener) + throw (std::invalid_argument); + + /** + * Send the onStop event to all attached listeners. + */ + virtual void + fireOnStopEvent(void) throw (); + /** * Specify which audio resource to play. * The file may be a playlist, referencing other files, which diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx index 156e7bc04..024d6cd44 100644 --- a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx +++ b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: fgerlits $ - Version : $Revision: 1.10 $ + Author : $Author: maroy $ + Version : $Revision: 1.11 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayerTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -46,6 +46,7 @@ #include "LiveSupport/Core/TimeConversion.h" #include "HelixPlayer.h" +#include "TestEventListener.h" #include "HelixPlayerTest.h" @@ -431,3 +432,142 @@ HelixPlayerTest :: animationWorkaroundTest(void) helixPlayer->deInitialize(); } + + +/*------------------------------------------------------------------------------ + * Test to see if attaching and detaching event listeners works. + *----------------------------------------------------------------------------*/ +void +HelixPlayerTest :: eventListenerAttachTest(void) + throw (CPPUNIT_NS::Exception) +{ + CPPUNIT_ASSERT_NO_THROW(helixPlayer->initialize()); + + Ptr::Ref listener1(new TestEventListener()); + Ptr::Ref listener2(new TestEventListener()); + bool gotException; + + // try with one listener + helixPlayer->attachListener(listener1); + try { + helixPlayer->detachListener(listener1); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + gotException = false; + try { + helixPlayer->detachListener(listener1); + } catch (std::invalid_argument &e) { + gotException = true; + } + CPPUNIT_ASSERT(gotException); + + // try with two listeners + helixPlayer->attachListener(listener1); + gotException = false; + try { + helixPlayer->detachListener(listener2); + } catch (std::invalid_argument &e) { + gotException = true; + } + CPPUNIT_ASSERT(gotException); + helixPlayer->attachListener(listener2); + try { + helixPlayer->detachListener(listener1); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + + helixPlayer->deInitialize(); +} + + +/*------------------------------------------------------------------------------ + * Test to see if the player event listener mechanism works. + *----------------------------------------------------------------------------*/ +void +HelixPlayerTest :: eventListenerTest(void) + throw (CPPUNIT_NS::Exception) +{ + CPPUNIT_ASSERT_NO_THROW(helixPlayer->initialize()); + + Ptr::Ref sleepT(new time_duration(microseconds(10))); + Ptr::Ref listener1(new TestEventListener()); + helixPlayer->attachListener(listener1); + + // try with one listener + CPPUNIT_ASSERT(!listener1->stopFlag); + try { + helixPlayer->open("file:var/test.mp3"); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(!helixPlayer->isPlaying()); + CPPUNIT_ASSERT(!listener1->stopFlag); + helixPlayer->start(); + CPPUNIT_ASSERT(helixPlayer->isPlaying()); + CPPUNIT_ASSERT(!listener1->stopFlag); + while (helixPlayer->isPlaying()) { + CPPUNIT_ASSERT(!listener1->stopFlag); + TimeConversion::sleep(sleepT); + } + CPPUNIT_ASSERT(!helixPlayer->isPlaying()); + CPPUNIT_ASSERT(listener1->stopFlag); + listener1->stopFlag = false; + + // try with two listeners + Ptr::Ref listener2(new TestEventListener()); + helixPlayer->attachListener(listener2); + + CPPUNIT_ASSERT(!listener1->stopFlag); + CPPUNIT_ASSERT(!listener2->stopFlag); + try { + helixPlayer->open("file:var/test.mp3"); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(!helixPlayer->isPlaying()); + CPPUNIT_ASSERT(!listener1->stopFlag); + CPPUNIT_ASSERT(!listener2->stopFlag); + helixPlayer->start(); + CPPUNIT_ASSERT(helixPlayer->isPlaying()); + CPPUNIT_ASSERT(!listener1->stopFlag); + CPPUNIT_ASSERT(!listener2->stopFlag); + while (helixPlayer->isPlaying()) { + CPPUNIT_ASSERT(!listener1->stopFlag); + CPPUNIT_ASSERT(!listener2->stopFlag); + TimeConversion::sleep(sleepT); + } + CPPUNIT_ASSERT(!helixPlayer->isPlaying()); + CPPUNIT_ASSERT(listener1->stopFlag); + CPPUNIT_ASSERT(listener2->stopFlag); + listener1->stopFlag = false; + listener2->stopFlag = false; + + // try with only the second listener + helixPlayer->detachListener(listener1); + + CPPUNIT_ASSERT(!listener2->stopFlag); + try { + helixPlayer->open("file:var/test.mp3"); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(!helixPlayer->isPlaying()); + CPPUNIT_ASSERT(!listener2->stopFlag); + helixPlayer->start(); + CPPUNIT_ASSERT(helixPlayer->isPlaying()); + CPPUNIT_ASSERT(!listener2->stopFlag); + while (helixPlayer->isPlaying()) { + CPPUNIT_ASSERT(!listener2->stopFlag); + TimeConversion::sleep(sleepT); + } + CPPUNIT_ASSERT(!helixPlayer->isPlaying()); + CPPUNIT_ASSERT(listener2->stopFlag); + listener2->stopFlag = false; + + + helixPlayer->close(); + helixPlayer->deInitialize(); +} + diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h index 5fbaca722..beb277926 100644 --- a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h +++ b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: fgerlits $ - Version : $Revision: 1.8 $ + Author : $Author: maroy $ + Version : $Revision: 1.9 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayerTest.h,v $ ------------------------------------------------------------------------------*/ @@ -57,8 +57,8 @@ namespace PlaylistExecutor { /** * Unit test for the HelixPlayer class. * - * @author $Author: fgerlits $ - * @version $Revision: 1.8 $ + * @author $Author: maroy $ + * @version $Revision: 1.9 $ * @see HelixPlayer */ class HelixPlayerTest : public CPPUNIT_NS::TestFixture @@ -69,13 +69,17 @@ class HelixPlayerTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(simplePlayTest); CPPUNIT_TEST(checkErrorConditions); CPPUNIT_TEST(smilTest); + // CPPUNIT_TEST(smilParallelTest0); // CPPUNIT_TEST(smilParallelTest1); // CPPUNIT_TEST(smilParallelTest2); // CPPUNIT_TEST(smilParallelTest3); // CPPUNIT_TEST(smilParallelTest4); // CPPUNIT_TEST(smilSoundAnimationTest); + CPPUNIT_TEST(animationWorkaroundTest); + CPPUNIT_TEST(eventListenerAttachTest); + CPPUNIT_TEST(eventListenerTest); CPPUNIT_TEST_SUITE_END(); private: @@ -194,6 +198,22 @@ class HelixPlayerTest : public CPPUNIT_NS::TestFixture void animationWorkaroundTest(void) throw (CPPUNIT_NS::Exception); + /** + * Test to see if attaching and detaching event listeners works. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + eventListenerAttachTest(void) throw (CPPUNIT_NS::Exception); + + /** + * Test to see if the player event listener mechanism works. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + eventListenerTest(void) throw (CPPUNIT_NS::Exception); + public: /** diff --git a/livesupport/modules/playlistExecutor/src/TestEventListener.h b/livesupport/modules/playlistExecutor/src/TestEventListener.h new file mode 100644 index 000000000..e108cbd5a --- /dev/null +++ b/livesupport/modules/playlistExecutor/src/TestEventListener.h @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Media Development Loan Fund + + This file is part of the LiveSupport project. + http://livesupport.campware.org/ + To report bugs, send an e-mail to bugs@campware.org + + LiveSupport 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. + + LiveSupport 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 LiveSupport; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + Author : $Author: maroy $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/TestEventListener.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef TestEventListener_h +#define TestEventListener_h + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "configure.h" +#endif + +#include "LiveSupport/PlaylistExecutor/AudioPlayerEventListener.h" + + +namespace LiveSupport { +namespace PlaylistExecutor { + +using namespace boost; + +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A simple event listener, used for testing. + * + * @author $Author: maroy $ + * @version $Revision: 1.1 $ + */ +class TestEventListener : public AudioPlayerEventListener +{ + public: + /** + * A flag set by the onStop() event to true. + */ + bool stopFlag; + + /** + * Constructor + */ + TestEventListener(void) throw () + { + stopFlag = false; + } + + /** + * A virtual destructor, as this class has virtual functions. + */ + virtual + ~TestEventListener(void) throw () + { + } + + /** + * Catch the event when playing has stopped. + * This will happen probably due to the fact that the + * audio clip has been played to its end. + */ + virtual void + onStop(void) throw () + { + stopFlag = true; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +} // namespace PlaylistExecutor +} // namespace LiveSupport + + +#endif // TestEventListener_h +