In the schematics of my previous posts I talked about sources, sinks, pads, nodes and so forth. In my code I have avoided making the pins explicit. Each node is either a sink, a source or both. sink and source are implemented as abstract classes which provide the means to transfer buffers and to notify/get notified when buffers are available.
I decided against using boost::signals in the end because it really introduced alot of unecessary complexities and added a few hundrer kilobytes of extra swag to my errormessages that I really didn't need. Instead I opted for writing my own lean and pretty naive implementation of the observer pattern.
Source.hpp
/*
* Source.hpp
*
* Created on: Jun 12, 2012
* Author: lennart
*/
#ifndef SOURCE_HPP_
#define SOURCE_HPP_
#include "SimpleObserver.hpp"
namespace filtergraph {
using namespace std;
using namespace simple_observer;
template<class T>
class Sink;
template<class T>
class Source: public Observee {
public:
Source() :
Observee() {
}
virtual ~Source() {
}
// Connect the given sink
void addSubscriber(Sink<T> &sink) {
//cout << "addSubscriber()n";
registerObserver((Observer &) sink);
}
// Disconnect the given sink
void removeSubscriber(Sink<T> &sink) {
//cout << "removeSubscriber()n";
removeObserver((Observer &) sink);
}
// Tell sinks connected to this source that a new buffer has arrived
void broadcastSubscribers() {
//cout << "broadcastSubscribers()n";
notifyObservers();
}
// Block until a new buffer object is ready
virtual void pumpSource() = 0;
// Borrow current buffer object
virtual T &borrowBuffer() = 0;
// Return a copy of the current buffer object
T ©Buffer() {
return new T(borrowBuffer());
}
};
} /* namespace filtergraph */
#endif /* SOURCE_HPP_ */
Sink.hpp
#ifndef SINK_HPP_
#define SINK_HPP_
#include "SimpleObserver.hpp"
#include "Source.hpp"
namespace filtergraph {
using namespace std;
using namespace simple_observer;
template<class T>
class Sink: public Observer {
public:
// Connect to the given source
void subscribeTo(Source<T> &source) {
source.addSubscriber(*this);
}
//Disconnect from the given source
void unsubscribeFrom(Source<T> &source) {
source.removeSubscriber(*this);
}
public:
Sink() :
Observer() {
}
virtual ~Sink() {
}
void handleObserverNotification(Observee &observee) {
handleSource((Source<T> &) observee);
}
// Called by sources when new buffer is available
virtual void handleSource(Source<T> &source)=0;
};
} /* namespace filtergraph */
#endif /* SINK_HPP_ */
No comments:
Post a Comment