ASPiK SDK
dispatchlist.h
1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4 
5 #ifndef __dispatchlist__
6 #define __dispatchlist__
7 
8 #include <vector>
9 
10 //------------------------------------------------------------------------
11 namespace VSTGUI {
12 
13 template <typename T>
15 {
16 public:
17  DispatchList ();
18 
19  void add (const T& obj);
20  void add (T&& obj);
21  void remove (const T& obj);
22  void remove (T&& obj);
23  bool empty () const;
24 
25  template <typename Procedure>
26  void forEach (Procedure proc);
27 
28  template <typename Procedure>
29  void forEachReverse (Procedure proc);
30 
31 private:
32  using Array = std::vector<T>;
33 
34  void postForEach ();
35 
36  Array entries;
37  Array toRemove;
38  Array toAdd;
39  bool inForEach {false};
40 };
41 
42 //------------------------------------------------------------------------
43 template <typename T>
45 {
46 }
47 
48 //------------------------------------------------------------------------
49 template <typename T>
50 inline void DispatchList<T>::add (const T& obj)
51 {
52  if (inForEach)
53  toAdd.emplace_back (obj);
54  else
55  entries.emplace_back (obj);
56 }
57 
58 //------------------------------------------------------------------------
59 template <typename T>
60 inline void DispatchList<T>::add (T&& obj)
61 {
62  if (inForEach)
63  toAdd.emplace_back (std::move (obj));
64  else
65  entries.emplace_back (std::move (obj));
66 }
67 
68 //------------------------------------------------------------------------
69 template <typename T>
70 inline void DispatchList<T>::remove (const T& obj)
71 {
72  if (inForEach)
73  toRemove.emplace_back (obj);
74  else
75  {
76  auto it = std::find (entries.begin (), entries.end (), obj);
77  if (it != entries.end ())
78  entries.erase (it);
79  }
80 }
81 
82 //------------------------------------------------------------------------
83 template <typename T>
84 inline void DispatchList<T>::remove (T&& obj)
85 {
86  if (inForEach)
87  toRemove.emplace_back (std::move (obj));
88  else
89  {
90  auto it = std::find (entries.begin (), entries.end (), obj);
91  if (it != entries.end ())
92  entries.erase (it);
93  }
94 }
95 
96 //------------------------------------------------------------------------
97 template <typename T>
98 inline bool DispatchList<T>::empty () const
99 {
100  return entries.empty ();
101 }
102 
103 //------------------------------------------------------------------------
104 template <typename T>
105 inline void DispatchList<T>::postForEach ()
106 {
107  if (!toAdd.empty ())
108  {
109  for (auto&& it : toAdd)
110  add (std::move (it));
111  toAdd.clear ();
112  }
113  if (!toRemove.empty ())
114  {
115  for (auto&& it : toRemove)
116  remove (std::move (it));
117  toRemove.clear ();
118  }
119 }
120 
121 //------------------------------------------------------------------------
122 template <typename T>
123 template <typename Procedure>
124 inline void DispatchList<T>::forEach (Procedure proc)
125 {
126  if (entries.empty ())
127  return;
128 
129  bool wasInForEach = inForEach;
130  inForEach = true;
131  for (auto& it : entries)
132  proc (it);
133  inForEach = wasInForEach;
134  if (!inForEach)
135  postForEach ();
136 }
137 
138 //------------------------------------------------------------------------
139 template <typename T>
140 template <typename Procedure>
141 inline void DispatchList<T>::forEachReverse (Procedure proc)
142 {
143  if (entries.empty ())
144  return;
145 
146  bool wasInForEach = inForEach;
147  inForEach = true;
148  for (auto it = entries.rbegin (); it != entries.rend (); ++it)
149  proc (*it);
150  inForEach = wasInForEach;
151  if (!inForEach)
152  postForEach ();
153 }
154 
155 //------------------------------------------------------------------------
156 } // VSTGUI
157 
158 #endif // __dispatchlist__
Definition: dispatchlist.h:14
Definition: customcontrols.cpp:8