Line data Source code
1 : /*
2 : MIT License
3 :
4 : Copyright (c) 2020 Igor Korsukov
5 :
6 : Permission is hereby granted, free of charge, to any person obtaining a copy
7 : of this software and associated documentation files (the "Software"), to deal
8 : in the Software without restriction, including without limitation the rights
9 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 : copies of the Software, and to permit persons to whom the Software is
11 : furnished to do so, subject to the following conditions:
12 :
13 : The above copyright notice and this permission notice shall be included in all
14 : copies or substantial portions of the Software.
15 :
16 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 : SOFTWARE.
23 : */
24 : #pragma once
25 :
26 : #include "asyncable.h"
27 : #include "channel.h"
28 :
29 : namespace muse::async {
30 : template<typename T>
31 : class ChangedNotifier;
32 :
33 : template<typename T>
34 : class ChangedNotify
35 : {
36 : public:
37 0 : ChangedNotify()
38 0 : : m_data(std::make_shared<Data>()) {}
39 :
40 : ChangedNotify(const ChangedNotify& notify)
41 : : m_data(notify.m_data) {}
42 :
43 0 : ~ChangedNotify() = default;
44 :
45 : template<typename Call>
46 0 : void onChanged(Asyncable* receiver, Call f, Asyncable::Mode mode = Asyncable::Mode::SetOnce)
47 : {
48 0 : m_data->changed.onReceive(receiver, f, mode);
49 0 : }
50 :
51 : template<typename Call>
52 0 : void onItemChanged(Asyncable* receiver, Call f, Asyncable::Mode mode = Asyncable::Mode::SetOnce)
53 : {
54 0 : m_data->itemChanged.onReceive(receiver, f, mode);
55 0 : }
56 :
57 : template<typename Call>
58 0 : void onItemAdded(Asyncable* receiver, Call f, Asyncable::Mode mode = Asyncable::Mode::SetOnce)
59 : {
60 0 : m_data->itemAdded.onReceive(receiver, f, mode);
61 0 : }
62 :
63 : template<typename Call>
64 0 : void onItemRemoved(Asyncable* receiver, Call f, Asyncable::Mode mode = Asyncable::Mode::SetOnce)
65 : {
66 0 : m_data->itemRemoved.onReceive(receiver, f, mode);
67 0 : }
68 :
69 : template<typename Call>
70 : void onItemReplaced(Asyncable* receiver, Call f, Asyncable::Mode mode = Asyncable::Mode::SetOnce)
71 : {
72 : m_data->itemReplaced.onReceive(receiver, f, mode);
73 : }
74 :
75 0 : void disconnect(Asyncable* receiver)
76 : {
77 0 : m_data->changed.disconnect(receiver);
78 0 : m_data->itemChanged.disconnect(receiver);
79 0 : m_data->itemAdded.disconnect(receiver);
80 0 : m_data->itemRemoved.disconnect(receiver);
81 0 : m_data->itemReplaced.disconnect(receiver);
82 0 : }
83 :
84 : private:
85 : friend class ChangedNotifier<T>;
86 :
87 : struct Data {
88 : Channel<> changed;
89 : Channel<const T&> itemChanged;
90 : Channel<const T&> itemAdded;
91 : Channel<const T&> itemRemoved;
92 : Channel<const T&, const T&> itemReplaced;
93 : };
94 :
95 : std::shared_ptr<Data> m_data;
96 : };
97 :
98 : template<typename T>
99 : class ChangedNotifier
100 : {
101 : public:
102 0 : ChangedNotifier()
103 0 : : m_notify(std::make_shared<ChangedNotify<T> >()) {}
104 0 : ~ChangedNotifier() {}
105 :
106 0 : std::shared_ptr<ChangedNotify<T> > notify() const
107 : {
108 0 : return m_notify;
109 : }
110 :
111 0 : void changed()
112 : {
113 0 : m_notify->m_data->changed.send();
114 0 : }
115 :
116 0 : void itemChanged(const T& item)
117 : {
118 0 : m_notify->m_data->itemChanged.send(item);
119 0 : }
120 :
121 0 : void itemAdded(const T& item)
122 : {
123 0 : m_notify->m_data->itemAdded.send(item);
124 0 : }
125 :
126 0 : void itemRemoved(const T& item)
127 : {
128 0 : m_notify->m_data->itemRemoved.send(item);
129 0 : }
130 :
131 0 : void itemReplaced(const T& oldItem, const T& newItem)
132 : {
133 0 : m_notify->m_data->itemReplaced.send(oldItem, newItem);
134 0 : }
135 :
136 : private:
137 : std::shared_ptr<ChangedNotify<T> > m_notify;
138 : };
139 : }
|