PDA

Просмотр полной версии : Event Listerer Viewer существует?


MidnightOne
25.04.2010, 22:51
Добрый вечер.
Столкнулся с проблемой. У меня около 2,5 тысяч строк кода, а сегодня я сделал большое нововведение. Теперь не знаю какие ивент лиснеры висят, а какие - нет.

Вопрос: Существует-ли что-то, что может показать список всех добавленных лисенеров в рантайме? (динамически)

Буду очень признателен.

BlooDHounD
25.04.2010, 23:08
это Вы про профайлер?

Nirth
25.04.2010, 23:11
Я кстати недавно написал утилитку, для работы с событиями в functional style, может показатся слегка нестандартным подходом, если не разу не видели haskell/erlang/scala/scheme/ocaml, но работает (внизу статьи):
http://blog.kiichigo.eu/?p=201

BlooDHounD
25.04.2010, 23:15
Nirth, меня в ней смутило:...
protected function listen( closure:Function ):void
{
closure.addEventListener( Event.COMPLETE, handleComplete );
...
closure у тебя Function. но у типа Function нету addEventListener.

Добавлено через 1 минуту
и собственно передаёшь ты потом в listen именно addEventListener. в общем если так и надо, то я ничего не понял.

Добавлено через 3 минуты
и ещё не очень ясно с методом handle. handleComplete, handleStatus и т.д.

Nirth
25.04.2010, 23:40
Я обновил код на всякий случай:
/*
The MIT License

Copyright (c) 2010 David Sergey, nirth@fouramgames.com, nirth.furzahad@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package kii.utils
{
public function listen( closure:Function, ...rest:* ):void
{
var i:uint = 0;
var l:uint = rest.length;
var args:Array = [];

if( rest[l - 3] is Boolean )
args = rest.splice( -3, 3 );
else if( rest[l - 2] is Boolean )
args = rest.splice( -2, 2 );
else if( rest[l - 1] is Boolean )
args = rest.splice( -1, 1 );

log( 'args:', args );
if( closure.length == 3 && args.length > 1 )
args = [args[0]];

if( rest[0] is Function )
var handler:Function = rest.shift();

if( handler as Function ) //We assuming that all Events have one Handler
for( i = 0; i < rest.length; i ++ )
closure.apply( null, [ rest[i], handler ].concat( args ) );
else //Else we asume that arguments are passed in a way [event, handler, event, handler]
for( i = 0; i < rest.length; i += 2 )
closure.apply( null, [rest[i], rest[i + 1]].concat( args ) );
}
}

/*
The MIT License

Copyright (c) 2010 David Sergey, nirth@fouramgames.com, nirth.furzahad@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package kii.utils
{
import flash.events.IEventDispatcher;
/**
*
* @example
* <code>
* var listen:Function = switcher( this, handle, FlexEvent.CREATION_COMPLETE, FlexEvent.PREINITIALIZE, FlexEvent.INITIALIZE );
listen( true ); //Adds listener "handle" to CREATION_COMPLETE, PREINITIALIZE, INITIALIZE events
listen( false ); //Removes them
//Or
var listen:Function = switcher( this, FlexEvent.CREATION_COMPLETE, handleCreationComplete,
FlexEvent.PREINITIALIZE, handlePreInitialize,
FlexEvent.INITIALIZE, handleInitialize,
false, 0, true ); //capture = false, priority = 0, weakReference = true
listen( true ); //Adds handleCreationComplete => CREATION_COMPLETE, handlePreInitialize => PREINITIALIZE etc.
listen( false ); //Removes them
*/
public function switcher( dispatcher:IEventDispatcher, ...rest ):Function
{
return function( add:Boolean ):void
{
if( add )
listen.apply( null, [dispatcher.addEventListener].concat( rest ) );
else
listen.apply( null, [dispatcher.removeEventListener].concat( rest ) );
};
}
}

listen принимает первым параметром removeEventListener или addEventListener (в зависимости от, того хочешь ли ты добавить или удалить события.
После первого параметра, можно передавать аргументы либо:
Функция, Событие, Событие, Событие ...
Либо
Событие, Функция, Событие, Функция ...

Первый вариант подписывает 1 хендлер, для всех событий. Второй делает индивидуальные хендлеры для сабытий.
[as3]listener( addEventListener, 'complete', myCompleteHandler, 'error', myErrorHandler' ); //подпишет myCompleteHandler( event:Event) под complete событие и тд.
listener( addEventListener, universalHandler, 'complete', 'error' ); //подпишет один хендлер под оба события.

Последний 1-3 параметра могут быть в формате Boolean | Boolean, Number | Boolean, Number, Boolean собственно это для bubbles, priority, weakReference параметров.

Функция свитчер, вместо метода, берет первым аргументром экземпляр IEventDispatcher, и возвращает метод, если аргумент true то будет использоватся IEventDispatcher.addEventListener, если false то IEventDispatcher.removeEventListener.

Вобщем это может выглядеть как функциональное вуду, но за 3 месяца работы со Скалой и две недели с Эрлангом с таким даже привычней работать, чем с чистым ООП ^_^.

i.o.
26.04.2010, 09:25
Nirth, код какой-то индусский. Поясняю:
Что это за такое свойство length у функции?? У вас динамические функции на входе что ли?
closure.length == 3
Потом непонятно почему в условии стоит as вместо is
if( handler as Function )
Потом switcher возвращает функцию, которую нужно обязательно тоже вызвать и передать true или false. Что нельзя сразу после или перед dispatcher:IEventDispatcher вставить add:Boolean ??
Есть еще одно сомнительное место:

if( rest[l - 3] is Boolean )
args = rest.splice( -3, 3 );
else if( rest[l - 2] is Boolean )
args = rest.splice( -2, 2 );
else if( rest[l - 1] is Boolean )
args = rest.splice( -1, 1 );

Идет сразу проверка rest[l - 3] без проверки длины массива, а что если rest.length == 2? Нехорошо обращаться к элементу с индексом -1.

orcpochta
26.04.2010, 09:45
это Вы про профайлер?

что такое профайлер? зачем он нужен и с чем его едят? :)

Nirth
26.04.2010, 11:16
@i.o.
Nirth, код какой-то индусский.
Расизм это не признак присутствия интеллекта если что ^_^.
Дальнейшие ваши ремарки тоже не убеждают меня в том, что у вас IQ хотя бы выше 115.

Приятной жизни ^_^

СлаваRa
26.04.2010, 11:17
Что это за такое свойство length у функции??
Вы не знаете, что у функции есть это свойство?

Идет сразу проверка rest[l - 3] без проверки длины массива, а что если rest.length == 2? Нехорошо обращаться к элементу с индексом -1.
а с чего будет обращение к индексу -1? эта конструкция будет false.

i.o.
26.04.2010, 11:50
Про интеллект тут речи не шло, я высказал всего лишь свое мнение с пояснением. Прошу извинить меня, если кого оскорбил.
Что это за такое свойство length у функции??
Да, не знал, как выяснилось, это недокументированное свойство.
а с чего будет обращение к индексу -1? эта конструкция будет false.
Как это с чего??
Если rest.length == 2, то l = 2, следовательно 2-3 = -1, следовательно при первой проверке будет rest[-1]. Теперь понятно почему -1??

И еще хотелось бы узнать почему
if( handler as Function )

Nirth
26.04.2010, 14:02
Прошу извинить меня, если кого оскорбил.
Ок, забыли.

И еще хотелось бы узнать почему

Игнорируем первый параметр ( closure:Function ).
Метод listen принимает параметры двумя шаблонами: первый это:
хэндлер, событие1, событие2, событие3 – в этом случае, для всех событий будет один обработчик. Этот обработчик if..if else..else или switchem уже разбертся, что и куда.
второй это:
событие1, хендлер1, событие2, хендлер2 и тд.

if( rest[0] is Function )
var handler:Function = rest.shift();
Это краткая запись (shortcut) для записи:

var handler:Function;
if( rest[0] is Function )
handler = rest.shift();
То есть, если первый парметр функция, то мы сносим первый элемент из массива rest, и передаем его, переменной handler.

Далее мне нужно проверить, назначено ли что либо в handler, я могу сделать это через handler == null, handler === null, handler, handler is Function, handler as Funcition.
handler == null, handler === null, и просто handler в if блоке выдаст мне Warning (при компиляции mxmlc ). Чтобы держать код чистым, я могу использовать либо as или in конструкцию. То есть я хочу построить условие
Если ( переменная хендлер определенна ) { делай вот это } так как я ранее. Я мог бы использовать is в обоих случаях, но так как контекст очень похож ( if блок ) использовать разные конструкции является более правильным решением, так как хоть они и похожи по результату, это различные действия. Если бы контекст был разный (например один if блок а другой цикл) то применение is было бы приоритетней.

Psycho Tiger
26.04.2010, 15:28
log( 'args:', args );
А что есть log? Функция в твоём пакете?

Я мог бы использовать is в обоих случаях, но так как контекст очень похож ( if блок ) использовать разные конструкции является более правильным решением, так как хоть они и похожи по результату, это различные действия. Если бы контекст был разный (например один if блок а другой цикл) то применение is было бы приоритетней.
Объясни почему. Это хороший стиль программирования или что?

Nirth
26.04.2010, 16:13
@Psycho Tiger
Да это нечто вроде trace, в моем пакете, для быстрого логгирования.

Объясни почему. Это хороший стиль программирования или что?
Это семантическая заметка. Ну представь себе предложение:
Я пошел в магазин, потом я отправился в аэропорт.
В обоих случаях ты куда то вдигаешься, то есть выполняешь два одинаковых действия, но цели совсем разные. Поэтому мы используем синонимы, вместо использования одного слова (отправился в магазин, отправился в путешествие тоже грамматически правильно сказать, но менее понятно, и стилистически не правильно). В моем случае я проводил 2 действия, и поэтому решил отметить это другим "выражением-синонимом".

Psycho Tiger
26.04.2010, 18:30
Хм, если честно не понимаю толка от этого, наоборот, если по запарке просматриваешь код и однотипные действия (а нам и там и там нужно лишь проверить принадлежность к типу) и операторы пляшут можно выпасть в ступор ненадолго, а там и мысль потерять, что же ты хотел сделать =). На данном этапе своего развития придерживаюсь мнения, что однотипные действия должны быть сделаны однотипно, если это вменяемо (т.е. нет явного ущерба производительности, нет хаков и т.д.).