Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 1.0/2.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 22.10.2006, 04:11
Ромастый вне форума Посмотреть профиль Отправить личное сообщение для Ромастый Найти все сообщения от Ромастый
  № 1  
Ответить с цитированием
Ромастый
 
Аватар для Ромастый

Регистрация: Jan 2004
Адрес: На чердаке.
Сообщений: 1,112
По умолчанию Перехват и исполнение

Как-то, еще давным-давно в эпоху mx2004, встала задача перехватывать вызов нужных методов каких-либо объектов, без того, чтобы прописывать в них бродкасты.
Набросал такой вот класс:
Код:
import mx.events.EventDispatcher;
import mx.utils.Delegate;
//
class EventInterceptor {
	var _targ = new Object();
	var _func:Function;
	var _func_name:String;
	private var dispatchEvent:Function;
	public var addEventListener, removeEventListener:Function;
	var onEvent:Function;
	//
	function EventInterceptor() {
		EventDispatcher.initialize(this);
		this.addEventListener("onEvent", this);
	}
	//
	public function intercept(obj:Object, func:String):Void {
		if (_targ && _func) {
			dismiss();
		}
		_targ = obj;
		_func_name = func;
		_func = obj[func];
		_targ[func] = Delegate.create(this, executeEvent);
	}
	//
	public function dismiss():Void {
		_targ[_func_name] = _func;
	}
	//
	private function executeEvent():Void {
		_func.apply(_targ, arguments);
		dispatchEvent({type:"onEvent", target:_targ, event:_func_name});
	}
}
Жуткий гибрид Делегата и ЕвентДиспетчера. Хых.. Написал и забыл.

Не так давно была тема по динамическому добавлению/удалению действий, к примеру, в onEnterFrame без полного переписывания.
Решил поэкспериментировать.
К примеру есть на сцене 2 клипа: mc1 и mc2
Код:
mc1.move = function() {
	this._x += 20;
};
mc1.onEnterFrame = function() {
	this.move();
};

EI1 = new EventInterceptor();
EI1.intercept(mc1, "move");
EI1.onEvent = function(evt_obj) {
_root.mc2._x += 2;
trace("1: "+this+"   "+evt_obj.target+"  "+evt_obj.event);
};
//
EI2 = new EventInterceptor();
EI2.intercept(mc1, "move");
EI2.onEvent = function(evt_obj) {
_root.mc1._y += 2;
trace("2: "+this+"   "+evt_obj.target+"  "+evt_obj.event);
};
//
EI3 = new EventInterceptor();
EI3.intercept(mc1, "move");
EI3.onEvent = function(evt_obj) {
_root.mc2._y += 2;
trace("3: "+this+"   "+evt_obj.target+"  "+evt_obj.event);
};
Плюсы такого подхода:
Экземпляры интерсептора перехватывают вызов метода move, и выполняют свои действия. Все ок.

Но. Минусы:
1. Все перехваты осуществляются последовательно, а не независимо. То есть следующий интерсептор перехватывает не mc1.move, как казалось бы, а делегат предыдущего.
2.Вытекает из первой. Если мы удаляем предыдущий перехватчик, то и следующий за ним тоже перестает работать.

Вопрос: может кто делал что-то подобное и как-то еще решал такую задачу?
__________________
...Тебе страшно? Мне - нет.

Старый 22.10.2006, 14:48
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 2  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,784
Я долго пытался понять, что ты хочешь сделать и почему нельзя тупо заменить (дать ссылку) move другим методом, а?

Старый 22.10.2006, 21:10
Ромастый вне форума Посмотреть профиль Отправить личное сообщение для Ромастый Найти все сообщения от Ромастый
  № 3  
Ответить с цитированием
Ромастый
 
Аватар для Ромастый

Регистрация: Jan 2004
Адрес: На чердаке.
Сообщений: 1,112
Гм... Наверное привел не очень наглядный пример.
Будем перехватывать не move, а onEnterFrame:
Код:
EI1.intercept(mc1, "onEnterFrame");
EI2.intercept(mc1, "onEnterFrame");
EI3.intercept(mc1, "onEnterFrame");
На исходном onEnterFrame клипа mc1 висит только движение по оси x этого клипа (код в предыдущем посте). Создание трех перехватчиков добавляет еще три движения (по осям y и x обоих клипов). То есть формально мы динамически добавляем в onEnterFrame новые действия без того, чтобы его переписывать.
Но фактически, повторюсь, каждый последующий экземпляр перехватывает не mc1.onEnterFrame, как мы вроде бы написали, а всего лишь предыдущий по цепочке.
Проблемы возникнут, когда мы захотим удалить какое-то действие из onEnterFrame - перестанут работать и все последующие.

Вот и любопытно, какие есть соображения по поводу, как эту дрянь переделать так, чтобы перехваты шли независимо, а не последовательно.
__________________
...Тебе страшно? Мне - нет.

Старый 22.10.2006, 21:17
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 4  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,784
А чем не устраивает подписка/отписка методов на события?
Делаешь мувик вещателем, ставишь на onEnterFrame dispatchEvent({type:'onEnterFrame'}), затем добавляешь mc.addEventListener('onEnterFrame',anyMethod1); и т.д.

Старый 22.10.2006, 21:17
Ромастый вне форума Посмотреть профиль Отправить личное сообщение для Ромастый Найти все сообщения от Ромастый
  № 5  
Ответить с цитированием
Ромастый
 
Аватар для Ромастый

Регистрация: Jan 2004
Адрес: На чердаке.
Сообщений: 1,112
Вообще в свое время EventInterceptor создавался для других целей, как вспомогательный класс.
Но захотелось попробовать его и в таком аспекте. Тогда и столкнулся с вышеописанной проблемой... Есть соображения, как исхитриться это сделать именно в таком варианте, или же только кардинально другим подходом можно?
__________________
...Тебе страшно? Мне - нет.

Старый 22.10.2006, 21:19
Ромастый вне форума Посмотреть профиль Отправить личное сообщение для Ромастый Найти все сообщения от Ромастый
  № 6  
Ответить с цитированием
Ромастый
 
Аватар для Ромастый

Регистрация: Jan 2004
Адрес: На чердаке.
Сообщений: 1,112
Вот. Как раз тогда задача стояла перехватывать вызов любых методов, без инициализации перехватываемых объектов, и вообще любого вмешательства в код извне.
__________________
...Тебе страшно? Мне - нет.

Старый 22.10.2006, 21:24
Ромастый вне форума Посмотреть профиль Отправить личное сообщение для Ромастый Найти все сообщения от Ромастый
  № 7  
Ответить с цитированием
Ромастый
 
Аватар для Ромастый

Регистрация: Jan 2004
Адрес: На чердаке.
Сообщений: 1,112
Поясню, почему это нужно было.
Как один из примеров: в контексте той задачи некоторые объекты могли инициализироваться Диспетчером или другим бродкастером уже после того, как требовалось отслеживать вызов их методов.
Вторая причина наверное носила скорее принципиальный характер. Перехватывать вызов без вмешательства в код. То есть дописывать бродкасты в каждом методе. А их мог быть не один десяток.
__________________
...Тебе страшно? Мне - нет.

Старый 22.10.2006, 21:27
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 8  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,784
Что мешает переназначить onEnterFrame на другой метод и в нём убирать/добавлять вызываемые методы?
Одновременно выполнить все методы на одном событии невозможно в принципе.

Старый 22.10.2006, 21:27
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 9  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
я бы по-простому сделал :
Код:
Object.prototype.addFunc=function(func:String,toAdd:Function){
		if(!this._adds){
			this._adds=[];
			this.naitiveFunc=this[func];
			this[func]=function(){
				this.naitiveFunc();
				for(var i in this._adds)this._adds[i]();
			}
		}
		this._adds.push(toAdd);
}

mc1.move = function() {
	this._x += 20;
};
mc1.onEnterFrame = function() {
		this.move();
	};
mc1.addFunc("move",function(){
		_root.mc2._x += 2;
	});

mc1.addFunc("move",function(){
		_root.mc2._y += 2;
	});

Старый 22.10.2006, 21:52
Ромастый вне форума Посмотреть профиль Отправить личное сообщение для Ромастый Найти все сообщения от Ромастый
  № 10  
Ответить с цитированием
Ромастый
 
Аватар для Ромастый

Регистрация: Jan 2004
Адрес: На чердаке.
Сообщений: 1,112
to __etc: Да в принципе ничего не мешает
Сделать компромиссное решение с тем, что предложил silin.

to silin: про добавление в массив тоже приходила мысля в голову. Правда в этом варианте еще придется отслеживать порядковые номера в массиве, чтобы удалять или перемещать нужные действия.
ТОгда как с независимыми экземплярами интерсептора мы уже сразу имеем прямые ссылки на них.

Так что действительно, тут придется прибегать к компромиссному решению. Оставаясь в контексте исходной задачи (не меняя исходный код и не делая перехватываемый объект вещателем) вешать на одно событие (или метод) один перехватчик. А уже на onEvent перехватчика - работу по добавлению/удалению действий в массив.
__________________
...Тебе страшно? Мне - нет.

Создать новую тему Ответ Часовой пояс GMT +4, время: 02:51.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 02:51.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.