Simple Example: Using Boost Signals with Cinder

The Observer pattern is a good way of simplifying the parts that need to know about each other, and be tied together in a complex program. Here’s how a simple how to of using Boost::Signals in a Cinder project.

One thing to note, is that we have to use ‘Signals2.hpp’ not ‘Signals.hpp’, because ‘Signals.hpp’ requires it be compiled before it is used, and can lead to compilation errors for some reason in a Cinder project.


 * Mario Gonzalez
 * http://onedayitwillmake
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/Vector.h"
#include "cinder/app/MouseEvent.h"
#include "cinder/Rand.h"
#include "gl.h"

#include "Button.h"
#include "boost/bind.hpp"

class HelloWorldApp : public ci::app::AppBasic {
	void setup();
	void prepareSettings( ci::app::AppBasic::Settings *settings );
	void mouseDown( ci::app::MouseEvent event );
	void update();
	void draw();

	// An imaginary button which contains the Signal
	Button button;

	// This will be the callback
	void onButtonWasClicked( Button* buttonInstance );

void HelloWorldApp::prepareSettings( ci::app::AppBasic::Settings *settings ) {
	settings->setWindowSize( 800, 600 );

void HelloWorldApp::setup() {
	// Get the signal instance
	// Use boost::bind, to bind our class's function, to our (this) specific instnace
	// _1 is a typedef for boost::arg - So we're creating a spot for the first argument in the function
	button.getSignal()->connect(boost::bind(&HelloWorldApp::onButtonWasClicked, this, _1));

void HelloWorldApp::mouseDown( ci::app::MouseEvent event ) {
	// Test it out, this should fire the signal

void HelloWorldApp::onButtonWasClicked( Button* buttonInstance ) {
	// Outputs: Button instance 'Button1' was pressed!
	std::cout << "Button instance '" << buttonInstance->getId() << "' was pressed!" << std::endl;

void HelloWorldApp::update() { }
void HelloWorldApp::draw() {
	// clear out the window with black
	ci::gl::clear( ci::Color( 0, 0, 0 ) );

CINDER_APP_BASIC( HelloWorldApp, ci::app::RendererGl )

Button.h - which will dispatch the signal

#ifndef BUTTON_H_
#define BUTTON_H_


class Button {
	// this typedef creates a simple shorthand, so that ButtonSignal refers to boost::signals2::signal
	// If you wanted you could use the long name instead, but its easier to typo
	typedef boost::signals2::signal ButtonSignal;

	virtual ~Button();
	void clicked();

	std::string getId() { return _id; };
	ButtonSignal* getSignal() { return &_signal; }; // Notice we return a pointer to the signal
	std::string _id;
	ButtonSignal    _signal;

#endif /* BUTTON_H_ */


#include "Button.h"
#include "boost/bind.hpp"

Button::Button() {
	_id = "Button1";

Button::~Button() {

 * Dispatch the event to all listeners
void Button::clicked() {
	_signal( this );

If you wanted no arguments passed, simply remove the _1 parameter and change your method signatures accordingly. As you can guess, you could extrapolate it to have say five arguments by using boost::bind(&HelloWorldApp::onButtonWasClicked, this, _1, _2, _3, _4, _5)

That's about it - not too hard after you figure out the 'Signals2.hpp' requirement