Replace signals/slots impl with the observable library

This commit is contained in:
David Capello 2016-06-28 17:22:23 -03:00
parent bfb65c3d96
commit da128d3a6e
15 changed files with 46 additions and 724 deletions

3
.gitmodules vendored
View File

@ -30,3 +30,6 @@
[submodule "src/clip"]
path = src/clip
url = https://github.com/aseprite/clip.git
[submodule "src/observable"]
path = src/observable
url = https://github.com/dacap/observable.git

View File

@ -80,12 +80,18 @@ endif()
######################################################################
# Aseprite Libraries (in preferred order to be built)
# Disable observable tests
set(OBSERVABLE_TESTS OFF CACHE BOOL "Compile observable tests")
add_subdirectory(observable)
include_directories(observable)
# Our base library
add_subdirectory(base)
# Directory where base/config.h file is located
include_directories(${BASE_INCLUDE_DIR})
# Disable clip
# Disable clip examples
set(CLIP_EXAMPLES OFF CACHE BOOL "Compile clip examples")
add_subdirectory(clip)

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -9,6 +9,7 @@
#define APP_APP_MENUS_H_INCLUDED
#pragma once
#include "base/connection.h"
#include "base/disable_copying.h"
#include "base/unique_ptr.h"
#include "ui/base.h"

View File

@ -16,58 +16,44 @@
namespace app {
EditorObservers::EditorObservers()
{
}
void EditorObservers::addObserver(EditorObserver* observer)
{
m_observers.addObserver(observer);
}
void EditorObservers::removeObserver(EditorObserver* observer)
{
m_observers.removeObserver(observer);
}
void EditorObservers::notifyDestroyEditor(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onDestroyEditor, editor);
notifyObservers(&EditorObserver::onDestroyEditor, editor);
}
void EditorObservers::notifyStateChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onStateChanged, editor);
notifyObservers(&EditorObserver::onStateChanged, editor);
}
void EditorObservers::notifyScrollChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onScrollChanged, editor);
notifyObservers(&EditorObserver::onScrollChanged, editor);
}
void EditorObservers::notifyZoomChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onZoomChanged, editor);
notifyObservers(&EditorObserver::onZoomChanged, editor);
}
void EditorObservers::notifyBeforeFrameChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onBeforeFrameChanged, editor);
notifyObservers(&EditorObserver::onBeforeFrameChanged, editor);
}
void EditorObservers::notifyAfterFrameChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onAfterFrameChanged, editor);
notifyObservers(&EditorObserver::onAfterFrameChanged, editor);
}
void EditorObservers::notifyBeforeLayerChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onBeforeLayerChanged, editor);
notifyObservers(&EditorObserver::onBeforeLayerChanged, editor);
}
void EditorObservers::notifyAfterLayerChanged(Editor* editor)
{
m_observers.notifyObservers(&EditorObserver::onAfterLayerChanged, editor);
notifyObservers(&EditorObserver::onAfterLayerChanged, editor);
}
} // namespace app

View File

@ -10,18 +10,13 @@
#pragma once
#include "app/ui/editor/editor_observer.h"
#include "base/observers.h"
#include "base/observable.h"
namespace app {
class Editor;
class EditorObservers {
class EditorObservers : public base::Observable<EditorObserver> {
public:
EditorObservers();
void addObserver(EditorObserver* observer);
void removeObserver(EditorObserver* observer);
void notifyDestroyEditor(Editor* editor);
void notifyStateChanged(Editor* editor);
void notifyScrollChanged(Editor* editor);
@ -30,9 +25,6 @@ namespace app {
void notifyAfterFrameChanged(Editor* editor);
void notifyBeforeLayerChanged(Editor* editor);
void notifyAfterLayerChanged(Editor* editor);
private:
base::Observers<EditorObserver> m_observers;
};
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -9,6 +9,7 @@
#define APP_UI_RECENT_LISTBOX_H_INCLUDED
#pragma once
#include "base/connection.h"
#include "ui/listbox.h"
namespace app {

View File

@ -11,7 +11,6 @@
#include "app/color.h"
#include "app/tools/active_tool_observer.h"
#include "base/observers.h"
#include "base/time.h"
#include "doc/context_observer.h"
#include "doc/document_observer.h"

View File

@ -31,7 +31,6 @@ set(BASE_SOURCES
base64.cpp
cfile.cpp
chrono.cpp
connection.cpp
convert_to.cpp
debug.cpp
dll.cpp
@ -65,8 +64,9 @@ if(WIN32)
win32_exception.cpp)
endif()
# TODO remove dependency with observable library
add_library(base-lib ${BASE_SOURCES})
target_link_libraries(base-lib modp_b64)
target_link_libraries(base-lib obs modp_b64)
if(WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)

View File

@ -1,27 +0,0 @@
// Aseprite Base Library
// Copyright (c) 2001-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "base/connection.h"
#include "base/signal.h"
namespace base {
void Connection::disconnect()
{
if (!m_slot)
return;
m_signal->disconnectSlot(m_slot);
delete m_slot;
m_slot = NULL;
}
} // namespace base

View File

@ -8,52 +8,12 @@
#define BASE_CONNETION_H_INCLUDED
#pragma once
#include "obs/connection.h"
namespace base {
class Signal;
class Slot;
class Connection {
public:
Connection() : m_signal(nullptr), m_slot(nullptr) {
}
Connection(Signal* signal, Slot* slot) :
m_signal(signal), m_slot(slot) {
}
void disconnect();
operator bool() {
return (m_slot != nullptr);
}
private:
Signal* m_signal;
Slot* m_slot;
};
class ScopedConnection {
public:
ScopedConnection() {
}
ScopedConnection(const Connection& conn) : m_conn(conn) {
}
ScopedConnection& operator=(const Connection& conn) {
m_conn.disconnect();
m_conn = conn;
return *this;
}
~ScopedConnection() {
m_conn.disconnect();
}
private:
Connection m_conn;
};
using Connection = obs::connection;
using ScopedConnection = obs::scoped_connection;
} // namespace base

View File

@ -1,5 +1,5 @@
// Aseprite Base Library
// Copyright (c) 2001-2013 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,43 +8,31 @@
#define BASE_OBSERVABLE_H_INCLUDED
#pragma once
#include "base/observers.h"
#include "obs/observable.h"
namespace base {
template<typename Observer>
class Observable {
class Observable : private obs::observable<Observer> {
typedef obs::observable<Observer> Base;
public:
void addObserver(Observer* observer) {
m_observers.addObserver(observer);
Base::add_observer(observer);
}
void removeObserver(Observer* observer) {
m_observers.removeObserver(observer);
Base::remove_observer(observer);
}
void notifyObservers(void (Observer::*method)()) {
m_observers.notifyObservers(method);
Base::notify_observers(method);
}
template<typename A1>
void notifyObservers(void (Observer::*method)(A1), A1 a1) {
m_observers.template notifyObservers<A1>(method, a1);
template<typename ...Args>
void notifyObservers(void (Observer::*method)(Args...), Args ...args) {
Base::template notify_observers<Args...>(method, std::forward<Args>(args)...);
}
template<typename A1, typename A2>
void notifyObservers(void (Observer::*method)(A1, A2), A1 a1, A2 a2) {
m_observers.template notifyObservers<A1, A2>(method, a1, a2);
}
template<typename A1, typename A2, typename A3>
void notifyObservers(void (Observer::*method)(A1, A2, A3), A1 a1, A2 a2, A3 a3) {
m_observers.template notifyObservers<A1, A2, A3>(method, a1, a2, a3);
}
private:
Observers<Observer> m_observers;
};
} // namespace base

View File

@ -1,97 +0,0 @@
// Aseprite Base Library
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef BASE_OBSERVERS_H_INCLUDED
#define BASE_OBSERVERS_H_INCLUDED
#pragma once
#include "base/debug.h"
#include <algorithm>
#include <vector>
namespace base {
template<typename T>
class Observers {
public:
typedef T observer_type;
typedef std::vector<observer_type*> list_type;
typedef typename list_type::iterator iterator;
typedef typename list_type::const_iterator const_iterator;
bool empty() const { return m_observers.empty(); }
std::size_t size() const { return m_observers.size(); }
// Adds the observer in the collection. The observer is owned by the
// collection and will be destroyed calling the T::dispose() member
// function.
void addObserver(observer_type* observer) {
ASSERT(std::find(m_observers.begin(), m_observers.end(), observer) == m_observers.end() && "You've tried to add an observer that already is in the collection");
m_observers.push_back(observer);
}
// Removes the observer from the collection. After calling this
// function you own the observer so you have to dispose it.
void removeObserver(observer_type* observer) {
iterator it = std::find(m_observers.begin(), m_observers.end(), observer);
if (it != m_observers.end())
m_observers.erase(it);
else {
ASSERT(false && "You've tried to remove an observer that isn't in the collection");
}
}
void notifyObservers(void (observer_type::*method)()) {
list_type copy = m_observers;
for (iterator
it = copy.begin(),
end = copy.end(); it != end; ++it) {
if (*it)
((*it)->*method)();
}
}
template<typename A1>
void notifyObservers(void (observer_type::*method)(A1), A1 a1) {
list_type copy = m_observers;
for (iterator
it = copy.begin(),
end = copy.end(); it != end; ++it) {
if (*it)
((*it)->*method)(a1);
}
}
template<typename A1, typename A2>
void notifyObservers(void (observer_type::*method)(A1, A2), A1 a1, A2 a2) {
list_type copy = m_observers;
for (iterator
it = copy.begin(),
end = copy.end(); it != end; ++it) {
if (*it)
((*it)->*method)(a1, a2);
}
}
template<typename A1, typename A2, typename A3>
void notifyObservers(void (observer_type::*method)(A1, A2, A3), A1 a1, A2 a2, A3 a3) {
list_type copy = m_observers;
for (iterator
it = copy.begin(),
end = copy.end(); it != end; ++it) {
if (*it)
((*it)->*method)(a1, a2, a3);
}
}
private:
list_type m_observers;
};
} // namespace base
#endif // BASE_OBSERVERS_H_INCLUDED

View File

@ -1,5 +1,5 @@
// Aseprite Base Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,321 +8,18 @@
#define BASE_SIGNAL_H_INCLUDED
#pragma once
#include "base/connection.h"
#include "base/remove_from_container.h"
#include "base/slot.h"
#include <vector>
#include "obs/signal.h"
namespace base {
class Signal {
public:
virtual ~Signal() { }
virtual void disconnectSlot(Slot* slot) = 0;
};
// Signal0_base<R> - Base class to delegate responsibility to
// functions of zero arguments.
template<typename R>
class Signal0_base : public Signal {
public:
typedef R ReturnType;
typedef Slot0<R> SlotType;
typedef std::vector<SlotType*> SlotList;
using Signal0 = obs::signal0<R>;
Signal0_base() { }
~Signal0_base() {
for (SlotType* slot : m_slots)
delete slot;
}
Signal0_base(const Signal0_base&) { }
Signal0_base operator=(const Signal0_base&) {
return *this;
}
Connection addSlot(SlotType* slot) {
m_slots.push_back(slot);
return Connection(this, slot);
}
template<typename F>
Connection connect(const F& f) {
return addSlot(new Slot0_fun<R, F>(f));
}
template<class T>
Connection connect(R (T::*m)(), T* t) {
return addSlot(new Slot0_mem<R, T>(m, t));
}
virtual void disconnectSlot(Slot* slot) override {
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
protected:
SlotList m_slots;
};
// Signal0<R>
template<typename R>
class Signal0 : public Signal0_base<R> {
public:
// GCC needs redefinitions
typedef Signal0_base<R> Base;
typedef Slot0<R> SlotType;
typedef typename Base::SlotList SlotList;
Signal0() {
}
R operator()(R default_result = R()) {
R result(default_result);
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = (*slot)();
}
return result;
}
template<typename Merger>
R operator()(R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = merger(result, (*slot)());
}
return result;
}
};
// Signal0<void>
template<>
class Signal0<void> : public Signal0_base<void> {
public:
// GCC needs redefinitions
typedef Signal0_base<void> Base;
typedef Slot0<void> SlotType;
typedef Base::SlotList SlotList;
Signal0() { }
void operator()() {
SlotList copy = Base::m_slots;
for (SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
(*slot)();
}
}
};
// Signal1_base<R, A1> - Base class to delegate responsibility to
// functions of one argument.
template<typename R, typename A1>
class Signal1_base : public Signal {
public:
typedef R ReturnType;
typedef Slot1<R, A1> SlotType;
typedef std::vector<SlotType*> SlotList;
using Signal1 = obs::signal1<R, A1>;
Signal1_base() { }
~Signal1_base() {
for (SlotType* slot : m_slots)
delete slot;
}
Signal1_base(const Signal1_base&) { }
Signal1_base operator=(const Signal1_base&) {
return *this;
}
Connection addSlot(SlotType* slot) {
m_slots.push_back(slot);
return Connection(this, slot);
}
template<typename F>
Connection connect(const F& f) {
return addSlot(new Slot1_fun<R, F, A1>(f));
}
template<class T>
Connection connect(R (T::*m)(A1), T* t) {
return addSlot(new Slot1_mem<R, T, A1>(m, t));
}
virtual void disconnectSlot(Slot* slot) override {
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
protected:
SlotList m_slots;
};
// Signal1<R, A1>
template<typename R, typename A1>
class Signal1 : public Signal1_base<R, A1>
{
public:
// GCC needs redefinitions
typedef Signal1_base<R, A1> Base;
typedef Slot1<R, A1> SlotType;
typedef typename Base::SlotList SlotList;
Signal1() { }
R operator()(A1 a1, R default_result = R()) {
R result(default_result);
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = (*slot)(a1);
}
return result;
}
template<typename Merger>
R operator()(A1 a1, R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = merger(result, (*slot)(a1));
}
return result;
}
};
// Signal1<void, A1>
template<typename A1>
class Signal1<void, A1> : public Signal1_base<void, A1>
{
public:
// GCC needs redefinitions
typedef Signal1_base<void, A1> Base;
typedef Slot1<void, A1> SlotType;
typedef typename Base::SlotList SlotList;
Signal1() { }
void operator()(A1 a1) {
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
(*slot)(a1);
}
}
};
// Signal2_base<R, A1, A2> - Base class to delegate responsibility to
// functions of two arguments.
template<typename R, typename A1, typename A2>
class Signal2_base : public Signal {
public:
typedef R ReturnType;
typedef Slot2<R, A1, A2> SlotType;
typedef std::vector<SlotType*> SlotList;
Signal2_base() { }
~Signal2_base() {
for (SlotType* slot : m_slots)
delete slot;
}
Signal2_base(const Signal2_base&) { }
Signal2_base operator=(const Signal2_base&) {
return *this;
}
Connection addSlot(SlotType* slot) {
m_slots.push_back(slot);
return Connection(this, slot);
}
template<typename F>
Connection connect(const F& f) {
return addSlot(new Slot2_fun<R, F, A1, A2>(f));
}
template<class T>
Connection connect(R (T::*m)(A1, A2), T* t) {
return addSlot(new Slot2_mem<R, T, A1, A2>(m, t));
}
virtual void disconnectSlot(Slot* slot) override {
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
protected:
SlotList m_slots;
};
// Signal2<R, A1>
template<typename R, typename A1, typename A2>
class Signal2 : public Signal2_base<R, A1, A2> {
public:
// GCC needs redefinitions
typedef Signal2_base<R, A1, A2> Base;
typedef Slot2<R, A1, A2> SlotType;
typedef typename Base::SlotList SlotList;
Signal2() {
}
R operator()(A1 a1, A2 a2, R default_result = R()) {
R result(default_result);
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = (*slot)(a1, a2);
}
return result;
}
template<typename Merger>
R operator()(A1 a1, A2 a2, R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = merger(result, (*slot)(a1, a2));
}
return result;
}
};
// Signal2<void, A1>
template<typename A1, typename A2>
class Signal2<void, A1, A2> : public Signal2_base<void, A1, A2> {
public:
// GCC needs redefinitions
typedef Signal2_base<void, A1, A2> Base;
typedef Slot2<void, A1, A2> SlotType;
typedef typename Base::SlotList SlotList;
Signal2() {
}
void operator()(A1 a1, A2 a2) {
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
(*slot)(a1, a2);
}
}
};
using Signal2 = obs::signal2<R, A1, A2>;
} // namespace base

View File

@ -1,188 +0,0 @@
// Aseprite Base Library
// Copyright (c) 2001-2013, 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef BASE_SLOT_H_INCLUDED
#define BASE_SLOT_H_INCLUDED
#pragma once
#include "base/disable_copying.h"
namespace base {
class Slot {
public:
Slot() { }
virtual ~Slot() { }
private:
DISABLE_COPYING(Slot);
};
// Slot0 - Base class for delegates of zero arguments.
template<typename R>
class Slot0 : public Slot {
public:
Slot0() { }
Slot0(const Slot0& s) { (void)s; }
virtual ~Slot0() { }
virtual R operator()() = 0;
};
// Slot0_fun - hold a F instance and use the function call operator
template<typename R, typename F>
class Slot0_fun : public Slot0<R> {
F f;
public:
Slot0_fun(const F& f) : f(f) { }
Slot0_fun(const Slot0_fun& s) : Slot0<R>(s), f(s.f) { }
~Slot0_fun() { }
R operator()() { return f(); }
};
template<typename F>
class Slot0_fun<void, F> : public Slot0<void> {
F f;
public:
Slot0_fun(const F& f) : f(f) { }
Slot0_fun(const Slot0_fun& s) : Slot0<void>(s), f(s.f) { }
~Slot0_fun() { }
void operator()() { f(); }
};
// Slot0_mem - pointer to a member function of the T class
template<typename R, class T>
class Slot0_mem : public Slot0<R> {
R (T::*m)();
T* t;
public:
Slot0_mem(R (T::*m)(), T* t) : m(m), t(t) { }
Slot0_mem(const Slot0_mem& s) : Slot0<R>(s), m(s.m), t(s.t) { }
~Slot0_mem() { }
R operator()() { return (t->*m)(); }
};
template<class T>
class Slot0_mem<void, T> : public Slot0<void> {
void (T::*m)();
T* t;
public:
Slot0_mem(void (T::*m)(), T* t) : m(m), t(t) { }
Slot0_mem(const Slot0_mem& s) : Slot0<void>(s), m(s.m), t(s.t) { }
~Slot0_mem() { }
void operator()() { (t->*m)(); }
};
// Slot1 - Base class for delegates of one argument.
template<typename R, typename A1>
class Slot1 : public Slot {
public:
Slot1() { }
Slot1(const Slot1& s) { (void)s; }
virtual ~Slot1() { }
virtual R operator()(A1 a1) = 0;
};
// Slot1_fun - hold a F instance and use the function call operator
template<typename R, typename F, typename A1>
class Slot1_fun : public Slot1<R, A1> {
F f;
public:
Slot1_fun(const F& f) : f(f) { }
Slot1_fun(const Slot1_fun& s) : Slot1<R, A1>(s), f(s.f) { }
~Slot1_fun() { }
R operator()(A1 a1) { return f(a1); }
};
template<typename F, typename A1>
class Slot1_fun<void, F, A1> : public Slot1<void, A1> {
F f;
public:
Slot1_fun(const F& f) : f(f) { }
Slot1_fun(const Slot1_fun& s) : Slot1<void, A1>(s), f(s.f) { }
~Slot1_fun() { }
void operator()(A1 a1) { f(a1); }
};
// Slot1_mem - pointer to a member function of the T class
template<typename R, class T, typename A1>
class Slot1_mem : public Slot1<R, A1> {
R (T::*m)(A1);
T* t;
public:
Slot1_mem(R (T::*m)(A1), T* t) : m(m), t(t) { }
Slot1_mem(const Slot1_mem& s) : Slot1<R, A1>(s), m(s.m), t(s.t) { }
~Slot1_mem() { }
R operator()(A1 a1) { return (t->*m)(a1); }
};
template<class T, typename A1>
class Slot1_mem<void, T, A1> : public Slot1<void, A1> {
void (T::*m)(A1);
T* t;
public:
Slot1_mem(void (T::*m)(A1), T* t) : m(m), t(t) { }
Slot1_mem(const Slot1_mem& s) : Slot1<void, A1>(s), m(s.m), t(s.t) { }
~Slot1_mem() { }
void operator()(A1 a1) { (t->*m)(a1); }
};
// Slot2 - Base class for delegates of two arguments.
template<typename R, typename A1, typename A2>
class Slot2 : public Slot {
public:
Slot2() { }
Slot2(const Slot2& s) { (void)s; }
virtual ~Slot2() { }
virtual R operator()(A1 a1, A2 a2) = 0;
};
// Slot2_fun - hold a F instance and use the function call operator
template<typename R, typename F, typename A1, typename A2>
class Slot2_fun : public Slot2<R, A1, A2> {
F f;
public:
Slot2_fun(const F& f) : f(f) { }
Slot2_fun(const Slot2_fun& s) : Slot2<R, A1, A2>(s), f(s.f) { }
~Slot2_fun() { }
R operator()(A1 a1, A2 a2) { return f(a1, a2); }
};
template<typename F, typename A1, typename A2>
class Slot2_fun<void, F, A1, A2> : public Slot2<void, A1, A2> {
F f;
public:
Slot2_fun(const F& f) : f(f) { }
Slot2_fun(const Slot2_fun& s) : Slot2<void, A1, A2>(s), f(s.f) { }
~Slot2_fun() { }
void operator()(A1 a1, A2 a2) { f(a1, a2); }
};
// Slot2_mem - pointer to a member function of the T class
template<typename R, class T, typename A1, typename A2>
class Slot2_mem : public Slot2<R, A1, A2> {
R (T::*m)(A1, A2);
T* t;
public:
Slot2_mem(R (T::*m)(A1, A2), T* t) : m(m), t(t) { }
Slot2_mem(const Slot2_mem& s) : Slot2<R, A1, A2>(s), m(s.m), t(s.t) { }
~Slot2_mem() { }
R operator()(A1 a1, A2 a2) { return (t->*m)(a1, a2); }
};
template<class T, typename A1, typename A2>
class Slot2_mem<void, T, A1, A2> : public Slot2<void, A1, A2> {
void (T::*m)(A1, A2);
T* t;
public:
Slot2_mem(void (T::*m)(A1, A2), T* t) : m(m), t(t) { }
Slot2_mem(const Slot2_mem& s) : Slot2<void, A1, A2>(s), m(s.m), t(s.t) { }
~Slot2_mem() { }
void operator()(A1 a1, A2 a2) { return (t->*m)(a1, a2); }
};
} // namespace base
#endif

1
src/observable Submodule

@ -0,0 +1 @@
Subproject commit 873aaa15d9bcd98fcee3a35a9d35b826d6805ab4