OpenCPN Partial API docs
Loading...
Searching...
No Matches
observable.h
1/*************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: General observable implementation with several specializations.
5 *
6 * Copyright (C) 2022 Alec Leamas
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the
20 * Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 **************************************************************************/
23
24#ifndef OBSERVABLE_H
25#define OBSERVABLE_H
26
27#include <memory>
28#include <mutex>
29#include <string>
30#include <utility>
31#include <vector>
32
33#include <wx/event.h>
34
35#include "observable_evt.h"
36
37#ifndef DECL_EXP
38#if defined(_MSC_VER) || defined(__CYGWIN__)
39#define DECL_EXP __declspec(dllexport)
40#elif defined(__GNUC__) || defined(__clang__)
41#define DECL_EXP __attribute__((visibility("default")))
42#else
43#define DECL_EXP
44#endif
45#endif // DECL_EXP
46
48std::string ptr_key(const void* ptr);
49
50class Observable;
52
55public:
56
58 virtual std::string GetKey() const = 0;
59};
60
61
67 friend class Observable;
68 friend ListenersByKey& GetInstance(const std::string& key);
69
70public:
72
73private:
74 static ListenersByKey& GetInstance(const std::string& key);
75
76 ListenersByKey(const ListenersByKey&) = delete;
77 ListenersByKey& operator=(const ListenersByKey&) = default;
78
79 std::vector<std::pair<wxEvtHandler*, wxEventType>> listeners;
80};
81
83class Observable : public KeyProvider {
84 friend class ObservableListener;
85
86public:
88 Observable(const std::string& _key)
89 : key(_key), m_list(ListenersByKey::GetInstance(_key)) {}
90
93
95 virtual const void Notify();
96
98 const void Notify(std::shared_ptr<const void> p) { Notify(p, "", 0, 0); }
99
104 bool Unlisten(wxEvtHandler* listener, wxEventType ev);
105
107 std::string GetKey() const { return key; }
108
110 const std::string key;
111
112protected:
118 const void Notify(std::shared_ptr<const void> ptr, const std::string& s,
119 int num, void* client_data);
120
126 const void Notify(const std::string& s, void* client_data) {
127 Notify(nullptr, s, 0, client_data);
128 }
129
130
131private:
133 void Listen(wxEvtHandler* listener, wxEventType ev_type);
134
135 ListenersByKey& m_list;
136
137 mutable std::mutex m_mutex;
138};
139
143class DECL_EXP ObservableListener final {
144public:
146 ObservableListener() : key(""), listener(0), ev_type(wxEVT_NULL) {}
147
149 ObservableListener(const std::string& k, wxEvtHandler* l, wxEventType e)
150 : key(k), listener(l), ev_type(e) {
151 Listen();
152 }
153
155 ObservableListener(const KeyProvider& kp, wxEvtHandler* l, wxEventType e) :
156 ObservableListener(kp.GetKey(), l, e) {}
157
160 : key(other.key), listener(other.listener), ev_type(other.ev_type) {
161 other.Unlisten();
162 Listen();
163 }
164
165 ObservableListener(const ObservableListener& other) = delete;
166 ObservableListener& operator=(ObservableListener&) = delete;
167
168 ~ObservableListener() { Unlisten(); }
169
171 void Listen(const std::string& key, wxEvtHandler* listener, wxEventType evt);
172
177 void Listen(const KeyProvider& kp, wxEvtHandler* l, wxEventType evt) {
178 Listen(kp.GetKey(), l, evt);
179 }
180
181private:
182 void Listen();
183 void Unlisten();
184
185 std::string key;
186 wxEvtHandler* listener;
187 wxEventType ev_type;
188};
189
191template <typename T>
192std::shared_ptr<const T> UnpackEvtPointer(ObservedEvt ev) {
193 return std::static_pointer_cast<const T>(ev.GetSharedPtr());
194}
195
196#endif // OBSERVABLE_H
Interface implemented by classes which listens.
Definition: observable.h:54
virtual std::string GetKey() const =0
Return key used to listen and notify.
Private helper class.
Definition: observable.h:66
Keeps listening over it's lifespan, removes itself on destruction.
Definition: observable.h:143
ObservableListener(ObservableListener &&other)
A listener can only be transferred using std::move().
Definition: observable.h:159
ObservableListener(const KeyProvider &kp, wxEvtHandler *l, wxEventType e)
Construct a listening object listening to kp.GetKey()
Definition: observable.h:155
ObservableListener(const std::string &k, wxEvtHandler *l, wxEventType e)
Construct a listening object listening to key k.
Definition: observable.h:149
void Listen(const KeyProvider &kp, wxEvtHandler *l, wxEventType evt)
Set object to send wxEventType ev to listener on changes in a KeyProvider.
Definition: observable.h:177
ObservableListener()
Default constructor, does not listen to anything.
Definition: observable.h:146
The observable notify/listen basic nuts and bolts.
Definition: observable.h:83
std::string GetKey() const
Retrieve the actual listening key:
Definition: observable.h:107
const std::string key
The key used to create and clone.
Definition: observable.h:110
const void Notify(std::shared_ptr< const void > p)
Notify all listeners about variable change with a shared_ptr payload.
Definition: observable.h:98
Observable(const std::string &_key)
Create an instance listening to given key.
Definition: observable.h:88
Observable(const KeyProvider &kp)
Create an instance listening to key provided by kp.GetKey().
Definition: observable.h:92
const void Notify(const std::string &s, void *client_data)
Notify all listeners: send them a 'type' ObservedEvt message as defined by listen() with optional dat...
Definition: observable.h:126
bool Unlisten(wxEvtHandler *listener, wxEventType ev)
Remove window listening to ev from list of listeners.
Definition: observable.cpp:67
virtual const void Notify()
Notify all listeners about variable change.
Definition: observable.cpp:94
Adds a std::shared<void> element to wxCommandEvent.
Definition: ocpn_plugin.h:1615