OpenLexocad  28.0
PropertyLink.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include <Base/Log.h>
5 #include <Base/Writer.h>
6 #include <Base/StringTool.h>
7 #include <Core/CoreDocument.h>
11 
12 namespace Core
13 {
14 template <typename T>
15 struct TypeName
16 {
17  static const char* Get() { return typeid(T).name(); }
18 };
19 
20 //----------------------------------------------------------------------------
21 // PropertyLink<T>
22 //----------------------------------------------------------------------------
23 
24 template <typename T>
26 {
27  TYPESYSTEM_PROPERTY_HEADER(PropertyLink, Core::PropertyLinkBase);
29 
30 public:
31  void setValue(T value) { inherited::setValue(value); }
32  T getValue() const { return static_cast<T>(inherited::getValue()); }
33 
34  void restore(Base::AbstractXMLReader& reader, Base::PersistenceVersion& lversion) override
35  {
36  inherited::restore(reader, lversion);
37  if (hObject.getStatus() == Object_Hnd::Valid && getValue() && !dynamic_cast<T>(inherited::getValue()))
38  {
39  setValue(nullptr);
40  cDebug("ERROR: Trying to fill PropertyLink with object of wrong type!");
41  }
42  }
43 
44  bool removeLink( DocObject* /*o*/) override
45  {
46  setValue(nullptr);
47  return true;
48  }
49 
50  bool addLink(DocObject* o) override
51  {
52  setValue((T)o);
53  return true;
54  }
55 };
56 
57 #ifndef SWIG
58 template <typename T>
59 Base::Type PropertyLink<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName<PropertyLink<T>>::Get());
60 #endif
61 
62 
63 //----------------------------------------------------------------------------
64 // PropertyLinkSet<T>
65 //----------------------------------------------------------------------------
66 
67 template <typename T>
69 {
70  TYPESYSTEM_PROPERTY_HEADER(PropertyLinkSet, Core::PropertyLinkSetBase);
72 
73 public:
74  void setValue(const std::unordered_set<T>& linkset) { inherited::setValue(*(const std::unordered_set<Core::DocObject*>*)(&linkset)); }
75  const std::unordered_set<T>& getValue() const { return *(const std::unordered_set<T>*)(&_linkSet); }
76 
77  bool addLink(T link) { return inherited::addLink(link); }
78  bool removeLink(T link) { return inherited::removeLink(link); }
79 
80  void addLinks(const std::unordered_set<T>& linkset) { inherited::addLinks(*(const std::unordered_set<Core::DocObject*>*)(&linkset)); }
81 };
82 
83 #ifndef SWIG
84 template <typename T>
85 Base::Type PropertyLinkSet<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName<PropertyLinkSet<T>>::Get());
86 #endif
87 
88 
89 //----------------------------------------------------------------------------
90 // PropertyLinkList
91 //----------------------------------------------------------------------------
92 
93 class LX_CORE_EXPORT PropertyLinkList : public PropertyLinkListBase
94 {
96 
97 public:
98  PropertyLinkList() = default;
99  virtual ~PropertyLinkList() = default;
100 
101  void setValue(const std::list<Core::DocObject*>& list) override;
102  bool setValueFromVariant(const Core::Variant& value) override;
103  void copyValue(Core::Property* p) override;
104 
105  bool addLink(Core::DocObject* o) override;
106  bool removeLink(Core::DocObject* o) override;
107  void setEmpty() override;
108 
109  Core::Variant getVariant() const override;
110 
112  bool isEqual(const Property* p) const override;
113 };
114 
115 
116 //----------------------------------------------------------------------------
117 // PropertyTypedLinkList
118 //----------------------------------------------------------------------------
119 
120 template <typename T>
121 class PropertyTypedLinkList : public PropertyLinkListBase //@todo mondzi: check if everything works
122 {
123  TYPESYSTEM_PROPERTY_HEADER(PropertyTypedLinkList, Core::PropertyLinkListBase);
124 
125 public:
126  void setValue(const std::list<T>& aList);
127  bool setValueFromVariant(const Core::Variant& value) override;
128  void copyValue(Core::Property* p) override;
129  const std::list<T>& getValue() const { return *(const std::list<T>*)(&_linkList); };
130 
131  bool addLink(T link);
132  bool removeLink(T link);
133  bool hasLink(T link) const;
134 
135  void setEmpty();
136  inline bool isEmpty() const { return _linkList.empty(); }
137 
138  size_t getSize() const { return _linkList.size(); }
139 
142  bool isEqual(const Property*) const override;
143 };
144 
145 #ifndef SWIG
146 template <typename T>
147 Base::Type PropertyTypedLinkList<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName<PropertyTypedLinkList<T>>::Get());
148 #endif
149 
150 // implementation
151 
152 template <typename T>
154 {
155  return std::find(_linkList.begin(), _linkList.end(), link) != _linkList.end();
156 }
157 
158 template <typename T>
160 {
161  if (const PropertyTypedLinkList<T>* other = dynamic_cast<const PropertyTypedLinkList<T>*>(p))
162  return _linkList == other->_linkList;
163 
164  return false;
165 }
166 
167 template <typename T>
169 {
170  if (!link)
171  return false;
172 
173  aboutToSetValue();
174  if (link)
175  link->ref();
176  onAddLink(link);
177  _linkList.push_back(link);
178  hasSetValue();
179  return true;
180 }
181 
182 template <typename T>
184 {
185  if (!link)
186  return false;
187  if (!hasLink(link))
188  return false;
189 
190  link->unref();
191  aboutToSetValue();
192  onRemoveLink(link);
193  _linkList.remove(link);
194  hasSetValue();
195  return true;
196 }
197 
198 
199 
200 template <typename T>
201 void PropertyTypedLinkList<T>::setValue(const std::list<T>& list)
202 {
203  aboutToSetValue();
204  for (Core::DocObject* link : _linkList)
205  {
206  if (link)
207  link->unref();
208  }
209 
210  onRemoveLinks(_linkList);
211  _linkList = *(const std::list<Core::DocObject*>*)(&list);
212  onAddLinks(_linkList);
213 
214  for (Core::DocObject* link : _linkList)
215  {
216  if (link)
217  link->ref();
218  }
219  hasSetValue();
220 }
221 
222 template <typename T>
224 {
226  {
227  std::list<Core::DocObject*> linkList = value.toLinkList();
228  for (Core::DocObject* o : linkList)
229  {
230  if (o && !dynamic_cast<T>(o))
231  {
232  cDebug("ERROR: Cannot set Core::PropertyTypedLinkList value");
233  return false;
234  }
235  }
236  setValue(*(const std::list<T>*)(&linkList));
237  return true;
238  }
239 
240  cDebug("ERROR: Cannot set Core::PropertyTypedLinkList value");
241  return false;
242 }
243 
244 template <typename T>
246 {
247  assert(p->getTypeId() == getTypeId() && "Wrong property type!");
248  if (p->getTypeId() == getTypeId())
249  {
251  setValue(other->getValue());
252  }
253 }
254 
255 template <typename T>
257 {
258  aboutToSetValue();
259  for (Core::DocObject* link : _linkList)
260  {
261  if (link)
262  link->unref();
263  }
264 
265  onRemoveLinks(_linkList);
266  _linkList.clear();
267  hasSetValue();
268 }
269 
270 template <typename T>
272 {
273  std::vector<Core::DocObject*> toSave;
274  for (Core::DocObject* obj : _linkList)
275  {
276  if (!obj)
277  {
278  // can nullptr be valid? -mh-
279  toSave.push_back(obj);
280  }
281  else if (obj && (!obj->isTemporary() || obj->mustbeSaved()))
282  {
283  toSave.push_back(obj);
284  }
285  }
286 
287  writer << "<Link size=\"" << toSave.size() << "\"/>";
288 
289  for (Core::DocObject* link : toSave)
290  {
291  writer << "<Link value=\"" << (link ? link->getId() : std::string()) << "\"/>";
292  }
293 }
294 
295 template <typename T>
297 {
298  _linkList.clear();
299  reader.readElement("Link");
300  int size = (reader.getAttributeAsInteger(L"size"));
301 
302  for (int i = 0; i < size; i++)
303  {
304  reader.readElement("Link");
305 
306  Base::String value = reader.getAttribute(L"value");
307  std::string id = Base::StringTool::toQString(value).toUtf8().constData();
308  if (!id.empty())
309  {
310  Core::CoreDocument* cd = ((Core::DocObject*)getContainer())->getDocument();
311  T link = dynamic_cast<T>(cd->getObjectById(id));
312  if (link)
313  {
314  link->ref();
315  onAddLink((Core::DocObject*)link);
316  _linkList.push_back(link);
317  }
318  else
319  {
320  cDebug("Error: Core::PropertyLinkList::restore ExecObject: %s not found!", id.c_str());
321  }
322  }
323  }
324 }
325 
329 
330 } // namespace Core
Base::Type
Definition: Type.h:51
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
Definition: CoreDocument.h:269
cDebug
LX_BASE_EXPORT Base::LogClass cDebug()
AbstractXMLReader.h
Core::Variant::canConvert
bool canConvert(Variant::Type t) const
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::Variant
Definition: Variant.h:78
Base::AbstractWriter
Definition: Writer.h:13
Core::Variant::toLinkList
std::list< Core::DocObject * > toLinkList(bool *ok=nullptr) const
Base::AbstractXMLReader
Definition: AbstractXMLReader.h:7
Core::CoreDocument::getObjectById
virtual Core::DocObject * getObjectById(const DocObject::IdType &id) const
Returns the object with this id.
Writer.h
Core::Object_Hnd::Valid
@ Valid
Definition: Object_Hnd.h:16
CoreDocument.h
Base::AbstractXMLReader::getAttribute
virtual Base::String getAttribute(const char *AttrName) const =0
Core::version
LX_CORE_EXPORT Version & version
Core::TypeName::Get
static const char * Get()
Definition: PropertyLink.h:17
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
Core::DECLARE_PROPERTY_FACTORY
DECLARE_PROPERTY_FACTORY(PropertyAxis1_Factory, Core::PropertyAxis1)
Log.h
Core::TypeName
Definition: PropertyLink.h:16
Base::AbstractXMLReader::readElement
virtual void readElement(const char *ElementName=0)=0
Core::Variant::LinkList
@ LinkList
Definition: Variant.h:152
Core::Object_Hnd::getStatus
Status getStatus() const