diff --git a/Makefile.am b/Makefile.am index de292f44..e21b97d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,7 @@ UTIL_INCLUDE = \ point.hpp \ range.hpp \ region.hpp \ + signal.hpp \ stream.hpp \ types.hpp \ vector.hpp \ @@ -38,6 +39,7 @@ UTIL_FILES = \ point.cpp \ range.cpp \ region.cpp \ + signal.cpp \ stream.cpp \ types.cpp \ vector.cpp \ diff --git a/signal.cpp b/signal.cpp new file mode 100644 index 00000000..d9e293b4 --- /dev/null +++ b/signal.cpp @@ -0,0 +1,22 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + + +#include "signal.hpp" + diff --git a/signal.hpp b/signal.hpp new file mode 100644 index 00000000..b6a480e9 --- /dev/null +++ b/signal.hpp @@ -0,0 +1,70 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + +#ifndef __SIGNAL_HPP +#define __SIGNAL_HPP + +#include +#include +#include + + +template +class signal { + public: + typedef Ret (*callback_function)(Args...); + typedef std::function callback_object; + + protected: + std::vector m_children; + + public: + signal () + { m_children.reserve (16); } + + /// Add a callback to list. + void connect (callback_object _cb) + { m_children.push_back (_cb); } + void connect (callback_function _cb) + { m_children.push_back (_cb); } + + /// Remove all instances of callback `cb' + void disconnect (callback_function _cb) + { disconnect (callback_object (_cb)); } + + /// Remove all instances of callback `cb' + void disconnect (callback_object _cb) { + m_children.erase (std::remove (m_children.begin (), + m_children.end (), + _cb), + m_children.end ()); + } + + /// Remove all callbacks + void clear (void) + { m_children.clear (); } + + /// Execute all callbacks. Does not combine results. + void operator () (Args&... tail) { + for (auto i = m_children.begin (), end = m_children.end (); i != end; ++i) + (*i)(tail...); + } +}; + +#endif // __SIGNAL_HPP diff --git a/test/.gitignore b/test/.gitignore index 5407c90c..a82d7fb0 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -6,4 +6,5 @@ /maths /matrix /range +/signal /version diff --git a/test/Makefile.am b/test/Makefile.am index d3887ac0..efccdd5b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -7,35 +7,48 @@ AM_CPPFLAGS = \ AM_LDFLAGS = $(COMMON_LDFLAGS) -TEST_BIN = backtrace float range maths matrix version ip hton +TEST_BIN = \ + backtrace \ + float \ + hton \ + ip \ + maths \ + matrix \ + range \ + signal \ + version + TESTS = $(TEST_BIN) json.pl check_PROGRAMS = $(TEST_BIN) json-check EXTRA_DIST = json.pl -backtrace_SOURCES = backtrace.cpp backtrace_CPPFLAGS = $(COMMON_CXXFLAGS) -backtrace_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) +backtrace_LDADD = $(builddir)/../libutil.la +backtrace_SOURCES = backtrace.cpp +float_LDADD = $(builddir)/../libutil.la float_SOURCES = float.cpp -float_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) - -range_SOURCES = range.cpp -range_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) - -maths_SOURCES = maths.cpp -maths_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) - -matrix_SOURCES = matrix.cpp -matrix_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) - -version_SOURCES = version.cpp -version_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) - -ip_SOURCES = ip.cpp -ip_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) +hton_LDADD = $(builddir)/../libutil.la hton_SOURCES = hton.cpp -hton_LDADD = $(builddir)/../libutil.la $(BOOST_SYSTEM_LIB) -json_check_SOURCES = json-check.cpp +ip_LDADD = $(builddir)/../libutil.la +ip_SOURCES = ip.cpp + json_check_LDADD = $(builddir)/../libutil.la $(BOOST_FILESYSTEM_LIB) +json_check_SOURCES = json-check.cpp + +maths_LDADD = $(builddir)/../libutil.la +maths_SOURCES = maths.cpp + +matrix_LDADD = $(builddir)/../libutil.la +matrix_SOURCES = matrix.cpp + +range_LDADD = $(builddir)/../libutil.la +range_SOURCES = range.cpp + +signal_LDADD = $(builddir)/../libutil.la +signal_SOURCES = signal.cpp + +version_LDADD = $(builddir)/../libutil.la +version_SOURCES = version.cpp diff --git a/test/signal.cpp b/test/signal.cpp new file mode 100644 index 00000000..89fa04b7 --- /dev/null +++ b/test/signal.cpp @@ -0,0 +1,50 @@ +#include + +#include "../signal.hpp" +#include "../debug.hpp" + +void +increment_uint (unsigned int &val) + { ++val; } + + +void +test_null (void) { + signal void_signal; + void_signal (); +} + + +void +test_single (void) { + unsigned int val = 0; + signal void_signal; + + void_signal.connect (increment_uint); + void_signal (val); + + check_eq (val, 1); +} + + +void +test_double (void) { + unsigned int val = 0; + signal void_signal; + + void_signal.connect (increment_uint); + void_signal.connect (increment_uint); + void_signal (val); + + check_eq (val, 2); +} + + +int +main (int, char **) { + test_null (); + test_single (); + test_double (); + + return EXIT_SUCCESS; +}