ObjectPath.hpp
1 #pragma once
2 #include <score/model/path/ObjectIdentifier.hpp>
3 #include <score/tools/SafeCast.hpp>
4 
5 #include <QObject>
6 #include <QPointer>
7 #include <QString>
8 
9 #include <score_lib_base_export.h>
10 
11 #include <initializer_list>
12 #include <type_traits>
13 #include <vector>
14 namespace score
15 {
16 struct DocumentContext;
17 }
18 class QObject;
19 
36 class SCORE_LIB_BASE_EXPORT ObjectPath
37 {
38  friend ObjectIdentifierVector::iterator begin(ObjectPath& path) noexcept
39  {
40  return path.m_objectIdentifiers.begin();
41  }
42 
43  friend ObjectIdentifierVector::iterator end(ObjectPath& path) noexcept
44  {
45  return path.m_objectIdentifiers.end();
46  }
47 
48  friend bool operator==(const ObjectPath& lhs, const ObjectPath& rhs) noexcept
49  {
50  return lhs.m_objectIdentifiers == rhs.m_objectIdentifiers;
51  }
52 
53  friend bool operator!=(const ObjectPath& lhs, const ObjectPath& rhs) noexcept
54  {
55  return lhs.m_objectIdentifiers != rhs.m_objectIdentifiers;
56  }
57 
58 public:
59  ObjectPath() noexcept { }
60  ~ObjectPath() noexcept = default;
61  QString toString() const noexcept;
62 
63  explicit ObjectPath(std::vector<ObjectIdentifier> vec) noexcept
64  : m_objectIdentifiers{std::move(vec)}
65  {
66  }
67 
68  ObjectPath(std::initializer_list<ObjectIdentifier> lst) noexcept
69  : m_objectIdentifiers(lst)
70  {
71  }
72 
73  ObjectPath(const ObjectPath& obj) noexcept
74  : m_objectIdentifiers{obj.m_objectIdentifiers}
75  {
76  }
77 
78  ObjectPath(ObjectPath&& obj) noexcept
79  : m_objectIdentifiers{std::move(obj.m_objectIdentifiers)}
80  {
81  }
82 
83  ObjectPath& operator=(ObjectPath&& obj) noexcept
84  {
85  m_objectIdentifiers = std::move(obj.m_objectIdentifiers);
86  m_cache.clear();
87  return *this;
88  }
89 
90  ObjectPath& operator=(const ObjectPath& obj) noexcept
91  {
92  m_objectIdentifiers = obj.m_objectIdentifiers;
93  m_cache.clear();
94  return *this;
95  }
96 
97  static ObjectPath
98  pathBetweenObjects(const QObject* const parent_obj, const QObject* target_object);
99 
109  template <class T>
110  T& find(const score::DocumentContext& ctx) const
111  {
112  // First see if the pointer is still loaded in the cache.
113  if(!m_cache.isNull())
114  {
115  return *safe_cast<T*>(m_cache.data());
116  }
117  else // Load it by hand
118  {
119  auto ptr = safe_cast<typename std::remove_const<T>::type*>(find_impl(ctx));
120  m_cache = ptr;
121  return *ptr;
122  }
123  }
124 
130  template <class T>
131  T* try_find(const score::DocumentContext& ctx) const noexcept
132  {
133  try
134  {
135  if(!m_cache.isNull())
136  {
137  return safe_cast<T*>(m_cache.data());
138  }
139  else // Load it by hand
140  {
141  auto ptr
142  = static_cast<typename std::remove_const<T>::type*>(find_impl_unsafe(ctx));
143  m_cache = ptr;
144  return ptr;
145  }
146  }
147  catch(...)
148  {
149  return nullptr;
150  }
151  }
152 
153  const ObjectIdentifierVector& vec() const noexcept { return m_objectIdentifiers; }
154 
155  ObjectIdentifierVector& vec() noexcept { return m_objectIdentifiers; }
156 
157  void resetCache() const noexcept { m_cache = {}; }
158 
159 private:
160  // Throws
161  QObject* find_impl(const score::DocumentContext& ctx) const;
162 
163  // Returns nullptr
164  QObject* find_impl_unsafe(const score::DocumentContext& ctx) const noexcept;
165 
166  ObjectIdentifierVector m_objectIdentifiers;
167  mutable QPointer<QObject> m_cache;
168 };
169 
170 SCORE_LIB_BASE_EXPORT void
171 replacePathPart(const ObjectPath& src, const ObjectPath& target, ObjectPath& toChange);
172 inline uint qHash(const ObjectPath& obj, uint seed)
173 {
174  return qHash(obj.toString(), seed);
175 }
176 
177 namespace std
178 {
179 template <>
180 struct SCORE_LIB_BASE_EXPORT hash<ObjectIdentifier>
181 {
182  std::size_t operator()(const ObjectIdentifier& path) const;
183 };
184 template <>
185 struct SCORE_LIB_BASE_EXPORT hash<ObjectPath>
186 {
187  std::size_t operator()(const ObjectPath& path) const;
188 };
189 }
The ObjectIdentifier class.
Definition: ObjectIdentifier.hpp:21
The ObjectPath class.
Definition: ObjectPath.hpp:37
T * try_find(const score::DocumentContext &ctx) const noexcept
Tries to find an object.
Definition: ObjectPath.hpp:131
T & find(const score::DocumentContext &ctx) const
find the object described by the ObjectPath
Definition: ObjectPath.hpp:110
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: DocumentContext.hpp:18