added AudioPlayerEventListener, resolving issue #794

see http://bugs.campware.org/view.php?id=794
This commit is contained in:
maroy 2005-04-12 12:06:35 +00:00
parent 8a3acfc9de
commit c29f887c8e
8 changed files with 515 additions and 17 deletions

View file

@ -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 <exception>
#include <stdexcept>
#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

View file

@ -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<AudioPlayerEventListener>::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<AudioPlayerEventListener>::Ref eventListener)
throw (std::invalid_argument) = 0;
/**
* Specify which audio resource to play.
* The file may be a playlist, referencing other files, which

View file

@ -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;

View file

@ -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<AudioPlayerEventListener>::Ref eventListener)
throw ()
{
listeners.push_back(eventListener);
}
/*------------------------------------------------------------------------------
* Detach an event listener.
*----------------------------------------------------------------------------*/
void
HelixPlayer :: detachListener(Ptr<AudioPlayerEventListener>::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
*----------------------------------------------------------------------------*/

View file

@ -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;
* <!ATTLIST helixPlayer fadeLookAheatTime #IMPLIED >
* </pre></code>
*
* @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<Ptr<AudioPlayerEventListener>::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<AudioPlayerEventListener>::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<AudioPlayerEventListener>::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

View file

@ -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<TestEventListener>::Ref listener1(new TestEventListener());
Ptr<TestEventListener>::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<time_duration>::Ref sleepT(new time_duration(microseconds(10)));
Ptr<TestEventListener>::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<TestEventListener>::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();
}

View file

@ -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:
/**

View file

@ -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