Observer pattern doesn't work
Sep 23, 2009 at 4:17pm UTC
Hi,
In my library I have this situation (summarized);
Public Interface header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
struct IAudioEventDispatcher
{
virtual void AttachEventHandler(void * handler) = 0;
virtual void DetachEventHandler(void * handler) = 0;
virtual ~IAudioEventDispatcher(){}
};
struct IWaveStream : public IAudioEventDispatcher
{
...some methods...
}
struct IWaveStreamEvents
{
virtual void OnStreamStateChanged(IWaveStream* Sender, int new_state) = 0;
virtual void OnStreamDebugMsg(IWaveStream* Sender, std::string msg) = 0;
virtual void OnStreamEnd(IWaveStream* Sender) = 0;
};
struct IAudioDevice : public IAudioEventDispatcher
{
...general device methods...
}
struct IAudioPlayer : public IAudioDevice
{
...player specific methods....
}
AudioPlayer implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
class AudioPlayer : public IAudioPlayer, public IWaveStreamEvents
{
public :
// IAudioDevice methods impl
.....
// IAudioPlayer methods impl
....
// IAudioEventDispatcher implementation
void AttachEventHandler(void * handler);
void DetachEventHandler(void * handler);
// Events from WaveStream objects
void OnStreamStateChanged(IWaveStream* Sender, int new_state);
void OnStreamDebugMsg(IWaveStream* Sender, std::string msg);
void OnStreamEnd(IWaveStream* Sender);
private :
std::list<IAudioDeviceEvents*> listeners_;
}
IWaveStream* AudioPlayer::CreateStream(std::string key, int channel)
{
//Create a WaveStream object for the channel
IWaveStream* stream = &this ->Channel(channel).AddStream(key);
//Bind the player to the WaveStream events handler
stream->AttachEventHandler(this );
// Return a reference to the stream object
return stream;
};
WaveStream implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
class ISessionEvents
{
public :
virtual void ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &rtppack) = 0;
virtual void OnTimeout(RTPSourceData *srcdat) = 0;
virtual void OnBYEPacket(RTPSourceData *srcdat) = 0;
};
class EuroRTPSession : public RTPSession
{
private :
ISessionEvents* ev_handler_;
public :
EuroRTPSession(ISessionEvents* ev_handler) : ev_handler_(ev_handler) {};
protected :
void OnPollThreadStep();
void ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &rtppack);
void OnBYEPacket(RTPSourceData *srcdat);
void OnTimeout(RTPSourceData *srcdat);
};
class WaveStream : public IWaveStream, ISessionEvents
{
public :
// IWaveStream implementation
....
// IAudioEventDispatcher implementation
void AttachEventHandler(void * handler);
void DetachEventHandler(void * handler);
// ISessionEvents implementation
void ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &rtppack);
void OnTimeout(RTPSourceData *srcdat);
void OnBYEPacket(RTPSourceData *srcdat);
private :
EuroRTPSession session_;
std::list<IWaveStreamEvents*> listeners_;
}
void EuroRTPSession::ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &rtppack)
{
//Relay the event
if (ev_handler_) ev_handler_->ProcessRTPPacket(srcdat, rtppack);
}
WaveStream::WaveStream() : session_(this )
{
};
void WaveStream::RaiseStateChanged(EStreamState state)
{
state_ = state;
// Call the Event handler for each listeners
BOOST_FOREACH(IWaveStreamEvents* ev, listeners_){
ev->OnStreamStateChanged(this , state);
}
};
void WaveStream::ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &rtppack)
{
// RTP Packet received
if (state_ != SS_RECEIVING) RaiseStateChanged(SS_RECEIVING);
}
The caller program, creates an AudioPlayer object and a WaveStream through the factory method AudioPlayer::CreateStream.
In this method the Player add itself to the WaveStream's listener list to receive its events.
The problem in this code is that, when the flow arrives at WaveStream::RaiseStateChanged the calling to ev->OnStreamStateChanged(this, state); doesn't call AudioPlayer::OnStreamStateChanged and I don't know why!
Any suggestions?
Thanks in advance,
Daniele.
Sep 24, 2009 at 1:13pm UTC
I changed the IWaveStream class, not deriving anymore from IAudioEventDispatcher and adding the two methods explicitly in the class body, specifying the interface instead of void*:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
struct IWaveStreamEvents
{
virtual void OnStreamStateChanged(IWaveStream* Sender, int new_state) = 0;
virtual void OnStreamDebugMsg(IWaveStream* Sender, std::string msg) = 0;
virtual void OnStreamEnd(IWaveStream* Sender) = 0;
};
struct IWaveStream
{
...some methods...
virtual void AttachEventHandler(IWaveStreamEvents* handler) = 0;
virtual void DetachEventHandler(IWaveStreamEvents* handler) = 0;
}
And in this way it works....mah!
Maybe becasue before IAudioPlayer and IWaveStream derives both from IAudioEventDispatcher? I don't know!
Cheers.
Daniele
Topic archived. No new replies allowed.