Под событием, в данном случае, понимается способ оповещения сервером заинтересованной стороны (клиентов) об изменении своего состояния. Для того, чтобы клиент мог обрабатывать событие, он должен создать связь между объектом события и обработчиком. В качестве обработчиков вуступают методы объектов, т.е. обработчик задается указателем на объект и указателем на метод. С одним событием м.б. связано несколько обработчиков. При генерации события указываются аргументы, которые получат обработчики события (т.е. методы). В процессе генерации события быдут вызваны все обработчики с указанными аргументами.
Класс Cntm::DirectEvent является шаблоном. В качестве параметра шаблона указывается сигнатура функции (т.е. без указания конкретного класса обработчика), которая будет использоваться при генерации события. Пример объвления события: DirectEvent<void (int,const string&,Class1*,const Class2::Ptr&)> ChangeEvent; Методы обработчиков должны иметь такую же сигнатуру, как и событие. При попытке связать событие с собработчиком с другой сигнатурой будет выдана ошибка компиляции, т.е. обеспечивается жесткая проверка типов. Возвращаемое значение (если его тип не void) при вызове обработчиков игнорируется. Обычно объект события объявляется как public поле объекта, генерирующего событие.
Свзывание события с обработчиком осуществляется с помощью специального класса Cntm::EventLink (не является шаблоном). Что бы создать связь нужно создать объект этого класса и указать событие и обработчик (указатель на объект, указатель на метод). При уничтожении этого объекта связь будет автоматически разорвана. Также у этого класса есть метод Attach(), позволяющий изменить связь и имеющий такие же аргументы, что и конструктор (при этом старая связь разрывается и создается новая), а также метод Detach(), разрывающий текущую связь. Рассмотрим пример: EventLink onChangeClass1(object1->ChangeEvent, this, &ThisClass::OnChangeClass1); onChangeClass1.Attach(object2->ChangeEvent, this, &ThisClass::OnChangeClass2); onChangeClass1.Detach();
Генерация события производится с помощью оператора operator() объекта события. В качестве аргументов этого оператора указываются аргументы, которые будут переданы обработчикам. Пример: ChangeEvent(45, "Привет всем обработчикам", this, object2); Вызов обработчиков прямого события происходит в момент генерации, т.е. в операторе operator() объекта события.
Теперь подробнее о связях событий с обработчиками. Класс Cntm::EventLink имеет конструктор по умолчанию, который инициализирует пустую связь. Конструкторы связывания и методы Attach() имеют 3 параеметра. Рассмотрим их:
Некоторые особенности работы.
Время жизни объектов и подсчет ссылок. На объект, обрабатывающий событие (если это объект с подсчетом ссылок, наследующий Cntm::IRefObject) кол-во ссылок не увеличивается (что бы не препятствовать его удалению). Если после создания связи и до ее разрыва произойдет уничтожение объекта события, ничего страшного не случится, просто событие больше никогда не будет сгенерировано. Если во время существования связи произойдет уничтожение объкта обработчика, то это приведет к ошибкам выполнения, поэтому время жизни связи не должно превышать время жизни объекта обработчика.
Процесс генерации события. Вызываются только те обработчики, которые были добавлены до генерации события. Если обработчик добавлен после генерации события (например, в одном из обработчиков), то добавленный обработчик вызван не будет. Если обработчик был удален в момент генерации до его вызова, то гарантируется, что он не будет вызван. Для объектов обработчиков, являющихся объектами с подсчетом ссылок: если на момент вызова обработчика события на объект не осталось ссылок, но он еще существует (находится в удаляемом состоянии, см. Cntm::IRefObject), то вызов обработчика произведен не будет, если вызов обработчика произведен, то гарантируется наличие хотя бы одной ссылки на объект обработчика до выхода из метода обработки. Исключения, сгенерированные в обработчиках, ни как не влияют на вызов других обработчиков, они просто игнорируются. Относительно аргументов события: 1. изменения аргументов коснутся всех обработчиков, которые будут вызваны после изменившего; 2. если аргумент передан по ссылке, то нет гарантии, что если обработчик произведет изменение этого аргумента, то это изменение отразится на исходном значении аргумента, которое было передано при генерации.
Данный класс обеспечивает многопоточность.
См. определение в файле DirectEvent.h строка 57
Друзья | |
class | SignatureArgsCollector< DirectEvent< SignatureT >, void, SignatureInfo< SignatureT >, SignatureInfo< SignatureT >::argsCount > |
friend class SignatureArgsCollector< DirectEvent< SignatureT >, void, SignatureInfo< SignatureT >, SignatureInfo< SignatureT >::argsCount > [friend] |
См. определение в файле DirectEvent.h строка 61
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |