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_
#include <boost/signals2.hpp>
#include <iostream>
class Button {
	// this typedef creates a simple shorthand, so that ButtonSignal refers to boost::signals2::signal<void( Button* )>
	// If you wanted you could use the long name instead, but its easier to typo
	typedef boost::signals2::signal<void( Button* )> 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

3 thoughts on “Simple Example: Using Boost Signals with Cinder”

  1. Prefixing your c++ variable names with an underscore is very bad as these names are reserved for toolchain usage. Thus it’s a bad habit to propagate and might break on certain platforms with certain compilers.

    1. @notamused – I could see that as being a good reason, but on the other hand I have never had any problems with any toolchains while using ‘_’.

      I’m not saying you’re incorrect, because I do see everyone prefix with ‘m’ for member instead. However I’m wondering if it’s still a valid reason

  2. It’s a totally invalid reason because

    A) it’s C++ and namespaces (including class) are there to prevent nameclashes,
    B) toolchains use double underscore prefixes, not single, and
    C) many C-based guidelines actually condone prefixing variables with an undercore. In fact, clang will give one to you by default in Obj-C for your @property’s.

    An ‘m’ prefix is an alternative to this that is preferred within the cinder codebase, but that is merely for stylistic reasons.

Leave a Reply

Your email address will not be published. Required fields are marked *