![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
[+1 18.03.08]
Регистрация: Nov 2006
Сообщений: 223
|
waitForClick - всего лишь тривиальный пример.
А как тебе такое: var connected:bool = false;
var attempts:int=0;
while (!connected && attempts<3) {
if (sock.connect()) {
connected = true;
} else {
attempts++;
sleep(500);
}
}
sock.connect() и sleep() в данном случае - синхронные методы. Попробуй написать вышеприведённый код на классическом AS3, затем сравним. ------------------------- Другой пример. В одном проекте мне необходимо было рисовать различные псевдо-3D объекты в аксонометрической проекции. Для отрисовки каждого объекта требуется одна или несколько текстур. Текстуры хранятся во внещних файлах. Разумеется, загружать текстуру каждый раз, когда он потребовалась - слишком дорогое удовольствие, поэтому я сделал кеш текстур, основной метод которого выглядел так: При старте приложения загружались все необходимые текстуры (коих тогда было мало), затем объекты в любой момент могли взять нужные текстуры. Но после уточнения ТЗ оказалось, что в реальной работе текстур может быть тысячи, а то и десятки тысяч. Все их загружать в память просто не реально. Поэтому надо использовать ленивую загрузку - текстура загружается только при первом обращении к ней. Но в таком случае я не могу сразу вернуть BitmapData! Ведь возможно такой текстуры в кеше ещё нет, следовательно она будет загружаться, следовательно потребуется какое-то время. Пришлось добавлять callback'и. Но мало того - пришлось полностью переделывать отрисовку объектов. Если раньше это был один метод (у разных типов объектов - свой), то теперь мне пришлось его разбивать на части, чтобы гарантировать, что текстура точно загружена. Если бы я мог сделать getTexture синхронным, то таких значительных переделок не потребовалось бы. Последний раз редактировалось WindWalker; 10.04.2008 в 14:45. |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Ну connect в AS3 не синхронный, начнем с этого.
Подход к текстурам неверный, поверхность должна получить адрес текстуры и все, она начнет грузить текстуру или не начнет, пусть сама решает. Если поверхность скрылась, то она может положить в общий кеш текстуру (если текстура успела загрузиться). Если поверхность скрылась, а текстура загрузилась позже, то положить сразу кеш. Кеш сам по себе очищает себя, скажем, раз в пять минут, убивая все битмапы. Вы сваливаете свою ошибку проектирования на язык, который ничем вас на самом деле не обидел. Последний раз редактировалось etc; 10.04.2008 в 14:41. |
|
|||||
|
Регистрация: Sep 2007
Адрес: Путенбург
Сообщений: 147
|
Из много букв, отбросив лишнее, выделил такую суть:
Цитата:
Цитата:
__________________
<!-- КРЭКС ПЭКС ФЛЭКС --> |
|
|||||
|
[+1 18.03.08]
Регистрация: Nov 2006
Сообщений: 223
|
Именно!
Приведённый код - пример того, как выглядел бы код, если бы connect был синхронным. Напиши эквивалент этого кода с помощью асинхронного connect. И мы вместе почувствуем разницу. |
|
|||||
|
Регистрация: Sep 2007
Адрес: Путенбург
Сообщений: 147
|
Цитата:
А попробуйте (допишите сами ) на классическом (допишите сами) и посмотрим кто круче, типа того.
__________________
<!-- КРЭКС ПЭКС ФЛЭКС --> |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Цитата:
…
socket.addEventListener(IOErrorEvent.IO_Error, this.handler_ioError);
…
private var _attempts:uint = 0;
private var _timeoutID:uint;
private function connect():void {
this._attempts++;
try {
socket.connect(…);
} catch (error:Error) {
this.attempt();
}
}
private function attempt():void {
if (this._attempts > 2) {
clearTimeout(this._timeoutID);
// bla-bla, показываем ошибку
} else this._timeoutID = setTimeout(this.connect, 500);
}
private function handler_ioError(event:IOErrorEvent):void {
this.attempt();
}
|
|
|||||
|
[+1 18.03.08]
Регистрация: Nov 2006
Сообщений: 223
|
Итак, во-первых - длиннее.
Во-вторых, цикл уже не так очевиден. В-третьих - порядок действий уже не так очевиден, появляется псевдорекурсия: connect может вызвать attempt, attempt косвенно вызывает connect. B это всего для двух "долгоиграющих" действий: connect и таймаут. Теперь маленькое добавление: если соединение не удалось, то показать диалоговое окно с надписью: "Connection failed" и кнопкой OK. Делать следующую попытку только после того, как пользователь нажмёт OK. Как меняется код на выдуманном языке: var connected:bool = false;
var attempts:int=0;
while (!connected && attempts<3) {
if (sock.connect()) {
connected = true;
} else {
showMessage("Error", "Connection failed", [OK]);
attempts++;
sleep(500);
}
}
------------------- Цитата:
А если другая поверхность начала загружать эту текстуру, но ещё пока не загрузила? Последний раз редактировалось WindWalker; 10.04.2008 в 15:19. |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
…
socket.addEventListener(IOErrorEvent.IO_Error, this.handler_ioError);
…
private var _attempts:uint = 0;
private var _timeoutID:uint;
private function connect():void {
this._attempts++;
try {
socket.connect(…);
} catch (error:Error) {
this.attempt();
}
}
private function attempt():void {
if (this._attempts > 2) {
// bla-bla, показываем ошибку
} else {
this.showMessage("Error", "Connection failed", Message.OK);
}
}
private function handler_ioError(event:IOErrorEvent):void {
this.attempt();
}
private function handler_okClick(event:Event):void {
this.hideMessage();
this.connect();
}
|
|
|||||
|
[+1 18.03.08]
Регистрация: Nov 2006
Сообщений: 223
|
Итого: +1 функция (новый обработчик).
addListener в одном месте, действие, которое может инициировать событие - в другом, обработчик события - в третьем, и после этого ещё и повторный вызов connect. А теперь дальше. QA посмотрели наше приложение и сказали: что-то слишком часто сообщение появляется. Надо сделать так, чтобы сперва делалось три попытки (молча), а если они не удались, то тогда уже показывать сообщение. Между попытками пауза 500 мс. Сообщение должно теперь содержать YES и NO. Если отвечает YES, то снова делать три попытки. var connected:bool = false;
var attempts:int=0;
do {
while (!connected && attempts<3) {
if (sock.connect()) {
connected = true;
} else {
attempts++;
sleep(500);
}
}
if (!connected) {
var answer = showMessage("Error", "Connection failed", [BTN_YES, BTN_NO]);
}
} while (!connected && answer == BTN_YES);
Ваш ход? |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Я не играю с вами в шахматы, потому как мой ход очевиден и смысла в продолжении нет. Если вы ради сомнительного удобства собираетесь ваять конвееры и псевдомногопоточность — вперед. Но это AS way, и это не Java, в очередной раз говорю.
Вам всего навсего нужен sleep, а многопоточность тут особо и не нужна. Чего вы хотите примерами кода доказать — я не знаю. Я вам докажу, что можно без многопоточности, пусть и длиннее, но никаких проблем в понимании логики лично я не вижу. Если вы видите, то AS — не ваше. Последний раз редактировалось etc; 10.04.2008 в 15:42. |
![]() |
![]() |
Часовой пояс GMT +4, время: 07:28. |
|
|
« Предыдущая тема | Следующая тема » |
|
|