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

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

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

Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
По умолчанию Какой тип должен возвращать метод, если он должен возвращать разные события (типы)

Помогите, не могу сообразить.
У меня есть кастом событие ServerEvent от которого наследуют другие ивенты ServerTableState, ServerPlayerAction, ServerBadCommand, etc.

Поскольку от сервера приходят XMLи, а компоненты приложения работают с ивентами, я решил сбацать класс XML2Event, который бы получал на входе xml а возвращал бы кастомный ивент, который можно было бы далее диспатчить.

Код AS3:
public class XML2Event
{
 
  public function XML2Event() {		
 
  }
 
  // Какой класс должен быть в объявлении метода вместо Object, 
  // учитывая, что возращаться могут разные ивенты? Object?
  public function parse(obj:Object):Object {
    var event:Object;
    var xml = new XML(obj);
 
    switch(xml.localName()) {
      case("server_state"):
         ...
         event = new ServerTableState(...);
         break;
      case("player_action"):
         ...
         event = new ServerPlayerAction(...);
         break;
      default: // bad command
         ...
         event = new ServerBadCommand(...);
    }
    return(event);
  }
 
}
В общем, как правильно объявить метод - как возвращающей Object, ServerEvent?
И как правильно приводить созданные разные ивенты к типу возращаемого объекта?

Т.е. как правильно написать метод, возвращающий объекты разных классов?

Старый 28.02.2011, 19:10
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 2  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Switch - плохой подход, единственное оправдание использованию switch'a - это оптимизация на низком уровне (как правило при чтении и парсинге данных из потока и т.п.) в энтерпрайз switch противопоказан.
Если нет однозначности, что возвращать из функции - это плохой дизайн. Т.е. это значит, что функция выполняет более одной задачи, либо объекты неправильно типизированы. Такую ситуацию, как у вас можно разрулить например:
Код AS3:
private var typesTable:Object = { "foo": Foo, "bar": Bar };
private var callbacksTable:Object = { "foo": fooCallback, "bar": barCallback };
. . .
function fooCallback(value:Foo):void { . . . }
function barCallback(value:Bar):void { . . . }
function createFromDefinition(type:String):void
{
    callbacksTable[type](new this.typesTable[type]());
}
Таким образом вы "красиво" потеряете один тип, при этом сохранив строгую типизацию.
__________________
Hell is the possibility of sanity


Последний раз редактировалось wvxvw; 28.02.2011 в 19:15.
Старый 28.02.2011, 19:34
zhoran вне форума Посмотреть профиль Отправить личное сообщение для zhoran Найти все сообщения от zhoran
  № 3  
Ответить с цитированием
zhoran

Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
Идея понятна, но как-то не полностью что-ли.
Из сокета приходят xml разной степени сложности. Надо где-то разместить код, который будет их рабирать, формировать структуры данных, которые нужно передавать дальше разным компонентам UI. Вы предлагаете где этот кусок расположить?

вот, к примеру:
Код AS3:
case("player_action"):
    var action:String = xml.@action;
    var amount:Number = xml.@amount;
    event = new ServerPlayerAction(action, amount);
    break;


Последний раз редактировалось zhoran; 28.02.2011 в 19:54.
Старый 28.02.2011, 19:51
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 4  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Я бы делал так:
список классов-сообщений: MessageA, MessageB... MessageZ, все наследуются от Message
у каждого есть метод clone(from:XML):Message который читает содержание из потока и создают свою копию исходя из полученных данных. Прийдется создать по экземпляру (лишнему) каждого сообщения, но, я не думаю, что это прям такая нагрузка, зато удобно.
T.е. у вас будет таблица, например:
Код AS3:
private static const MESSAGES:Object = { messageA: new MessageA(), messageB: new MessageB() . . . };
private function parse(event:ProgressEvent):void
{
    var messageXML:XML = XML(this._socket.readUTFBytes(this._socket.bytesAvailable));
    var message:Message = (MESSAGES[messageXML.localName()] as Message).clone(messageXML);
    . . .
}
__________________
Hell is the possibility of sanity

Старый 28.02.2011, 20:05
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 5  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
вместо
Код AS3:
private static const MESSAGES:Object = { messageA: new MessageA(), messageB: new MessageB() . . . };
можно использовать registerClassAlias и getClassByAlias
__________________
Отряд Котовскага

Старый 28.02.2011, 20:13
zhoran вне форума Посмотреть профиль Отправить личное сообщение для zhoran Найти все сообщения от zhoran
  № 6  
Ответить с цитированием
zhoran

Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
Интересная идея, возможно ли обойтись без объектов, что-то типа?

Код AS3:
private static const MESSAGES:Object = { "messageA": MessageA, "messageB": MessageB . . . };
private function parse(event:ProgressEvent):void
{
    var message:Message = (new MESSAGES[messageXML.localName()](messageXML) as Message);
    . . .
}
щас попробую

Добавлено через 3 минуты
Цитата:
Сообщение от Котяра Посмотреть сообщение
можно использовать registerClassAlias и getClassByAlias
Ага, спс, но станет ли короче и понятнее?

Старый 28.02.2011, 20:39
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 7  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,601
Записей в блоге: 17
Цитата:
Switch - плохой подход, единственное оправдание использованию switch'a - это оптимизация на низком уровне (как правило при чтении и парсинге данных из потока и т.п.) в энтерпрайз switch противопоказан.
Речь конкретно в этом случае или вообще?

Цитата:
Ага, спс, но станет ли короче и понятнее?
Будет просто чуть логичней.

Старый 28.02.2011, 20:47
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 8  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Наугад скопировал какой-то из 100500 свитчей в проекте который сейчас переделываю...
Код AS3:
private function handleAPICalls(call:String, params:Array):void
{
	var opponentData:UserData = VideoRoundData.getInstance().users.opponent;
//			MonsterDebugger.trace(call, params, MonsterDebugger.COLOR_ERROR);
	switch(call)
	{
		case ApplicationCallEnum.CLOSE_APPLICATION:
			killApp();
			break;
		case ApplicationCallEnum.RESTART_APPLICATION:
			VideoRoundData.getInstance().managersBridge.inCallManager.runApp(VideoRoundData.getInstance().sessionData.curApplication);
			break;				
		case ApplicationCallEnum.SEND_GIFT:
			var giftId:String = params[0];
			var giftVo:GiftVo = VideoRoundData.getInstance().listsData.getActionVOById(ActionsEnum.GIFTS,giftId); 
 
			if (opponentData)
				VideoRoundData.getInstance().managersBridge.inCallManager.sendGift(opponentData.userServerData.clientId, giftVo);
			else
				VideoRoundData.getInstance().managersBridge.inCallManager.sendGift(null, giftVo);
			break;				
		case ApplicationCallEnum.CHANGE_EFFECT:
			var effectId:String = params[0];
			var effectVo:EffectVo = VideoRoundData.getInstance().listsData.getActionVOById(ActionsEnum.EFFECTS,effectId); 
 
			if(opponentData)
				VideoRoundData.getInstance().managersBridge.inCallManager.setEffect(opponentData.userServerData.clientId, effectVo);
			else 
				VideoRoundData.getInstance().managersBridge.inCallManager.setEffect(null, effectVo);
			break;
		case ApplicationCallEnum.CHANGE_SKIN:
			var skinId:String = params[0];
			var skinVo:SkinVo = VideoRoundData.getInstance().listsData.getActionVOById(ActionsEnum.SKINS,skinId); 
 
			if (opponentData)
				VideoRoundData.getInstance().managersBridge.inCallManager.setSkin(opponentData.userServerData.clientId, skinVo);
			else 
				VideoRoundData.getInstance().managersBridge.inCallManager.setSkin(null, skinVo);
			break;
		case ApplicationCallEnum.GET_PARTICIPANTS:
			var clientId		:String = VideoRoundData.getInstance().users.client.userServerData.clientId;
			var opponentId		:String = (opponentData != null)? opponentData.userServerData.clientId : "";
 
			callApplication(ApplicationCallEnum.GET_PARTICIPANTS_CALLBACK, clientId+","+opponentId);
			//_____Shooters		
			if (opponentData)
			{
				var	userDataParam:String = 	VideoRoundData.getInstance().users.client.userServerData.name + "," 
											+ VideoRoundData.getInstance().users.client.userServerData.photo + "," 
											+ VideoRoundData.getInstance().users.opponent.userServerData.name + ","
											+ VideoRoundData.getInstance().users.opponent.userServerData.photo;
			}
			else
			{
				userDataParam	= 	VideoRoundData.getInstance().users.client.userServerData.name + "," 
					+ VideoRoundData.getInstance().users.client.userServerData.photo + "," 
					+ VideoRoundData.getInstance().users.client.userServerData.name + ","
					+ VideoRoundData.getInstance().users.client.userServerData.photo;						
			}
			callApplication("remoteSetClientsParams", userDataParam);
			break;
		case ApplicationCallEnum.GET_SKINS:
			callApplication(ApplicationCallEnum.GET_SKINS_CALLBACK, constructShortVoList("skins"));
			break;
		case ApplicationCallEnum.GET_EFFECTS:
			callApplication(ApplicationCallEnum.GET_EFFECTS_CALLBACK, constructShortVoList("effects"));
			break;
		case ApplicationCallEnum.GET_GIFTS:
			callApplication(ApplicationCallEnum.GET_GIFTS_CALLBACK, constructShortVoList("gifts"));
			break;
		case ApplicationCallEnum.SEND_MESSAGE:
			var message:String = params[0];
 
			if(opponentData)
				VRViewEventDispatcher.getInstance().dispatchEvent(new VRViewEvent(VRViewEvent.SEND_CHAT_MESSAGE, message));
			break;				
 
 
	}
}
Хочется взять что-нибудь твердое и тяжолое в руку..

>Интересная идея, возможно ли обойтись без объектов, что-то типа?
Конструктор нельзя параметризовать. Т.е. вы в таком случае не застрахованы от ошибки (можно что-то не то передать в конструктор, и компилятор это не проверит). А так - конечно можно.
__________________
Hell is the possibility of sanity


Последний раз редактировалось wvxvw; 28.02.2011 в 20:52.
Старый 28.02.2011, 21:04
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 9  
Ответить с цитированием
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Цитата:
Сообщение от zhoran Посмотреть сообщение
Помогите, не могу сообразить.
У меня есть кастом событие ServerEvent от которого наследуют другие ивенты ServerTableState, ServerPlayerAction, ServerBadCommand, etc.
Не упоминайте etc всуе! )

А вот мне сразу не понравились эти ServerEvent. Я стараюсь проектировать приложение так, чтобы не зависеть от источника данных. Чего и Вам советую.
__________________
Воспитан в TimeZero. Работаю в Mail.ru.


Последний раз редактировалось dimarik; 28.02.2011 в 21:06.
Старый 28.02.2011, 21:08
zhoran вне форума Посмотреть профиль Отправить личное сообщение для zhoran Найти все сообщения от zhoran
  № 10  
Ответить с цитированием
zhoran

Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
Цитата:
Сообщение от dimarik Посмотреть сообщение
А вот мне сразу не понравились эти ServerEvent. Я стараюсь проектировать приложение так, чтобы не зависеть от источника данных. Чего и Вам советую.
Не зависеть это хорошо, но не понятно что Вы имеете в виду в контексте ServerEvent.

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

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

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


 


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


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