it's sample from ARX2002_SDK\docsamps\persreac.
By "Alines" cmd will create 2 line and having persistent reactor to each other.
if your "Copy" one of the line,CAD will abort with "Internal error : dbobji : notifyReators 1 "
you can compile the list cpp's code and appload it to have a test!
Help me please!
regards
jzq
#include <string.h> #include <stdlib.h> #include <aced.h> #include <dbents.h> #include <dbsymtb.h> #include <dbapserv.h> #include <adslib.h> void assocLines(); void addToModelSpace(AcDbObjectId&, AcDbEntity*); void initApp(void); void unloadApp(void); extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode, void*); // THE FOLLOWING CODE APPEARS IN THE SDK DOCUMENT. class AsdkObjectToNotify : public AcDbObject { public: ACRX_DECLARE_MEMBERS(AsdkObjectToNotify); AsdkObjectToNotify() {}; void eLinkage(AcDbObjectId i, double f=1.0) {mId=i; mFactor=f; }; void modified(const AcDbObject*); private: AcDbObjectId mId; double mFactor; }; ACRX_DXF_DEFINE_MEMBERS(AsdkObjectToNotify, AcDbObject, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 0, ASDKOBJECTTONOTIFY, persreac); void AsdkObjectToNotify::modified(const AcDbObject* pObj) { AcDbLine *pLine = AcDbLine::cast(pObj); if (!pLine) { const char* cstr = pObj->isA()->name(); acutPrintf("This is a %s.\n", cstr); acutPrintf("I only work with lines. Sorry.\n"); return; } acutPrintf("\nReactor attached to %lx calling %lx.\n", pLine->objectId(), mId); AcDbLine *pLine2; if (acdbOpenObject((AcDbObject*&)pLine2, mId, AcDb::kForWrite) == Acad::eOk) { // get length of line entity we're being notified // has just been modified // AcGePoint3d p = pLine->startPoint(); AcGePoint3d q = pLine->endPoint(); AcGeVector3d v = q-p; double len = v.length(); // // update other entity to match: // p = pLine2->startPoint(); q = pLine2->endPoint(); v = q-p; v = len * mFactor * v.normal(); pLine2->setEndPoint(p+v);//will error pLine2->close(); } } // Creates two lines and two AsdkObjectToNotify objects and // ties them all together. // void assocLines() { AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); AcDbObjectId aId, bId; AcDbLine *pLineA = new AcDbLine; pLineA->setDatabaseDefaults(pDb); pLineA->setStartPoint(AcGePoint3d(1, 1, 0)); pLineA->setEndPoint(AcGePoint3d(2, 1, 0)); addToModelSpace(aId, pLineA); ads_printf( "Line A is %lx from 1,1 to 2,1.\n", pLineA->objectId()); AcDbLine *pLineB = new AcDbLine; pLineB->setDatabaseDefaults(pDb); pLineB->setStartPoint(AcGePoint3d(1, 2, 0)); pLineB->setEndPoint(AcGePoint3d(2, 2, 0)); addToModelSpace(bId, pLineB); ads_printf("Line B is %lx from 1,2 to 2,2.\n", pLineB->objectId()); // Open the named object dictionary, check if there is // an entry with the key "ASDK_DICT". If not, create a // dictionary and add it. // AcDbDictionary *pNamedObj; AcDbDictionary *pNameList; pDb->getNamedObjectsDictionary(pNamedObj, AcDb::kForWrite); if (pNamedObj->getAt("ASDK_DICT", (AcDbObject*&)pNameList, AcDb::kForWrite) == Acad::eKeyNotFound) { pNameList = new AcDbDictionary; AcDbObjectId DictId; pNamedObj->setAt("ASDK_DICT", pNameList, DictId); } pNamedObj->close(); // Create the AsdkObjectToNotify for lineA // AsdkObjectToNotify *pObj = new AsdkObjectToNotify(); pObj->eLinkage(bId); AcDbObjectId objId; if ((pNameList->getAt("object_to_notify_A", objId)) == Acad::eKeyNotFound) { pNameList->setAt("object_to_notify_A", pObj, objId); pObj->close(); } else { delete pObj; ads_printf("object_to_notify_A already exists\n"); } // Set up persistent reactor link between line a // and AsdkObjectToNotify // pLineA->addPersistentReactor(objId); pLineA->close(); // Create the AsdkObjectToNotify for LineB // pObj = new AsdkObjectToNotify(); pObj->eLinkage(aId); if ((pNameList->getAt("object_to_notify_B", objId)) == Acad::eKeyNotFound) { pNameList->setAt("object_to_notify_B", pObj, objId); pObj->close(); } else { delete pObj; ads_printf("object_to_notify_B already exists\n"); } pNameList->close(); // Set up persistent reactor link between line b // and AsdkObjectToNotify // pLineB->addPersistentReactor(objId); pLineB->close(); } // Adds an entity to Model Space, but does not close // the entity. // void addToModelSpace(AcDbObjectId &objId, AcDbEntity* pEntity) { AcDbBlockTable *pBlockTable; AcDbBlockTableRecord *pSpaceRecord; acdbHostApplicationServices()->workingDatabase() ->getSymbolTable(pBlockTable, AcDb::kForRead); pBlockTable->getAt(ACDB_MODEL_SPACE, pSpaceRecord, AcDb::kForWrite); pBlockTable->close(); pSpaceRecord->appendAcDbEntity(objId, pEntity); pSpaceRecord->close(); } void initApp() { acedRegCmds->addCommand("ASDK_ALINES", "ASDK_ALINES", "ALINES", ACRX_CMD_MODAL, assocLines); AsdkObjectToNotify::rxInit(); acrxBuildClassHierarchy(); } void unloadApp() { acedRegCmds->removeGroup("ASDK_ALINES"); deleteAcRxClass(AsdkObjectToNotify::desc()); } AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* appId) { switch (msg) { case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(appId); acrxDynamicLinker->registerAppMDIAware(appId); initApp(); break; case AcRx::kUnloadAppMsg: unloadApp(); } return AcRx::kRetOK; }
Solved! Go to Solution.
Solved by fenton.webb. Go to Solution.
void
AsdkObjectToNotify::modified(const AcDbObject* pObj)
{
....
pLine2->setEndPoint(p+v);//will error
}
Oh sorry, I missed your point at the very start - you "copied" the objects.
The sample merely shows how to link to objects so that updating one object updates the other to suit. Copying is not supported by this sample. If you want to implement copying then you will have to implement an AcRxEventReactor::beginDeepCloneXlation() to handle setting up the links, and also, your modified code will have to include flags that are set by corresponding AcRxEventReactor::beginDeepClone() and AcRxEventReactor::endDeepClone() so that your modified function knows not to do anything