This patch substitutes by isAttachedToDocument() (almost) everywhere where
getNameInDocument() is used for this purpose.
The very few places not touched by this patch demand a (just a little) less trivial change.
When we change the returning type of getNameInDocument() to std::string,
those places will be easily found, because they shall generate a compiler error
(converting std::string to bool).
Rationale:
The fact that getNameInDocument() return nullptr to indicate
that the object is not attached to a document is responsible for lots of bugs
where the developer does not check for "nullptr".
The idea is to eliminate all those uses of getNameInDocument() and, in the near future,
make getNameInDocument() return always a valid std::string.
==================================================================
The problem:
OriginGroupExtension::OriginGroupExtension () {
initExtensionType(OriginGroupExtension::getExtensionClassTypeId());
EXTENSION_ADD_PROPERTY_TYPE ( Origin, (0), 0, App::Prop_Hidden, "Origin linked to the group" );
}
initializes the Origin property to null.
Then Document::Restore => readObjects => addObject => slotNewObject => ViewProviderDocumentObject::updateView => ViewProviderBody::updateData => ViewProviderGeometryObject::updateData =>
ViewProviderDocumentObject::updateData => ViewProvider::updateData => ViewProviderOriginGroupExtension::extensionUpdateData => updateOriginSize() => OriginGroupExtension::getOrigin,
the latter throws an exception because the origin property is null.
Afterwards, the origin property is initialized during Document::Restore => readObjects => ExtensionContainer::Restore() => PropertyContainer::Restore() => App::PropertyLink::Restore()
=> App::PropertyLink::setValue() => Property::hasSetValue, which triggers an onChange: Body::onChanged => BodyBase::onChanged => Feature::onChanged => DocumentObject::onChanged =>
Document::onChangedProperty => Document::slotChangedObject => ViewProviderOriginGroupExtension::slotChangedObjectGui => ViewProviderOriginGroupExtension::updateOriginSize =>
OriginGroupExtension::getOrigin,
now, the latter that is the same that was throwing the exception and generating the error message above, does not throw anymore because Origin has been initialized.
When creating a new object, isNew==true; whereas when loading a file, isNew==false. Therefore, when loading a file setupObject is not executed. SetupObject, effectively initializes
the extension via: Body::setupObject => DocumentObject::setupObject => OriginGroupExtension::onExtendedSetupObject.
DocumentObject * Document::addObject(const char* sType, const char* pObjectName, bool isNew)
{
[more code here]
// Call the object-specific initialization
if (!d->undoing && !d->rollback && isNew) {
pcObject->setupObject ();
}
[more code here]
As DocumentObject code is generic for all objects (workbenches), by design it was chosen to initialize the object only if new. Therefore a object or an extension of a object being restored,
between the addition (addObject) and the restoring of the properties, must by design expect it not to be initialized.
The solution:
Making use of the Restore flag at document level (the one at object level is not sufficient), no exception regarding the null property is reported during document restoring.
Ticket:
https://freecadweb.org/tracker/view.php?id=2530fixes#2530
Due to problems onthe windows platform the virtual inheritance approach must be dropped. NExt to the already reimplemented proeprty interface the Type interface is reimplemented too. This change allows to revert some earlier changes.
FreeCADs property system utilises some pointer math to calculate the offset between
property and base class. Due to virtual inheritance of th ePropertyContainer the memory
layout has been changed to rather random, which has lead to crashes dependend on the
order of object initialisation.
The solution is to not make PropertyContaner virtual but a class below, Base::Persitance.
Then the memory layout is random for Persistance, but it is perfectly aligned for the
base class chains from PropertyContainer onwards as well as from Extension onwards.
Hence the proeprty system was changed to take the offset always from those two.