OpenLexocad  28.0
PropertyLinkMap.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <Base/Writer.h>
5 #include <Base/StringTool.h>
6 #include <Core/DbgInfo.h>
7 #include <Core/CoreDocument.h>
9 
10 
11 namespace Core
12 {
20 class LX_CORE_EXPORT PropertyType2Link : public Core::PropertyLinkBaseBase
21 {
23 
24 public:
25  void setValue(const std::map<Base::Type, Core::DocObject*>& list);
26  bool setValueFromVariant(const Core::Variant& v) override;
27  [[nodiscard]] Core::Variant getVariant(void) const override { return Core::Variant(_linkMap); }
28  [[nodiscard]] const std::map<Base::Type, Core::DocObject*>& getValue() const { return _linkMap; }
29  [[nodiscard]] std::vector<Core::DocObject*> getLinks() override;
30 
31  void copyValue(Core::Property* p) override;
32  void deepCopy(Core::Property* p, Core::CoreDocument* dest_doc, DocObjectMap& copyMap) override;
33 
34  bool hasKey(Base::Type type) const;
35  bool hasLink(Core::DocObject* link) const;
36  bool addLink(Core::DocObject* link) override;
37  bool removeLink(Core::DocObject* link) override;
38  [[nodiscard]] Core::DocObject* getLink(Base::Type type) const;
39 
40  [[nodiscard]] bool isEmpty() const;
41  void setEmpty();
42  [[nodiscard]] size_t getSize() const;
43 
44  void save(Base::AbstractWriter& writer, Base::PersistenceVersion& save_version) override;
46 
47  bool isEqual(const Property* o) const override;
48  const Core::PropertyKind getPropertyKind(void) const override;
49 
50  std::shared_ptr<Core::DbgInfo> getDbgInfo() const override;
51  Core::Property* copy(void) const override;
52  void paste(const Core::Property& from) override;
53 
54 protected:
55  std::map<Base::Type, Core::DocObject*> _linkMap;
56 };
57 
58 
66 template <typename T>
68 {
69  TYPESYSTEM_PROPERTY_HEADER(PropertyLinkMap, Core::PropertyLinkBaseBase);
70 
71 public:
72  void setValue(const std::map<T, Core::DocObject*>& list);
73  bool setValueFromVariant(const Core::Variant&) override;
74  [[nodiscard]] Core::Variant getVariant(void) const override;
75  [[nodiscard]] const std::map<T, Core::DocObject*>& getValue() const { return _linkMap; }
76  [[nodiscard]] std::vector<Core::DocObject*> getLinks() override;
77 
78  void copyValue(Core::Property* p) override;
79  void deepCopy(Core::Property* p, Core::CoreDocument* dest_doc, DocObjectMap& copyMap) override;
80 
81  bool hasKey(T key) const;
82  bool hasLink(Core::DocObject* link) const;
83  bool addLink(Core::DocObject* link) override { return false; }
84  bool addLink(T key, Core::DocObject* link);
85  bool removeLink(Core::DocObject* link) override;
86  Core::DocObject* getLink(T key) const;
87 
88  [[nodiscard]] bool isEmpty() const;
89  void setEmpty();
90  [[nodiscard]] size_t getSize() const;
91 
92  void save(Base::AbstractWriter& writer, Base::PersistenceVersion& save_version) override;
94 
95  bool isEqual(const Property* o) const override;
96  const Core::PropertyKind getPropertyKind(void) const override;
97 
98  std::shared_ptr<Core::DbgInfo> getDbgInfo() const override;
99  Core::Property* copy(void) const override;
100  void paste(const Core::Property& from) override;
101 
102 protected:
103  std::map<T, Core::DocObject*> _linkMap;
104 };
105 
106 
107 #ifndef SWIG
108 
109 template <typename T>
110 struct TypeName2
111 {
112  static const char* Get() { return typeid(T).name(); }
113 };
114 
115 template <typename T>
116 Base::Type PropertyLinkMap<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName2<PropertyLinkMap<T>>::Get());
117 #endif
118 
122 
123 template <typename T>
124 void PropertyLinkMap<T>::setValue(const std::map<T, Core::DocObject*>& map)
125 {
126  aboutToSetValue();
127  for (auto pairIt : _linkMap)
128  {
129  if (pairIt.second)
130  pairIt.second->unref();
131  onRemoveLink(pairIt.second);
132  }
133 
134  _linkMap = *(const std::map<T, Core::DocObject*>*)(&map);
135 
136  for (auto pairIt : _linkMap)
137  {
138  onAddLink(pairIt.second);
139  if (pairIt.second)
140  pairIt.second->ref();
141  }
142  hasSetValue();
143 }
144 
145 template <typename T>
147 {
148  cWarn("Core::PropertyLinkMap::setValueFromVariant, Variant not implemented.");
149  return false;
150 }
151 
152 template <typename T>
154 {
155  cWarn("Core::PropertyLinkMap::setValueFromVariant, Variant not implemented.");
156  return Core::Variant();
157 }
158 
159 template <typename T>
161 {
162  const auto it = _linkMap.find(key);
163  if (it != _linkMap.end())
164  return it->second;
165 
166  return nullptr;
167 }
168 
169 template <typename T>
171 {
172  assert(p->getTypeId() == getTypeId() && "Wrong property type!");
173  if (p->getTypeId() == getTypeId())
174  {
176  setValue(other->getValue());
177  }
178 }
179 
180 template <typename T>
182 {
183  assert(p->getTypeId() == getTypeId() && "Wrong property type!");
184  if (p->getTypeId() == getTypeId())
185  {
187 
188  setEmpty();
189  for (auto pairIt : source->getValue())
190  {
191  auto it = copyMap.find(pairIt.second);
192  if (it != copyMap.end())
193  {
194  addLink(it->second);
195  }
196  else
197  {
198  Core::DocObject* dest_obj = dest_doc->copyObject(pairIt.second, copyMap);
199  copyMap[pairIt.second] = dest_obj;
200  addLink(dest_obj);
201  }
202  }
203  }
204 }
205 
206 template <typename T>
208 {
209  aboutToSetValue();
210  for (auto pairIt : _linkMap)
211  {
212  if (pairIt.second)
213  pairIt.second->unref();
214  onRemoveLink(pairIt.second);
215  }
216 
217  _linkMap.clear();
218  hasSetValue();
219 }
220 
221 template <typename T>
222 bool PropertyLinkMap<T>::hasKey(T key) const
223 {
224  const auto it = _linkMap.find(key);
225  return it != _linkMap.end();
226 }
227 
228 template <typename T>
230 {
231  // Traverse the map
232  for (const auto& [key, value] : _linkMap)
233  if (value == link)
234  return true;
235 
236  return false;
237 }
238 
239 template <typename T>
241 {
242  if (!link)
243  return false;
244 
245  aboutToSetValue();
246  link->ref();
247  onAddLink(link);
248  _linkMap.emplace(key, link);
249  hasSetValue();
250 
251  return true;
252 }
253 
254 template <typename T>
256 {
257  if (!link)
258  return false;
259 
260  // Traverse the map
261  for (const auto& [key, value] : _linkMap)
262  {
263  if (value == link)
264  {
265  aboutToSetValue();
266  link->unref();
267  onRemoveLink(link);
268 
269  _linkMap.erase(key);
270  hasSetValue();
271 
272  return true;
273  }
274  }
275 
276  return false;
277 }
278 
279 template <typename T>
280 std::vector<Core::DocObject*> PropertyLinkMap<T>::getLinks()
281 {
282  std::vector<Core::DocObject*> links;
283 
284  for (auto pairIt : _linkMap)
285  {
286  links.push_back(pairIt.second);
287  }
288 
289  return links;
290 }
291 
292 template <typename T>
294 {
295  return _linkMap.empty();
296 }
297 
298 template <typename T>
300 {
301  return _linkMap.size();
302 }
303 
304 template <typename T>
306 {
307  writer << "<Link size=\"" << _linkMap.size() << "\"/>";
308 
309  for (const auto& [key, value] : _linkMap)
310  {
311  if (value)
312  {
313  writer << "<Key value=\"" << key << "\"/>";
314  writer << "<Link value=\"" << value->getId() << "\"/>";
315  }
316  }
317 }
318 
319 template <typename T>
321 {
322  _linkMap.clear();
323  reader.readElement("Link");
324  const int size = reader.getAttributeAsInteger(L"size");
325 
326  for (int i = 0; i < size; i++)
327  {
328  reader.readElement("Link");
329 
330  Base::String value = reader.getAttribute(L"value");
331  std::string id = Base::StringTool::toQString(value).toUtf8().constData();
332  if (id.empty())
333  {
334  // DG ????
335  // onAddLink(0);
336  //_linkList.push_back(0);
337  }
338  else
339  {
340  Core::DocObject* o = nullptr;
341  if (Core::DocObject* container = Base::cast2<Core::DocObject>(getContainer()))
342  o = (Core::DocObject*)container->getDocument()->getObjectById(id);
343  else if (Core::CoreDocument* doc = Base::cast2<Core::CoreDocument>(getContainer()))
344  o = (Core::DocObject*)doc->getObjectById(id);
345 
346  if (o)
347  {
348  reader.readElement("Key");
349 
350  o->ref();
351  onAddLink(o);
352  if (std::is_same<T, int>::value)
353  _linkMap.emplace(reader.getAttributeAsInteger(L"value"), o);
354  else if (std::is_same<T, double>::value)
355  _linkMap.emplace(reader.getAttributeAsDouble(L"value"), o);
356  else if (std::is_same<T, std::string>::value)
357  _linkMap.emplace(reader.getAttributeAsDouble(L"value"), o);
358  }
359  else
360  {
361  if (Core::DocObject* container = dynamic_cast<Core::DocObject*>(getContainer()))
362  cWarn("Core::PropertyLinkMap::restore (%s) Container (%s) (%s), Object %s not exists!", getName().c_str(),
363  container->getTypeId().getName().c_str(), container->getId().c_str(), id.c_str());
364  else
365  cWarn("Core::PropertyLinkMap::restore (%s), Object %s not exists!", getName().c_str(), id.c_str());
366  }
367  }
368  }
369 }
370 
371 template <typename T>
373 {
374  return Core::P_MODIFY_LINK;
375 }
376 
377 template <typename T>
379 {
380  if (const PropertyLinkMap<T>* other = dynamic_cast<const PropertyLinkMap<T>*>(o))
381  return _linkMap == other->_linkMap;
382 
383  return false;
384 }
385 
386 template <typename T>
387 std::shared_ptr<Core::DbgInfo> PropertyLinkMap<T>::getDbgInfo() const
388 {
389  QString s = QString("size: %1").arg(_linkMap.size());
390 
391  Base::String name = Base::StringTool::toString(getName());
392  Base::String type = Base::StringTool::toString(getTypeId().getName());
393  Base::String value = s.toStdWString();
394  auto info = Core::DbgInfo::createDbgInfo<Core::DbgInfo>(name, value, type, nullptr);
395  for (const auto& [key, link] : _linkMap)
396  {
397  s = QString("key: %1, val: %2").arg(key).arg(link ? link->getId().c_str() : "nullptr");
398  value = s.toStdWString();
399  name = Base::StringTool::toString(link ? link->getTypeId().getName() : "");
400  type = Base::StringTool::toString(link ? link->getTypeId().getName() : "");
401  auto m0 = Core::DbgInfo::createDbgInfo<Core::DbgInfoLink>(name, value, type, info);
402  m0->object = link;
403  }
404 
405  return info;
406 }
407 
419 template <typename T>
421 {
423  p->setValue(_linkMap);
424  return p;
425 }
426 
437 template <typename T>
439 {
440  const PropertyLinkMap<T>& FromList = dynamic_cast<const PropertyLinkMap<T>&>(from);
441  setValue(FromList._linkMap);
442 }
443 
444 } // namespace Core
Base::Type
Definition: Type.h:51
Core::TypeName2::Get
static const char * Get()
Definition: PropertyLinkMap.h:112
Base::StringTool::toQString
static QString toQString(const Base::String &str)
Converts a Base::String to a QString.
Base::Type::badType
static const Type badType(void)
Definition: Type.h:97
Core::CoreDocument::copyObject
Core::DocObject * copyObject(Core::DocObject *o, DocObjectMap &copyMap)
Creates a copy of 'o' and adds it to the document, provides map of pairs original-copy to see which o...
Core::CoreDocument
Definition: CoreDocument.h:269
Core::PropertyKind
PropertyKind
Definition: Property.h:42
cWarn
LX_BASE_EXPORT Base::LogClass cWarn()
Core::DocObject::getDocument
Core::CoreDocument * getDocument() const
Returns the CoreDocument of this DocObject.
Core::DocObjectMap
std::map< Core::DocObject *, Core::DocObject * > DocObjectMap
Definition: DocObject.h:50
Base::StringTool::toString
static Base::String toString(const T &t)
Definition: StringTool.h:58
Core::DocObject::unref
void unref(void)
AbstractXMLReader.h
Core::TypeName2
Definition: PropertyLinkMap.h:111
Base::Type::createType
static const Type createType(const Type parent, const char *name, instantiationMethod method=0)
Base::AbstractWriter::size
virtual uint64_t size()
Definition: Writer.h:63
StringTool.h
Core::DocObject
Definition: DocObject.h:54
Base::AbstractXMLReader::getAttributeAsInteger
virtual long getAttributeAsInteger(const char *AttrName) const =0
Base::PersistenceVersion
Definition: Persistence.h:13
Core
Definition: Base.h:5
Core::DocObject::ref
void ref(void)
Core::Variant
Definition: Variant.h:78
Base::AbstractWriter
Definition: Writer.h:13
Base::AbstractXMLReader
Definition: AbstractXMLReader.h:7
Core::P_MODIFY_LINK
@ P_MODIFY_LINK
Definition: Property.h:45
Core::CoreDocument::getObjectById
virtual Core::DocObject * getObjectById(const DocObject::IdType &id) const
Returns the object with this id.
Writer.h
CoreDocument.h
Base::AbstractXMLReader::getAttribute
virtual Base::String getAttribute(const char *AttrName) const =0
DbgInfo.h
Core::version
LX_CORE_EXPORT Version & version
Core::Property
Definition: Property.h:72
Base::String
A Utf-16 (windows) or ucs4 (unix) encoded string class.
Definition: String.h:18
Base::BaseClass::getTypeId
virtual Type getTypeId(void) const
TYPESYSTEM_HEADER
#define TYPESYSTEM_HEADER()
define for subclassing Base::BaseClass
Definition: Base.h:12
Base::AbstractXMLReader::getAttributeAsDouble
virtual double getAttributeAsDouble(const char *AttrName) const =0
Base::AbstractXMLReader::readElement
virtual void readElement(const char *ElementName=0)=0