App: add Property::isSame() API
To compare if two property contains the same content. The default implementation in Property uses the persistense interface to save both properties to string and compares the content. This may not work at the moment if the property saves content in separate file or in binary. Various properties have cheaper implementation to direct compare their internal values.
This commit is contained in:
@@ -276,6 +276,17 @@ void Property::setStatus(Status pos, bool on) {
|
||||
bits.set(pos,on);
|
||||
setStatusValue(bits.to_ulong());
|
||||
}
|
||||
|
||||
bool Property::isSame(const Property &other) const {
|
||||
if(other.getTypeId() != getTypeId() || getMemSize() != other.getMemSize())
|
||||
return false;
|
||||
|
||||
Base::StringWriter writer,writer2;
|
||||
Save(writer);
|
||||
other.Save(writer2);
|
||||
return writer.getString() == writer2.getString();
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
//**************************************************************************
|
||||
// PropertyListsBase
|
||||
|
||||
@@ -236,6 +236,9 @@ public:
|
||||
/// Called before a child property changing value
|
||||
virtual void aboutToSetChildValue(Property &) {}
|
||||
|
||||
/// Compare if this property has the same content as the given one
|
||||
virtual bool isSame(const Property &other) const;
|
||||
|
||||
friend class PropertyContainer;
|
||||
friend struct PropertyData;
|
||||
friend class DynamicProperty;
|
||||
@@ -492,6 +495,11 @@ public:
|
||||
|
||||
const_reference operator[] (int idx) const {return _lValueList[idx];}
|
||||
|
||||
virtual bool isSame(const Property &other) const override {
|
||||
return this->getTypeId() == other.getTypeId()
|
||||
&& this->getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
virtual void setPyObject(PyObject *value) override {
|
||||
try {
|
||||
setValue(getPyValue(value));
|
||||
|
||||
@@ -103,6 +103,13 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
virtual unsigned int getMemSize (void) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& _BaseFileName == static_cast<decltype(this)>(&other)->_BaseFileName
|
||||
&& _OriginalName == static_cast<decltype(this)>(&other)->_OriginalName
|
||||
&& _cValue == static_cast<decltype(this)>(&other)->_cValue;
|
||||
}
|
||||
|
||||
/** get a temp file name in the transient path of the document.
|
||||
* Using this file for new Version of the file and set
|
||||
* this file with setValue() is the fastest way to change
|
||||
|
||||
@@ -108,6 +108,11 @@ public:
|
||||
return Base::Unit();
|
||||
}
|
||||
|
||||
virtual bool isSame(const Property &other) const override {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Base::Vector3d _cVec;
|
||||
};
|
||||
@@ -278,6 +283,11 @@ public:
|
||||
return sizeof(Base::Matrix4D);
|
||||
}
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Base::Matrix4D _cMat;
|
||||
};
|
||||
@@ -345,6 +355,11 @@ public:
|
||||
return sizeof(Base::Placement);
|
||||
}
|
||||
|
||||
virtual bool isSame(const Property &other) const override {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
static const Placement Null;
|
||||
|
||||
private:
|
||||
|
||||
@@ -84,6 +84,27 @@ void PropertyLinkBase::hasSetValue() {
|
||||
Property::hasSetValue();
|
||||
}
|
||||
|
||||
bool PropertyLinkBase::isSame(const Property &other) const
|
||||
{
|
||||
if(other.isDerivedFrom(PropertyLinkBase::getClassTypeId())
|
||||
|| getScope() != static_cast<const PropertyLinkBase*>(&other)->getScope())
|
||||
return false;
|
||||
|
||||
static std::vector<App::DocumentObject*> ret;
|
||||
static std::vector<std::string> subs;
|
||||
static std::vector<App::DocumentObject*> ret2;
|
||||
static std::vector<std::string> subs2;
|
||||
|
||||
ret.clear();
|
||||
subs.clear();
|
||||
ret2.clear();
|
||||
subs2.clear();
|
||||
getLinks(ret,true,&subs,false);
|
||||
static_cast<const PropertyLinkBase *>(&other)->getLinks(ret2,true,&subs2,true);
|
||||
|
||||
return ret==ret2 && subs==subs2;
|
||||
}
|
||||
|
||||
void PropertyLinkBase::unregisterElementReference() {
|
||||
}
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ public:
|
||||
* Retrieve what kind of links are allowed. Only in the Local GeoFeatureGroup, in this and
|
||||
* all Childs or to all objects within the Glocal scope.
|
||||
*/
|
||||
LinkScope getScope() {return _pcScope;};
|
||||
|
||||
LinkScope getScope() const {return _pcScope;};
|
||||
|
||||
protected:
|
||||
LinkScope _pcScope = LinkScope::Local;
|
||||
};
|
||||
@@ -288,6 +288,8 @@ public:
|
||||
}
|
||||
//@}
|
||||
|
||||
virtual bool isSame(const Property &other) const override;
|
||||
|
||||
/** Enable/disable temporary holding external object without throwing exception
|
||||
*
|
||||
* Warning, non-PropertyXLink related property does not have internal
|
||||
|
||||
@@ -207,7 +207,7 @@ void PropertyPath::setValue(const char * Path)
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
boost::filesystem::path PropertyPath::getValue() const
|
||||
const boost::filesystem::path &PropertyPath::getValue(void) const
|
||||
{
|
||||
return _cValue;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,11 @@ public:
|
||||
virtual void setPathValue(const App::ObjectIdentifier & path, const boost::any & value);
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const { return _lValue; }
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
protected:
|
||||
long _lValue;
|
||||
};
|
||||
@@ -107,7 +112,7 @@ public:
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
boost::filesystem::path getValue(void) const;
|
||||
const boost::filesystem::path &getValue(void) const;
|
||||
|
||||
virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyPathItem"; }
|
||||
|
||||
@@ -122,6 +127,11 @@ public:
|
||||
|
||||
virtual unsigned int getMemSize (void) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
protected:
|
||||
boost::filesystem::path _cValue;
|
||||
};
|
||||
@@ -217,6 +227,11 @@ public:
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier & /*path*/) const;
|
||||
virtual bool getPyPathValue(const ObjectIdentifier &path, Py::Object &r) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getEnum() == static_cast<decltype(this)>(&other)->getEnum();
|
||||
}
|
||||
|
||||
private:
|
||||
Enumeration _enum;
|
||||
std::string _editorTypeName;
|
||||
@@ -391,6 +406,10 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
virtual unsigned int getMemSize (void) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValues() == static_cast<decltype(this)>(&other)->getValues();
|
||||
}
|
||||
private:
|
||||
std::set<long> _lValueSet;
|
||||
};
|
||||
@@ -444,7 +463,11 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual unsigned int getMemSize (void) const;
|
||||
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValues() == static_cast<decltype(this)>(&other)->getValues();
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string,std::string> _lValueList;
|
||||
@@ -495,6 +518,11 @@ public:
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value);
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
protected:
|
||||
double _dValue;
|
||||
};
|
||||
@@ -679,6 +707,11 @@ public:
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value);
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getStrValue() == static_cast<decltype(this)>(&other)->getStrValue();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string _cValue;
|
||||
};
|
||||
@@ -722,6 +755,11 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
virtual unsigned int getMemSize (void) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& _uuid.getValue() == static_cast<decltype(this)>(&other)->_uuid.getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Base::Uuid _uuid;
|
||||
};
|
||||
@@ -738,6 +776,11 @@ public:
|
||||
virtual ~PropertyFont();
|
||||
virtual const char* getEditorName(void) const
|
||||
{ return "Gui::PropertyEditor::PropertyFontItem"; }
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
};
|
||||
|
||||
class AppExport PropertyStringList: public PropertyListsT<std::string>
|
||||
@@ -819,6 +862,11 @@ public:
|
||||
void setPathValue(const App::ObjectIdentifier &path, const boost::any &value);
|
||||
const boost::any getPathValue(const App::ObjectIdentifier &path) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _lValue;
|
||||
};
|
||||
@@ -892,7 +940,11 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual unsigned int getMemSize (void) const{return sizeof(Color);}
|
||||
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Color _cCol;
|
||||
@@ -979,6 +1031,11 @@ public:
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual unsigned int getMemSize (void) const{return sizeof(_cMat);}
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Material _cMat;
|
||||
|
||||
@@ -71,6 +71,12 @@ public:
|
||||
virtual void setPathValue(const App::ObjectIdentifier &path, const boost::any &value);
|
||||
virtual const boost::any getPathValue(const App::ObjectIdentifier &path) const;
|
||||
|
||||
virtual bool isSame(const Property &other) const {
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue()
|
||||
&& _Unit == static_cast<decltype(this)>(&other)->_Unit;
|
||||
}
|
||||
|
||||
protected:
|
||||
Base::Quantity createQuantityFromPy(PyObject *value);
|
||||
Base::Unit _Unit;
|
||||
|
||||
Reference in New Issue
Block a user