AcDbObjectReactor
События Мониторов, имеющие отношение к определенному созданию объекта — базы данных, модификации, стиранию.
AcDbEntityReactor
Контролирует дополнительное, примитив-определенное событие, типа изменяемой графики.
В большинстве случаев, только стандартные методы C++ необходимы для создания новых переходных реакторных классов. Макрокоманды ObjectARX, которые создают объект описателя класса для нового реакторного класса, не обычно используются, чтобы происходить от этих реакторных классов.
Каждый родительский класс содержит набор виртуальных функций уведомления, которые могут быть осуществлены вашим новым полученным классом. Например, AcDbObjectReactor класс содержит следующие функции уведомления, которые отвечают на связанные объектом события:
§ cancelled()
§ copied()
§ erased()
§ goodbye()
§ openedForModify()
§ modified()
§ subObjModified()
§ modifyUndone()
§ modifiedXData()
§ unappended()
§ reappended()
§ objectClosed()
Каждая из этих функций требует указателя на уведомителя события. Базовый класс, AcDbObjectReactor, имеет выполнение NULL для всех этих функций. В вашем полученном реакторном классе, осуществьте функции, соответствующие{*передающие*} типу уведомлений, которыми Вы заинтересованы. Тогда инициализируйте реактор, и добавьте это к любому числу объектов базы данных, использующих AcDbObject:: addReactor() функция. Чтобы добавлять или удалять переходный реактор к объекту уведомителя, объект может быть открытый в любом состоянии (чтение, записывать, или уведомлять).
Добавление или удаление переходного реактора не проверено механизмом отмены. (Для постоянных реакторов, объект уведомителя должен быть открыт для записи, и добавления, или удаление реакторов проверено механизмом отмены.)
Поскольку Вы создавали переходный реакторный объект, Вы также ответствены за удаление этого.
Когда объект стерт, например, это вызывает стертую передачу () функцией уведомления на каждом реакторе в его списке. Если Вы осуществили стертый () функция для вашего реактора, та функция будет вызвана{*названа*} объектом базы данных, и Вы можете тогда брать любое специальное действие, соответствующий вашему приложению, когда объект стерт.
AcDbObject и События Уведомления Базы данных
Когда Вы получаете стертый () уведомление на объекте базы данных, объект отмечено как стерто, но - все еще часть базы данных. Когда Вы получаете недобавленный в конец () уведомление, объект было отмечено недобавленным в конец и - не часть базы данных, если это не повторно добавлено в конец. До свидания () уведомление на объекте послано непосредственно перед тем, как это уходит полностью. Эти сигналы уведомления, что объект собирается быть удаленным из базы данных и удален от памяти.
Вы можете хотеть удалить ваш реактор из объекта, когда Вы получаете стертый () или недобавленный в конец () уведомление. Однако, если Вы удаляете реактор в этой точке, Вы не будете получать повторно добавленный в конец () или нестертый () уведомление для того объекта. Чтобы контролировать эти события, используйте эквивалентные уведомления на базе данных, не только объект:
AcDbDatabaseReactor::objectErased()
AcDbDatabaseReactor::objectUnappended()
AcDbDatabaseReactor::objectReappended()
Заказные Уведомления
Когда модификации совершены{*переданы*} на объекте, объект закрыт, который вызывает подзавершение () виртуальная функция AcDbObject. В перегрузке этой функции в вашем классе пользователя, Вы можете уведомлять другие, что Вы закрываетесь после модификации. Эти уведомления должны быть ваше заказное уведомление в форме заказных функций на вашем классе. Не используйте уведомления, обеспеченные на AcDbObjectReactor для этой цели.
Использование Редактора Реактор
AcEditorReactor класс обеспечивает много функций для ответа на различные события. Несколько из этих функций - beginClose (), beginDxfIn (), dxfInComplete (), beginSave (), и saveComplete (). Никакое взаимодействие AutoLISP не может быть выполнено в пределах функции уведомления.
См. главу 18, при Глубоко Имитации, ” для обсуждения редактора, реакторные функции, касающиеся глубокого аналога и wblock имитируют операции.
Использование Реактора Базы данных
Следующий пример использует реактор, полученный из 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;
}
Использование Объектного Реактора
Заставлять один объект базы данных реагировать на другой объект базы данных
1 Получают класс из AcDbObject (или любой из его подклассов).
2 Осуществляют функции уведомления.
3 Инициализируют объект класса.
4 Добавляют объект к базе данных, и назначают владельца.
5 Добавляют это к объекту уведомителя с AcDbObject:: addPersistentReactor () функция.
Этот механизм позволяет Вам определять зависимости в пределах базы данных, которые сохраняются, когда база данных сохранена и освежена всякий раз, когда это - узда - stantiated.
Используйте макрокоманды ObjectARX, когда Вы получаете новый объектный реакторный класс так, чтобы объект описателя класса был создан для этого. (Если Вы не используете макрокоманды ObjectARX, ваш класс наследует описание класса его родителя, когда это сохранено, и его тождество будет потеряно, когда файл читается в.)
Получение ID Объектного Реактора
Каждый объект базы данных обслуживает{*поддерживает*} список реакторов на себе. Некоторые - переходные реакторы, и некоторые постоянны. Переходные реакторы - образцы классов, полученных из AcDbObjectReactor, принимая во внимание, что постоянные реакторы - объект IDs объектов резидента базы.
Следующий код показывает, как перерыть список реакторов, чтобы найти ваш переходный или постоянный реактор. Чрезвычайно важно, что Вы проверяете специфический вход в реакторном списке, чтобы быть постоянным реактором, используя функцию AcDbIsPersistentReactor. Если это - постоянный реактор, Вы можете использовать соответствующую функцию, чтобы получить ее объект ID. Если это - не постоянный реактор, Вы можете приводить вход в AcDbObjectReactor.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |


