EntityList.hpp
1 #pragma once
2 #include <score/tools/Debug.hpp>
3 #include <score/tools/std/IndirectContainer.hpp>
4 
5 #include <ossia/detail/algorithms.hpp>
6 
7 #include <list>
8 
9 namespace score
10 {
11 
12 template <typename T>
14 {
15 public:
16  // The real interface starts here
17  using value_type = T;
18  auto begin() const { return score::make_indirect_iterator(m_list.begin()); }
19  auto cbegin() const { return score::make_indirect_iterator(m_list.cbegin()); }
20  auto end() const { return score::make_indirect_iterator(m_list.end()); }
21  auto cend() const { return score::make_indirect_iterator(m_list.cend()); }
22  auto size() const { return m_list.size(); }
23  bool empty() const { return m_list.empty(); }
24  auto& unsafe_list() { return m_list; }
25  const auto& list() const { return m_list; }
26  const auto& get() const { return m_list.get(); }
27  T& at(const Id<T>& id)
28  {
29  auto it = find(id);
30  SCORE_ASSERT(it != m_list.end());
31  return *it;
32  }
33  T& at(const Id<T>& id) const
34  {
35  auto it = find(id);
36  SCORE_ASSERT(it != m_list.end());
37  return **it;
38  }
39  T& at_pos(std::size_t n) const
40  {
41  SCORE_ASSERT(n < m_list.size());
42  auto it = m_list.begin();
43  std::advance(it, n);
44  return **it;
45  }
46  auto find(const Id<T>& id) const
47  {
48  return ossia::find_if(m_list, [&](auto ptr) { return ptr->id() == id; });
49  }
50  auto find(const Id<T>& id)
51  {
52  return ossia::find_if(m_list, [&](auto ptr) { return ptr->id() == id; });
53  }
54 
55  auto index(const Id<T>& id) const
56  {
57  auto it = ossia::find_if(m_list, [&](auto ptr) { return ptr->id() == id; });
58  ;
59  SCORE_ASSERT(it != m_list.end());
60  return std::distance(m_list.begin(), it);
61  }
62 
63  // public:
64  mutable Nano::Signal<void(T&)> mutable_added;
65  mutable Nano::Signal<void(const T&)> added;
66  mutable Nano::Signal<void(const T&)> removing;
67  mutable Nano::Signal<void(const T&)> removed;
68  mutable Nano::Signal<void()> orderChanged;
69 
70  void add(T* t)
71  {
72  SCORE_ASSERT(t);
73  unsafe_list().push_back(t);
74 
75  mutable_added(*t);
76  added(*t);
77  }
78 
79  void erase(T& elt)
80  {
81  auto it = ossia::find(m_list, &elt);
82  SCORE_ASSERT(it != m_list.end());
83 
84  removing(elt);
85  m_list.erase(it);
86  removed(elt);
87  }
88 
89  void remove(T& elt)
90  {
91  erase(elt);
92  delete &elt;
93  }
94 
95  void remove(T* elt) { remove(*elt); }
96 
97  void remove(const Id<T>& id)
98  {
99  auto it = find(id);
100  SCORE_ASSERT(it != m_list.end());
101  auto& elt = **it;
102 
103  removing(elt);
104  m_list.erase(it);
105  removed(elt);
106  delete &elt;
107  }
108 
109  void clear()
110  {
111  while(!m_list.empty())
112  {
113  remove(*m_list.begin());
114  }
115  }
116 
117  void insert_at(std::size_t pos, T* t)
118  {
119  SCORE_ASSERT(pos <= m_list.size());
120  auto it = m_list.begin();
121  std::advance(it, pos);
122 
123  m_list.insert(it, t);
124  mutable_added(*t);
125  added(*t);
126  }
127  void move(const Id<T>& id, std::size_t pos)
128  {
129  auto new_it = m_list.begin();
130  std::advance(new_it, pos);
131  auto it1 = find(id);
132  m_list.splice(new_it, m_list, it1);
133 
134  orderChanged();
135  }
136 
137 private:
138  std::list<T*> m_list;
139 };
140 
141 }
The id_base_t class.
Definition: Identifier.hpp:57
Definition: EntityList.hpp:14
Base toolkit upon which the software is built.
Definition: Application.cpp:90