Использование Реактора Базы данных
Следующий пример использует реактор, полученный из AcDbDatabaseReactor, чтобы следить за числом объектов в настоящее время в базе данных. Это осуществляет три функции уведомления для реакторного класса: objectAppended (), objectModified (), и objectErased (). Watch_db () функция добавляет реактор к текущей базе данных. Clear_reactors () функция удаляет реактор из базы данных и удаляет реактор базы данных.
class AsdkDbReactor;
long gEntAcc = 0; // Global entity count
AsdkDbReactor *gpDbr = NULL; // Pointer to database reactor
// Custom AcDbDatabaseReactor class for database
// event notification.
//
class AsdkDbReactor : public AcDbDatabaseReactor
{
public:
virtual void objectAppended(const AcDbDatabase* dwg,
const AcDbObject* dbObj);
virtual void objectModified(const AcDbDatabase* dwg,
const AcDbObject* dbObj);
virtual void objectErased(const AcDbDatabase* dwg,
const AcDbObject* dbObj, Adesk::Boolean pErased);
};
// Called whenever an object is added to the database.
//
void
AsdkDbReactor::objectAppended(const AcDbDatabase* db,
const AcDbObject* pObj)
{
printDbEvent(pObj, "objectAppended");
acutPrintf(" Db==%lx\n", (long) db);
gEntAcc++;
acutPrintf("Entity Count = %d\n", gEntAcc);
}
// Called whenever an object in the database is modified.
//
void
AsdkDbReactor::objectModified(const AcDbDatabase* db, const AcDbObject* pObj)
{
printDbEvent(pObj, "objectModified");
acutPrintf(" Db==%lx\n", (long) db);
}
// Called whenever an object is erased from the database.
//
void
AsdkDbReactor::objectErased(const AcDbDatabase* db, const AcDbObject* pObj, Adesk::Boolean pErased)
{
if (pErased) {
printDbEvent(pObj, "objectErased");
gEntAcc--;
} else {
printDbEvent(pObj, "object(Un)erased");
gEntAcc++;
}
acutPrintf(" Db==%lx\n", (long) db);
acutPrintf("Entity Count = %d\n", gEntAcc);
}
// Prints the message passed in by pEvent; then
// calls printObj() to print the information about
// the object that triggered the notification.
//
void printDbEvent(const AcDbObject* pObj, const char* pEvent)
{
acutPrintf(" Event: AcDbDatabaseReactor::%s ", pEvent);
printObj(pObj);
}
// Prints out the basic information about the object pointed
// to by pObj.
//
void printObj(const AcDbObject* pObj)
{
if (pObj == NULL) {
acutPrintf("(NULL)");
return;
}
AcDbHandle objHand;
char handbuf[17];
// Get the handle as a string.
//
pObj->getAcDbHandle(objHand);
objHand.getIntoAsciiBuffer(handbuf);
acutPrintf(
"\n (class==%s, handle==%s, id==%lx, db==%lx)",
pObj->isA()->name(), handbuf,
pObj->objectId().asOldId(), pObj->database());
}
// Adds a reactor to the database to monitor changes.
// This can be called multiple times without any ill
// effect because subsequent calls will be ignored.
//
void watchDb()
{
if (gpDbr == NULL) {
gpDbr = new AsdkDbReactor();
}
acdbHostApplicationServices()->workingDatabase()->addReactor(gpDbr);
acutPrintf(
" Added Database Reactor to "
"acdbHostApplicationServices()->workingDatabase().\n");
}
// Removes the database reactor.
//
void clearReactors()
{
if (acdbHostApplicationServices()->workingDatabase() != NULL) {
acdbHostApplicationServices()->workingDatabase()->removeReactor(gpDbr);
delete gpDbr;
gpDbr = NULL;
}
}
// ObjectARX entry point function
//
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)
{
switch (msg) {
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(appId);
acrxDynamicLinker->registerAppNotMDIAware(appId);
acedRegCmds->addCommand("ASDK_NOTIFY_TEST",
"ASDK_WATCH",
"WATCH",
ACRX_CMD_TRANSPARENT,
watchDb);
acedRegCmds->addCommand("ASDK_NOTIFY_TEST",
"ASDK_CLEAR",
"CLEAR",
ACRX_CMD_TRANSPARENT,
clearReactors);
break;
case AcRx::kUnloadAppMsg:
clearReactors();
acedRegCmds->removeGroup("ASDK_NOTIFY_TEST");
break;
}
return AcRx::kRetOK;
}