Обозреватель

Observer

суббота, 27 декабря 2008 г.

AS3 Удаление объекта //Хак

AS3 Удаление объекта. ruFlash

Nox Noctis:

Хак с двумя локалконнекшнами рассказал Грант Скиннер еще в 2006 году.
Гуглом можно найти. Как он дошел до жизни такой -- неведомо, но это
работает.

try {
new LocalConnection().connect("gc");
new LocalConnection().connect("gc");
} catch (error:Error) {
// ignore
}


Это заставит GC запустится. Однако, стоит учитывать, что за один проход
коллектор может и не собрать весь мусор (никто этого и не обещал).

> Есть ещё метод gc(), но он работает только в Debug версии
> проигрывателя.

Кстати в AIR работает и в недебаговой версии, если контент, который
запускает System.gc() находится в песочнице установленного AIR-приложения.

воскресенье, 9 ноября 2008 г.

Шаблон Модель-Представление-Контроллер

Шаблон Модель-Представление-Контроллер. fla_master

Продолжение статьи: Что такое шаблон Модель-Представление-Контроллер?



SRC:
O’Rеillу. ActionScript 3.0 Design Patterns.
Глава 12. Model-View-Controller Pattern.

Продолжение. См. начало главы об MVC



Создание вложенных Представлений

Для демонстрации вложенных Представлений мы создадим узел составного Представления и два дочерних компонента, как показано на Рисунке 12-2.



Рисунок 12-2. Структура вложенных Представлений в минималистичном примере


Сначала мы создадим составное Представление под названием RootNodeView. Это составное Представление будет получать ввод с клавиатуры от сцены. Это Представление также зарегистрируется для получения уведомлений об обновлении от Модели. Составное Представление RootNodeView обзаведется двумя дочерними компонентами: CharCodeLeafView и AsciiCharLeafView. CharCodeLeafView будет отслеживать код последнего введенного с клавиатуры символа. AsciiCharLeafView будет отслеживать ASCII-символ, соответствующий этому коду символа. Давайте сначала создадим составное Представление, как показано в Примере 12-9.

Пример 12-9. RootNodeView.as


package {

import flash.events.*;

import flash.display.*;



public class RootNodeView extends CompositeView {



public function RootNodeView(aModel:IModel,aController:Object=null) {

super(aModel,aController);

// подписывается на получение событий нажатий клавиш от сцены

target.addEventListener(KeyboardEvent.KEY_DOWN,this.onKeyPress);

}



private function onKeyPress(event:KeyboardEvent):void {

// передается на обработку в Контроллер (Стратегия)

controller as IKeyboardInputHandler.keyPressHandler(event);

}



}

}


Класс RootNodeView, показанный в Примере 12-9, расширяет класс CompositeView. Он не отрисовывает пользовательский интерфейс, а просто слушает события нажатия клавиш и передает их на обработку Контроллеру. Обратите внимание на присутствие super в конструкторе, что требуется для вызова конструктора родителя класса. А теперь мы можем создать два компонентных Представления (Примеры 12-10 и 12-11).

Пример 12-10. CharCodeLeafView.as


package {

import flash.events.Event;



public class CharCodeLeafView extends ComponentView {



public function CharCodeLeafView(aModel:IModel,aController:Object=null) {

super(aModel,aController);

}



override public function update(event:Event=null):void {

// получить данные от Модели и обновление Представления

trace(model.getKey());

}



}

}


Пример 12-11. AsciiCharLeafView.as


package {

import flash.events.Event;



public class AsciiCharLeafView extends ComponentView {



public function AsciiCharLeafView(aModel:IModel,aController:Object=null) {

super(aModel,aController);

}



override public function update(event:Event=null):void {

// получить данные от Модели и обновление Представления

trace(String.fromCharCode(model.getKey()));

}



}

}


Оба класса компонентного Представления — CharCodeLeafView (Пример 12-10) и AsciiCharLeafView (Пример 12-11) — расширяют класс ComponentView (Пример 12-8). Обратите внимание, что они не получают пользовательского ввода. Поэтому этим двум Представлениям не требуется принимать ссылку на Контроллер в конструкторе. Ссылка на Контроллер в данном случае будет иметь значение по умолчанию null.

Все что теперь осталось, это построить триаду MVC с вложенными Представлениями. Мы позволим клиенту строить вложенные Представления и зарегистрировать корневой узел в Модели для получения уведомлений об обновлении


Построение структуры вложенных Представлений

Построение структуры вложенных Представлений идентично разработке составной структуры с использованием шаблона Компоновщик. Мы можем представить себе Предсталение как дерево (расширяющееся сверху вниз) и использовать метод add() для добавление в составное Представление дочерних Представлений.


var model:IModel = new Model( );



var controller:IKeyboardInputHandler = new Controller(model);



// составное Представление

var rootView:CompositeView = new RootNodeView(model,controller, this.stage);



// добавление дочерних Представлений

rootView.add(new CharCodeLeafView(model));

rootView.add(new AsciiCharLeafView(model));



// подписка на получение уведомлений от Модели

model.addEventListener(Event.CHANGE, rootView.update);


Заметьте, что только корневое Представление регистрируется у Модели для получения событий обновления. Это объясняется тем, что корневое Представление является составным, и событие пробегает по каждой из его веток. Теперь, когда нажимается клавиша на клавиатуре, одна «дочка» выведет код символа, а другая — соотвествующий ASCII-символ. Такая много-компонентная структура будет работать при увеличении числа компонентов так же хорошо, как и в этом нашем простом минималистичном примере.

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


Основные преимущества шаблона MVC

Главная польза от применения шаблона MVC — это гибкость, которая упрощает построение приложений, имеющих пользовательский интерфейс. Шаблон разделяет Модель, Представление и Контроллер и прибегает к шаблонам Обозреватель, Стретегия и Компоновщик для их декомпозиции.

  • MVC состоит из трех элементов, называемых Модель, Представление и Контроллер, которые распределяют участки ответственности в приложениях с графическим интерфейсом.

  • Взаимоотношение между Моделями и Представлениями представляет собой выделение Конкретного Субъекта и Конкретного Обозревателя в шаблоне Обозреватель.

  • Взаимоотношения между Представлениями и Контроллерами представляют собой Контекст и Конкретную Стратегию в шаблоне Стратегия.

  • Множественные Представления могут регистрироваться в Модели.

  • Представления могут быть вложенными с использованием шаблона Компоновщик для создания сложного пользовательского интерфейса, упрощая процесс обновления.




Продолжение следует...

Что такое шаблон Модель-Представление-Контроллер?


Заимствую эту статью лишь по той причине, что на работе LJ закрыт для доступа.
Шаблон Модель-Представление-Контроллер. fla_master



SRC:
O’Rеillу. ActionScript 3.0 Design Patterns.
Глава 12. Model-View-Controller Pattern.

Начало.


Что такое шаблон Модель-Представление-Контроллер?

«Модель—Представление—Контроллер» (Model-View-Controller, MVC) — это составной шаблон, или несколько шаблонов, работающих совместно для реализации сложных приложений. Наиболее часто этот шаблон используется для создания интерфейсов приложений, и как следует из названия, состоит из трех элементов:

Модель (Model)
Содержит данные и логику приложения для управления состоянием этого приложения

Представление (View)
Реализует пользовательский интерфейс и состояние приложения, наблюдаемые на экране

Контроллер (Controller)
Обрабатывает действия пользователя, влияющие на состояние приложения.

Мощь шаблона MVC напрямую обуславливается разделением этих трех элементов с целью избежать пересечений зон ответственности каждого из них. Давайте посмотрим, за что отвечает каждый из элементов.


Модель

Модель отвечает за управление состоянием приложения. Логика приложения в модели представлена двумя важными задачами: модель отвечает на запросы относительно состояния приложения, и выполняет действия в ответ на запрос об изменении состояния.

Представление

Представление — это внешний облик приложения. Пользователь взаимодействует с приложением через Представление. Приложение может содержать несколько Представлений, которые могут быть как механизмом ввода, так и механизмом вывода. Например, в портативном цифровом плеере, таком как iPod, экран устройства будет Представлением. Кнопки плеера также считаются Представлением. Экран показывает название и продолжительность песни, изображение обложки альбома, и прочее, что соотносится с текущим состоянием устройства. Представление не обязательно должно быть видимым. В портативном плеере музыка, которая играет в наушниках, также является Представлением. Например, нажатие кнопки может вызвать некоторую слышимую ответную реакцию в виде щелчка в наушниках. Изменение громкости также отражается по каналу аудио-выхода. Слышимая ответная реакция связана с состоянием приложения.

Контроллер

Хотя термин Контроллер неявно подразумевает интерфейс, посредством которого управляется приложение, в шаблоне MVC Контроллер не содержит никаких элементов пользовательского интерфейса. Как говорилось выше, элементы пользовательского интерфейса, которые обеспечивают ввод, относятся к компоненту Представление. Контроллер же определяет, как Представления отзываются на ввод пользователя.

Допустим, наш цифровой плеер имеет кнопки Громче и Тише в Представлении. Громкость звука является переменной состояния. Модель будет отслеживать эту переменную, чтобы менять значение этой переменной в соответствии с логикой приложения. Если значение громкости звука проградуировать от 0 до 10, Контроллер определит, насколько нужно прибавить или убавить звук при одиночном нажатии на одну из этих кнопок. Поведение может сообщить Модели, что нужно увеличить громкость на 0,5 или на 0,1, или любое другое значение, как задано программно. В таком ключе, Контроллер — это специфичные реализации, которые определяют, каким образом приложение ответит на ввод пользователя.


Хотя каждый элемент в триаде MVC имеет отдельную и уникальную зону ответственности, они не функционируют в изоляции. На самом деле, с тем чтобы составить шаблон MVC, каждому элементу следует коммуницировать с остальными. Что это значит, мы рассмотрим ниже.


Взаимодействие элементов MVC

Каждый элемент в шаблоне MVC общается с остальными весьма специфичными способами. Коммуницирование реализуется последовательностью событий, которые обычно запускаются взаимодействием пользователя с приложением. Последовательность событий выглядит так:

  1. Пользователь взаимодействует с элементом интерфейса (например, нажимает на кнопку в Представлении).

  2. Представление отсылает событие нажатия Контроллеру, чтобы решить, как это нажатие обработать.

  3. Контроллер меняет Модель на основе того, что он решил относительно нажатия кнопки.

  4. Модель информирует Представление о том, что состояние Модели изменилось.

  5. Представление читает информацию о состоянии в Модели и самостоятельно видоизменяется.



Рисунок 12-1. Направления коммуницирования между элементами MVC

Это очень простая схема того, как взаимодействуют элементы MVC. В некоторых случаях Контроллер может просто указать Представлению чтобы оно изменилось. Это единственный случай, когда изменения в Представлении становятся необходимыми из-за действий пользователя и не требуют изменений в Модели, а просто приводят к одним только визуальным изменениям. Например, вспомните о том, как пользователь выбирает песню на цифровом плеере. Он выбирает песню из списка кнопками прокрутки. Представление должно сообщить Контроллеру, что нажаты кнопки Листать вверх или Листать вниз, но Контроллеру не нужно информировать об этом Модель. Он напрямую говорит Представлению прокрутить список песен в нужном направлении. Такое действие пользователя не требует изменений в Модели. Однако, когда пользователь выберет песню из списка и запустит её на воспроизведение, Контроллер изменит Модель, чтобы отразить это изменение в значении воспроизводимой в данный момент песни.

Кроме того, изменения в Модели не всегда инициируются действиями пользователя. Модель может обновиться сама, основываясь на неких событиях. Возьмем, например, индикатор стоимости акций. Модель не связана с текущей стоимостью акций. Однако, стоимость сама по себе меняется, и Модель может установить таймер, чтобы периодически получать обновленные данные от веб-сервиса. И тогда, всякий раз, как только Модель обновит свои данные о стоимости акций, она проинформирует Представление о том, что состояние изменилось.

Другой особенностью шаблона MVC является то, что каждая такая Модель может иметь более одного Представления, ассоциированного с ней. Например, в нашем портативном плеере установки громкости могут быть отображены на дисплее с помощью индикатора уровня. А кроме того, уровень звука на аудио-выходе соотносится с громкостью звука в наушниках. И дисплей, и звук в наушниках являются Представлениями состояния устройства.

Взгляните на Рисунок 12-1 и обратите внимание на направление стрелок. Они показывают, кто инициирует взаимодействие между элементами. Для того, чтобы один MVC-элемент смог сообщаться с другим, ему нужно знать о нем и владеть ссылкой на этот элемент.

Думайте о Модели, Представлении и Контроллере как о трех разных классах. Давайте посмотрим, каким классам нужно иметь ссылки на остальные классы:

Модель
Ей нужно иметь ссылку на Представление

Представление
Ему нужно иметь ссылку и на Модель, и на Контроллер

Контроллер
Ему необходимо владеть ссылкой на Модель

Мы начали с того что заявили, что MVC – это составной шаблон, который объединяет несколько шаблонов. Вам, должно быть, интересно, какие шаблоны вошли в данный составной шаблон. Или, точнее, чем они могут быть представлены? Главным преимуществом использования шаблона MVC является возможность разъединять его на составляющие три элемента. Это позволяет нам увязать несколько Представлений с одной Моделью, заменять Модели и Контроллеры, не затрагивая другие элементы. Но некоторые элементы в триаде MVC должны поддерживать ссылки на остальные элементы, а также поддерживать активный обмен данными между ними. Как мы можем назвать такое разделение? Это имеет отношение к паттернам Observer (Обозреватель), Strategy (Стратегия) и Composite (Компоновщик).


Внедрение шаблонов в MVC

Как мы уже рассмотрели, Модель может быть ассоциирована с несколькими Представлениями. В MVC Модели нужно информировать все связанные с ней Представления о происходящих изменениях. К тому же, это нужно делать без знания специфичных подробностей относительно Представлений, и даже без информации о том, скольким Представлениям следует измениться. Эта задача лучше всего решается применением реализации шаблона Обозреватель (см. Главу 8).

Каждая Модель может иметь несколько Представлений, с ней связанных. Так же, Представления могут быть сложными, с несколькими окнами или панелями, внутри которых находятся другие элементы пользовательского интерфейса. Например, такие элементы интерфейса как кнопки, текстовые поля, списки, ползунки и т.п. могут быть сгруппированы в панель с закладками, а панель в свою очередь может быть частью окна наравне с другими панелями. Каждая кнопка или группа кнопок может быть Представлением. То же самое с коллекцией текстовых полей. Представляется полезным обращаться с панелью или окошком, которые содержат коллекции простых Представлений, таким же образом, как мы обращаемся с любыми другими Представлениями. Именно здесь использование шаблона Компоновщик сэкономит нам много сил (см. Главу 6). Почему реализация шаблона Компоновщик столь полезна в данном контексте? Если Представления могут быть вложенными, а они таковы, если созданы с применением шаблона Компоновщик, процесс обновления упрощается. Событие обновления автоматически обойдет все потомственные Представления. Создание сложных Представлений становится проще, когда нет необходимости рассылать индивидуальные сообщения об обновлении каждому вложенному Представлению.

Представления ограничивают свою деятельность лишь внешним представлением состояния Модели. Они передают события пользовательского интерфейса Контроллеру. Поэтому, Контроллер – это в большей степени алгоритм того, как обработать пользовательский ввод в конкретном Представлении. Такое делегирование инкапсулирует реализацию того как конкретный элемент пользовательского элемента ведет себя в условиях изменения Модели. Мы может довольно просто заменить один Контроллер для одного и того же Представления, чтобы получить другое поведение. Это идеальный контекст для реализации щаблона Стратегия.

Далее мы рассмотрим, как эти шаблоны реализованы в MVC, на примере разработки минималистичного примера.


Минималистичный пример шаблона MVC

Этот простой пример отслеживает нажатия клавиш. Когда нажимается очередная клавиша, это приводит к изменению Модели и информированию Представления о необходимости обновиться. Представление задействует стандартное окно вывода Output во Flash, чтобы поместить туда код символа, который ввел пользователь. Код символа — это числовое значение символа в кодовой таблице текущей раскладки. Этот пример объясняет, каким образом шаблоны Обозреватель, Стратегия и Компоновщик интегрированы в MVC.


Модель как Конкретный Субьект в шаблоне Обозреватель

Взаимоотношения между Моделью и Представлением — это связь между Субъектом и Обозревателем (См. Главу 8). Модель должна реализовать интерфейс Субъекта, который является частью шаблона Обозреватель. К счастью, ActionScript 3.0 имеет встроенные классы, уже реализующие этот принцип, используя модель событий ActionScript чтобы информировать Обозревателей об изменениях.

Класс EventDispatcher в ActionScript 3.0

Класс EventDispatcher снабжен интерфейсом IEventDispatcher. Наравне с другими методами, интерфейс IEventDispatcher определяет следующие методы, необходимые для субъекта в шаблоне Обозреватель. (См. документацию по AS3 для подробной информации о всех параметрах методов).


addEventListener(type:String,

listener:Function,

useCapture:Boolean = false,

priority:int = 0,

useWeakReference:Boolean = false):void



removeEventListener(type:String,

listener:Function,

useCapture:Boolean = false):void



dispatchEvent(event:Event):Boolean


Чтобы Модель могла выступить в качестве Конкретного Субъекта в шаблоне Обозреватель, необходимо реализовать интерфейс IEventDispatcher. Однако, самый простой способ для определенного пользовательского класса заполучить способность распространять события – это наследовать от класса EventDispatcher.

Обозреватель регистрирует методы слушателя, чтобы получать уведомлении от объектов EventDispatcher, методом addEventListener( ).

Модель

Наша Модель сохраняет код символа, соответствующий нажатой клавише, в свойстве. Необходимо реализовать сеттер и геттер, чтобы стало возможным Представлению и Контроллеру получить доступ к этому свойству и изменять его. Давайте определим интерфейс для нашей Модели (Пример 12-1).

Пример 12-1. IModel.as


package {

import flash.events.*;



public interface IModel extends IEventDispatcher {

function setKey(key:uint):void;

function getKey():uint;

}

}


Интерфейс IModel, показанный в Примере 12-1, расширяет интерфейс IEventDispatcher и определяет пару методов для прочтения и установки кода символа последней нажатой клавиши. Поскольку интерфейс IModel расширяет IEventDispatcher, любой класс, реализующий его, должен реализовать все методы, определенные в обоих интерфейсах. Класс Model, показанный в Примере 12-2, реализует интерфейс IModel.

Пример 12-2. Model.as


package {

import flash.events.*;



public class Model extends EventDispatcher implements IModel {



private var lastKeyPressed:uint=0;



public function setKey(key:uint):void {

this.lastKeyPressed=key;

dispatchEvent(new Event(Event.CHANGE)); // распространяется событие

}



public function getKey():uint {

return lastKeyPressed;

}

}

}


Класс Model расширяет класс EventDispatcher, который уже реализовал интерфейс IEventDispatcher. Обратите внимание, что функция dispatchEvent() вызывается внутри метода setKey(). Она отсылает событие CHANGE всем зарегистрированным обозревателям, как только значение lastKeyPressed изменится внутри метода setKey().


Контроллер как Конкретная Стратегия в шаблоне Стратегия.

Отношения между Контроллером и Представлением можно представить как стратегию и контекст в шаблоне Стратегия. Каждый Контроллер будет конкретной стратегией, реализующей требуемое поведение в рамках интерфейса Стратегии.


Контроллер

В нашем минималистичном примере поведение, требуемое от Контроллера, это всего лишь принятие события о нажатии клавиши. IKeyboardInputHandler — это интерфейс Стратегии (Пример 12-3), где определен единственный метод keyPressHandler( ).

Пример 12-3. IKeyboardInputHandler.as


package {

import flash.events.*;



public interface IKeyboardInputHandler {

function keyPressHandler(event:KeyboardEvent):void;

}

}


Конкретным Контроллером будет класс Controller (Пример 12-4), который реализует интерфейс IKeyboardInputHandler.

Пример 12-4. Controller.as


package {

import flash.events.*;



public class Controller implements IKeyboardInputHandler {



private var model:IModel;



public function Controller(aModel:IModel) {

this.model=aModel;

}



public function keyPressHandler(event:KeyboardEvent):void {

model.setKey(event.charCode); // изменяем модель

}

}

}


Обратите внимание, что Контроллер имеет конструктор, который в качестве параметра принимает экземпляр Модели. Это необходимо для того, чтобы Контроллер смог установить связь с Моделью, как это показано на Рисунке 12-1. Поэтому необходимо хранить ссылку на Модель.

Метод keyPressHandler( ) принимает событие пользовательского интерфейса (в данном случае KeyboardEvent) как параметр, и потом решает как его обработать. В нашем примере он просто устанавливает код нажатой клавиши в Модели.


Представление как Конкретный Обозреватель в шаблоне Обозреватель и Контекст в шаблоне Стратегия

Представление, возможно, наиболее сложный элемент в шаблоне MVC. Он играет роль интегрирующей части в реализации шаблонов как Обозревателя, так и Стратегии, что формирует основу его взаимоотношения с Моделью и Контроллером. Класс View, показанный в Примере 12-5, реализует Представление в минималистичном примере.

Пример 12-5. View.as


package {

import flash.events.*;

import flash.display.*;



public class View {



private var model:IModel;



private var controller:IKeyboardInputHandler;



public function View(aModel:IModel,oController:IKeyboardInputHandler,target:Stage) {

this.model=aModel;

this.controller=oController;



// подписывается на получение уведомлений от Модели

model.addEventListener(Event.CHANGE,this.update);



// подписывается на получение нажатий клавиш от сцены

target.addEventListener(KeyboardEvent.KEY_DOWN,this.onKeyPress);



}



private function update(event:Event):void {

// получение данных от Модели и обновление Представления

trace(model.getKey());

}



private function onKeyPress(event:KeyboardEvent):void {

// обработка передается в Контроллер (Стратегия) на обработку

controller.keyPressHandler(event);

}

}

}



Представление нуждается в ссылках на Модель и на Контроллер для взаимодействия с ними, как показано на Рисунке 12-1. И экземпляр Модели, и экземпляр Контроллера передаются Представлению в его конструкторе. К тому же, Представление в нашем примере нуждается в ссылке на сцену (Stage), чтобы зарегистрировать себя как получателя событий нажатия клавиш.

Кроме того что класс View рисует пользовательский интерфейс, он выполняет еще пару важных задач. Он регистрируется у Модели для получения событий об обновлении, и делегирует Контроллеру обработку ввода пользователя. В нашем примере Представление не имеет внешнего видимого присутствия на сцене, но отображает состояние Модели в окне вывода Output. Ему нуждается в получении события нажатия клавиши, и регистрирует метод onKeyPress( ) для получения события KEY_DOWN от сцены. Вторая задача – это зарегистрировать метод слушателя update( ) для получения события CHANGE от модели. При получении уведомления об изменении, метод update() прочитывает код последней нажатой клавиши из Модели и печатает его в окне вывода, используя функцию trace().


Построение триады MVC

Мы рассмотрели реализацию каждой из трех составляющих шаблон MVC частей по отдельности. Однако, должен существовать клиент, который инициализирует каждый элемент и построит модель MVC. На самом деле, никакого сложного построения не будет — все что нужно уже сделано при написании классов Модели, Представления и Контроллера. В Примере 12-6 приводится класс Flash-документа, который иллюстрирует элементы MVC.

Пример 12-6. Main.as (основной класс минималистичного примера)


package {



import flash.display.*;

import flash.events.*;



/**

* Main Class

* @ purpose: Document class for movie

*/




public class Main extends Sprite {



public function Main() {

var model:IModel=new Model ;

var controller:IKeyboardInputHandler=new Controller(model);

var view:View=new View(model,controller,this.stage);

}

}

}


После того как Модель, Контроллер и Представление инициализированы, они установят связь друг с другом и начнут работать. Нажатие клавиши на клавиатуре приведет к выводу кода соответствующего символа в окне Output.

Вам нужно запретить шорткаты для тестирования нажатий клавиш. В противном случае пользовательский интерфейс Flash перехватит события нажатия клавиш, которые соответствуют шорткатам. Чтобы запретить шорткаты, выберите Disable Keyboard Shortcuts из меню Control во время выполнения ролика.

Обратите внимание, что экземпляр Модели передается Контроллеру. Подобным образом экземпляры Модели и Контроллера передаются Представлению. Мы можем просто заместить существующие Модель и Контроллер другими, при условии, что они реализуют интерфейсы IModel и IKeyboardInputHandler. Дополнительные Представления также могут быть безболезненно добавлены прямо в отношения Субъект-Обозреватель между Моделью и Представлением. Модель ничего не знает о Представлениях, так как это забота Представления — зарегистрировать себя в качестве слушателя уведомлений об изменении Модели. Это большой плюс шаблона MVC; Модель, Представление и Контроллер разделены, слабо связаны, что придает гибкости в их использовании.


Вложенные Представления и узлы шаблона Компоновщик

Как вы помните, Представление, возможно, самый сложный элемент в триаде MVC, поскольку в контексте MVC он задействован как в реализации шаблона Обозреватель, так и в Стратегии. Наши элементы Представления способны быть более сложными, поскольку могут реализовать третий шаблон — Компоновщик (см. примеры шаблона Компоновщик в Главе 6). Реализация Представлений как элементов шаблона Компоновщик позволяет разобраться со сложными пользовательскими интерфейсами, которые содержат множественные Представления. Вложение Представлений превносит некоторые преимущества в процесс обновления пользовательского интерфейса, так как обновления могут распространяться по ветвям структурного дерева составного Представления. Также составные Представления могут добавлять и удалять вложенные Представления, основываясь на режиме работы приложения и пользовательских настройках. Хорошим примером сложного интерфейса является панель Properties Inspector в среде разработки Flash. Содержимое Properties Inspector зависит от контекста, и элементы интерфейса появляются и исчезают в зависимости от того, какой объект выделен на сцене.


Компонент и составное Представление

Первым шагом будет создание компонента и составных классов для Представления. Эти классы должны быть описаны как абстрактные, должны быть подклассами и не должны порождать экземпляры, как показано в Примере 12-7.

Пример 12-7. ComponentView.as


package {



import flash.errors.IllegalOperationError;

import flash.events.Event;

import flash.display.Sprite;



// АБСТРАКТНЫЙ класс (от него нужно наследовать, не создавая экземпляра данного класса)

public class ComponentView extends Sprite {

{



protected var model:Object;

protected var controller:Object;



public function ComponentView(aModel:Object,aController:Object=null) {

this.model=aModel;

this.controller=aController;

}



public function add(c:ComponentView):void {

throw new IllegalOperationError("add operation not supported");

}



public function remove(c:ComponentView):void {

throw new IllegalOperationError("remove operation not supported");

}



public function getChild(n:int):ComponentView {

throw new IllegalOperationError("getChild operation not supported");

return null;

}



// АБСТРАКТНЫЙ метод(должен быть замещен в классе-потомке)

public function update(event:Event=null):void {

}



}

}

}


Класс ComponentView из Примера 12-7 определяет абстрактный интерфейс для Представления компонента. Это похоже на класс классического компонента из Главы 6, но с несколькими ключевыми отличиями. Класс ComponentView хранит ссылку на Модель и Представление, и содержит конструктор. Не все Представления обрабатывают ввод пользователя, и компонентное Представление может быть сконструировано с простой передачей экземпляра Модели. Поэтому параметр aController принимает в конструкторе значение null по умолчанию. Также обратите внимание, что класс ComponentView унаследован от класса Sprite. Это логично, поскольку большинство Представлений рисуют пользовательский интерфейс на сцене. Мы можем использовать свойства и методы, реализованные в классе Sprite, для рисования и добавления объектов в список отображения.

Метод update( ) должен вести себя как абстрактный метод. Дочерние Представления, являющиеся потомками ComponentView, должны заместить и реализовать метод update( ), чтобы уметь обновлять свою часть пользовательского интерфейса. По этой причине методу передается параметр типа Event. Этот параметр также по умолчанию установлен в null, что позволяет вызывать update() без передачи события как параметра. Такой подход полезен, когда изначально отрисованный пользовательский интерфейс находится в своем состоянии по умолчанию, и наш следующий пример иллюстрирует это.

Класс CompositeView расширяет ComponentView и замещает методы, которые отвечают за дочерние Представления.

Пример 12-8. CompositeView.as


package {



import flash.events.Event;



// АБСТРАКТНЫЙ класс (от него нужно наследовать, не создавая экземпляра данного класса)

public class CompositeView extends ComponentView {



private var aChildren:Array;



public function CompositeView(aModel:Object,aController:Object=null) {

super(aModel,aController);

this.aChildren=new Array ;

}



override public function add(c:ComponentView):void {



aChildren.push(c);

}



override public function update(event:Event=null):void {

for each (var c:ComponentView in aChildren) {

c.update(event);

}

}



}

}


Обратите внимание на замещаемую (override) функцию update( ) класса CompositeView в Примере 12-8. Она вызывает метод update у всех дочерних классов. Поэтому, вызов функции update() в корне структуры составного Представления приведет к распространению обновления по структуре и обойдет дерево компонента, обновляя все Представления. Давайте расширим классы CompositeView и ComponentView, и создадим структуру Представлений, чтобы посмотреть как это работает

вторник, 21 октября 2008 г.

Application.application.url in Flash AS3 //Доступ к информации загрузчика

Application.application.url in Flash AS3, renaun.com

The solution to accessing the loader information url property is quite easy in Flash ActionScript 3. But when you Google for the solution its not obvious. Hence I am creating a post about it.

In Flex you can access the url of the SWF by accessing Application.application.url. What this value represents is the root.loaderInfo.url property. So in Flash and AS3 you would do this:


var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.border = true;
addChild(tf);

tf.appendText("params:" + "\n");
try {
var keyStr:String;
var valueStr:String;
tf.appendText(LoaderInfo(this.root.loaderInfo).url + "\n");
var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters;
for (keyStr in paramObj) {
valueStr = String(paramObj[keyStr]);
tf.appendText("\t" + keyStr + ":\t" + valueStr + "\n");
}
} catch (error:Error) {
tf.appendText(error.toString());
}


The important part is accessing the root's loaderInfo object. The above code also shows how to access the FlashVar parameters in ActionScript 3.

Example code referenced from here.

среда, 24 сентября 2008 г.

Компилятор флеша на флеше

Финал обсуждения "Собрать MovieClip" приводит к очень важному ресурсу:
http://eval.hurlant.com/
Здесь есть некая библиотечка, которая позволит откомпилировать код "налету" и отправить готовый SWF на сервер!

четверг, 14 августа 2008 г.

Пробуем haxeVideo. //Обзор HaxeVideo

Пробуем haxeVideo. Flash. Flex. AIR. Haxe.
Хорошо написано о том, где скачать, куда распаковать, рабочий пример (на AS3).

Ключевые фразы:
Компилируем приложение и запускаем. В директории установки haxeVideo, в папке videos можно увидеть файл temp.flv, медленно увеличивающего свой размер по мере поступления потока на сервер.
В итоге мы запустили сервер haxeVideo и написали простейшее приложение для него, которое передает поток для записи его на сервере. Также в директории установки haxeVideo можно найти исходники сервера и пример клиентского приложения, написанные на haxe.

Как сделать заливку фона повторяющимся (тайленым) изображением. //Пример кода

Flex 2 Application Repeating BackgroundImage Style (updated).

В кратце - класс экстендит RectangularBorder и осуществляет программную заливку.

Код прилагается:
http://renaun.com/flex2/posts/repeatedbackground/index.html

Стандарты кодирования в AS3. //Полезно

Стандарты кодирования в AS3. Flash. Flex. AIR. Haxe.

Статья посвящена систематизации стиля кодирования AS3.

http://flash-santer.com/docs/Coding%20Standards.doc - документ, описывающий систему.

четверг, 19 июня 2008 г.

Как узнать параметры компиляции во Flex Builder.

Оригинал. Flashimp

Всё просто:
Открываем файл ".actionScriptProperties" в папке вашего проекта и смотрим:
строчка ноды "‹compiler›" как раз содержит все параметры помпилятора

‹compiler
additionalCompilerArguments="-load-config ../flex-config.xml"
copyDependentFiles="true"
enableModuleDebug="true"
flexSDK="Flex 3"
generateAccessible="false"
htmlExpressInstall="true"
htmlGenerate="true"
htmlHistoryManagement="false"
htmlPlayerVersion="9.0.28"
htmlPlayerVersionCheck="false"
outputFolderPath="bin-debug"
sourceFolderPath="src"
strict="true"
useApolloConfig="false"
verifyDigests="true"
warn="true"›

Создаём в папке проекта файл "flex-config.xml".
За основу берём его же из sdk (flexSDK\frameworks\flex-config.xml).
Убиваем/изменяем что лично вам необходимо.
Не забываем указать используемые библиотеки, но лучше это сделать не конкретно указав каждую, а указать только папки с ними, а компилятор уж сам пусть разбирается, какие юзать:
‹library-path›
‹path-element›libs‹/path-element>
‹path-element›../../frameworks/libs‹/path-element›
‹path-element›../../frameworks/libs/player‹/path-element›
‹path-element›../../frameworks/locale/{locale}‹/path-element›
‹/library-path›

Далее открываем cmd и пишем:
‹url_to_mxmlc.exe› ‹url_to_Main.as› -load-config ‹url_to_flex-config.xml›

Собственно всё :)
Подробнее узнать как писать flex-config.xml и вообще работать с компилятором mxmlc можно узнать из справки к Flex Builder'у.

среда, 14 мая 2008 г.

Повышение производительности AS3 приложений //Очень полезные советы

Оригинал. Flex 2 & Co

Здесь представлены некоторые приемы, которые помогут повысить производительность наших приложений:

1) Создавайте константы для часто используемых объектов типа new Point(0,0) или new Rectangle(0,0,320,240):

//вызов 100000 раз: 75мс
new Point(0,0);
//или
private static const POINT:Point = new Point(0,0);
//8мс
POINT;


Быстрее на 838%

2) Сократите указания на статические члены классов. Вместо этого старайтесь использовать переменные пакета:
//15мс
SomeClass.somevar;
package somepackage{
public const somevar:int;
}
//8мс
somevar;

на 66% быстрее

3) Сохраняйте getter свойства в локальных переменных при их использовании более одного раза.

somesprite.graphics.clear();
somesprite.graphics.beginFill(0x000000);
somesprite.graphics.drawRect(0,0,10,10);
somesprite.graphics.endFill();

// лучше заменить на

var n:Graphics = somesprite.graphics;
n.clear();
n.beginFill(0x000000);
n.drawRect(0,0,10,10);
n.endFill();


4) Создавайте собственные reflection-методы вместо использования getDefinitionByName(getQualifiedClassName(object))
utils reflection
// 503мс
var someclass:Class = getDefinitionByName(getQualifiedClassName(someObject));
// getter reflection
public class SomeClass {
public function get reflect():Class {
return SomeClass;
}
}
// 9мс
var someclass:Class = object.reflect();

быстрее на 5489%

5) Страрайтесь использовать строгое типизирование

6) Приводите к нужным типам, например, при чтении из массива.
Быстрее будет обращаться к image

var image: BitmapData = images[index];
image.getPixel(x,y)
//чем к
images[index].getPixel(x,y);


7) Где возможно, используйте int вместо Number

8) Операторы побитового сдвига работают быстрее:

Побитовый сдвиг влево быстрее на 300% при умножении на любую степень двойки:

x = x * 2;
x = x * 64;
//равно:
x = x << 1;
x = x << 6;


Побитовый сдвиг вправо быстрее на 350% при делении на любую степень двойки:

x = x / 2;
x = x / 64;
//равно:
x = x >> 1;
x = x >> 6;


Извлечение компонентов цвета:

//24bit
var color:uint = 0x336699;
var r:uint = color >> 16;
var g:uint = color >> 8 & 0xFF;
var b:uint = color & 0xFF;
//32bit
var color:uint = 0xff336699;
var a:uint = color >>> 24;
var r:uint = color >>> 16 & 0xFF;
var g:uint = color >>> 8 & 0xFF;
var b:uint = color & 0xFF;


Объединение компонентов цвета:

//24bit
//24bit
var r:uint = 0x33;
var g:uint = 0x66;
var b:uint = 0x99;
var color:uint = r << 16 | g << 8 | b;

//32bit
var a:uint = 0xff;
var r:uint = 0x33;
var g:uint = 0x66;
var b:uint = 0x99;
var color:uint = a << 24 | r << 16 | g << 8 | b;


9) Обмен значениями численных переменных без использования временной переменной:

var t:int = a;
a = b;
b = t;
//равно:
a ^= b;
b ^= a;
a ^= b;


Быстрее на 20%.

10) Инкремент/декремент.
Внимание: это пример понижения производительности, но зато есть возможность понизить читабельность кода для врагов:)

i = -~i; // i++
i = ~-i; // i--


11) Смена знака с помощью NOT или XOR (говорят на 300% быстрее):

i = -i;
//равно:
i = ~i + 1;
//или
i = (i ^ -1) + 1;


12) Подсчет остатка

Если делитель является степенью двух, то остаток можно подсчитать быстрее на 600% следующим образом:
остаток = делимое & (делитель - 1);

x = 131 % 4;
//равно:
x = 131 & (4 - 1);


13) Проверка на четность/нечетность:

isEven = (i % 2) == 0;
//равно:
isEven = (i & 1) == 0;


Быстрее на 600%.

14) Абсолютное значение. Версия 1 быстрее на 250%, чем Math.abs(), а версия 2 быстрее на 20%, чем версия 1.

//версия 1
i = x < 0 ? -x : x;
//версия 2
i = (x ^ (x >> 31)) - (x >> 31);


15) Сравнение двух числе на равенство знаков

eqSign = a * b > 0;
//равно:
eqSign = a ^ b >= 0;


На 35% быстрее.

16) Быстрое конвертирование цвета из R5G5B5 в R8G8B8


R8 = (R5 << 3) | (R5 >> 2)
G8 = (R5 << 3) | (R5 >> 2)
B8 = (R5 << 3) | (R5 >> 2)


17) a++ быстрее, чем a = a + 1 и т.п.

18) Умножение быстрее деления.

Лучше использовать a = b*.5 вместо a = b / 2

19) int(1.5) быстрее, чем Math.floor(1.5)
Аналогично int(1.5) + 1 быстрее, чем Math.ceil(1.5)


четверг, 3 апреля 2008 г.

Презентации с Флэш-потрошителя

Ниже приводятся две презентации, позаимствованные с Флэш Потрошителя.

Эльдар Прилуцкий: Событийная модель AS3.0, доклад c UAFPUG-1
Ростислав Сирык: PureMVC в картинках, доклад c UAFPUG-1

Модифицировать сообщения, посланные в блог через функцию SlideShare "Embed" не представляется возможным, поэтому, из соображений полит-корректности постю это сообщение.

PureMVC в картинках - часть 1

Событийная модель Action Script 3.0 //www.flash-ripper.com

вторник, 25 марта 2008 г.

Что мы знаем о 3D-движках во Flash? //Обзор 3D Flash-технологий

Оригинал. Флэш Потрошитель

Трехмерные миры во флэше растут не по годам, а по часам. Что у нас есть сегодня?

Papervision3D
Отец большинства современных трехмерных движков для Flash. Довольно быстро развивается, имеет экспериментальные ветви разработки. Куча демок (по первой ссылке). Open Source.

Away3D
Полностью самостоятельный движок, хотя изначально базировался на коде Papervision3D, но по ходу проекта был переписан практически заново. Создан Александром Задорожным из Киева (код, насколько я знаю, редактировался в FAR'е). Содержит массу уникальных возможностей, в т. ч. для текстурирования, освещения и придания рельефа поверхностям. Признан настолько хорошим, что авторы самого Papervision3D решили включить наработки Away3D в свой основной проект. К работе над Away3D уже подключилось несколько талантливых разработчиков. Open Source.

Sandy
Известен тем, что в использовании еще проще, чем Papervision3D (не базируясь на нем ни в коей мере), хотя и не имеет такой популярности. В общем, я не очень много знаю про Sandy, но демки у него тоже красивые. Open Source.

FFilmation AS3 Flash Isometric EngineМногообещающий изометрический движок (на русском),
показывающий очень неплохую производительность. Open Source.

Игровая платформа Alternativa Platform
Платформа для трехмерных игр, разрабатываемая Группой Товарищей из Перми. За флэш отвечает Антон Волков. Движок впечатляет уникальными возможностями и перфекционистской проработкой всего на свете, имеет продуманную схему интеграции с сервером.

ZenBullets Flash Isometric 3D Game Engine
Про этот движок я знаю еще меньше, позиционируется как изометрическая игровая платформа, но демки пока весьма скромные.

SWFZ
... кажись, единственный честный рейтрейсер (отрисовка по-пиксельно)

понедельник, 24 марта 2008 г.

Создание кастомного Design-time View для своего Flex 3 компонента //Важно

Оригинал. Флэш Потрошитель

Иногда необходимо сделать кастомный Design-time Preview для компонента (это его вид в "Design View" Flex Builder-а). Для этих целей в Adobe Flex 3 SDK есть недокументированый класс mx.core.UIComponentGlobals. В этом волшебном классе лежит не менее волшебное поле designMode:Boolean.
В Design View среда Flex Builder пытается "выполнить" код и отобразить что-либо, следовательно можно прописать проверку на designMode и делать то, что хотим.
Итак:1. Возьмем ActionScript-компонент для Flex Bulder 3.2. Заоверрайдим метод createChildren():
override protected function createChildren():void {
super.createChildren();
if (UIComponentGlobals.designMode) {
//здесь мы создаем child-ы, которые будут в design mode
}
}

3. Заоверрайдим метод updateDisplayList():
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (UIComponentGlobals.designMode) {
//здесь мы рисуем то, что будет видно в design mode
}else {
//а здесь то, что в runtime
}
}

Вуаля! Пример компонента можно взять здесь.

воскресенье, 9 марта 2008 г.

AS2 автоматическая сборка компонентов без Flash IDE, с помощью FlashDevelop //Инструкция

Оригинал.

Да-да стоят перед некоторыми и такие задачи :)

Итак, надо:
собрать swc, включающий swf компонента, catalog.xml, asi-файлы классов.

swf должен содержать клип, ассоциированный с классом компонента и все
графические ассеты в библиотеке.

здесь помогает swfmill - пишем xml собираем swf. ( :) предварительно
пришлось поразбирать несколько swf, компиленных во FLASH IDE чтоб
понять как писать xml)

<... редакция класса ... >

компилим mtasc - с инъекцией кода (проще говоря обновляем классы в ролике)

для генерации asi используем igen из тулзов flashdevelop'a
(оказывается asi это intrinsic :) )

пишем bat-файл (запускаем его как post-build команду), нечто вроде:

rem установка переменных

set tools="C:\Documents and Settings\ddns\Local Settings\Application
Data\FlashDevelop\Tools\"

rem вызываем igen

%tools%\igen\igen -clean src bin

rem переименовываем получившиеся *.as файлы в *.asi

for /R bin\ %%A in (*.as) do if exist %%A (
erase /q bin\%%~nA.asi // если такой файлик есть то стираем его.
rename %%A %%~nA.asi
)

erase bin\3d.swc

rem архивируем winrar'ом в zip

C:\Progra~1\winrar\winrar a -afzip bin\3d -r -ep1 -m5 -x*.bat -x*.exe bin\

rem изменяем расширение на *.swc
rename bin\3d.zip 3d.swc

rem :) опционально подкладываем файлик в папку компонентов флеша.

copy /Y /B bin\3d.swc "C:\Documents and Settings\ddns\Local
Settings\Application Data\Adobe\Flash
CS3\en\Configuration\Components\"

/////////////////////


Остается нерешенным вопрос, а как бы сгенерировать автоматически catalog.xml
для компонента?
Кто-нибудь что-нибудь посоветует?

xml вида:

<componentPackage xmlns="http://www.macromedia.com/flash/swccatalog/7">
<component id="myComponent" class="ComponentClass"
implementation="libc.swf" iconFile="libc.png"
src="Component3Dworks.asi" modified="1204586771">
<movieBounds xmin="0" xmax="11000" ymin="0" ymax="8000" />
<include id="boundingBox_mc"/>
<include id="activity"/>
<exportAfter id="__Packages.ComponentClass"/>
<class id="ComponentClass" >
</class>
<class id="MovieClip" >
</class>
<asset id="boundingBox_mc" modified="1204576209">
</asset>
<asset id="activity" modified="1204578626">
</asset>
<asset id="__Packages.ComponentClass" src="ComponentClass.asi"
modified="1204586020">
</asset>
</component>

воскресенье, 24 февраля 2008 г.

AIR Applications Ext. Updating //Приложение к статье RAFPUG 3

Оригинал. Flashimp.ru

Переписал com.codeazur.utils.AIRRemoteUpdater и вот что получилось: UpdaterExample Чтоб увидеть в работе выполните вследующие действия:
-- импортируйте во флекс скачанный проект
-- откройте конфигурационный файл проекта «UpdaterExample-app.xml»
-- измените в нём значение в ноде «» на 1 Получится так «1»
-- скомпилите проект
-- установите только что созданное приложение
-- найдите в «Program Files» наше приложение и в его корневую директорию скопируйте (если её нет) папку «assets» , которая лежит у Вас в импортированном проекте в папке «src». В этой папке должен лежать дистрибутив AIR-приложения с тем же ApplicationID и большим значением версии в «UpdaterExample-app.xml». Имя дистрибутива я «гвоздями» забил: Открываем в проекте «scripts/update.as» и смотрим восьмую строку.
-- идём на «рабочий стол» и запескаем наше приложение
-- давим кнопку «Alert applicationDescriptor»
-- давим кнопку «Update» и радуемся жизни :)

вторник, 19 февраля 2008 г.

Как настроить правильную выдачу AIR-файлов с сервера //Строчка к конфигурации Apache

Оригинал. Флэш Потрошитель

Чтобы сервер давал пользователям скачать с него AIR-файлы, нужно указать ему их MIME-тип:

AddType application/vnd.adobe.air-application-installer-package+zip .air

Если вам повезет, тип указывать не придется. Если не повезет, или везение закончится при обновлении серверного ПО, то пользователи вместо AIR-файлов будут получать не AIR-файлы.

Я внедрил эту информацию в Apache через файл .htaccess в соответствующем каталоге — и все.
Если вы решите поступить так же, то учтите, что предпочтительнее добавить MIME-тип в конфигурацию сервера (а не в .htaccess) и сохраните производительность, ведь конфигурация читается один раз на старте, а файлы .htaccess запрашиваются значительно чаще — при доступе к файлам.

понедельник, 18 февраля 2008 г.

Средства программной анимации: где взять, что и получить за это. //Твинеры разных сортов

Оригинал. 33 коровы.

Большинство наверое использовала в своих проектах для программной анимации класс mx.transitions.Tween, так знайте он не одинок в своем роде). Кто его не видел — исправляетесь, прочитав его описание с примерами.

Всего существует несколько проектов, которые помогают программировать анимацию, в начале классы от “родного” производителя:
  • mx.transitions.Tween, есть как и в CS3 так и МХ-8 флешах )
  • mx.effects.Tween есть в как и в AS2 так и AS3 вариантах, AS3 примечателен тем, что лежит в основе всех эффектов используемых во Flex, в использовании не очень удобен, но терпим, он единственный доступен, по умолчанию, во флексе.

Оба класса имеют недостатки: если экземпляр класса описан как локальная переменная то мусорщик свободно может его убить и эффект не до играет до конца.

И классы от стороннего производителя:

  • Tweener (caurina.transitions.Tweener), домашняя страничкаРадует поддержкой ActionScript 2.0, for Flash 7 and Flash Lite 2.0 ActionScript 2.0, for Flash 8, ActionSctipt 3.0, также портирован для JavaScript и haXe. Рост тоже очень радовался за него.
  • TweenLite, обещают быструю производительность и дополнительные настройки уравнений движения. Есть версия для ActionScript 2.0 и ActionScript 3.0, Страницы содержат описание, примеры кода и использования данного класса
  • AS3 Animation System v2.0 — много очень много разных плюшек, заточеных под AS3, нужно просто полистать документацию (лежит в архиве с исходниками лежит в архиве с исходниками )
  • GOASAP. Самый шустрый из твинов. Ребятки чтобы доказать это наваяли тесты производительности

Как видно из этой диаграммы cтандартный твин просто отдыхает, что есть обидно( а если учитывать ресурсоемкость флекс-фреймворка то это вобще плохо.
В данной статье я не рассматривал классы которые имею только AS2 версию, потому что это уже не актуально!

четверг, 17 января 2008 г.

Вся правда о ASDoc комментариях. Часть первая. Создание ASDoc комментариев. //Выбраны основные положения

Оригинал. LIFE.Flash.

А вместе с ASDoc пришел новый набор правил, с которыми я хотел бы вас познакомить. Правил довольно много. Формат ASDoc это, модифицированный под ActionScript, формат javadocs.

Элементы, поддерживаемые в ASDoc

ASDoc поддерживает следующие элементы, встречающиеся в ActionScript файле:

  • многострочные комментарии (multi-line comments)
  • ASDoc теги
  • определения class и interface
  • свойства
  • методы
  • set/get методы
  • теги метаданных (metadata tags)

Включение ASDoc комментариев

Документация в исходном коде, включается в комментарии, которые начинаются с /** (две звездочки) и заканчиваются */ .Если вы используйте многострочный текст, для документирования того или иного элемента кода, разделяйте каждую новую строчку промежуточной (или как ее еще называю – ведущей) звездочкой. Применение данного метода делает ваш код более читабельным и, что не менее важно, гарантирует правильный синтаксический анализ ваших комментариев.
Когда ASDoc выполняет грамматический разбор комментариев, ведущие звездочки (*) после начала комментария /**, табуляция и пробелы (если они есть) после ведущих звездочек, удаляются. Остается лишь текст.

Пример ASDoc комментария:

/**
* Comment text.
*
* @tag Tag text.
*/

Для того, что бы добавить дополнительный параграф используйте стандартный HTML-тег <p></p>.

Вставлять комментарий необходимо до объявления класса, интерфейса, конструктора или тега метаданных.

ASDoc игнорирует комментарии, вставленные в тело функции. Признается только один комментарий, который описывает функцию до ее объявления.
Также, распространенной ошибкой, является вставка комментария описывающий класс, не над непосредственным объявлением класса, а над import. Избегайте данной ошибки, так как ASDoc просто проигнорирует такой комментарий.

Основное описание начинается сразу после разделителя /** и продолжается до раздела тегов. Первое предложение основного описания, должно содержать краткое, но полное описание сущности комментируемого (класса, функции, метода, свойства и т.д.). Основное описание заканчивается сразу после первой точки или разделителя строки (\r).
Секция тегов, начинается сразу после первого тега, который объявляется символом @ в начале линии. С помощью тегов создаются отдельные заголовки, например такие как –

  • param (параметры),
  • return (результаты возврата функции), а также
  • see (смотреть, т.е. своеобразная ссылка, на другую функцию, документацию которой необходимо прочитать).
Вы можете создавать неограниченное число тегов; некоторые теги могут повторяться, например, такие как @param и @see, но (!) другие нет.

ASDoc генерирует документацию всех публичных элементов ActionScript-класса, даже если вы игнорируете комментарии. Если вы хотите что бы ASDoc игнорировал какой-то элемент, вы можете использовать тег @private. Тег @private может содержать дополнительный пояснительный текст.
Тегом @private, вы можете запретить генерацию не только приватных элементов класса, но и всего класса в частности (так как документация генерируется и для всех публичных классов тоже). Для этого необходимо включить тег @private в описание класса.

Несколько правил парсинга (синтаксического анализа) ASDoc комментариев:

  • Все элементы кода, находящиеся после ASDoc комментария, копируются в генерируемый файл документации.
  • Если у ASDoc комментарий отсутствует, то в элемент кода генерируется без всякой документации.
  • Если в ASDoc комментарии встречается тег @private, ASDoc игнорирует это элемент кода (если эта функция не изменена в конфигурации ASDoc).
    В ASDoc однострочный комментарий // и многострочный комментарий, начинающийся с одной звездочкой /*, игнорируются.
  • Форматированные участки (<p>, <b>, <i> и т.п.) встречающиеся в ASDoc комментариях допускаются. Но учтите, некоторые элементы должны вводиться в виде кодовых эквивалентах HTML. Например, знак больше (>) или меньше (<) должны быть прописаны как < и >. Или например амперсанд “&” должен быть прописан как &.
  • Не забывайте, что теги HTML обязаны наследовать правила форматирования формата XML, т.е. если вы открываете тег, то он должен быть обязательно закрыт. Например тег <li> должен быть закрыт тегом </li>.

ActionScript разработчики знают о том, что свойства, схожие по типу данных, можно объявлять через запятую. Но, при генерации документации, такая особенность не учтена, что в принципе вполне логично. Каждое свойство должно объявляться индивидуально.

Геттер/сеттер методы обрабатываются ASDoc отдельно, так как эти элементы используются как свойства, хотя на самом деле ими не являются. Поэтому ASDoc создает для каждого геттер/сеттер метода документацию, аналогичную документации свойств.
Обычно для геттер/сеттер метода создается единый комментарий, с одним описанием. А сеттер комментируется тегом @private. Это рекомендуется делать, так как обычно геттер объявляется раньше сеттера.

ASDoc может выдать ошибку, если ваш исходный файл содержит символы, имеющие кодировку не UTF-8. В этом случае, при генерации документации, ASDoc вернет номер строки, где встречаются некорректные символы.

Обработка метаданных

Для определения элементов компонента, Flex использует теги метаданных. ASDoc поддерживает теги метаданных и обращается к ним также, как к методам и свойствам.Поддерживаемые теги метаданных в ASDoc:

  • [Event(name=" eventName ", type=" eventType ")]
  • [Style(name=" styleName ", type=" type ", format=" format ", inherit="yesno")]
  • [Effect(name=" effectName ", event=" triggeringEventName ")]
  • [Bindable("event="eventname")]
  • [DefaultProperty(" name ")]
  • [Exclude(name=" elementName ", kind="propertymethodeventstyleeffect")]

Разработчики применяют теги метаданных, чтобы документировать события, стили, эффекты, применяемые в классе. Метаданные, бывают в виде [Event args], [Style args], и [Effect args] и обычно создаются сразу после объявления класса.

/** * Defines the name style. */
[Style "name"]

Для событий и эффектов, тег метаданных включает в себя имя класса, непосредственно связанного с событием или эффектом. Приведем пример из класса mx.controls.Button:

/**
* ... this event is dispatched repeatedly as long as the button stays down.
*
* @eventType mx.events.FlexEvent.BUTTON_DOWN
*/
[Event(name="buttonDown", <strong>type="mx.events.FlexEvent"</strong>)]

Для такого комментария, ASDoc сделает следующее:

  • В конечном файле, класса mx.controls.Button, ASDoc создаст ссылку на класс события (mx.events.FlexEvent), определенного в аргументе type.
  • Также, ASDoc копирует описание константы, значение которой возвращает Event.type класса Button. В ASDoc вы можете использовать тег @eventType, для определения константы. В данном примере, ASDoc копирует описание константы mx.events.FlexEvent.BUTTON_DOWN класса Button. Константа mx.events.FlexEvent.BUTTON_DOWN определяет значение объекта, связанного с событием.

В ASDoc комментарии, для константы mx.events.FlexEvent.BUTTON_DOWN вы должны вставить в таблицу возвращаемые значения (bubbles, cancelable, target, и currentTarget) свойства класса Event.

Для примера, рекомендуется посмотреть весь класс mx.controls.Button и классы mx.events.FlexEvent.
Для каждого метода или свойства, вы должны определять, какие события отправляются (или как говорят “диспатчатся”) методу или свойству. Для этого необходимо использовать тег @event описывая каждый метод или свойство. Тег @event имеет следующий формат:

@event eventName eventObjectClassName [description]

среда, 16 января 2008 г.

Опасные FlashVars //Советы относительно Flashvars

Оригинал. Блог одиноко стоящего игрока вспышки.
Flashvars долго казались мне самой безобидной субстанцией.Однако и у них есть пара опасных моментов.

  • Не забываем, что все данные, переданные через flashvars - это String.То есть если нужно передать число или булеву переменную - будьте добры, используйте приведение типов. И лучше руками, не полагаясь на автомат.
  • Недавно обнаруженная грабля.Допустим у нас есть флешка, на основном таймлайне которой мы импортируем пакет flash.filters.* . Или не импортируем на таймлайн, но создаем переменную некоего класса SomeClass, в коде которого мы как раз и производим этот импорт.Так вот ежели мы передадим flashvar flash=kill_my_package, то мы наглухо убъем доступ к пакету flash. Точно так же можно убить пакеты mx, ru, com и все необходимое )). Однако если мы будем импортировать пакеты на временной линейке любого другого мувиКлипа, лежащего на основной линейке, то все будет работать.

А вывод прост: следим за именами переменных, откуда бы они не приходили. Потому как и во вложенном клипе можно убить доступ к пакету, просто объявив в нем переменную

var flash:Boolean = false;

вторник, 15 января 2008 г.

SmartFont //Класс загрузки внешних библиотек шрифтов

Оригинал. Блог одиноко стоящего игрока вспышки.

Над проблемой загрузки внешних библиотек шрифтов не трудился, наверное, только ленивый.
Вариантов решения проблемы много. Коммерческие, не коммерческие, рабочие, не рабочие, удобные и неудобные.
Вашему вниманию мой класс SmartFont.На сайте поддержки описаны все телодвижения, здесь же упомяну только общий ход использования:

var my_font:SmartFont = new SmartFont();
my_font.load(“someFont.swf”);
my_font.onLoad = function():Void {
trace(“Шрифт: “+this._font+” готов к использованию”);
}

понедельник, 14 января 2008 г.

С чем же едят H.264? //О поддержке видео-кодека H.264 flash-плеером

Оригинал. Блог одиноко стоящего игрока вспышки.

Итак, о поддержке видео-кодека H.264 мы услышали, но как с ним работать в условиях флеш-плеера? Да ничего особенного, как оказалось. Все тот же Джастин Эврертт-Чёрч, все разложил по полочкам.Даже если ваш проект скомпилирован под 7-й плеер, все равно вы можете работать с этим кодеком. Все дело именно в новом плеере.
Раньше у нас было два кодека on2vp6 и SorensonSpark. Оба кодека использовались в контейнере FLV. Новый кодек пакуется в контейнер mp4 и это жесткое требование - мп4 и все тут. К слову сказать - это общепринятая практика. Многие mov, 3gp и m4v файлы пакуют видео через кодек h.264 именно в контейнер mp4.Если же мы имеем фал другой организации - тогда, конечно, флеш плеер ничего сним сделать не сможет.Если вы сами пакуете свои видео файлы - то тут все понятно - правильно пакуем, и все будет хорошо. Если вам попался чей то видео файл - то самый простой способ проверить его совместимость с плеером - просто проиграть его в нем )