I usually don't implement Partial Undo in custom entities, it is way easier to use the default aproach of calling assertWriteEnabled(Adesk::kTrue) (the default parameter by the way), yet sometimes you may feel guilty for saving your entire class data every time the object is modified, then you implement Partial Undo. Well, the important fact is, I'm working with a custom entity that had Partial Undo implemented, and someone reported that the AudoCAD was crashing after Undoing modifications on this entity. After some tests I discovered it would happen only in ACAD 64bit. According to Autodesk Help, the partial undo implementation should be like this:
MyCustomEntity::methodThatModifyMyentity()
{
assertWriteEnabled(Adesk::kFalse, Adesk::kTrue);
AcDbDwgFiler *pFiler = NULL;
if ((pFiler = undoFiler()) != NULL)
{
// pay attention here
undoFiler()->writeItem((long)MyCustomEntity::desc());
// write here whatever you have to write
}
// modify here whatever you have to modify
return Acad::eOk;
}
Acad::ErrorStatus MyCustomEntity::applyPartialUndo(AcDbDwgFiler* filer, AcRxClass* classObj)
{
if (classObj != MyCustomEntity::desc())
return MyCustomEntityParent::applyPartialUndo(filer, classObj);
// read whatever you have to read
return Acad::eOk;
}Problem here is: 64 bit pointers are
64 bit integers, yet 64 bit long is still 32 bit integers!
So, if you use undoFiler()->writeItem((long) MyCustomEntity::desc()), classObj may differ from MyCustomEntity::desc().
This can be solved like this:
MyCustomEntity::methodThatModifyMyentity()
{
assertWriteEnabled(Adesk::kFalse, Adesk::kTrue);
AcDbDwgFiler *pFiler = NULL;
if ((pFiler = undoFiler()) != NULL)
{
#ifdef _WIN64
undoFiler()->writeAddress(MyCustomEntity::desc());
#else
undoFiler()->writeItem((long)MyCustomEntity::desc());
#endif
// write here whatever you have to write
}
// modify here whatever you have to modify
return Acad::eOk;
}Its probably safe to use writeAddress in both cases, 64 and 32 bit,
but I feel better separating it.
No comments:
Post a Comment