Quantcast
Channel: Autodesk AutoCAD forums
Viewing all articles
Browse latest Browse all 14319

arx2002 docsamps\persreac has big bug?

$
0
0
class AsdkObjectToNotify : public AcDbObject
//
// AsdkObjectToNotify - customized AcDbObject for persistent
// reactor to notify:
//
{
public:
    ACRX_DECLARE_MEMBERS(AsdkObjectToNotify);
    AsdkObjectToNotify() {};
    void eLinkage(AcDbObjectId i, double f=1.0)
        {mId=i; mFactor=f; };
    void              modified(const AcDbObject*);
    Acad::ErrorStatus dwgInFields(AcDbDwgFiler*);
    Acad::ErrorStatus dwgOutFields(AcDbDwgFiler*) const;
    Acad::ErrorStatus dxfInFields(AcDbDxfFiler*);
    Acad::ErrorStatus dxfOutFields(AcDbDxfFiler*) const;
private:
    AcDbObjectId mId;
    double mFactor;
};

ACRX_DXF_DEFINE_MEMBERS(AsdkObjectToNotify, AcDbObject, 
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 
0, \
    ASDKOBJECTTONOTIFY, persreac);

// This function is called everytime the line it's
// "watching" is modified.  When it's called, it opens the
// other line of the pair and changes that line's length to
// match the new length of the line that's just been
// modified.
// 
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;
    }
	AcDbObjectId  IdAttch=pLine->objectId();
    acutPrintf("\nReactor attached to %lx calling %lx.\n",
        IdAttch, mId);

    // This open will fail during notification caused by
    // reactor being added to the entity or when this
    // notification is in reaction to a change due to the
    // other line's reactor changing this line.  This will
    // properly prevent an infinite recursive cross loop
    // between the two lines and their reactors.
    // 
    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);//error!!
        pLine2->close();
    }
}


// Files object's information in from DWG, UNDO, etc.
//
Acad::ErrorStatus
AsdkObjectToNotify::dwgInFields(AcDbDwgFiler* filer)
{
    assertWriteEnabled();
    AcDbObject::dwgInFields(filer);
    filer->readItem(&mFactor);
    filer->readItem((AcDbSoftPointerId*) &mId);
    return filer->filerStatus();
}


// Files object's information out to DWG, UNDO, etc.
//
Acad::ErrorStatus
AsdkObjectToNotify::dwgOutFields(AcDbDwgFiler* filer) const
{
    assertReadEnabled();
    AcDbObject::dwgOutFields(filer);
    filer->writeItem(mFactor);
    filer->writeItem((AcDbSoftPointerId&)mId);
    return filer->filerStatus();
}


// Files object's information in from DXF and LISP/ADS
//
Acad::ErrorStatus
AsdkObjectToNotify::dxfInFields(AcDbDxfFiler* filer)
{
    assertWriteEnabled();

    Acad::ErrorStatus es;
    if ((es = AcDbObject::dxfInFields(filer))
        != Acad::eOk)
    {
        return es;
    }

    // Check if we're at the right subclass data marker
    //
    if(!filer->atSubclassData("AsdkObjectToNotify")) {
        return Acad::eBadDxfSequence;
    }

    struct resbuf rbIn;

    while (es == Acad::eOk) {
        if ((es = filer->readItem(&rbIn)) == Acad::eOk) {
            if (rbIn.restype == AcDb::kDxfReal) {
                mFactor = rbIn.resval.rreal;
            } else if (rbIn.restype
                == AcDb::kDxfSoftPointerId)
            {
                // ObjectIds are filed in as ads_names
                // 
                acdbGetObjectId(mId, rbIn.resval.rlname);
            } else {   // invalid group
                return(filer->pushBackItem());
            }
        }
    }
    return filer->filerStatus();
}


// files object's information out to DXF and LISP/ADS
//
Acad::ErrorStatus
AsdkObjectToNotify::dxfOutFields(AcDbDxfFiler* filer) const
{
    assertReadEnabled();
    AcDbObject::dxfOutFields(filer);
    filer->writeItem(AcDb::kDxfSubclass,"AsdkObjectToNotify");
    filer->writeItem(AcDb::kDxfReal, mFactor);
    filer->writeItem(AcDb::kDxfSoftPointerId, mId);
    return filer->filerStatus();
}


// 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();
}

 after run cmd "alines" then "copy" cmd on one the lines.

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

will cause INTERNAL ERROR: dbobji: notifyReactors 1


Viewing all articles
Browse latest Browse all 14319

Trending Articles