mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +00:00
Simplify slot disconnections with the new Connection and ScopedConnection classes
This commit is contained in:
parent
f8eae50e8a
commit
6924990992
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
23
src/base/connection.cpp
Normal 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
56
src/base/connection.h
Normal 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
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user