mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-27 06:35:16 +00:00
Replace signals/slots impl with the observable library
This commit is contained in:
parent
bfb65c3d96
commit
da128d3a6e
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -30,3 +30,6 @@
|
|||||||
[submodule "src/clip"]
|
[submodule "src/clip"]
|
||||||
path = src/clip
|
path = src/clip
|
||||||
url = https://github.com/aseprite/clip.git
|
url = https://github.com/aseprite/clip.git
|
||||||
|
[submodule "src/observable"]
|
||||||
|
path = src/observable
|
||||||
|
url = https://github.com/dacap/observable.git
|
||||||
|
@ -80,12 +80,18 @@ endif()
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Aseprite Libraries (in preferred order to be built)
|
# 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)
|
add_subdirectory(base)
|
||||||
|
|
||||||
# Directory where base/config.h file is located
|
# Directory where base/config.h file is located
|
||||||
include_directories(${BASE_INCLUDE_DIR})
|
include_directories(${BASE_INCLUDE_DIR})
|
||||||
|
|
||||||
# Disable clip
|
# Disable clip examples
|
||||||
set(CLIP_EXAMPLES OFF CACHE BOOL "Compile clip examples")
|
set(CLIP_EXAMPLES OFF CACHE BOOL "Compile clip examples")
|
||||||
add_subdirectory(clip)
|
add_subdirectory(clip)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// 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
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -9,6 +9,7 @@
|
|||||||
#define APP_APP_MENUS_H_INCLUDED
|
#define APP_APP_MENUS_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/connection.h"
|
||||||
#include "base/disable_copying.h"
|
#include "base/disable_copying.h"
|
||||||
#include "base/unique_ptr.h"
|
#include "base/unique_ptr.h"
|
||||||
#include "ui/base.h"
|
#include "ui/base.h"
|
||||||
|
@ -16,58 +16,44 @@
|
|||||||
|
|
||||||
namespace app {
|
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)
|
void EditorObservers::notifyDestroyEditor(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onDestroyEditor, editor);
|
notifyObservers(&EditorObserver::onDestroyEditor, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyStateChanged(Editor* editor)
|
void EditorObservers::notifyStateChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onStateChanged, editor);
|
notifyObservers(&EditorObserver::onStateChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyScrollChanged(Editor* editor)
|
void EditorObservers::notifyScrollChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onScrollChanged, editor);
|
notifyObservers(&EditorObserver::onScrollChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyZoomChanged(Editor* editor)
|
void EditorObservers::notifyZoomChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onZoomChanged, editor);
|
notifyObservers(&EditorObserver::onZoomChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyBeforeFrameChanged(Editor* editor)
|
void EditorObservers::notifyBeforeFrameChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onBeforeFrameChanged, editor);
|
notifyObservers(&EditorObserver::onBeforeFrameChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyAfterFrameChanged(Editor* editor)
|
void EditorObservers::notifyAfterFrameChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onAfterFrameChanged, editor);
|
notifyObservers(&EditorObserver::onAfterFrameChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyBeforeLayerChanged(Editor* editor)
|
void EditorObservers::notifyBeforeLayerChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onBeforeLayerChanged, editor);
|
notifyObservers(&EditorObserver::onBeforeLayerChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorObservers::notifyAfterLayerChanged(Editor* editor)
|
void EditorObservers::notifyAfterLayerChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_observers.notifyObservers(&EditorObserver::onAfterLayerChanged, editor);
|
notifyObservers(&EditorObserver::onAfterLayerChanged, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -10,18 +10,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "app/ui/editor/editor_observer.h"
|
#include "app/ui/editor/editor_observer.h"
|
||||||
#include "base/observers.h"
|
#include "base/observable.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
class Editor;
|
class Editor;
|
||||||
|
|
||||||
class EditorObservers {
|
class EditorObservers : public base::Observable<EditorObserver> {
|
||||||
public:
|
public:
|
||||||
EditorObservers();
|
|
||||||
|
|
||||||
void addObserver(EditorObserver* observer);
|
|
||||||
void removeObserver(EditorObserver* observer);
|
|
||||||
|
|
||||||
void notifyDestroyEditor(Editor* editor);
|
void notifyDestroyEditor(Editor* editor);
|
||||||
void notifyStateChanged(Editor* editor);
|
void notifyStateChanged(Editor* editor);
|
||||||
void notifyScrollChanged(Editor* editor);
|
void notifyScrollChanged(Editor* editor);
|
||||||
@ -30,9 +25,6 @@ namespace app {
|
|||||||
void notifyAfterFrameChanged(Editor* editor);
|
void notifyAfterFrameChanged(Editor* editor);
|
||||||
void notifyBeforeLayerChanged(Editor* editor);
|
void notifyBeforeLayerChanged(Editor* editor);
|
||||||
void notifyAfterLayerChanged(Editor* editor);
|
void notifyAfterLayerChanged(Editor* editor);
|
||||||
|
|
||||||
private:
|
|
||||||
base::Observers<EditorObserver> m_observers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// 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
|
// 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
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
@ -9,6 +9,7 @@
|
|||||||
#define APP_UI_RECENT_LISTBOX_H_INCLUDED
|
#define APP_UI_RECENT_LISTBOX_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/connection.h"
|
||||||
#include "ui/listbox.h"
|
#include "ui/listbox.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include "app/color.h"
|
#include "app/color.h"
|
||||||
#include "app/tools/active_tool_observer.h"
|
#include "app/tools/active_tool_observer.h"
|
||||||
#include "base/observers.h"
|
|
||||||
#include "base/time.h"
|
#include "base/time.h"
|
||||||
#include "doc/context_observer.h"
|
#include "doc/context_observer.h"
|
||||||
#include "doc/document_observer.h"
|
#include "doc/document_observer.h"
|
||||||
|
@ -31,7 +31,6 @@ set(BASE_SOURCES
|
|||||||
base64.cpp
|
base64.cpp
|
||||||
cfile.cpp
|
cfile.cpp
|
||||||
chrono.cpp
|
chrono.cpp
|
||||||
connection.cpp
|
|
||||||
convert_to.cpp
|
convert_to.cpp
|
||||||
debug.cpp
|
debug.cpp
|
||||||
dll.cpp
|
dll.cpp
|
||||||
@ -65,8 +64,9 @@ if(WIN32)
|
|||||||
win32_exception.cpp)
|
win32_exception.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# TODO remove dependency with observable library
|
||||||
add_library(base-lib ${BASE_SOURCES})
|
add_library(base-lib ${BASE_SOURCES})
|
||||||
target_link_libraries(base-lib modp_b64)
|
target_link_libraries(base-lib obs modp_b64)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
@ -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
|
|
@ -8,52 +8,12 @@
|
|||||||
#define BASE_CONNETION_H_INCLUDED
|
#define BASE_CONNETION_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "obs/connection.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
class Signal;
|
using Connection = obs::connection;
|
||||||
class Slot;
|
using ScopedConnection = obs::scoped_connection;
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Base Library
|
// 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.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -8,43 +8,31 @@
|
|||||||
#define BASE_OBSERVABLE_H_INCLUDED
|
#define BASE_OBSERVABLE_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/observers.h"
|
#include "obs/observable.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
template<typename Observer>
|
template<typename Observer>
|
||||||
class Observable {
|
class Observable : private obs::observable<Observer> {
|
||||||
|
typedef obs::observable<Observer> Base;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void addObserver(Observer* observer) {
|
void addObserver(Observer* observer) {
|
||||||
m_observers.addObserver(observer);
|
Base::add_observer(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeObserver(Observer* observer) {
|
void removeObserver(Observer* observer) {
|
||||||
m_observers.removeObserver(observer);
|
Base::remove_observer(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyObservers(void (Observer::*method)()) {
|
void notifyObservers(void (Observer::*method)()) {
|
||||||
m_observers.notifyObservers(method);
|
Base::notify_observers(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A1>
|
template<typename ...Args>
|
||||||
void notifyObservers(void (Observer::*method)(A1), A1 a1) {
|
void notifyObservers(void (Observer::*method)(Args...), Args ...args) {
|
||||||
m_observers.template notifyObservers<A1>(method, a1);
|
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
|
} // namespace base
|
||||||
|
@ -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
|
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Base Library
|
// 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.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -8,321 +8,18 @@
|
|||||||
#define BASE_SIGNAL_H_INCLUDED
|
#define BASE_SIGNAL_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/connection.h"
|
#include "obs/signal.h"
|
||||||
#include "base/remove_from_container.h"
|
|
||||||
#include "base/slot.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace base {
|
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>
|
template<typename R>
|
||||||
class Signal0_base : public Signal {
|
using Signal0 = obs::signal0<R>;
|
||||||
public:
|
|
||||||
typedef R ReturnType;
|
|
||||||
typedef Slot0<R> SlotType;
|
|
||||||
typedef std::vector<SlotType*> SlotList;
|
|
||||||
|
|
||||||
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>
|
template<typename R, typename A1>
|
||||||
class Signal1_base : public Signal {
|
using Signal1 = obs::signal1<R, A1>;
|
||||||
public:
|
|
||||||
typedef R ReturnType;
|
|
||||||
typedef Slot1<R, A1> SlotType;
|
|
||||||
typedef std::vector<SlotType*> SlotList;
|
|
||||||
|
|
||||||
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>
|
template<typename R, typename A1, typename A2>
|
||||||
class Signal2_base : public Signal {
|
using Signal2 = obs::signal2<R, A1, A2>;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
|
||||||
|
188
src/base/slot.h
188
src/base/slot.h
@ -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
1
src/observable
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 873aaa15d9bcd98fcee3a35a9d35b826d6805ab4
|
Loading…
x
Reference in New Issue
Block a user