ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

"copy" 1 of 2 lines that have presistent reactor with each other will crash

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
jzq740176597
636 Views, 3 Replies

"copy" 1 of 2 lines that have presistent reactor with each other will crash

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;
}

 

3 REPLIES 3
Message 2 of 4
fenton.webb
in reply to: jzq740176597

Where does it crash for you?



Fenton Webb
AutoCAD Engineering
Autodesk

Message 3 of 4
jzq740176597
in reply to: fenton.webb

void
AsdkObjectToNotify::modified(const AcDbObject* pObj)
{

....

     pLine2->setEndPoint(p+v);//will error

}

Message 4 of 4
fenton.webb
in reply to: jzq740176597

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

 




Fenton Webb
AutoCAD Engineering
Autodesk

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost