修复 XEquipment 外壳/Impl 分离机制的 M1-M7 缺陷
- M1 createParamEquImpl 成功替换前释放旧 impl,消除 inplace 编辑泄漏 - M2 copyFrom2 先克隆成功再替换,避免旧 impl 泄漏或被置空 - M3 copyFrom 补基类深拷贝并兜底重建 impl,修复 clone/复制得到空壳 - M4 在 XEquipmentImplBase 注明 impl 不拥有 xdata 的所有权契约 - M5 draw3dByImp 改用临时数组,绘制失败时保留旧 3D 缓存并提示 - M6 抽出 makeTempClone(),集中 ToJson 的克隆/补数据/拷 part 流程 - M7 getUniqueName 的 %s 统一传 LPCTSTR、修正 sizeof,XL 的 %d 改 %f
This commit is contained in:
1 parent
d33ab67b13
commit
75819c0b72
4 files changed
+67
-28
No files matched your search
@@ -245,14 +245,17 @@ Acad::ErrorStatus AecDbXEquipment::copyFrom(const AcRxObject* pSrc)
|
||||
AssertWriteEnabled();
|
||||
AecDbXEquipment *pSrcEqu = AecDbXEquipment::cast(pSrc);
|
||||
if (!pSrcEqu) return Acad::eInvalidInput;
|
||||
|
||||
// 基类链通过 CopyObject(dwgOut -> dwgIn) 深拷参数,dwgInFields 内会重建 m_pImpl
|
||||
Acad::ErrorStatus es = AecDbBDPipeBase::copyFrom(pSrc);
|
||||
if (es != Acad::eOk) return es;
|
||||
|
||||
if (!m_pImpl)
|
||||
m_pImpl = createParamEquImpl(GetType(), false);
|
||||
|
||||
// 放在重建之后:工厂里的 getInterfaces 可能覆盖读进来的管嘴
|
||||
m_interfaces = pSrcEqu->m_interfaces;
|
||||
return Acad::eOk;
|
||||
//AssertWriteEnabled();
|
||||
//AecDbXEquipment *pSrcEqu = AecDbXEquipment::cast(pSrc);
|
||||
//if (!pSrcEqu) return Acad::eInvalidInput;
|
||||
//m_mapSpecXData.CopyFrom(pSrcEqu->GetSpecialtyData());
|
||||
//m_pImpl = pSrcEqu->cloneImpl(&m_mapSpecXData);
|
||||
//return Acad::eOk;
|
||||
}
|
||||
|
||||
Acad::ErrorStatus AecDbXEquipment::copyFrom2(const AcRxObject* pSrc)
|
||||
@@ -260,8 +263,15 @@ Acad::ErrorStatus AecDbXEquipment::copyFrom2(const AcRxObject* pSrc)
|
||||
AssertWriteEnabled();
|
||||
AecDbXEquipment *pSrcEqu = AecDbXEquipment::cast(pSrc);
|
||||
if (!pSrcEqu) return Acad::eInvalidInput;
|
||||
|
||||
m_mapSpecXData.CopyFrom(pSrcEqu->GetSpecialtyData());
|
||||
m_pImpl = pSrcEqu->cloneImpl(&m_mapSpecXData);
|
||||
|
||||
// 先克隆成功再替换:cloneImpl 在源对象没有 impl 时返回 NULL
|
||||
XEquipmentImplBase *pNewImpl = pSrcEqu->cloneImpl(&m_mapSpecXData);
|
||||
DELETE_PTR(m_pImpl);
|
||||
m_pImpl = pNewImpl;
|
||||
if (!m_pImpl)
|
||||
m_pImpl = createParamEquImpl(GetType(), false);
|
||||
return Acad::eOk;
|
||||
}
|
||||
|
||||
@@ -647,6 +657,8 @@ XEquipmentImplBase* AecDbXEquipment::createParamEquImpl(const int & type, bool b
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 工厂成功后替换旧 impl(inplace 编辑会对同一实体重复调用)
|
||||
DELETE_PTR(m_pImpl);
|
||||
m_pImpl = pImp;
|
||||
|
||||
// 接口生成一下
|
||||
@@ -738,11 +750,19 @@ int AecDbXEquipment::GetSectionDraw(const AcGePoint3d& ptFr, const AcGePoint3d&
|
||||
void AecDbXEquipment::draw3dByImp()
|
||||
{
|
||||
if (!m_pImpl) return;
|
||||
RemoveAllX3dPart();
|
||||
|
||||
// 先画到临时数组,成功后再整体替换缓存:各设备 draw3d 在取数失败时会中途 return,
|
||||
// 直接往缓存里 add 会让设备停留在“部分更新”状态。
|
||||
AcDbVoidPtrArray ar;
|
||||
m_pImpl->draw3d(ar);
|
||||
m_pImpl->getInterfaces(m_interfaces);
|
||||
|
||||
if (ar.isEmpty() && !Get3DBuffer().isEmpty())
|
||||
{
|
||||
acutPrintf(_T("\n设备参数绘制失败,保留原有三维显示。"));
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveAllX3dPart();
|
||||
|
||||
for (int i = 0; i < ar.length(); ++i)
|
||||
{
|
||||
@@ -751,6 +771,8 @@ void AecDbXEquipment::draw3dByImp()
|
||||
|
||||
AddX3dPart(pPart, (AcDb::BoolOperType)pPart->GetBoolOperFor());
|
||||
}
|
||||
|
||||
m_pImpl->getInterfaces(m_interfaces);
|
||||
}
|
||||
|
||||
bool AecDbXEquipment::isType(AcDbObjectId &id, const int &type)
|
||||
@@ -767,6 +789,25 @@ bool AecDbXEquipment::isType(AecDbXEquipment *pEqu, const int &type)
|
||||
return pEqu->GetType() == type;
|
||||
}
|
||||
|
||||
AecDbXEquipment* AecDbXEquipment::makeTempClone() const
|
||||
{
|
||||
AecDbXEquipment *pNew = (AecDbXEquipment *)clone();
|
||||
if (!pNew) return NULL;
|
||||
|
||||
// clone() 只带走了 m_interfaces,参数和 impl 必须靠 copyFrom2 补齐
|
||||
pNew->copyFrom2(this);
|
||||
pNew->Clean3DBuffer();
|
||||
|
||||
int count(GetX3dPartCount());
|
||||
for (int i(0); i < count; ++i)
|
||||
{
|
||||
AecDbX3dPart *pPart = new AecDbX3dPart;
|
||||
pPart->CopyFrom(GetX3dPart(i));
|
||||
pNew->AddX3dPart(pPart);
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
SHJson::WValue& AecDbXEquipment::ToJson(bool bExprotGeo) const
|
||||
{
|
||||
using namespace SHJson;
|
||||
@@ -776,20 +817,12 @@ SHJson::WValue& AecDbXEquipment::ToJson(bool bExprotGeo) const
|
||||
AcGeVector3d vtDir;
|
||||
GetInsert(ptIns, vtDir);
|
||||
|
||||
AecDbXEquipment *p = (AecDbXEquipment *)clone();
|
||||
AecDbXEquipment *p = makeTempClone();
|
||||
if (!p)
|
||||
return AecDbBDPipeBase::ToJson(bExprotGeo);
|
||||
|
||||
std::shared_ptr<AecDbXEquipment> pNew(p);
|
||||
pNew->copyFrom2(this);
|
||||
pNew->Clean3DBuffer();
|
||||
|
||||
int count(GetX3dPartCount());
|
||||
for (int i(0); i < count; ++i)
|
||||
{
|
||||
AecDbX3dPart *pPart = new AecDbX3dPart;
|
||||
pPart->CopyFrom(GetX3dPart(i));
|
||||
p->AddX3dPart(pPart);
|
||||
}
|
||||
|
||||
// 现在需要将pNew移动到原点,并把方向置为x方向
|
||||
AcGeMatrix3d mat;
|
||||
mat.setToTranslation(-ptIns.asVector());
|
||||
|
||||
Reference in new issue
Block a user