Тема OS18асу. Понятие событийного программирования. Событийно-управляемое программирование - объектно-ориентированное программирование, при котором задаются реакции программы на различные события. Эволюция языков системного программирования asm->c->c++->java->python/jscript? Обзор сценариев. Процесс отладки. Использование объектов ActiveX. Апплеты Java (Агенты): Сигнал-Событие-Сообщение-Действие; Вариант событийного стиля: программирования от приоритетов Клиент-cервер и ООП; ООАнализ, ООДизайн и ООП-кодирование; понимание концепции событийно-управляемого программирования: переменные, циклические операторы, процедуры; объекты, свойства, методы и события. объект Event: Класс, Абстракция, Инкапсуляция, Наследование, Полиморфизм Событийное программирование предполагает наличие возможностей по управлению выполнением задач со стороны пользователя посредством возможностей операционной системы через события объектов. Перехват событий. Событие (прерывание) - это способность объекта реагировать на события, которые могут исходить от пользователя программы, и представляют собой программы. Программы обслуживания событий программируются в отличие от методов объектов теми, кто непосредственно использует эти объекты в своих программах. Пример 1. Наиболее часто используемым событием является событие Click. Это событие наступает, когда пользователь производит щелчок кнопкой мыши. Рассмотрим ситуацию, когда при щелчке мышью на форме Form1, необходимо изменить цвет фона формы по случайному закону. Пример 2. Можно организовать считывание координат курсора мыши и вывода их в активные элементы управления типа метка Label1 и Label2. Для решения этой задачи существует событие MouseMove. В таблице 1. приведены наиболее употребительные событий объектов Windows. Событие Назначение события Какие объекты имеют это событие Click Нажатие клавиши мыши Все объекты DlbClick Двойное нажатие клавиши мыши Все объекты Activate Загрузка объекта для выполнения UserForm Terminate Закрытие объекта UserForm MouseMove Передвижение указателя мыши по объекту Все объекты GotFocus Получения фокуса Все объекты KeyPress Отслеживание нажатия и отпускания клавиши Все объекты KeyDown Отслеживание нажатия клавиши Все объекты KeyUp Отслеживание отпускания клавиши Все объекты Любой активный элемент управления или объект современной операционной системы характеризуется большим числом свойств, методов и событий. Некоторые свойства, методы и события являются общими для всех объектов. Но у каждого типа элемента управления или типа объекта в Windows имеются свои специфичные свойства, методы и события. Чтобы обеспечить возможность внешней синхронизации процессов в фазе "пользователь" OS UNIX имитирует для каждого процесса систему программных прерываний, называемых сигналами. Сигнальный механизм позволяет процессу реагировать на различные события, моменты появления которых не могут быть заранее предусмотрены. Обработка сигналов позволяет реализовать популярную в настоящее время методологию событийного программирования. Событие, сообщение, демон Исторически этот стиль как определенный прием сформировался в области разработки операционных систем, где естественно связывать понятие события с прерываниями. Прерывание - это сигнал от одного из устройств (может быть, и от самого процессора), который говорит о том, что произошло нечто, на что следует обратить внимание. Когда происходит прерывание, операционная система распознает, какая причина его вызвала, и далее формирует событие как информационный объект, вызывающий реакцию программной системы. Возможны разные способы реагирования на события, в том числе и передача его для обработки той программе, при выполнении которой возникло прерывание, породившее это событие. Из потребности такой обработки, собственно говоря, и сформировался событийно-ориентированный стиль программирования. Наиболее очевидная область его адекватного применения - реализация интерактивных взаимодействий программы с пользователем и решение других подобных задач (например, тех, которые требуют опроса датчиков состояния каких-либо технологических процессов). В частности, при взаимодействии с пользователем чаще всего достаточно таких событий, как нажатие на клавишу, перемещение курсора мыши, указание световой кнопки и т. п. Не случайно именно те прерывания, которые способна перенаправить операционная система для обработки на уровень пользовательской программы, стали основой для выработки систем событий, реакция на которые задается в событийно-ориентированном стиле. События этого рода можно передать от одного обработчика к другому, не нарушая условий адекватного применения данного стиля: для этого достаточно объявить такое перенаправление события порождением нового события. Но требуется также генерация событий, не связанных с прерываниями. К примеру, программируя в событийно-ориентированном стиле, естественно объявить событием ситуацию, когда значение одной переменной становится больше другой. Однако такого рода свойства вычислительного процесса никак не отражаются в системе прерываний, а потому обычные языковые средства событийно-ориентированного программирования (например, в Delphi), часто провозглашаемые как универсальные, здесь не помогут. Необходимы иные механизмы, которые уводят программиста из области шаблонов проектов, стандартизующих обработку событий. Об этом обстоятельстве, ограничивающем применимость подхода, предпочитают умалчивать, и, как обычно бывает в подобных ситуациях, при беглом знакомстве с соответствующими средствами могут возникнуть ни на чем не основанные ожидания с последующими разочарованиями и даже отторжением стиля, хорошо работающего на своем месте. Примером языка, до некоторой степени ориентированного на событийно-ориентированное программирование, может служить Perl. Событийный стиль удобен не только на уровне конкретного программирования. Часто концептуальное осмысление задачи полезно проводить в терминах системы событий, а уж затем решать, как реализовывать систему: непосредственно использовать события как средство управления, моделировать событийное взаимодействие имеющимися средствами или вообще отказаться от этого механизма в данной разработке. В качестве иллюстрации этого тезиса опишем с позиций событийного стиля программирования взаимоотношения между синтаксическим анализом и вычислениями семантики программы. Реализация этих взаимоотношений - обычная задача, решаемая при разработке любого транслятора. В событийном описании этой задачи в качестве событий системы естественно рассматривать распознавание во входном потоке (транслируемом тексте) синтаксических единиц, то есть конструкций языка. Такое событие требует в качестве обработчика семантическую подпрограмму, связанную с распознаваемой конструкцией. Следовательно, выявлены два автономных процесса: синтаксический анализ, задающий генерацию событий, и семантическая обработка, осуществляемая как последовательность вызовов семантических подпрограмм-реакций, упорядоченная событиями. Коль скоро есть концептуальное разделение процессов, его можно воплотить в реальной системе в событийном стиле. Это решение влечет за собой следующее. Необходимость рассмотрения в качестве событий двух фактов: начала и завершения распознавания конструкции, поскольку именно с ними, а не с конструкцией в целом связываются семантические действия. Для обсуждаемой задачи существенно, что события возникают не в произвольном порядке, их множество имеет вполне определенную структуру. Не удивительно, что эта структура в точности соответствует синтаксической структуре текста: например, событие завершения распознавания конструкции не может возникать раньше, чем возникнет событие начала конструкции. Следствием этой структуры является понятие ожидания вполне определенных, а не произвольных событий. Если ожидание не оправдалось, то это можно считать событием еще одного вида: ошибочная ситуация. Количество таких событий в точности равно числу наборов ожидаемых событий. При событийном программировании разделение процессов генерации и обработки событий влечет за собой их полную независимость. В практике программирования транслирующих систем это качество считается не очень удобным, и вместо событийного механизма обычно используется схема сопрограммного взаимодействия с так называемым синтаксическим управлением: синтаксический анализатор сам вызывает нужные семантические программы, когда распознает необходимость сделать это (в событийном стиле это означает генерацию соответствующего события). Нет никакого противоречия между двумя схемами, и единственное различие между ними в том, что при синтаксическом управлении ожидание события оказалось возможным подменить прямым вызовом подпрограммы. Иными словами, в схеме трансляции удается статически, до выполнения программы вычислить события, наступление которых требует вызова их обработчиков (семантических подпрограмм). Вообще, сопрограммное взаимодействие можно трактовать как статически вычисленную событийность). Разумеется, рамки событийного программирования много шире тех случаев, когда можно статически определять необходимость активизации обработчика. Полезно объединение генерации событий с их обработкой, и за счет него можно растворять события в программе. В частности, и по этой причине следует рассматривать событийное программирование как самостоятельный стиль. Но интересны и такие случаи, когда объединение, хотя и возможно, но не делается. Конкретный пример - XML/XSL технология, для которой разделение структуры и интерпретации текста считается принципиальным: это позволяет строить съемные системы обработки, иметь несколько независимых таких систем для разного назначения. В своей сфере применения многовариантность имеет большие преимущества, но, как всегда, перенос принципов данной технологии куда угодно чреват уже не раз отмеченной неадекватностью. Программирование от приоритетов Обсуждая событийное программирование, мы упомянули о том, что при программировании в этом стиле может возникнуть потребность в упорядочивании выполнения нескольких конкурирующих между собой реакций на события. Достаточно универсальным средством удовлетворения этой потребности является приписывание реакциям приоритетов: сначала выполняются те реакции, которые имеют больший приоритет. Этот прием, как выявилось на практике, пригоден для решения достаточно широкого круга задач. Он стал основой для формирования самостоятельного варианта событийного стиля: программирования от приоритетов. Данный стиль порождена практическими потребностями. Она предназначена для организации работы многих взаимодействующих процессов, динамически порождаемых и исчезающих. Фундаментальных теоретических исследований в области программирования от приоритетов почти нет. В частности, в классической работе Хоара [29], в которой рассматривается управление взаимодействующими процессами, предполагается, что программа написана в традиционном структурном стиле и никаких попыток приспособить ее к обстановке, где имеется много процессов, нет2). Стиль программирования от приоритетов не реализован систематически в виде законченного языка (в качестве некоторой попытки можно привести проект Joule, см. http://www.agorics.com/Library/joule.html), но часто используется в прикладных языках скриптов для управления процессами или событиями либо в распределенных системах, либо на полуаппаратном уровне (так называемые встроенные программы, являющиеся частью специализированного прибора или устройства). В программировании от приоритетов, как и в сентенциальном программировании, порядок расположения операторов в программе не играет принципиальной роли, зато важен приоритет оператора, то есть некоторое значение, принадлежащее в самом общем случае частично-упорядоченному множеству и почти всегда рассматриваемое как элементарное. После завершения очередного оператора среди оставшихся выбирается оператор с максимальным приоритетом. Если таких операторов с равными или несравнимыми приоритетами несколько, то, вообще говоря, в идеале надо было бы выбирать один из них недетерминированно. Об операторах, имеющих приоритеты, можно говорить, когда программирование от приоритетов реализовано в специально предназначенном для этого стиля языке. Если же приходится моделировать программирование от приоритетов в обычном языке, то в качестве таких операторов могут выступать иные структурные единицы текста программы. В объектно-ориентированном языке, как правило, это методы объектов. При назначении приоритетов важно различать случаи, когда они задаются для операторов как элементов текста программы и когда приоритеты вводятся для динамических структурных единиц, то есть для тех элементов процесса вычислений, которые возникают в ходе выполнения программы, но связаны с тем или иным оператором, приоритет которого определяется в рамках конкретного экземпляра (например, объекта). Таким образом выстраиваются разные системы приоритетов, причем во втором случае система приоритетов вынужденно оказывается динамической. На практике обычно используют жесткую дисциплину, базирующуюся на порядке операторов в программе. Часто управление по приоритетам соединяется с так называемой системой демонов, то есть процедур, вызываемых при выполнении некоторого условия, а не в тот момент, когда при движении по тексту программы мы подошли к их явному вызову (сидит такой демон в засаде и выжидает момент, когда можно будет начать исполняться). И текущий <нормальный> процесс, и проснувшиеся демоны имеют свои приоритеты, и демон начнет исполняться, даже если он активизирован, лишь в том случае, если среди активных не осталось процесса с большим, чем у демона, приоритетом. Эта схема реализована, в частности, в системе UNIX. Уместно отметить, что событийно-ориентированное программирование порою может рассматриваться как вырожденный случай стиля программирования от приоритетов: для каждого экземпляра структурной единицы, способной реагировать на события, выставляется (бесконечно большой) приоритет, если этот экземпляр фактически должен активизировать реакцию, и не выставляется приоритет (выставляется бесконечно малый приоритет), если экземпляр не должен реагировать на событие. Общий случай стиля событийно-ориентированного программирования также близок к стилю программирования от приоритетов, если считать, что всем обработчикам события, которые должны быть выполнены при его появлении, присвоены приоритеты, соответствующие фактическому порядку их выполнения. Когда такой порядок неизвестен, можно считать, что всем активизируемым обработчикам присвоены равные приоритеты. Кардинальное различие между программированием от событий и от приоритетов состоит в принципах задания управления. В случае программирования от событий установлена прямая связь между событием и реакцией: если условие срабатывания открывает для обработчика возможность быть выполненным, то он обязательно будет выполнен в ответ на соответствующее событие. При программировании от приоритетов ситуация иная: задавая демону даже наивысший приоритет, можно лишь надеяться на то, что он сработает раньше других, причем, возможно, даже без появления какого бы то ни было события. Если абстрагироваться от механизма управления при оперировании с приоритетами и событиями, то можно считать эти два стиля вариантами одной сущности. Варианты событийного программирования от событий и приоритетов хорошо совмещаются, взаимно дополняя друг друга, когда целесообразна следующая архитектурная схема разработки программного проекта. От событий строятся фрагменты системы, которые отвечают за реакцию на каждое из событий, реализуемую разными обработчиками, а программирование этих обработчиков ведется от приоритетов. Рассмотрим написанный в двух вариантах на двух условных языках пример программы с приоритетами. 3: Цикл пока не будет все сделано { 5: Подготовка данных; 10: Обработка текущих изменений; } 4: Демон {Если Поступили данные То {Прием рутинных данных}; 8: Демон {Если Поступили экстренные данные То Запоминание экстренных изменений}; 12: Демон {Если Авария То Аварийные действия}; Пример 13.2.1. a: PRIO 3 {Prepare Data; SLEEP}; b: PRIO 10 {Process Changes; SLEEP}; c: PRIO 8 DAEMON IF Extra Data THEN Store Extra Data; AWAKE b FI; d: PRIO 12 DAEMON IF Alert THEN Emergency; FI; e: PRIO 2 DAEMON IF Idle THEN AWAKE a; FI; Пример 13.2.2. Видно, что в данном примере все приоритеты задавались статически. Именно к этому стремятся почти во всех случаях современной практики вычислений с приоритетами. Однако полной статичности можно добиться лишь в простейших случаях. Например, если процесс долго ждет своей очереди на исполнение, то естественно постепенно поднимать его приоритет. При этом приоритет такого <пользовательского> действия может превзойти приоритет системного процесса, и остается либо статически задавать каждому процессу допустимый максимальный приоритет, и мы вновь попадаем в ту же ловушку, либо задавать разным классам процессов приоритеты, просто не сравнимые по порядку, чтобы ни при каком нормальном исполнении приоритет пользовательского процесса не дорос, скажем, до 109, за которым начинаются приоритеты срочных системных демонов. Заметим, что назначение приоритетов операционной системой, <сверху>, принципиально ничего в данной картине не меняет. С точки зрения пользовательских программ эти приоритеты все равно статические. Рассмотрим теоретически, какие классы программ можно описать при помощи статических и динамических приоритетов. Оказывается, при помощи статических приоритетов, являющихся натуральными числами, невозможно описать даже примитивно-рекурсивные композиции исходных действий3). Таким образом, концептуально натуральных чисел недостаточно для описания приоритетов, но оказывается, что для них хватает ординалов (см. курс математической логики). Поскольку ординалы до ?0 имеют хорошую вычислительную модель, можно рассматривать целочисленные приоритеты как конкретную реализацию абстрактного класса таких ординалов. В случае реально распределенных или параллельных действий проблема приоритетов еще важнее и сложнее. Часто управление по приоритетам - единственный шанс справиться со сложностью такой нелинейной во времени системы. Тут уже и линейно упорядоченного множества приоритетов не хватает. В целом программирование от приоритетов является мощным, но специфическим орудием для описания глобальных совместных, параллельных или распределенных процессов. Его элементы проникают и в традиционные системы программирования в виде обработки исключительных ситуаций в программах. Здесь, как и в программировании от событий с обособленными реакциями, всего два приоритета, которые налагаются на структуру использующей конструкции. Противоречивость этого средства со структурным программированием только в том, что не всегда ясно, что делается далее, когда обработка исключения завершается. 1) Статическое вычисление некоторых частей программ - очень важный и имеющий в потенциале исключительно широкую область применения прием программирования. Если программист предусматривает, что его программа будет частично вычислена до основного выполнения программы, то он следует еще одному стилю - специализирующему программированию. 2) По этой причине область применения языка OCCAM, непосредственно реализующего идеи Хоара, оказалась неоправданно суженной до тех ситуаций, когда процессы жестко привязаны друг к другу статически описываемыми каналами передачи данных. 3) Правда, здесь мы отвлекаемся от реальных ограничений и считаем 1010000000000 столь же легко достижимым числом, как и 10. Понятия: событие (event), реакция (reaction), переменные (vars). В основу концепции управления объектами легла концепция "событийной управляемости" - объектами управляют события, с ними происходящие. Все очень просто - происходит какое-то событие и объект как-то на него реагирует. Собственно говоря, этот механизм мы наблюдаем в Windows: есть сообщения, очередь сообщений и, соответственно, обработчики сообщений. В нашем случае мы сами строим свой Windows - определяем сколько и какие сообщения будут у нас в движке и, соответственно, сколько и какие обработчики этих сообщений (естественно, у нас все это получится намного красивее и элегантее нежели в Windows ;-) События и обработчики событий являются очень важной частью для программирования. События, главным образом, инициируются теми или иными действиями пользователя. Если он щелкает по некоторой кнопке, происходит событие "Click". Если указатель мыши пересекает какую-либо ссылку гипертекста - происходит событие MouseOver. Существует несколько различных типов событий. Мы можем заставить нашу JavaScript-программу реагировать на некоторые из них. И это может быть выполнено с помощью специальных программ обработки событий. Так, в результате щелчка по кнопке может создаваться выпадающее окно. Это означает, что создание окна должно быть реакцией на событие щелка - Click. Программа - обработчик событий, которую мы должны использовать в данном случае, называется onClick. И она сообщает компьютеру, что нужно делать, если произойдет данное событие. Приведенный ниже код представляет простой пример программы обработки события onClick:
Модель событий в JavaScript 1.2: onEvent Abort Focus MouseOut Submit Blur KeyDown MouseOver Unload Click KeyPress MouseUp Change KeyUp Move DblClick Load Reset DragDrop MouseDown Resize Error MouseMove Select Событие (Event) - некоторое событие, произошедшее во внутренней системе движка. Примеры: ON_INIT - событие, вызываемое при инициализации объекта, ON_FRAME - событие, вызываемое каждый кадр, ON_HIT - при попадении в объект, ON_DESTROY - при уничтожении объекта и пр. То есть, можно определить сколь угодно много и любого рода события в своей системе. Так как объект может как-то реагировать на поступившее событие, то у нас появляется еще одно определение: - Реакция (Reaction) - определенное действие или набор действий, которые совершит объект при наступлении определенного события. Примеры: movDIRECTION - двигать объект в заданном направлении, setFOGCOLOR - изменить цвет тумана, getSPF - получить значение внутренней пременной движка, хранящей значение количества секунд в кадре, пр. Также очевидно, что количество реакций может быть неограничено и определяется в зависимости от требуемого уровня функциональности движка. Ведем третье определение, неотрывно связанное с понятием реакции: - Переменные (Vars) - это набор значений, являющихся как параметрами для реакций, так и отдельными наборами данных. К примеру: setFillColor (0,255,255) - в данном случае три значения переменных 0, 255 и 255 являются параметрами к реакции SetFillColor, устанавливающей цвет заливки, cmpVARNUMBER (R,V,N,c,J) - переменные являются параметрами функции сравнения пременной с числовым значением, var (4,100,200, 5, 17) - пременная 2 определяет, что реакция var определяет собой массив из четырех элементов - 100, 200, 5 и 17. Подытожив, можно сказать, что переменные это набор параметров рекций. Причем, некоторые реакции могут вовсе не иметь переменных (к примеру реакция, останавливающая игру при нажатии на любую клавишу), другие же могут содержать переменные по количеству требующихся реакции параметров, иные реакции, определяющие скопление данных, могут содержать большие массивы переменных. Также запомним одну важную особенность переменных - их можно изменять. Скрипты - это набор некоторых действий, выполняемых ВМ в зависимости от некоторых факторов. В качестве простого примера: при приближении игрока открываются ворота базы. Или более сложный пример: при неотключеной сигнализации при попытке открыть дверь срабатывает сирена. Во всех современных играх используется механизм скриптования игровых сцен. Вспомнить хотя бы Half-Life с его падающим шкафом при приближении. Применение скриптов достаточно широко - от изменений свойств игровых объектов и внутренних переменных до написания псевдопрограммного кода. То есть, с помощью скриптов можно не только изменять положение, наклон, скорость и прочие характеристики игровых объектов, но и изменять внутренние пременные игрового движка (к примеру, изменение плотности тумана в зависимости от времени суток с изменением заднего плана отсечения объектов или плавное изменение освещения всей сцены). Также хочется обратить особое внимание на создание скриптовых программ, являющихся по сути набором простых действий, которые выполняет движок. Становится понятно, что можно строить довольно сложные конструкции, что позволит обеспечить лучшую играбельность. Скрипт-программы обладают достаточными возможностями для изменения, сравнения внутренних переменных, а также реализацию условных и безусловных переходов, циклов, пр. Скрипт-программы как бы являются гибкой надстройкой над движком. Предоставляя скрипт-программам определенные "полномочия" по управлению движком можно добиться потрясающих эффектов. Становится легче организовывать модульность игрового движка - т.е. достаточно переопределить скрипты для объектов и получается полностью! другой сценарий, а возможно даже другой игровой мир - все зависит от сложности script-engine. Таким образом, имея один движок и сложную систему скриптов, можно создавать различные модификации игры, просто переписывая скрипт-программы. Естественно, что когда у игры появляются модификации, это продливает срок ее жизни, показывает, что игра не исчезла бесследно. Объект Event. В язык JavaScript 1.2 добавлен новый объект Event. Он содержит свойства, описывающие некое событие. Каждый раз, когда происходит какое-либо событие, объект Event передается соответствующей программе обработки. В примере на экран выводится некое изображение. Вы можете щелкнуть где-нибудь над ним клавишей мыши. В результате появится окошко сообщений, где будут показаны координаты той точки, где в этот момент находилась мышь. Код скрипта: Объект Event получил следующие свойства: Свойство Описание data Массив адресов URL оставленных объектов, когда происходит событие DragDrop. layerX Горизонтальное положение курсора (в пикселах) относительно слоя. В комбинации с событием Resize это свойство представляет ширину окна браузера. layerY Вертикальное положение курсора (в пикселах) относительно слоя. В комбинации с событием Resize это свойство представляет высоту окна браузера. modifiers Строка, задающая ключи модификатора - ALT_MASK, CONTROL_MASK, META_MASK или SHIFT_MASK pageX Горизонтальное положение курсора (в пикселах) относительно окна браузера. pageY Вертикальное положение курсора (в пикселах) относительно окна браузера. screenX Горизонтальное положение курсора (в пикселах) относительно экрана. screenY Вертикальное положение курсора (в пикселах) относительно экрана. target Строка, представляющая объект, которому исходно было послано событие. type Строка, указывающая тип события. which ASCII-значение нажатой клавиши или номер клавиши мыши. x Синоним layerX y Синоним layerY Перехват события Одна из важных особенностей языка - перехват события. Если кто-то, к примеру, щелкает на кнопке, то вызывается программа обработки события onClick, соответствующая этой кнопке. С помощью обработки событий Вы можете добиться того, чтобы объект, соответсвующий вашему окну, документу или слою, перехватывал и обрабатывал событие еще до того, как для этой цели объектом указанной кнопки будет вызван обработчик событий. Точно так же объект вашего окна, документа или слоя может обрабатывать сигнал о событии еще до того, как он достигает своего обычного адресата. "Кликните" по этой ссылке. Как видно, мы не указываем программы обработки событий в тэге . Вместо этого мы пишем window.captureEvents(Event.CLICK); с тем, чтобы перехватить событие Click объектом window. Обычно объект window не работает с событием Click. Однако, перехватив, мы затем его переадресуем в объект window. Заметим, что в Event.CLICK фрагмент CLICK должен писаться заглавными буквами. Если же Вы хотите перехватывать несколько событий, то Вам следует отделить их друг от друга символами |. Например: window.captureEvents(Event.CLICK | Event.MOVE); Помимо этого в функции handle(), назначенной нами на роль обработчика событий, мы пользуемся инструкцией return true;. В действительности это означает, что браузер должен обработать и саму ссылку, после того, как завершится выполнение функции handle(). Если же Вы напишете вместо этого return false;, то на этом все и закончится. Если теперь в тэге Вы зададите программу обработки события onClick, то поймете, что данная программа при возникновении данного события вызвана уже не будет. И это не удивительно, поскольку объект window перехватывает сигнал о событии еще до того, как он достигает объекта link. Если же Вы определите функцию handle() как function handle(e) { alert("Объект window перехватывает это событие!"); window.routeEvent(e); return true; } то компьютер будет проверять, определены ли другие программы обработки событий для данного объекта. Переменная e - это наш объект Event, передаваемый функции обработки событий в виде аргумента. Кроме того, Вы можете непосредственно послать сигнал о событии какому-либо объекту. Для этого Вы можете воспользоваться методом handleEvent(). Это выглядит следующим образом: "Кликните" по этой ссылке
Вторая ссылка Все сигналы о событиях Click, посылаются на обработку по второй ссылке - даже если Вы вовсе и не щелкнули ни по одной из ссылок! Следующий скрипт демонстрирует, как Ваш скрипт может реагировать на сигналы о нажатии клавиш. Нажмите на какую-либо клавишу и посмотрите, как работает этот скрипт. За последние несколько лет технология разработки программ претерпела изменения - визуальное программирование, - событийная логика программы, - компонентная технология, - использование макросредств и пр., что должно было бы отразиться на методике обучения; И схема "типичного пути начинающего программиста: Бейсик Х Паскаль Х Си++ Х программирование под Windows", при всей своей несовременности является весьма характерной. курс CS101, "ведение в программирование". Изучение механизмов исполнения алгоритмов по привычной уже последовательной модели "один поток команд - один поток данных" приводит к формированию стереотипа, от которого впоследствии бывает трудно избавиться. Отлаженную программу оценивают по результатам ее выполнения - а как же еще? Шествуя по этой натоптанной дорожке, преподаватели часто предлагают студентам воспринимать появление феномена Java как "вариации на тему C++". "Если же вы хотите, чтобы уже первые курсовые стали такими маленькими шедеврами, как клиент-серверные приложения или сетевые варианты динамичных видеоигр, то от родной методики старого варианта CS101 придется отказываться",- утверждает Линн Стайн. Итак, долой старый добрый текстик "Hello, world!"; его место занимает не менее крохотный, однако возмутительно зацикленный while (true) { echo(); }. В реальных программах сегодня приходится иметь дело с явно или неявно взаимодействующими (конкурентными) компонентами; именно их взаимодействие составляет суть работы программы. Результатом становится не вывод на экран числа или текста, мультимедийных окошек - нужное подчеркнуть, а непрерывный процесс связи с миром, внешним по отношению к программе. Именно этот внешний мир управляет поведением программы, а не одна только воля программиста. Концептуальные основы технологий программирования, основанных на событийной логике и работе взаимодействующих компонентов. "Раньше в изложении техники программирования мы действовали так, как будто требовалось обучить марсианина искусству приготовления сэндвичей; теперь же начинающему программисту предлагается роль режиссера или предпринимателя. Результат твоей работы - не сэндвич в одном экземпляре, а работоспособный бизнес или пьеса, идущая без накладок". Cобытийно-ориентированное программирование получает все большее распространение. Основная его специфика - инициатива принадлежит не самой программе, а внешнему миру, на события которого программа реагирует. Чаще всего событийно-ориентированное программирование связывают с объектно-ориентированным программированием, поскольку концепция объекта идеально подходит для работы с событиями. Тем не менее, существует множество случаев, когда оправдано событийно-ориентированное программирование без использования объектов, так и использование объектов для обычных (не событийных) программ. И если обычный алгоритм - "последовательность команд, понятных исполнителю", то обработка событий описывается набором последовательностей команд, выполняемых при наступлении внешних по отношению к ней событий, время и последовательность наступления которых, как правило, заранее не известны и могут отличаться от запуска к запуску. Очевидно, что подходы к решению задач в этих стилях кардинально различаются. Так же, как различаются и задачи, для которых они применимы. Попробуем определить, по каким признакам следует их различать. Приведем также несколько примеров задач, лучше всего решаемых как с событийным программированием, так и без него. Программа, для написания которой событийного программирования не требуется, обычно занимает всё предоставленное ей время процессора и движется от своего начального состояния (переданные ей при запуске параметры, входные файлы, текущие настройки), меняя "направление движения" лишь в исключительных случаях (ошибка ввода-вывода, неверные исходные данные, досрочное завершение пользователем её работы). Характерными примерами являются консольные архиваторы, компиляторы, и т.д. Если же программа большую часть времени находится в состоянии ожидания действий пользователя (или других не зависящих от неё событий) и число различных событий велико, то естественно написать её с использованием событийного программирования. Так, например, программа, управляющая работой проигрывателя компакт-дисков, должна обрабатывать как события нажатий на кнопки, событие изменения положения регулятора громкости, так и события, поступающие от проигрывателя: окончание песни, окончание диска и нажатия кнопок на проигрывателе. Для получения и распределения событий требуется менеджер событий, который уже есть в некоторых языках программирования (например, JAVA) или системах разработки (Delphi), в иных напротив, его требуется написать самостоятельно. Работа с событиями близка идеям объектно-ориентированного программирования, и сейчас практически везде, где требуется обработка событий, используются объекты. В настоящий момент подавляющее большинство пользовательских программ пишется именно с применением событийного объектно-ориентированного программирования. В качестве примера достаточно рассмотреть систему программирования Delphi, где всё несобытийное программирование скрыто от программиста. Тем не менее, сейчас событийное программирование изучается неоправданно поздно. Обычно сложность состоит не в принятии нового стиля программирования, а в переучивании и ломке устоявшихся стереотипов. Можно найти множество примеров событийно-ориентированного программирования, для понимания которых не требуется никаких специальных знаний в области информатики. Так, программа работы вахтера (записи в журнале при начале и окончании работы, проверка документов входящих, периодический обход здания) естественным образом формируется в терминах событийного программирования. Таким образом, существует потребность в обучающей среде, в которой событийное программирование было бы естественным и проводилось в игровой форме, подобно тому, как проводится оно в пакете "роботландия". Возможным вариантом такой среды может быть моделирования некого полигона, где проходят испытания роботы, цель которых - самосохранение и достижение некоторой цели (сбор предметов, конкуренция друг с другом, размножение). Ближайшей аналогией будет игра "бой в памяти" и целый класс аналогичных игр, отличиями будут язык программирования (высокого уровня, не такой, как абстрактный ассемблер в "бое") и внешнее по отношению к роботам обслуживание событий, должно существенно упростить программы для них и сделать среду пригодной для обучения на начальных этапах. Перенос знакомства с событийно-ориентированным программированием на начало изучения алгоритмизации должен способствовать его усвоению без необходимости переучиваться и ломать свои стереотипы.