Simplify slot disconnections with the new Connection and ScopedConnection classes

This commit is contained in:
David Capello 2014-06-12 22:29:19 -03:00
parent f8eae50e8a
commit 6924990992
14 changed files with 181 additions and 301 deletions

View File

@ -73,7 +73,6 @@ using namespace ui;
class PaletteEntryEditor : public Window {
public:
PaletteEntryEditor();
~PaletteEntryEditor();
void setColor(const app::Color& color);
@ -134,7 +133,7 @@ private:
// PaletteEntryEditor instance.
bool m_selfPalChange;
Signal0<void>::SlotType* m_palChangeSlot;
ScopedConnection m_palChangeConn;
// Internal-clipboard to copy & paste colors between palettes. It's
// used in onCopy/PasteColorsClick.
@ -327,17 +326,12 @@ PaletteEntryEditor::PaletteEntryEditor()
App::instance()->Exit.connect(&PaletteEntryEditor::onExit, this);
// Hook for palette change to redraw the palette editor frame
m_palChangeSlot =
m_palChangeConn =
App::instance()->PaletteChange.connect(&PaletteEntryEditor::onPalChange, this);
initTheme();
}
PaletteEntryEditor::~PaletteEntryEditor()
{
App::instance()->PaletteChange.disconnect(m_palChangeSlot);
}
void PaletteEntryEditor::setColor(const app::Color& color)
{
m_rgbSliders.setColor(color);

View File

@ -154,7 +154,7 @@ ColorSelector::ColorSelector()
selectColorType(app::Color::RgbType);
setPreferredSize(gfx::Size(300*jguiscale(), getPreferredSize().h));
m_onPaletteChangeSlot =
m_onPaletteChangeConn =
App::instance()->PaletteChange.connect(&ColorSelector::onPaletteChange, this);
m_tooltips.addTooltipFor(m_warningIcon, "This color isn't in the palette\nPress here to add it.", JI_BOTTOM);
@ -164,9 +164,6 @@ ColorSelector::ColorSelector()
ColorSelector::~ColorSelector()
{
App::instance()->PaletteChange.disconnect(m_onPaletteChangeSlot);
delete m_onPaletteChangeSlot;
getPin()->getParent()->removeChild(getPin());
}

View File

@ -25,6 +25,7 @@
#include "app/ui/hex_color_entry.h"
#include "app/ui/palette_view.h"
#include "app/ui/popup_window_pin.h"
#include "base/connection.h"
#include "base/signal.h"
#include "ui/button.h"
#include "ui/grid.h"
@ -82,7 +83,7 @@ namespace app {
GraySlider m_graySlider;
ui::Label m_maskLabel;
WarningIcon* m_warningIcon;
Signal0<void>::SlotType* m_onPaletteChangeSlot;
ScopedConnection m_onPaletteChangeConn;
// This variable is used to avoid updating the m_hexColorEntry text
// when the color change is generated from a

View File

@ -159,10 +159,10 @@ Editor::Editor(Document* document, EditorFlags flags)
this->setFocusStop(true);
m_currentToolChangeSlot =
m_currentToolChangeConn =
App::instance()->CurrentToolChange.connect(&Editor::onCurrentToolChange, this);
m_fgColorChangeSlot =
m_fgColorChangeConn =
ColorBar::instance()->FgColorChange.connect(Bind<void>(&Editor::onFgColorChange, this));
UIContext::instance()->getSettings()
@ -179,14 +179,6 @@ Editor::~Editor()
setCustomizationDelegate(NULL);
m_mask_timer.stop();
// Remove this editor as observer of CurrentToolChange signal.
App::instance()->CurrentToolChange.disconnect(m_currentToolChangeSlot);
delete m_currentToolChangeSlot;
// Remove this editor as observer of FgColorChange
ColorBar::instance()->FgColorChange.disconnect(m_fgColorChangeSlot);
delete m_fgColorChangeSlot;
}
WidgetType editor_type()

View File

@ -27,7 +27,7 @@
#include "app/ui/editor/editor_state.h"
#include "app/ui/editor/editor_states_history.h"
#include "base/compiler_specific.h"
#include "base/signal.h"
#include "base/connection.h"
#include "gfx/fwd.h"
#include "raster/frame_number.h"
#include "ui/base.h"
@ -260,9 +260,8 @@ namespace app {
// signal (because the editor can be destroyed and the application
// still continue running and generating CurrentToolChange
// signals).
Slot0<void>* m_currentToolChangeSlot;
Slot1<void, const app::Color&>* m_fgColorChangeSlot;
ScopedConnection m_currentToolChangeConn;
ScopedConnection m_fgColorChangeConn;
EditorObservers m_observers;

View File

@ -74,12 +74,7 @@ PaletteView::PaletteView(bool editable)
this->border_width.t = this->border_width.b = 1 * jguiscale();
this->child_spacing = 1 * jguiscale();
m_slot = App::instance()->PaletteChange.connect(&PaletteView::onAppPaletteChange, this);
}
PaletteView::~PaletteView()
{
App::instance()->PaletteChange.disconnect(m_slot);
m_conn = App::instance()->PaletteChange.connect(&PaletteView::onAppPaletteChange, this);
}
void PaletteView::setColumns(int columns)

View File

@ -21,8 +21,8 @@
#pragma once
#include "base/compiler_specific.h"
#include "base/connection.h"
#include "base/signal.h"
#include "base/slot.h"
#include "ui/widget.h"
#include <allegro/color.h>
@ -35,7 +35,6 @@ namespace app {
typedef std::vector<bool> SelectedEntries;
PaletteView(bool editable);
~PaletteView();
int getColumns() const { return m_columns; }
void setColumns(int columns);
@ -72,7 +71,7 @@ namespace app {
int m_rangeAnchor;
SelectedEntries m_selectedEntries;
bool m_isUpdatingColumns;
Slot0<void>* m_slot;
ScopedConnection m_conn;
};
ui::WidgetType palette_view_type();

View File

@ -93,7 +93,6 @@ ToolBar* ToolBar::m_instance = NULL;
ToolBar::ToolBar()
: Widget(kGenericWidget)
, m_tipTimer(300, this)
, m_closeSlot(NULL)
, m_openedRecently(false)
{
m_instance = this;
@ -415,11 +414,8 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
if (m_currentStrip && m_currentStrip->toolGroup() == tool_group)
return;
if (m_closeSlot) {
m_popupWindow->Close.disconnect(m_closeSlot);
delete m_closeSlot;
m_closeSlot = NULL;
}
if (m_closeConn)
m_closeConn.disconnect();
onClosePopup();
@ -446,7 +442,7 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
// In case this tool contains more than just one tool, show the popup window
m_popupWindow = new PopupWindow("", PopupWindow::kCloseOnClickOutsideHotRegion);
m_closeSlot = m_popupWindow->Close.connect(Bind<void, ToolBar, ToolBar>(&ToolBar::onClosePopup, this));
m_closeConn = m_popupWindow->Close.connect(Bind<void, ToolBar, ToolBar>(&ToolBar::onClosePopup, this));
m_openedRecently = true;
ToolStrip* toolstrip = new ToolStrip(tool_group, this);

View File

@ -21,7 +21,7 @@
#pragma once
#include "base/compiler_specific.h"
#include "base/slot.h"
#include "base/connection.h"
#include "gfx/point.h"
#include "ui/timer.h"
#include "ui/widget.h"
@ -99,7 +99,7 @@ namespace app {
ui::Timer m_tipTimer;
bool m_tipOpened;
Slot1<void, ui::CloseEvent&>* m_closeSlot;
Connection m_closeConn;
};
} // namespace app

View File

@ -18,6 +18,7 @@ endif()
set(BASE_SOURCES
cfile.cpp
chrono.cpp
connection.cpp
convert_to.cpp
errno_string.cpp
exception.cpp

23
src/base/connection.cpp Normal file
View File

@ -0,0 +1,23 @@
// Aseprite Base Library
// Copyright (c) 2001-2014 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"
void Connection::disconnect()
{
if (!m_slot)
return;
m_signal->disconnectSlot(m_slot);
delete m_slot;
m_slot = NULL;
}

56
src/base/connection.h Normal file
View File

@ -0,0 +1,56 @@
// Aseprite Base Library
// Copyright (c) 2001-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef BASE_CONNETION_H_INCLUDED
#define BASE_CONNETION_H_INCLUDED
#pragma once
class Signal;
class Slot;
class Connection {
public:
Connection() : m_signal(NULL), m_slot(NULL) {
}
Connection(Signal* signal, Slot* slot) :
m_signal(signal), m_slot(slot) {
}
void disconnect();
operator bool() {
return (m_slot != NULL);
}
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;
};
#endif

View File

@ -1,5 +1,5 @@
// Aseprite Base Library
// Copyright (c) 2001-2013 David Capello
// Copyright (c) 2001-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,16 +8,24 @@
#define BASE_SIGNAL_H_INCLUDED
#pragma once
#include "base/slot.h"
#include "base/compiler_specific.h"
#include "base/connection.h"
#include "base/disable_copying.h"
#include "base/remove_from_container.h"
#include "base/slot.h"
#include <vector>
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
{
class Signal0_base : public Signal {
public:
typedef R ReturnType;
typedef Slot0<R> SlotType;
@ -28,87 +36,39 @@ protected:
public:
Signal0_base() { }
Signal0_base(const Signal0_base<R>& s)
{
copy(s);
}
~Signal0_base()
{
disconnectAll();
}
~Signal0_base() { }
SlotType* addSlot(SlotType* slot)
{
Connection addSlot(SlotType* slot) {
m_slots.push_back(slot);
return slot;
return Connection(this, slot);
}
template<typename F>
SlotType* connect(const F& f)
{
Connection connect(const F& f) {
return addSlot(new Slot0_fun<R, F>(f));
}
template<class T>
SlotType* connect(R (T::*m)(), T* t)
{
Connection connect(R (T::*m)(), T* t) {
return addSlot(new Slot0_mem<R, T>(m, t));
}
const SlotList& getSlots() const
{
return m_slots;
}
void disconnect(SlotType* slot)
{
base::remove_from_container(m_slots, slot);
}
void disconnectAll()
{
typename SlotList::iterator end = m_slots.end();
for (typename SlotList::iterator
it = m_slots.begin(); it != end; ++it)
delete *it;
m_slots.clear();
}
bool empty() const
{
return m_slots.empty();
}
Signal0_base& operator=(const Signal0_base<R>& s) {
copy(s);
return *this;
virtual void disconnectSlot(Slot* slot) OVERRIDE {
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
private:
void copy(const Signal0_base<R>& s)
{
typename SlotList::const_iterator end = s.m_slots.end();
for (typename SlotList::const_iterator
it = s.m_slots.begin(); it != end; ++it) {
m_slots.push_back((*it)->clone());
}
}
DISABLE_COPYING(Signal0_base);
};
// Signal0<R>
template<typename R>
class Signal0 : public Signal0_base<R>
{
class Signal0 : public Signal0_base<R> {
public:
Signal0() { }
Signal0() {
}
Signal0(const Signal0<R>& s)
: Signal0_base<R>(s) { }
R operator()(R default_result = R())
{
R operator()(R default_result = R()) {
R result(default_result);
typename Signal0_base<R>::SlotList::iterator end = Signal0_base<R>::m_slots.end();
for (typename Signal0_base<R>::SlotList::iterator
@ -120,8 +80,7 @@ public:
}
template<typename Merger>
R operator()(R default_result, const Merger& m)
{
R operator()(R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
typename Signal0_base<R>::SlotList::iterator end = Signal0_base<R>::m_slots.end();
@ -137,16 +96,11 @@ public:
// Signal0<void>
template<>
class Signal0<void> : public Signal0_base<void>
{
class Signal0<void> : public Signal0_base<void> {
public:
Signal0() { }
Signal0(const Signal0<void>& s)
: Signal0_base<void>(s) { }
void operator()()
{
void operator()() {
SlotList::iterator end = m_slots.end();
for (SlotList::iterator
it = m_slots.begin(); it != end; ++it) {
@ -160,8 +114,7 @@ public:
// Signal1_base<R, A1> - Base class to delegate responsibility to
// functions of one argument.
template<typename R, typename A1>
class Signal1_base
{
class Signal1_base : public Signal {
public:
typedef R ReturnType;
typedef Slot1<R, A1> SlotType;
@ -172,73 +125,29 @@ protected:
public:
Signal1_base() { }
Signal1_base(const Signal1_base<R, A1>& s)
{
copy(s);
}
~Signal1_base()
{
disconnectAll();
}
~Signal1_base() { }
SlotType* addSlot(SlotType* slot)
{
Connection addSlot(SlotType* slot) {
m_slots.push_back(slot);
return slot;
return Connection(this, slot);
}
template<typename F>
SlotType* connect(const F& f)
{
Connection connect(const F& f) {
return addSlot(new Slot1_fun<R, F, A1>(f));
}
template<class T>
SlotType* connect(R (T::*m)(A1), T* t)
{
Connection connect(R (T::*m)(A1), T* t) {
return addSlot(new Slot1_mem<R, T, A1>(m, t));
}
const SlotList& getSlots() const
{
return m_slots;
}
void disconnect(SlotType* slot)
{
base::remove_from_container(m_slots, slot);
}
void disconnectAll()
{
typename SlotList::iterator end = m_slots.end();
for (typename SlotList::iterator
it = m_slots.begin(); it != end; ++it)
delete *it;
m_slots.clear();
}
bool empty() const
{
return m_slots.empty();
}
Signal1_base& operator=(const Signal1_base<R, A1>& s) {
copy(s);
return *this;
virtual void disconnectSlot(Slot* slot) OVERRIDE {
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
private:
void copy(const Signal1_base<R, A1>& s)
{
typename SlotList::const_iterator end = s.m_slots.end();
for (typename SlotList::const_iterator
it = s.m_slots.begin(); it != end; ++it) {
m_slots.push_back((*it)->clone());
}
}
DISABLE_COPYING(Signal1_base);
};
// Signal1<R, A1>
@ -248,11 +157,7 @@ class Signal1 : public Signal1_base<R, A1>
public:
Signal1() { }
Signal1(const Signal1<R, A1>& s)
: Signal1_base<R, A1>(s) { }
R operator()(A1 a1, R default_result = R())
{
R operator()(A1 a1, R default_result = R()) {
R result(default_result);
typename Signal1_base<R, A1>::SlotList::iterator end = Signal1_base<R, A1>::m_slots.end();
for (typename Signal1_base<R, A1>::SlotList::iterator
@ -264,8 +169,7 @@ public:
}
template<typename Merger>
R operator()(A1 a1, R default_result, const Merger& m)
{
R operator()(A1 a1, R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
typename Signal1_base<R, A1>::SlotList::iterator end = Signal1_base<R, A1>::m_slots.end();
@ -286,11 +190,7 @@ class Signal1<void, A1> : public Signal1_base<void, A1>
public:
Signal1() { }
Signal1(const Signal1<void, A1>& s)
: Signal1_base<void, A1>(s) { }
void operator()(A1 a1)
{
void operator()(A1 a1) {
typename Signal1_base<void, A1>::SlotList::iterator end = Signal1_base<void, A1>::m_slots.end();
for (typename Signal1_base<void, A1>::SlotList::iterator
it = Signal1_base<void, A1>::m_slots.begin(); it != end; ++it) {
@ -304,8 +204,7 @@ public:
// 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
{
class Signal2_base : public Signal {
public:
typedef R ReturnType;
typedef Slot2<R, A1, A2> SlotType;
@ -316,87 +215,39 @@ protected:
public:
Signal2_base() { }
Signal2_base(const Signal2_base<R, A1, A2>& s)
{
copy(s);
}
~Signal2_base()
{
disconnectAll();
}
~Signal2_base() { }
SlotType* addSlot(SlotType* slot)
{
Connection addSlot(SlotType* slot) {
m_slots.push_back(slot);
return slot;
return Connection(this, slot);
}
template<typename F>
SlotType* connect(const F& f)
{
Connection connect(const F& f) {
return addSlot(new Slot2_fun<R, F, A1, A2>(f));
}
template<class T>
SlotType* connect(R (T::*m)(A1, A2), T* t)
{
Connection connect(R (T::*m)(A1, A2), T* t) {
return addSlot(new Slot2_mem<R, T, A1, A2>(m, t));
}
const SlotList& getSlots() const
{
return m_slots;
}
void disconnect(SlotType* slot)
{
base::remove_from_container(m_slots, slot);
}
void disconnectAll()
{
typename SlotList::iterator end = m_slots.end();
for (typename SlotList::iterator
it = m_slots.begin(); it != end; ++it)
delete *it;
m_slots.clear();
}
bool empty() const
{
return m_slots.empty();
}
Signal2_base& operator=(const Signal2_base<R, A1, A2>& s) {
copy(s);
return *this;
virtual void disconnectSlot(Slot* slot) OVERRIDE {
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
private:
void copy(const Signal2_base<R, A1, A2>& s)
{
typename SlotList::const_iterator end = s.m_slots.end();
for (typename SlotList::const_iterator
it = s.m_slots.begin(); it != end; ++it) {
m_slots.push_back((*it)->clone());
}
}
DISABLE_COPYING(Signal2_base);
};
// Signal2<R, A1>
template<typename R, typename A1, typename A2>
class Signal2 : public Signal2_base<R, A1, A2>
{
class Signal2 : public Signal2_base<R, A1, A2> {
public:
Signal2() { }
Signal2() {
}
Signal2(const Signal2<R, A1, A2>& s)
: Signal2_base<R, A1, A2>(s) { }
R operator()(A1 a1, A2 a2, R default_result = R())
{
R operator()(A1 a1, A2 a2, R default_result = R()) {
R result(default_result);
typename Signal2_base<R, A1, A2>::SlotList::iterator end = Signal2_base<R, A1, A2>::m_slots.end();
for (typename Signal2_base<R, A1, A2>::SlotList::iterator
@ -408,8 +259,7 @@ public:
}
template<typename Merger>
R operator()(A1 a1, A2 a2, R default_result, const Merger& m)
{
R operator()(A1 a1, A2 a2, R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
typename Signal2_base<R, A1, A2>::SlotList::iterator end = Signal2_base<R, A1, A2>::m_slots.end();
@ -425,16 +275,12 @@ public:
// Signal2<void, A1>
template<typename A1, typename A2>
class Signal2<void, A1, A2> : public Signal2_base<void, A1, A2>
{
class Signal2<void, A1, A2> : public Signal2_base<void, A1, A2> {
public:
Signal2() { }
Signal2() {
}
Signal2(const Signal2<void, A1, A2>& s)
: Signal2_base<void, A1, A2>(s) { }
void operator()(A1 a1, A2 a2)
{
void operator()(A1 a1, A2 a2) {
typename Signal2_base<void, A1, A2>::SlotList::iterator end = Signal2_base<void, A1, A2>::m_slots.end();
for (typename Signal2_base<void, A1, A2>::SlotList::iterator
it = Signal2_base<void, A1, A2>::m_slots.begin(); it != end; ++it) {

View File

@ -8,47 +8,51 @@
#define BASE_SLOT_H_INCLUDED
#pragma once
#include "base/disable_copying.h"
class Slot {
public:
Slot() { }
virtual ~Slot() { }
private:
DISABLE_COPYING(Slot);
};
// Slot0 - Base class for delegates of zero arguments.
template<typename R>
class Slot0
{
class Slot0 : public Slot {
public:
Slot0() { }
Slot0(const Slot0& s) { (void)s; }
virtual ~Slot0() { }
virtual R operator()() = 0;
virtual Slot0* clone() const = 0;
};
// Slot0_fun - hold a F instance and use the function call operator
template<typename R, typename F>
class Slot0_fun : public Slot0<R>
{
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(); }
Slot0_fun* clone() const { return new Slot0_fun(*this); }
};
template<typename F>
class Slot0_fun<void, F> : public Slot0<void>
{
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_fun* clone() const { return new Slot0_fun(*this); }
};
// Slot0_mem - pointer to a member function of the T class
template<typename R, class T>
class Slot0_mem : public Slot0<R>
{
class Slot0_mem : public Slot0<R> {
R (T::*m)();
T* t;
public:
@ -56,12 +60,10 @@ public:
Slot0_mem(const Slot0_mem& s) : Slot0<R>(s), m(s.m), t(s.t) { }
~Slot0_mem() { }
R operator()() { return (t->*m)(); }
Slot0_mem* clone() const { return new Slot0_mem(*this); }
};
template<class T>
class Slot0_mem<void, T> : public Slot0<void>
{
class Slot0_mem<void, T> : public Slot0<void> {
void (T::*m)();
T* t;
public:
@ -69,50 +71,42 @@ public:
Slot0_mem(const Slot0_mem& s) : Slot0<void>(s), m(s.m), t(s.t) { }
~Slot0_mem() { }
void operator()() { (t->*m)(); }
Slot0_mem* clone() const { return new Slot0_mem(*this); }
};
// Slot1 - Base class for delegates of one argument.
template<typename R, typename A1>
class Slot1
{
class Slot1 : public Slot {
public:
Slot1() { }
Slot1(const Slot1& s) { (void)s; }
virtual ~Slot1() { }
virtual R operator()(A1 a1) = 0;
virtual Slot1* clone() const = 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>
{
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); }
Slot1_fun* clone() const { return new Slot1_fun(*this); }
};
template<typename F, typename A1>
class Slot1_fun<void, F, A1> : public Slot1<void, 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_fun* clone() const { return new Slot1_fun(*this); }
};
// 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>
{
class Slot1_mem : public Slot1<R, A1> {
R (T::*m)(A1);
T* t;
public:
@ -120,12 +114,10 @@ public:
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); }
Slot1_mem* clone() const { return new Slot1_mem(*this); }
};
template<class T, typename A1>
class Slot1_mem<void, T, A1> : public Slot1<void, A1>
{
class Slot1_mem<void, T, A1> : public Slot1<void, A1> {
void (T::*m)(A1);
T* t;
public:
@ -133,50 +125,42 @@ public:
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); }
Slot1_mem* clone() const { return new Slot1_mem(*this); }
};
// Slot2 - Base class for delegates of two arguments.
template<typename R, typename A1, typename A2>
class Slot2
{
class Slot2 : public Slot {
public:
Slot2() { }
Slot2(const Slot2& s) { (void)s; }
virtual ~Slot2() { }
virtual R operator()(A1 a1, A2 a2) = 0;
virtual Slot2* clone() const = 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>
{
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); }
Slot2_fun* clone() const { return new Slot2_fun(*this); }
};
template<typename F, typename A1, typename A2>
class Slot2_fun<void, F, A1, A2> : public Slot2<void, A1, 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_fun* clone() const { return new Slot2_fun(*this); }
};
// 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>
{
class Slot2_mem : public Slot2<R, A1, A2> {
R (T::*m)(A1, A2);
T* t;
public:
@ -184,12 +168,10 @@ public:
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); }
Slot2_mem* clone() const { return new Slot2_mem(*this); }
};
template<class T, typename A1, typename A2>
class Slot2_mem<void, T, A1, A2> : public Slot2<void, A1, A2>
{
class Slot2_mem<void, T, A1, A2> : public Slot2<void, A1, A2> {
void (T::*m)(A1, A2);
T* t;
public:
@ -197,7 +179,6 @@ public:
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); }
Slot2_mem* clone() const { return new Slot2_mem(*this); }
};
#endif