Как уже отмечалось выше задача об вызове каскада обработчиков событий ложится на процессор событий Ultima-S.
Например, по команде exec @ret=EvProcess 'off',@Class,'',0,1, @UDN,0,0
Процессор событий должен вызвать все обработчики события off (удалить объект) для данного экземпляра @UDN. При этом будут вызываться как обработчики предков, так и перехватчики событий созданные за счет мод событий.
Следует отметить, что хотя идея обработчика событий построенная на анализе заголовков процедур очень проста, но полностью функциональный вариант процессора событий является очень сложным, особенно в системе где срабатываний событий очень много. Ниже приведен упрощенный вариант процессора событий по состоянию декабрь 1996г. Такой вариант вполне приемлим для БД, где презентативная логика (формы объектов) находятся на клиенте. В Ultima-S где потенциально любое дейтсвие влечет за собой каскад срабатывающих обработчиков, что отрицательно сказвается на производительности. Процессор событий Ultima-S прошел длительную оптимизацию. В отличие от приведенного варианта от стал фактически прокси-сервером объектов со следующими технологиями кеширования:
Данные технологии позволяют добится производительности при работе через объектный протокол обмена не хуже чем при прямом доступе к таблицам (разница не ощутима).
CREATE PROCEDURE EvProcess
@EvName varchar(32), -- имя события E
@ClassName varchar(32), -- название класса T
@ViewMode varchar(32), -- название моды
@Before smallint, -- 1, если есть событие ДО
@After smallint, -- 1, если есть событие ПОСЛЕ, 2 для ViewMode
@p1 integer, @p2 integer, @p3 integer -- параметры
AS
-- рассылка сообщений
declare @cnt int, @Name varchar(32), @PName varchar(32), @ret int, @masterUDN int, @saved int, e @maxpr int
-- формирование таблицы иерархий классов
create table #Hier (Name varchar(24), Lev int)
select @cnt=0
while @ClassName<>NULL and @ClassName<>'' begin
insert into #Hier (Name,Lev) select @ClassName,@cnt
select @ClassName=BasedOn from Class where Name=@ClassName
select @cnt=@cnt+1
end
declare H cursor for select Name from #Hier order by Lev
open H
fetch next from H into @Name
while @@FETCH_STATUS <> -1 begin if @@FETCH_STATUS <> -2 begin
-- для данного класса ищем процедуры
declare Pr cursor for select name from sysobjects where (sysstat & 0xf = 4) and type='P' and name like ('%[_]'+@EvName+'[_]'+@Name)
open Pr
fetch next from Pr into @PName
while @@FETCH_STATUS <> -1 begin if @@FETCH_STATUS <> -2 begin
-- для процедур
exec @ret=@PName @p1,@p2,@p3
end fetch next from Pr into @PName end deallocate Pr
end fetch next from H into @Name end deallocate H
GO