Python's PubSub/observer Pattern for C++? - c++

i'm looking for a C++ replacement of the Python PubSub Library in which i don't have to connect a signal with a slot or so, but instead can register for a special Kind of messages, without knowing the object which can send it.

Perhaps you misunderstand what signals and slots are. With signals and slots you don't have to know who sends signals. Your "client" class just declares slots, and an outside manager can connect signals to them.
I recommend you to check out Qt. It's an amazing cross-platform library with much more than just GUI support. It has a convenient and efficient implementation of signals and slots which you can use.
These days it's also licensed with LGPL (in addition to GPL and commercial), so you can use it for practically any purpose.
Re your clarification comment, why not raise an exception for the error? The parent can notify the GUI, or alternatively the GUI can register for a signal the parent emits. This way the parent also doesn't have to know about the GUI.

Can you use the boost libraries? If so then combining the function and bind libraries allows you to do the following. You may be able to do the same using the tr1 functionality if your compiler supports it.
#include <iostream>
#include <list>
#include <boost/function.hpp>
#include <boost/bind.hpp>
typedef boost::function< void() > EVENT_T ;
template<typename F>
class Subject
{
public:
virtual void attach ( F o )
{
obs_.push_back ( o );
}
virtual void notify()
{
for ( typename std::list<F>::iterator i = obs_.begin(); i != obs_.end(); ++i )
( *i ) ();
}
private:
std::list<F> obs_;
} ;
class Button : public Subject<EVENT_T>
{
public:
void onClick()
{
notify() ;
};
};
class Player
{
public:
void play()
{
std::cout << "play" << std::endl ;
}
void stop()
{
std::cout << "stop" << std::endl ;
}
};
class Display
{
public:
void started()
{
std::cout << "Started playing" << std::endl ;
}
};
Button playButton ;
Button stopButton ;
Player thePlayer;
Display theDisplay ;
int main ( int argc, char **argv )
{
playButton.attach ( boost::bind ( &Player::play, &thePlayer ) );
playButton.attach ( boost::bind ( &Display::started, &theDisplay ) );
stopButton.attach ( boost::bind ( &Player::stop, &thePlayer ) );
playButton.onClick() ;
stopButton.onClick() ;
return 0;
}
So when you run this you get:
play
Started playing
stop
Press any key to continue.
So.. is this the kind of thing you are looking for?
See here and here for the source of most of this code.
EDIT: The boost::signal library might also do what you want.

Why don't you just implement one? It's not a complicated pattern (well, depending what you really want). Anyway, I already implemented a quick and dirty one some time ago. It is not optimized, synchronous and single threaded. I hope you can use it to make your own.
#include <vector>
#include <iostream>
#include <algorithm>
template<typename MESSAGE> class Topic;
class Subscriber;
class TopicBase
{
friend class Subscriber;
private:
virtual void RemoveSubscriber(Subscriber* subscriber)=0;
};
template<typename MESSAGE>
class Topic : public TopicBase
{
friend class Subscriber;
private:
class Callable
{
public:
Callable(Subscriber* subscriber, void (Subscriber::*method)(const MESSAGE&))
:m_subscriber(subscriber)
,m_method(method)
{
}
void operator()(const MESSAGE& message)
{
(m_subscriber->*m_method)(message);
}
bool operator==(const Callable& other) const
{
return m_subscriber == other.m_subscriber && m_method == other.m_method;
}
public:
Subscriber* m_subscriber;
void (Subscriber::*m_method)(const MESSAGE&);
};
public:
~Topic()
{
//unregister each subscriber
for(std::vector<Callable>::iterator i = m_subscribers.begin(); i != m_subscribers.end(); i++)
{
std::vector<TopicBase*>& topics = i->m_subscriber->m_topics;
for(std::vector<TopicBase*>::iterator ti = topics.begin();;)
{
ti = std::find(ti, topics.end(), this);
if(ti == topics.end()) break;
ti = topics.erase(ti);
}
}
}
void SendMessage(const MESSAGE& message)
{
for(std::vector<Callable>::iterator i = m_subscribers.begin(); i != m_subscribers.end(); i++)
{
(*i)(message);
}
}
private:
void Subscribe(Subscriber* subscriber, void (Subscriber::*method)(const MESSAGE&))
{
m_subscribers.push_back(Callable(subscriber, method));
subscriber->m_topics.push_back(this);
}
void Unsubscribe(Subscriber* subscriber, void (Subscriber::*method)(const MESSAGE&))
{
std::vector<Callable>::iterator i = std::find(m_subscribers.begin(), m_subscribers.end(), Callable(subscriber, method));
if(i != m_subscribers.end())
{
m_subscribers.erase(i);
subscriber->m_topics.erase(std::find(subscriber->m_topics.begin(), subscriber->m_topics.end(), this)); //should always find one
}
}
virtual void RemoveSubscriber(Subscriber* subscriber)
{
for(std::vector<Callable>::iterator i = m_subscribers.begin() ; i != m_subscribers.end(); i++)
{
if(i->m_subscriber == subscriber)
{
m_subscribers.erase(i);
break;
}
}
}
private:
std::vector<Callable> m_subscribers;
};
class Subscriber
{
template<typename T> friend class Topic;
public:
~Subscriber()
{
for(std::vector<TopicBase*>::iterator i = m_topics.begin(); i !=m_topics.end(); i++)
{
(*i)->RemoveSubscriber(this);
}
}
protected:
template<typename MESSAGE, typename SUBSCRIBER>
void Subscribe(Topic<MESSAGE>& topic, void (SUBSCRIBER::*method)(const MESSAGE&))
{
topic.Subscribe(this, static_cast<void (Subscriber::*)(const MESSAGE&)>(method));
}
template<typename MESSAGE, typename SUBSCRIBER>
void Unsubscribe(Topic<MESSAGE>& topic, void (SUBSCRIBER::*method)(const MESSAGE&))
{
topic.Unsubscribe(this, static_cast<void (Subscriber::*)(const MESSAGE&)>(method));
}
private:
std::vector<TopicBase*> m_topics;
};
// Test
Topic<int> Topic1;
class TestSubscriber1 : public Subscriber
{
public:
TestSubscriber1()
{
Subscribe(Topic1, &TestSubscriber1::onTopic1);
}
private:
void onTopic1(const int& message)
{
std::cout<<"TestSubscriber1::onTopic1 "<<message<<std::endl;
}
};
class TestSubscriber2 : public Subscriber
{
public:
void Subscribe(Topic<const char*> &subscriber)
{
Subscriber::Subscribe(subscriber, &TestSubscriber2::onTopic);
}
void Unsubscribe(Topic<const char*> &subscriber)
{
Subscriber::Unsubscribe(subscriber, &TestSubscriber2::onTopic);
}
private:
void onTopic(const char* const& message)
{
std::cout<<"TestSubscriber1::onTopic1 "<<message<<std::endl;
}
};
int main()
{
Topic<const char*>* topic2 = new Topic<const char*>();
{
TestSubscriber1 testSubscriber1;
Topic1.SendMessage(42);
Topic1.SendMessage(5);
}
Topic1.SendMessage(256);
TestSubscriber2 testSubscriber2;
testSubscriber2.Subscribe(*topic2);
topic2->SendMessage("owl");
testSubscriber2.Unsubscribe(*topic2);
topic2->SendMessage("owl");
testSubscriber2.Subscribe(*topic2);
delete topic2;
return 0;
}

Related

I want to use abstract classes from C++, but why do I get a segfault?

My purpose is to register the Hanlder object in the KibanaManager. When the KibanaManager obtains the log from the kibana server regularly, it will hand over the log to the Hanlder object in the queue for processing.
For example, if the Handler finds the ERROR log, it will call the showMessage function of Qt's SystemTrayIcon. A message popup appears in the lower right corner.
code show as below:
kibana.h:
namespace favour {
enum KIBANA_LOG_LEVEL {
...
};
struct KibanaLog {
...
};
class KEHandler {
public:
virtual void handler(KibanaLog *kl) {};
};
class KibanaManager {
private:
static std::vector<KEHandler *> HANDLERS;
public:
static void init();
static void registerHandler(KEHandler *handler);
private:
static void polling(void *message);
};
}
#endif
kibana.cpp:
using namespace std;
namespace favour {
vector<KEHandler *> KibanaManager::HANDLERS = vector<KEHandler *>();
void KibanaManager::init() {
pthread_t threadId;
int code = pthread_create(&threadId, nullptr, (void *(*)(void *)) &polling, nullptr);
if (code) {
errno = code;
string message = "Kibana Manager init failed.";
message.append(strerror(errno));
throw runtime_error(message);
}
}
void KibanaManager::registerHandler(KEHandler *handler) {
for (auto item : HANDLERS) {
if (item == handler) return;
}
HANDLERS.push_back(handler);
}
void KibanaManager::polling(void *message) {
while (1) {
sleep(1);
for (auto h : HANDLERS) {
KibanaLog log;
h->handler(&log);
}
}
}
}
KibanaManagerTest.cpp:
namespace favour {
class DemoHandler : public KEHandler {
public:
void handler(KibanaLog *log) override {
std::cout << "Hello World" << std::endl;
}
};
void KibanaManagerTest::registerHandlerTest() {
KibanaManager::init();
DemoHandler *handler = new DemoHandler;
KibanaManager::registerHandler(handler);
delete handler;
while (1) {};
}
}
The program did not run as I expected, but when calling the handler function inherited from KEHandler and overridden by DemoHandler, a bit segmentation fault occurred, which caused the program to crash.

How to handle Observables with different state-value types in the Observer

(Context and question first, skeleton code at the bottom of the post)
We are creating and implementing a C++ framework to use in environments like Arduino.
For this I want to use the Observer pattern, where any component interested in state-changes of sensors (Observables) can register itself and it will get notified of those changes by the Observable calling the notification() method of the Observer with itself as a parameter.
One Observer can observe multiple Observables, and vice versa.
The problem lies in the fact that the Observer needs to extract the current state of the Observable and do something with it, and this current state can take all forms and sizes, depending on the particular sensor that is the Observable.
It can of course be ordinal values, which are finite and can be coded out, like I did in the code below with the method getValueasInt() but it can also be sensor-specific structures, i.e. for a RealTimeClock, which delivers a struct of date and time values. The struct are of course defined at compile time, and fixed for a specific sensor.
My question: What is the most elegant, and future-modification proof solution or pattern for this ?
Edit: Note that dynamic_cast<> constructions are not possible because of Arduino limitations
I have created the following class-hierarchy (skeleton code):
class SenseNode
{
public:
SenseNode() {};
SenseNode(uint8_t aNodeId): id(aNodeId) {}
virtual ~SenseNode() {}
uint8_t getId() { return id; };
private:
uint8_t id = 0;
};
class SenseStateNode : virtual public SenseNode
{
public:
SenseStateNode(uint8_t aNodeId) : SenseNode(aNodeId) {}
virtual ~SenseStateNode() {}
/** Return current node state interpreted as an integer. */
virtual int getValueAsInt();
};
class SenseObservable: public SenseStateNode
{
public:
SenseObservable(uint8_t aNodeId);
virtual ~SenseObservable();
/** Notify all interested observers of the change in state by calling Observer.notification(this) */
virtual void notifyObservers();
protected:
virtual void registerObserver(SenseObserver *);
virtual void unregisterObserver(SenseObserver *);
};
class SenseObserver: virtual public SenseNode
{
public:
SenseObserver() {};
virtual ~SenseObserver();
/** Called by an Observable that we are observing to inform us of a change in state */
virtual void notification(SenseObservable *observable) {
int v = observable->getValueAsInt(); // works like a charm
DateTime d = observable-> ???? // How should i solve this elegantly?
};
};
My previous answer does not take into account that the same observer might me registered with different observables. I'll try to give a full solution here. The solution is very flexible and scalable but a bit hard to understand as it involves template meta programming (TMP). I'll start by outlining what the end result will look like and then move into the TMP stuff. Brace yourself, this is a LONG answer. Here we go:
We first have, for the sake of the example, three observables, each with its own unique interface which we will want later to access from the observer.
#include <vector>
#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <string>
class observable;
class observer {
public:
virtual void notify(observable& x) = 0;
};
// For simplicity, I will give some default implementation for storing the observers
class observable {
// assumping plain pointers
// leaving it to you to take of memory
std::vector<observer*> m_observers;
public:
observable() = default;
// string id for identifying the concrete observable at runtime
virtual std::string id() = 0;
void notifyObservers() {
for(auto& obs : m_observers) obs->notify(*this);
}
void registerObserver(observer* x) {
m_observers.push_back(x);
}
void unregisterObserver(observer*) {
// give your implementation here
}
virtual ~observable() = default;
};
// our first observable with its own interface
class clock_observable
: public observable {
int m_time;
public:
clock_observable(int time)
: m_time(time){}
// we will use this later
static constexpr auto string_id() {
return "clock_observable";
}
std::string id() override {
return string_id();
}
void change_time() {
m_time++;
notifyObservers(); // notify observes of time change
}
int get_time() const {
return m_time;
}
};
// another observable
class account_observable
: public observable {
double m_balance;
public:
account_observable(double balance)
: m_balance(balance){}
// we will use this later
static constexpr auto string_id() {
return "account_observable";
}
std::string id() override {
return string_id();
}
void deposit_amount(double x) {
m_balance += x;
notifyObservers(); // notify observes of time change
}
int get_balance() const {
return m_balance;
}
};
class temperature_observable
: public observable {
double m_value;
public:
temperature_observable(double value)
: m_value(value){}
// we will use this later
static constexpr auto string_id() {
return "temperature_observable";
}
std::string id() override {
return string_id();
}
void increase_temperature(double x) {
m_value += x;
notifyObservers(); // notify observes of time change
}
int get_temperature() const {
return m_value;
}
};
Notice that each observer exposes an id function returning a string which identifies it. Now, let's assume we want to create an observer which monitors the clock and the account. We could have something like this:
class simple_observer_clock_account
: public observer {
std::unordered_map<std::string, void (simple_observer_clock_account::*) (observable&)> m_map;
void notify_impl(clock_observable& x) {
std::cout << "observer says time is " << x.get_time() << std::endl;
}
void notify_impl(account_observable& x) {
std::cout << "observer says balance is " << x.get_balance() << std::endl;
}
// casts the observable into the concrete type and passes it to the notify_impl
template <class X>
void dispatcher_function(observable& x) {
auto& concrete = static_cast<X&>(x);
notify_impl(concrete);
}
public:
simple_observer_clock_account() {
m_map[clock_observable::string_id()] = &simple_observer_clock_account::dispatcher_function<clock_observable>;
m_map[account_observable::string_id()] = &simple_observer_clock_account::dispatcher_function<account_observable>;
}
void notify(observable& x) override {
auto f = m_map.at(x.id());
(this->*f)(x);
}
};
I am using an unoderded_map so that the correct dispatcher_function will be called depending on the id of the observable. Confirm that this works:
int main() {
auto clock = new clock_observable(100);
auto account = new account_observable(100.0);
auto obs1 = new simple_observer_clock_account();
clock->registerObserver(obs1);
account->registerObserver(obs1);
clock->change_time();
account->deposit_amount(10);
}
A nice thing about this implementation is that if you try to register the observer to a temperature_observable you will get a runtime exception (as the m_map will not contain the relevant temperature_observable id).
This works fine but if you try now to adjust this observer so that it can monitor temperature_observables, things get messy. You either have to go edit the simple_observer_clock_account (which goes against the closed for modification, open for extension principle), or create a new observer as follows:
class simple_observer_clock_account_temperature
: public observer {
std::unordered_map<std::string, void (simple_observer_clock_account_temperature::*) (observable&)> m_map;
// repetition
void notify_impl(clock_observable& x) {
std::cout << "observer1 says time is " << x.get_time() << std::endl;
}
// repetition
void notify_impl(account_observable& x) {
std::cout << "observer1 says balance is " << x.get_balance() << std::endl;
}
// genuine addition
void notify_impl(temperature_observable& x) {
std::cout << "observer1 says temperature is " << x.get_temperature() << std::endl;
}
// repetition
template <class X>
void dispatcher_function(observable& x) {
auto& concrete = static_cast<X&>(x);
notify_impl(concrete);
}
public:
// lots of repetition only to add an extra observable
simple_observer_clock_account_temperature() {
m_map[clock_observable::string_id()] = &simple_observer_clock_account_temperature::dispatcher_function<clock_observable>;
m_map[account_observable::string_id()] = &simple_observer_clock_account_temperature::dispatcher_function<account_observable>;
m_map[temperature_observable::string_id()] = &simple_observer_clock_account_temperature::dispatcher_function<temperature_observable>;
}
void notify(observable& x) override {
auto f = m_map.at(x.id());
(this->*f)(x);
}
};
This works but it is a hell of a lot repetitive for just adding one additional observable. You can also imagine what would happen if you wanted to create any combination (ie account + temperature observable, clock + temp observable, etc). It does not scale at all.
The TMP solution essentially provides a way to do all the above automatically and re-using the overriden implementations as opposed to replicating them again and again. Here is how it works:
We want to build a class hierarchy where the base class will expose a number of virtual notify_impl(T&) method, one for each T concrete observable type that we want to observe. This is achieved as follows:
template <class Observable>
class interface_unit {
public:
virtual void notify_impl(Observable&) = 0;
};
// combined_interface<T1, T2, T3> would result in a class with the following members:
// notify_impl(T1&)
// notify_impl(T2&)
// notify_impl(T3&)
template <class... Observable>
class combined_interface
: public interface_unit<Observable>...{
using self_type = combined_interface<Observable...>;
using dispatcher_type = void (self_type::*)(observable&);
std::unordered_map<std::string, dispatcher_type> m_map;
public:
void map_register(std::string s, dispatcher_type dispatcher) {
m_map[s] = dispatcher;
}
auto get_dispatcher(std::string s) {
return m_map.at(s);
}
template <class X>
void notify_impl(observable& x) {
interface_unit<X>& unit = *this;
// transform the observable to the concrete type and pass to the relevant interface_unit.
unit.notify_impl(static_cast<X&>(x));
}
};
The combined_interface class inherits from each interface_unit and also allows us to register functions to the map, similarly to what we did earlier for the simple_observer_clock_account. Now we need to create a recursive hierarchy where at each step of the recursion we override notify_impl(T&) for each T we are interested in.
// forward declaration
// Iface will be combined_interface<T1, T2>
// The purpose of this class is to implement the virtual methods found in the Iface class, ie notify_impl(T1&), notify_impl(T2&)
// Each ImplUnit provides an override for a single notify_impl(T&)
// Root is the base class of the hierarchy; this will be the data (if any) held by the observer
template <class Root, class Iface, template <class, class> class... ImplUnits>
struct hierarchy;
// recursive
template <class Root, class Iface, template <class, class> class ImplUnit, template <class, class> class... ImplUnits>
struct hierarchy<Root, Iface, ImplUnit, ImplUnits...>
: public ImplUnit< hierarchy<Root, Iface, ImplUnits...>, Root > {
using self_type = hierarchy<Root, Iface, ImplUnit, ImplUnits...>;
using base_type = ImplUnit< hierarchy<Root, Iface, ImplUnits...>, Root >;
public:
template <class... Args>
hierarchy(Args&&... args)
: base_type{std::forward<Args>(args)...} {
using observable_type = typename base_type::observable_type;
Iface::map_register(observable_type::string_id(), &Iface::template notify_impl<observable_type>);
}
};
// specialise if we have iterated through all ImplUnits
template <class Root, class Iface>
struct hierarchy<Root, Iface>
: public Root
, public observer
, public Iface {
public:
template <class... Args>
hierarchy(Args&&... args)
: Root(std::forward<Args>(args)...)
, Iface(){}
};
At each step of the recursion, we register the dispatcher_function to our map.
Finally, we create a class which will be used for our observers:
template <class Root, class Iface, template <class, class> class... ImplUnits>
class observer_base
: public hierarchy<Root, Iface, ImplUnits...> {
public:
using base_type = hierarchy<Root, Iface, ImplUnits...>;
void notify(observable& x) override {
auto f = this->get_dispatcher(x.id());
return (this->*f)(x);
}
template <class... Args>
observer_base(Args&&... args)
: base_type(std::forward<Args>(args)...) {}
};
Let's now create some observables. For simplicity, I assume that the observer has not data:
class observer1_data {};
// this is the ImplUnit for notify_impl(clock_observable&)
// all such implementations must inherit from the Super argument and expose the observable_type type member
template <class Super, class ObserverData>
class clock_impl
: public Super {
public:
using Super::Super;
using observable_type = clock_observable;
void notify_impl(clock_observable& x) override {
std::cout << "observer says time is " << x.get_time() << std::endl;
}
};
template <class Super, class ObserverdData>
class account_impl
: public Super {
public:
using Super::Super;
using observable_type = account_observable;
void notify_impl(account_observable& x) override {
std::cout << "observer says balance is " << x.get_balance() << std::endl;
}
};
template <class Super, class ObserverdData>
class temperature_impl
: public Super {
public:
using Super::Super;
using observable_type = temperature_observable;
void notify_impl(temperature_observable& x) override {
std::cout << "observer says temperature is " << x.get_temperature() << std::endl;
}
};
Now we can easily create any observer we want, no matter what combinations we want to use:
using observer_clock = observer_base<observer1_data,
combined_interface<clock_observable>,
clock_impl>;
using observer_clock_account = observer_base<observer1_data,
combined_interface<clock_observable, account_observable>,
clock_impl, account_impl>;
using observer_clock_account_temperature = observer_base<observer1_data,
combined_interface<clock_observable, account_observable, temperature_observable>,
clock_impl, account_impl, temperature_impl>;
int main() {
auto clock = new clock_observable(100);
auto account = new account_observable(100.0);
auto temp = new temperature_observable(36.6);
auto obs1 = new observer_clock_account_temperature();
clock->registerObserver(obs1);
account->registerObserver(obs1);
temp->registerObserver(obs1);
clock->change_time();
account->deposit_amount(10);
temp->increase_temperature(2);
}
I can appreciate there is a lot to digest. Anyway, I hope it is helpful. If you want to understand in detail the TMP ideas above have a look at the Modern C++ design by Alexandrescu. One of the best I've read.
Let me know if anything is not clear and I will edit the answer.
If the number of sensor types is more or less stable (and it is - the changes are pretty rare in most cases) - then just be prepared on Observer side to get several kind of notifications:
class Observer
{
public:
virtual void notify(SenseNode& node) {
// implement here general actions - like printing: not interested in this
}
virtual void notify(RealTimeClock& node) {
notify(static_cast<SenseNode&>(node));
// by default go to more general function
}
// and follow this pattern - for all nodes you want to handle
// add corresponding notify(T&) function
};
When it happens you have to add new node type - then just add new virtual function to your base Observer class.
To implement this mechanism on Observable side - use double dispatch pattern:
class SenseNode {
public:
virtual void notifyObserver(Observer& observer) {
observer.notify(*this);
}
};
class RealTimeClock : public virtual SenseNode {
public:
virtual void notifyObserver(Observer& observer) {
observer.notify(*this);
// this will select proper Observer::notify(RealTimeClock&)
// because *this is RealTimeCLock
}
};
class SenseObservable: public SenseStateNode
{
public:
virtual void notifyObservers() {
for (auto& observer : observers)
notifyObserver(observer);
}
};
How it works in practice, see live demo
Here is my take. If I understand correctly, each observer knows what concrete observable is monitoring; the problem is that the observer only gets a base class pointer to the concrete observable and hence cannot access the full interface. Assuming you can use static_cast as previous answers have assumed, my idea is to create an additional class which will be responsible for casting the base class pointer to the concrete one, thus giving you access to the concrete interface. The code below uses different names than the ones in your post, but it illustrates the idea:
#include <vector>
#include <algorithm>
#include <iostream>
class observable;
class observer {
public:
virtual void notify(observable&) = 0;
};
// For simplicity, I will give some default implementation for storing the observers
class observable {
// assumping plain pointers
// leaving it to you to take of memory
std::vector<observer*> m_observers;
public:
observable() = default;
void notifyObservers() {
for(auto& obs : m_observers) obs->notify(*this);
}
void registerObserver(observer* x) {
m_observers.push_back(x);
}
void unregisterObserver(observer* x) {
// give your implementation here
}
virtual ~observable() = default;
};
// our first observable with its own interface
class clock_observable
: public observable {
int m_time;
public:
clock_observable(int time)
: m_time(time){}
void change_time() {
m_time++;
notifyObservers(); // notify observes of time change
}
int get_time() const {
return m_time;
}
};
// another observable
class account_observable
: public observable {
double m_balance;
public:
account_observable(double balance)
: m_balance(balance){}
void deposit_amount(double x) {
m_balance += x;
notifyObservers(); // notify observes of time change
}
int get_balance() const {
return m_balance;
}
};
// this wrapper will be inherited and allows you to access the interface of the concrete observable
// all concrete observers should inherit from this class
template <class Observable>
class observer_wrapper
: public observer {
virtual void notify_impl(Observable& x) = 0;
public:
void notify(observable& x) {
notify_impl(static_cast<Observable&>(x));
}
};
// our first clock_observer
class clock_observer1
: public observer_wrapper<clock_observable> {
void notify_impl(clock_observable& x) override {
std::cout << "clock_observer1 says time is " << x.get_time() << std::endl;
}
};
// our second clock_observer
class clock_observer2
: public observer_wrapper<clock_observable> {
void notify_impl(clock_observable& x) override {
std::cout << "clock_observer2 says time is " << x.get_time() << std::endl;
}
};
// our first account_observer
class account_observer1
: public observer_wrapper<account_observable> {
void notify_impl(account_observable& x) override {
std::cout << "account_observer1 says balance is " << x.get_balance() << std::endl;
}
};
// our second account_observer
class account_observer2
: public observer_wrapper<account_observable> {
void notify_impl(account_observable& x) override {
std::cout << "account_observer2 says balance is " << x.get_balance() << std::endl;
}
};
int main() {
auto clock = new clock_observable(100);
auto account = new account_observable(100.0);
observer* clock_obs1 = new clock_observer1();
observer* clock_obs2 = new clock_observer2();
observer* account_obs1 = new account_observer1();
observer* account_obs2 = new account_observer2();
clock->registerObserver(clock_obs1);
clock->registerObserver(clock_obs2);
account->registerObserver(account_obs1);
account->registerObserver(account_obs2);
clock->change_time();
account->deposit_amount(10);
}
As you can see, you do not need to cast every time you create a new observable; the wrapper class does this for you. One issue you may face is registering an observer to the wrong observable; in this case the static_cast would fail but you would get no compilation issues. One way around it is to have the observable expose a string that identifies it and have the observer check that string when it's registering itself. Hope it helps.
You could go with
class SenseStateNode
{
...
virtual ObservableValue& getValue(); //or pointer, comes with different tradeoffs
};
That way, each SenseObservable can return a type derived from ObservableValue. Then, you just have to come up with a usable, generic API for this observable value.
For example, it could be:
class SenseObservable
{
DateTime* asDateTime(); //returns NULL if not a date
float* asFloat(); //returns NULL if not a float
};
The trick is to come with a usable, extensible and generic API for the various observable values. Also, you hve to return them by pointer or reference to not slice them. Then, either the user or the owner has to manage memory.
It may not be the most elegant solution, but the following is an option: define an EventArgs structure that can hold any kind of data, then do a cast in EventHandlers. Here's a snippet I just wrote (not a native speaker of CPP though):
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct EventArgs;
typedef void (*EventHandler)(EventArgs args);
typedef std::vector<EventHandler> BunchOfHandlers;
typedef std::map<string, BunchOfHandlers> HandlersBySubject;
struct EventArgs
{
void* data;
EventArgs(void* data)
{
this->data = data;
}
};
class AppEvents
{
HandlersBySubject handlersBySubject;
public:
AppEvents()
{
}
void defineSubject(string subject)
{
handlersBySubject[subject] = BunchOfHandlers();
}
void on(string subject, EventHandler handler)
{
handlersBySubject[subject].push_back(handler);
}
void trigger(string subject, EventArgs args)
{
BunchOfHandlers& handlers = handlersBySubject[subject];
for (const EventHandler& handler : handlers)
{
handler(args);
}
}
};
struct FooData
{
int x = 42;
string str = "Test";
};
struct BarData
{
long y = 123;
char c = 'x';
};
void foo_handler_a(EventArgs args)
{
FooData* data = (FooData*)args.data;
cout << "foo_handler_a: " << data->x << " " << data->str << endl;
}
void foo_handler_b(EventArgs args)
{
FooData* data = (FooData*)args.data;
cout << "foo_handler_b: " << data->x << " " << data->str << endl;
}
void bar_handler_a(EventArgs args)
{
BarData* data = (BarData*)args.data;
cout << "bar_handler_a: " << data->y << " " << data->c << endl;
}
void bar_handler_b(EventArgs args)
{
BarData* data = (BarData*)args.data;
cout << "bar_handler_b: " << data->y << " " << data->c << endl;
}
int main()
{
AppEvents* events = new AppEvents();
events->defineSubject("foo");
events->defineSubject("bar");
events->on("foo", foo_handler_a);
events->on("foo", foo_handler_a);
events->on("bar", bar_handler_b);
events->on("bar", bar_handler_b);
events->trigger("foo", EventArgs(new FooData()));
events->trigger("bar", EventArgs(new BarData()));
return 0;
}
Inspired by Backbone events and the general Event Bus pattern.
Difficulty of Observer Pattern in C++ is to handle life-time and un-registration.
You might use the following:
class Observer;
class IObserverNotifier
{
public:
virtual ~IObserverNotifier() = default;
virtual void UnRegister(Observer&) = 0;
};
class Observer
{
public:
explicit Observer() = default;
virtual ~Observer() {
for (auto* abstractObserverNotifier : mAbstractObserverNotifiers)
abstractObserverNotifier->UnRegister(*this);
}
Observer(const Observer&) = delete;
Observer(Observer&&) = delete;
Observer& operator=(const Observer&) = delete;
Observer& operator=(Observer&&) = delete;
void AddObserverNotifier(IObserverNotifier& observerNotifier)
{
mAbstractObserverNotifiers.insert(&observerNotifier);
}
void RemoveObserverNotifier(IObserverNotifier& observerNotifier)
{
mAbstractObserverNotifiers.erase(&observerNotifier);
}
private:
std::set<IObserverNotifier*> mAbstractObserverNotifiers;
};
template<typename ... Params>
class ObserverNotifier : private IObserverNotifier
{
public:
ObserverNotifier() = default;
~ObserverNotifier() {
for (const auto& p : mObserverCallbacks) {
p.first->RemoveObserverNotifier(*this);
}
}
ObserverNotifier(const ObserverNotifier&) = delete;
ObserverNotifier(ObserverNotifier&&) = delete;
ObserverNotifier& operator=(const ObserverNotifier&) = delete;
ObserverNotifier& operator=(ObserverNotifier&&) = delete;
void Register(Observer& observer, std::function<void(Params...)> f) {
mObserverCallbacks.emplace_back(&observer, f);
observer.AddObserverNotifier(*this);
}
void NotifyObservers(Params... args) const
{
for (const auto& p : mObserverCallbacks)
{
const auto& callback = p.second;
callback(args...);
}
}
void UnRegister(Observer& observer) override
{
mObserverCallbacks.erase(std::remove_if(mObserverCallbacks.begin(),
mObserverCallbacks.end(),
[&](const auto& p) { return p.first == &observer;}),
mObserverCallbacks.end());
}
private:
std::vector<std::pair<Observer*, std::function<void(Params...)>>> mObserverCallbacks;
};
And then usage would be something like:
class Sensor
{
public:
void ChangeTime() {
++mTime;
mOnTimeChange.NotifyObservers(mTime);
}
void ChangeTemperature(double delta) {
mTemperature += delta;
mOnTemperatureChange.NotifyObservers(mTemperature);
}
void RegisterTimeChange(Observer& observer, std::function<void(double)> f) { mOnTimeChange.Register(observer, f); }
void RegisterTemperatureChange(Observer& observer, std::function<void(double)> f) { mOnTemperatureChange.Register(observer, f); }
private:
ObserverNotifier<int> mOnTimeChange;
ObserverNotifier<double> mOnTemperatureChange;
int mTime = 0;
double mTemperature = 0;
};
class Ice : public Observer {
public:
void OnTimeChanged(int time) {
mVolume -= mLose;
mOnVolumeChange.NotifyObservers(mVolume);
}
void OnTemperatureChanged(double t) {
if (t <= 0) {
mLose = 0;
} else if (t < 15) {
mLose = 5;
} else {
mLose = 21;
}
}
void RegisterVolumeChange(Observer& observer, std::function<void(double)> f) { mOnVolumeChange.Register(observer, f); }
private:
ObserverNotifier<double> mOnVolumeChange;
double mVolume = 42;
double mLose = 0;
};
class MyObserver : public Observer {
public:
static void OnTimeChange(int t) {
std::cout << "observer says time is " << t << std::endl;
}
static void OnTemperatureChange(double temperature) {
std::cout << "observer says temperature is " << temperature << std::endl;
}
static void OnIceChange(double volume) {
std::cout << "observer says Ice volume is " << volume << std::endl;
}
};
And test it:
int main()
{
Sensor sensor;
Ice ice;
MyObserver observer;
sensor.RegisterTimeChange(observer, &MyObserver::OnTimeChange);
sensor.RegisterTemperatureChange(observer, &MyObserver::OnTemperatureChange);
ice.RegisterVolumeChange(observer, &MyObserver::OnIceChange);
sensor.RegisterTimeChange(ice, [&](int t){ice.OnTimeChanged(t);});
sensor.RegisterTemperatureChange(ice, [&](double t){ice.OnTemperatureChanged(t);});
sensor.ChangeTemperature(0);
sensor.ChangeTime();
sensor.ChangeTemperature(10.3);
sensor.ChangeTime();
sensor.ChangeTime();
sensor.ChangeTemperature(42.1);
sensor.ChangeTime();
}
Demo

Implementing the observer pattern using CRTP and 'anonymous types/template'

I'm developing a library that parses a certain XML file (using RapidXML) and returns an object of mine, containing that file data. That XML file is created by someone else's application. I needed to use the observer pattern because speed is extremely crucial, for example:
Suppose a file has 10.000 tag and its child nodes. In a simple parser, they would be added to a std::vector in the order they were found. Then, after the file was parsed, we would need to iterate over the 10.000 values AGAIN and do whatever we want with them.
By using the observer pattern, I allow external observers (whichever class that wants to observe and be notified about each fetched node has to inherit from AbstractObserver that comes with my library, and implement his functions) to be a part of the parsing process without the need to iterate X times again over the parsed nodes. HOWEVER... There are multiple kinds of nodes, for example: tileset, layer, imagelayer and so on (being necessary multiple onObserved and notify functions for its corresponding node, according to the Observer/Subject pattern, probably having a lot of 'duplicated' code - NOTE: inheritance is not used. See bellow a 'bad' example). I could simply make the nodes inherit from some sort of BaseNode class, but I dont want to use inheritance here since I dont want to deal with pointers. Instead, I'm using enums to type the nodes and thats where my problem lies.
/* ################## ABSTRACT OBSERVER #################### */
// Implements the observer pattern, using the CRTP pattern
template<class ConcreteObserver>
class AbstractObserver
{
public:
virtual ~AbstractObserver() { }
template<class Attribute>
inline void onObserved(Attribute attribute) {
// This requires ConcreteObserver to have a method onObservedImpl<Attribute>
static_cast<const ConcreteObserver*>(this)->onObservedImpl(attribute);
}
};
/* ################## ABSTRACT SUBJECT #################### */
class AbstractSubject
{
public:
virtual ~AbstractSubject() { }
// ???????
inline void attach(AbstractObserver<??????>* observer) {
m_observers.push_back(observer);
}
// ???????
inline void detatch(AbstractObserver<??????>* observer) {
auto& it = std::find(m_observers.begin(), m_observers.end(), observer);
// Remove the observer from the list, if it was observing
if (it != m_observers.end())
m_observers.erase(it);
}
protected:
template<typename Attribute>
void notify(Attribute& attribute) {
for (auto* observer : m_observers)
observer->onObserved(attribute)
}
private:
// ???????
std::vector<AbstractObserver<??????>*> m_observers;
};
/* ################## CONCRETE OBSERVER #################### */
class SomeConcreteObserver : public AbstractObserver<SomeConcreteObserver>
{
public:
// The CRTP 'virtual' function implementation
template<class Attribute>
void onObservedImpl(Attribute attribute)
{
// Filter the attribute and use it accordingly
switch (attribute.type)
{
// ....
}
}
};
/* ################## CONCRETE SUBJECT #################### */
class Parser : public AbstractSubject
{
public:
void parse(/* params */)
{
Foo f;
notify<Foo>(f);
// Later on....
Bar b;
notify<Bar>(b);
}
};
As we can see, I'm using the CRTP as well, since I need 'templated virtual functions', which is impossible to achieve otherwise. Since the AbstractObserver needs a type (because of the CRTP), I can't properly use them in the AbstractSubject class (see above). Is it even possible to use annonymous templates just like Java, or something like that? I believe this WOULD do the job.
Here is the implementation of a 'bad' example I thought of, but this is the best I could come up with for this situation:
// Remove the CRTP
class AbstractObserver
{
public:
virtual ~AbstractObserver() { }
virtual void onNodeA(NodeA n) = 0;
virtual void onNodeB(NodeB n) = 0;
virtual void onNodeC(NodeC n) = 0;
virtual void onNodeD(NodeD n) = 0;
virtual void onNodeE(NodeE n) = 0;
// .....
};
class AbstractSubject
{
public:
// ....
protected:
void notifyNodeA(NodeA n) {
for (auto* observer : m_observers)
observer->onNodeA(n);
}
void notifyNodeB(NodeB n) {
for (auto* observer : m_observers)
observer->NodeB(n);
}
void notifyNodeC(NodeC n) { }
void notifyNodeD(NodeD n) { }
void notifyNodeE(NodeE n) { }
// ....
private:
std::vector<Observer*> m_observers;
};
The solution has to use C++11 or bellow and no boost.
Solution #1: Quite wet but simple
#include <vector>
#include <algorithm>
#include <iostream>
template<typename TAttribute>
class Observer
{
public:
virtual void Observe(TAttribute& attribute) = 0;
virtual ~Observer() = default;
};
template<typename TAttribute>
class OutputtingObserver : public Observer<TAttribute>
{
public:
void Observe(TAttribute& attribute)
{
std::cout << attribute << std::endl;
}
~OutputtingObserver() = default;
};
template<typename TAttribute>
class Subject
{
private:
std::vector<Observer<TAttribute>*> mutable m_observers;
public:
void Attach(Observer<TAttribute>& observer) const
{
m_observers.push_back(&observer);
}
void Detach(Observer<TAttribute>& observer) const
{
m_observers.erase(std::remove(m_observers.begin(), m_observers.end(), &observer), m_observers.end());
}
void Notify(TAttribute& attribute)
{
for (auto observer : m_observers)
observer->Observe(attribute);
}
};
class NodeA
{
public:
friend std::ostream& operator<<(std::ostream& o, const NodeA& node)
{
return o << "a";
}
};
class NodeB
{
public:
friend std::ostream& operator<<(std::ostream& o, const NodeB& node)
{
return o << "b";
}
};
class Parser
{
private:
Subject<NodeA> m_subjectA;
Subject<NodeB> m_subjectB;
public:
void Parse()
{
auto a = NodeA();
auto b = NodeB();
m_subjectA.Notify(a);
m_subjectB.Notify(b);
}
void Attach(Observer<NodeA>& observer)
{
m_subjectA.Attach(observer);
}
void Attach(Observer<NodeB>& observer)
{
m_subjectB.Attach(observer);
}
};
int main()
{
auto observerA = OutputtingObserver<NodeA>();
auto observerB = OutputtingObserver<NodeB>();
auto parser = Parser();
parser.Attach(observerA);
parser.Attach(observerB);
parser.Attach(observerA);
parser.Parse();
return 1;
}
You would need to use composition here and have a subject for each type of node. However, this is compile-time validated so I'd prefer this to the second version.
Solution #2: Dynamic and closer to what you want
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <iostream>
class ObserverBase
{
public:
virtual ~ObserverBase() = default;
};
template<typename TAttribute>
class Observer : public ObserverBase
{
public:
virtual void Observe(TAttribute& attribute) = 0;
};
template<typename TAttribute>
class OutputtingObserver : public Observer<TAttribute>
{
public:
void Observe(TAttribute& attribute)
{
std::cout << attribute << std::endl;
}
~OutputtingObserver() = default;
};
template<typename TKey>
class Subject
{
private:
using ObserverList = std::vector<ObserverBase*>;
using ObserverMap = std::unordered_map<TKey, ObserverList>;
ObserverMap mutable m_observers;
public:
void Attach(TKey key, ObserverBase& observer) const
{
auto itr = m_observers.find(key);
if (itr == m_observers.end())
{
m_observers.emplace(std::make_pair(key, ObserverList { &observer }));
return;
}
itr->second.push_back(&observer);
}
void Detach(ObserverBase& observer) const
{
m_observers.erase(std::remove(m_observers.begin(), m_observers.end(), &observer), m_observers.end());
}
template<TKey key, typename TAttribute>
void Notify(TAttribute& attribute)
{
auto itr = m_observers.find(key);
if (itr == m_observers.end())
return;
for (auto observer : itr->second)
dynamic_cast<Observer<TAttribute>*>(observer)->Observe(attribute);
}
};
enum class NodeType
{
TypeA,
TypeB
};
class NodeA
{
public:
friend std::ostream& operator<<(std::ostream& o, const NodeA& node)
{
return o << "a";
}
};
class NodeB
{
public:
friend std::ostream& operator<<(std::ostream& o, const NodeB& node)
{
return o << "b";
}
};
class Parser
{
private:
Subject<NodeType> m_subject;
public:
void Parse()
{
auto a = NodeA();
auto b = NodeB();
m_subject.Notify<NodeType::TypeA, NodeA>(a);
m_subject.Notify<NodeType::TypeB, NodeB>(b);
}
void Attach(Observer<NodeA>& observer)
{
m_subject.Attach(NodeType::TypeA, observer);
}
void Attach(Observer<NodeB>& observer)
{
m_subject.Attach(NodeType::TypeB, observer);
}
};
int main()
{
auto observerA = OutputtingObserver<NodeA>();
auto observerB = OutputtingObserver<NodeB>();
auto parser = Parser();
parser.Attach(observerA);
parser.Attach(observerB);
parser.Attach(observerA);
parser.Parse();
return 1;
}
This is closer to your version. Quite unsafe and slower but slightly less typing.
Summary
Both output a\na\nb and both are something sewn together just as a minimal proof of concept, not something you should follow (especially the working with unordered_map feels quite nasty).
It's not directly what you want but I guess that you can take it from there...
I have strong feeling that there are better solutions to this so feel free to experiment.
EDIT:
Solution #3: Completely dynamic
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <typeinfo>
#include <typeindex>
template<typename TAttribute>
class Observer
{
public:
virtual void Observe(TAttribute& attribute) = 0;
virtual ~Observer() = default;
};
class Subject
{
private:
using ObserverList = std::vector<void*>;
using ObserverMap = std::unordered_map<std::type_index, ObserverList>;
ObserverMap mutable m_observers;
public:
template<typename TAttribute>
void Attach(Observer<TAttribute>& observer) const
{
auto index = std::type_index(typeid(Observer<TAttribute>));
auto itr = m_observers.find(index);
if (itr == m_observers.end())
{
m_observers.emplace(std::make_pair(index, ObserverList { &observer }));
return;
}
itr->second.push_back(&observer);
}
template<typename TAttribute>
void Detach(Observer<TAttribute>& observer) const
{
m_observers.erase(std::remove(m_observers.begin(), m_observers.end(), &observer), m_observers.end());
}
template<typename TAttribute>
void Notify(TAttribute& attribute)
{
auto itr = m_observers.find(std::type_index(typeid(Observer<TAttribute>)));
if (itr == m_observers.end())
return;
for (auto observer : itr->second)
static_cast<Observer<TAttribute>*>(observer)->Observe(attribute);
}
};
This is basically a ported C#'s version of Dictionary<Type, Object>, it uses rtti so you might get spat on by C++ hardliners...

Still an observer pattern?

Usually when I see tutorials about Observer Pattern I see an unique method called notify, but I'm wondering. What if I have different methods that can be called in different moments but needs to notify the others when this happen? Like events, am I doing this wrong? or still begin the observer pattern?
#include <iostream>
#include <algorithm>
#include <vector>
class Observer
{
public:
virtual void notifyBefore() = 0;
virtual void notifyAfter() = 0;
};
class Subject
{
public:
void attachObserver(Observer * observer)
{
observers.push_back(observer);
}
void detachObserver(Observer * observer)
{
auto index = std::find(observers.begin(), observers.end(), observer);
if (index != observers.end())
{
observers.erase(index);
}
}
virtual void notifyBefore()
{
for (auto current : observers)
{
current->notifyBefore();
}
}
virtual void notifyAfter()
{
for (auto current : observers)
{
current->notifyAfter();
}
}
private:
std::vector<Observer *> observers;
};
class ConcreteObserver : public Observer
{
public:
void notifyBefore()
{
std::cout << "You called me before..." << std::endl;
}
void notifyAfter()
{
std::cout << "You called me after..." << std::endl;
}
};
class ConcreteSubject : public Subject
{
public:
};
int main()
{
auto subject = new ConcreteSubject;
subject->attachObserver(new ConcreteObserver);
subject->notifyBefore();
for (int i = 0; i < 5; ++i)
std::cout << i << std::endl;
subject->notifyAfter();
}
Is it still an observer pattern? sure
You created an observer pattern with 2 types of events/notifications.
You could have written it as:
void notify(Type type);
Where Type is the type of event (e.g. an enum).
You can also pass other parameters to indicate other parameters relevant to the event.
void notify(Type type, std::string value);

How to add/design callback function

How do I setup/register a callback function, in C++, to call a function when there is data to be read from a queue?
Edit 1:
Using Neil's answer for a complete answer (in header file):
#include <vector.h>
class QueueListener {
public:
virtual void DataReady(class MyQueue *q) = 0;
virtual ~QueueListener() {}
};
class MyQueue {
public:
void Add (int x) {
theQueue.push_back(x);
for (int i = 0; i < theCallBacks.size(); i++) {
theCallBacks[i]->DataReady(this);
}
}
void Register (QueueListener *ql) {
theCallBacks.push_back(ql);
}
private:
vector <QueueListener *> theCallBacks;
vector <int> theQueue;
};
class MyListener : public QueueListener {
public:
virtual ~MyListener () {
printf("MyListener destructor!");
}
MyListener(MyQueue *q);
virtual void DataReady(class MyQueue *p);
};
And the registering:
#include "File1.h"
MyListener::MyListener(MyQueue *q)
{
q->Register(this);
}
void MyListener::DataReady(class MyQueue *p)
{
Sleep(500);
}
Then the calls:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MyQueue *q = new MyQueue();
MyListener ml(q);
q->Add(1);
}
In outline, create a QueueListener base class:
class QueueListener {
public:
virtual void DataReady( class MyQueue & q ) = 0;
virtual ~QueueListener() {}
};
and a queue class (make this queue of integers as example:
class MyQueue {
public:
void Add( int x ) {
theQueue.push_back( x );
for ( int i = 0; i < theCallBacks.size(); i++ ) {
theCallBacks[i]->DataReady( * this );
}
}
void Register( QueueListener * ql ) {
theCallBacks.push_back( ql );
}
private:
vector <QueueListener *> theCallBacks;
SomeQueueType <int> theQueue;
};
You derive the classes that want to be called back from QueueListener and implement the DataReady function. You then register instances of the derived class with your queue instance.
Have a look at Boost.Signals.
Example stolen from tutorial:
struct HelloWorld
{
void operator()() const
{
std::cout << "Hello, World!" << std::endl;
}
};
// ...
// Signal with no arguments and a void return value
boost::signal<void ()> sig;
// Connect a HelloWorld slot
HelloWorld hello;
sig.connect(hello);
// Call all of the slots
sig();
I like the approach that boost.asio uses for callback. In ASIO they are referred to as handlers. Please excuse my c++0x, it is so much faster to write than c++98.
class MyQueue
{
//...
Register( const std::function<void()>& callback )
{
m_callbacks.push_back(callback);
}
Add( const int& i )
{
// ...
for( const auto& callback: m_callbacks )
{
callback();
}
}
std::vector<std::function<void()>> m_callbacks;
};
class SomeClass
{
public:
void SomeQueueIsReady( MyQueue& )
{ /* do something with MyQueue */ }
};
void register_callback()
{
SomeClass some;
MyQueue queue;
// using bind
queue.Register( std::bind( &SomeClass::SomeQueueIsReady, &some, std::ref(queue) ) );
// or using a lambda
queue.Register( [&queue,&some](){ some.SomeQueueIsReady( queue ); } );
}
The key points are the callback is a functor so the user isn't tied to a particular class hierarchy and the callbacks don't take any parameters. If you want parameters passed in, you bind them yourself. The exception is if the callback produces information not available when the callback was registered. An example could be the time when the item was added.
There is nothing stopping you from using this solution in c++98. You cannot use lamdbas, but boost::function and boost::bind are near identical to their c++0x counter parts.
Be aware that you'll have to manage object lifetimes carefully. That is the case with either Neil's or my solution.