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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 25.03.2011, 13:05
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 21  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,784
Цитата:
Сообщение от Psycho Tiger Посмотреть сообщение
@etc, ResourceManager смотрит на расширение файла и возвращает экземпляр класса по getDefinition, если это .swf или что-нибудь другое, если расширение не swf? Или он работает с чем-то одним?
Ещё интересует прелоадинг ресурсов, я так понял getResource синхронный. И судя по всему он определен во вьюхе, не практикуешь загрузку классов только с кодом?
url это url, путь до файла. Расширение значения не имеет.
getResource синхронный, загрузка отдельно.

А вообще, вот у Блуда оно самое:
http://code.google.com/p/blooddy/sou...prite.as?r=270

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

блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
Код AS3:
super.getResource(url, className);
Код AS3:
protected final function getResource(bundleName:String, resourceName:String=null):Object {
Немного сигнатуры отличаются =)
Спасибо за ссылку )

Старый 26.03.2011, 00:01
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 23  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
То, что менеджер превращается в обертку, как раз вполне естественно. И что-то другое получить как раз достаточно сложно. Далее по порядку, так как разработка этого ResourceManager очень показательна с точки зрения процесса разработки.

Шаг первый. Формулировка задачи. Задача была сформулирована в первом сообщении. Плюс был приведен сценарий использования и API для него (ну и 99% других подобных случаев). Здесь же можно сформулировать интерфейс ResourceManager исходя из тех мест, где он применяется. Но ни в коем случае не из того, как он реализован внутри!

Шаг второй. Формализация задачи. Собственно, что должен делать мендежер?
1. Загружать ресурсы (транспорт по сети).
2. Хранить уже загруженные ресурсы.
3. Конвертировать "символические" имена в абсолютные.
4. Предзагружать ресурсы по требованию.
5. Предзагружать ресурсы при старте/инициализации.

Шаг третий. Проектирование и реализация. Очень важный здесь инструмент - Single Responsibility Principle - каждый "элемент" имеет ровно одну ответственность. Ответственность 3 элементарно реализуется отдельным классом (методом, если не пугают замыкания!). Ответственность 1 - уже реализована (транспорт, тот же BulkLoader и т.п.). Ответственность 5 при желании делается внешней с помощью отдельного метода. Остаются хранение и предзагрузка. Само по себе "хранение" уже реализовано - это обычные динамические объекты. Остается - предзагрузка ресурсов. Она зависит от хранения (в любом случае). Ее то и нужно реализовать. Плюс для ее реализации в любом случае нужно будет использовать какое-то хранилище данных. Реализуем (делегируя все, что можно). Смотрим, что получилось. Получилась "получение данных и хранение результатов запросов" по фунциям. Т.е. кэш . Или обертка поверх протокола получения данных. Гордо называем то, что у нас вышло Cache, по его основной функциональности и кладем в библиотеку. Авось, пригодится еще.

Шаг четвертый. Собираем все вместе. На предыдущем шаге мы научились решать отдельные "подзадачи". Теперь нужно решить исходную задачу. Фактически дословно пишем то, что хотелось изначально:
Код AS3:
public function createResourceManager(transport : SomeLoader, config : XML) : ResourceManager {
  const modRewrite : SomeLoader = createRewritingTransport(config, transport); //resp. 2, transport - resp. 1
  const result : ResourceManager = new ResourceManagerOfCache(new Cache(modRewrite)); // resp 3, resp. 4
  result.preloadResources(getInitialyPreloadedResources(config), function() : void {}); //resp 5
  return result;
}
Одним из ключевых моментов было разделение того, что именно реализовано (cache по сути) и тем, как оно используется ("роль" в приложении, ResourceManager).

Шаг пятый. Пожинаем плоды. У нас раньше получилась хорошая и достаточно удобная декомпозиция и удобный кэш. Теперь его можно использовать где-нибудь в другом месте. Например, можно кэшировать профили игроков социальной сети. В менеджер это не очень вписывалось, но у нас же есть кэш. Для усложнения предположим, что раньше SomeLoader получал ресурсы и обработчики по одному. В социальной сети же из соображений оптимальности лучше запрашивать и загружать профили пачками. Т.е. нужно изменить интерфейс "поставшика ресурсов" кэша на интерфейс со множественной загрузкой. Меняем интерфейс. Параллельно делаем загрузчик со "множественными" запросами поверх загрузчика с одиночными запросами (он достаточно прямолинеен). Меняем создание менеджера. Затем собираем кэш для социальной сети. Итого получаем:
Код AS3:
public function createResourceManager(transport : SomeLoader, config : XML) : ResourceManager {
  const modRewrite : SomeLoader = createRewritingTransport(config, bulkLoader);
  const bulkLoader : BulkLoader = new BulkLoaderOfSimpleLoader(modRewrite);
  const result : ResourceManager = new ResourceManagerOfCache(new Cache(bulkLoader));
  result.preloadResources(getInitialyPreloadedResources(config), function() : void {});
  return result;
}
 
public function createProfilesCache(profilesLoader : BulkLoader) : Cache {
  return new Cache(profilesLoader);
}
Да, появится еще обертка ProfileBulkLoader поверх используемой библиотеки социальной сети. Но она же примитивна до безобразия - преобразование одного вызова метода в другой. В принципе, если изначально loader является функцией (сформулирован по техническому интерфейсу вызова, а не по роли!), то лишних оберток даже создавать не придется. В результате - относительно сложная функциональность реализована один раз и используется во многих местах. Количество классов-оберток (конвертеров между различными интерфейсами) вполне возможно, увеличивается, но при этом обертки очень просты и вероятность ошибок в них низкая.

На практике такой детализации с самого начала не происходит. Не заводится лишних интерфейсов и т.п. А вот детальное разделение функциональности все равно делается. В результате при необходимости дальнейших изменений новые интерфейсы заводятся и затем просто по-другому сочетается старая функциональность.

Еще отмечу, что "переписывание" имен (modRewrite) можно было делать и "снаружи" кэша. Принципиально это ничего не изменяет, так как эта функциональность не зависит от других требуемых. Меняется только удобство написания обертки (может количество методов отличаться, например).

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

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
2maxkar
Блин, хорошо всё написано, но как-то "профакториально".
Видно человека с большим java-бэкграундом)
be simple
__________________
Отряд Котовскага

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

блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
@maxkar, спасибо за консультацию =)
В целом, примерно это у меня и вырисовывается, только классы немного по другому сгруппированы.
Что скажете по поводу моего текущего положения?
ResouceManager — собственно, всем заправляет
ResourceInfo — набор статических констант, вроде
Код AS3:
public static const IMAGE_TYPE:uint = 0;
public static const SWF_TYPE:uint = 1;
public static const XML_TYPE:uint = 2;
public static const SOUND_TYPE:uint = 3;
ResourceDataProvider — класс-коллекция для ResourceItemData (ниже). В нём хранятся все возможные ресурсы, он выдаёт ресурсы. По-сути, это мост между входным XML файлом и самим ResourceManager`ом, чтобы вход всегда можно было безболезненно поменять. (кстати, это GoF Bridge, я запамятовал?)
ResouceItemData — value object с вот такими полями:
Код AS3:
		public var type:uint;
		public var request:URLRequest;
		public var autoPreload:Boolean;
		public var data:*;
		public var loaded:Boolean = false;
		public var loadStarted:Boolean = false;
		public var soundLoaderContext:SoundLoaderContext;
		public var securityDomain:SecurityDomain;
		public var name:String;
		public var definitionName:String;
Меня немного сейчас напрягает, что для каждого элемента (будь то definition в swf, будь то картинка) создаётся один такой экземпляр. В итоге на 100 картинок будет 100 экземпляров класса. У Вас какие мысли по этому поводу, насколько плохо?
ResourceLoader — непосредственная обёртка над BulkLoader, которая качает файлы и заносит их в ResourceDataProvider. Он же вызывает callback`и, когда "группа" полностью готова к работе. (callback`и он получает от ResourceManager`а).

Старый 26.03.2011, 18:22
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 26  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Нормально.

На мост ResourceDataProvider вроде бы не тянет, хотя я в паттернах плохо разбираюсь. Это всего лишь интерфейс (ну или класс, в данном случае без разницы), необходимый для работы ResourceManager, обычная "внешняя зависимость". Если у нее удачный конструктор, то его тоже менять не придется, достаточно будет новый парсер данных написать .

Лишние данные в ResourceItemData не страшны. Даже на 100 картинок там всего пара килобайт лишних наберется. Не критично. Если хочется попробовать экономить, можно динамические объекты передавать для разных типов, но в общем то совсем не нужно.

Еще вариант - ResourceItemData могут создаваться динамически при запросе. Например, когда в XML указывается только путь к корневому каталогу картинок, а "именем" картинки является ее относительный путь.

Ну а для callback'ов все нужно грамотно реализовать. Там как раз самые большие сложности вроде:
Код AS3:
resourceManager.preloadResources(callback1, 'resource1', 'resource2', 'resource3');
resourceManager.preloadResources(callback2, 'resource4');
resourceManager.preloadResources(callback3, 'resource2', 'resource4');
В идеале ресурсы 2 и 4 должны быть загружены 1 раз, callback3 должен быть вызван один раз и только после того, когда ресурсы 2 и 4 готов (остальных можно не дожидаться, можно - дожидаться).

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

Регистрация: Sep 2002
Сообщений: 30,784
Psycho Tiger, по сути bundleName и есть url до файла)

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

блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
@maxkar, да-да, в callback`ах все сложности. Вчера пересмотрел взгляды на подход реализации callback`ов. Теперь ResourceItem хранит только то, что из файла надо тянуть, и тянет ссылку на ResourceFile. ResourceFile extends EventDispatcher, что даёт красивую картинку загрузок. ResourceGroup получает список файлов Vector.<ResourceFile>, которые надо загрузить. ResourceGroup смотрит, кто загружен, а кто ещё нет, и ждёт загрузки всех остальных, после чего вызывает callback. В итоге, экземпляров класса стало ещё больше, но картина стала ещё правильней =)

@etc, расскажи пожалуйста как у вас там загрузка происходит, я найти не могу. (лучше всего на пальцах, без кода)

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

Регистрация: Sep 2002
Сообщений: 30,784
Psycho Tiger, да там всё просто, ResourceSprite дёргает свой ResourceManager, из него и грузит.

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

блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
Это я понял =)
Интересует именно сама прогрузка. Как ResourceManager решает, что нужно что-то прогрузить? По запросу от ResourceSprite или контроллер, создавая вью всегда гарантирует что ресурсы загружены? Когда идёт загрузка ResourceSprite ожидает окончания, или создаётся после окончания загрузки? Как определяется, какие ресурсы нужны этому ResourceSprite?

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

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

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


 


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


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