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

Дисклеймер: я сам пользуюсь Flash и пробовал Flex. Делаю это потому, что очень многие вещи, которые Flash может, ни одна распространенная система пока не делает. И на нем можно делать потрясающие вещи (и для них он и нужен). Только запомните, дорогие читатели - делание чего-то приличного на Flash это всегда резьба против волокон, крутка веревок из травы и закат солнца вручную. Новые Макродобовские цацки решают 5 процентов проблем и как правило приносят еще 30 процентов новых.

Чтобы ощутить ситуацию, советую подписаться на Flashcoders. Вот недавно например:

var className:String = 'String'; 
var cls:Function = mx.utils.ClassFinder.findClass(className); 
var object:Object = new cls(); 

Если убогость подобного сниппета не очевидна сразу - надо прочитать его еще раз. И вспомнить, что это всего-лишь скриптовый язык, компилируемый в байткод. Но вместо того, чтобы сделать его удобным, Бангалор делает его “якобы быстрым” (работа его на любой Мак-системе до сих пор чудовищна, потому что плевать).

Или (привязка клипа с нужным классом - при том что класс уже был ему назначен:

Object.registerClass("mFooA", FooA);
var aObject:FooA_Class = FooA_Class(_root.attachMovie("FooA", "FooA", 1));

Или известная радость что…

For historical reasons an object which is of class MovieClip or an object which derives from class MovieClip can’t be instantiated directly via new

Это не чересчур?

Или:

I have a situation where my app doesn’t work on a PC with no sound card installed, because I depend on onSoundComplete for a couple of synchronised triggers and (guess what) onSoundComplete is never called if the machine doesn’t have a sound card. Not unexpected, I guess.

However, unfortunately System.capabilities.hasAudio doesn’t report false. I assume it only returns false for builds of a player that doesn’t have audio (for example, handhelds and so forth).

Вот вместо того, чтобы починить Все Это, или обеспечить нормальную поддержку BiDi-текста (и заняться миллионами совершенно позорнейших багов в самом Flash) Бангалор советует генерить MXML. Единственная причина существования которого - кастрированная виртуальная машина Flash, в которой нету компилятора.

Что же это такое? Ответ прост - это такой Windows-вариант.


Представьте себе перевернутую пирумиду. Острием она стоит на земле, а к верху распухает в большущее дерево Всякого Разного. В самом низу пирамиды - виртуальная машина Flash и законодательный запрет на чьи бы то ни было попытки ее воспроизвести. Вчерне - кривой вариант ECMAScript (кривой - потому что огромное количество функционала добавлено постфактум, и странным образом - например, не удаляются глобальные функции, но при этом добавляются эквивалентные им методы). На нее надеты совершенно клинические завороты с “как-бы-вроде-бы” строгой типизацией, которая (внимание) при компиляции плющит написанный код в традиционные ECMA-прототипы. Результатом этого является крайне сомнительный стиль программирования, в котором неясно. Единственная цель создания этого цирка - привлечение внимания людей, который писали на Java (хотя синтаксис оной тоже переснят не буквально - поскольку авторы страдают криворукостью, по странному стечению обстоятельств ActionScript новой формации более тягучий чем Java). Посчитайте символы:

Java:

public string doStuff() {}

ActionScript:

public function doStuff():String {}

Более того, за счет ограничений ECMA возникают крайне смешные проблемы. Например - в ECMA свойства обьекта и методы делят одно пространство имен (это дурацкое свойство есть и у Python кстати), что ведет к следующему. Есл нам нужно иметь методы-аксессоры, нельзя назвать свойство так же, как методы! То есть если в Ruby я могу определить аксессор в одну строчку, или по крайней мере иметь переменную и методы-аксессоры под одним именем:

attr_accessor :bile
def do_stuff
  @bile = "xxx"
end

то в ActionScript это автоматически будет СЕМЬ строчек и ДВА свойства обьекта (из которых одно - private):

private var _bile:String;
 
public set bile(newBile:String):String {
   return (_bile  = newBile); //doh!
}

public get bile():String {
   return _bile;
}

Кстати, угадайте с трех раз, доступен ли “публичный” атрибут bile в дебаггере. Угадали? Правильно. Как говорил Макс Лапшин прю любителей “постатичнее и побыстрее” - не дай бог еще один jmp придется делать.

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

    override public function get currentLabel():String 
    {
        var str:String = "Override: ";
        str += super.currentLabel;
        return str;
    }

В переводе на нормальный язык

def current_label
   "Override: " + super
end

Причем от такого увлечения ключевыми словами у меня всегда возникает странный вопрос. Что будет, если я возле метода напишу

protected final override intrinsic volatile specific terrific ... ... doStuff():String {}

Пример высосан из пальца но наличие такой механики рано или поздно приводит к ситуации когда комбинацию нужных “симулякров” метапрограммирования приходится собирать как пазл :-(

А на эту тему Бангалор тоже отличился. Симуляция метапрограммирования у них поддерживается с помощью аннотаций (типа [Inspectable]), поскольку создание нормального обьекта-класса, который в состоянии за себя отвечать, средствами ECMA невозможно. Даже если призвать на помощь весь Бангалор и отложить на пару лет выпуск всех продуктов для всех платформ кроме окошек. Из метода класса невозможно узнать класс обьекта. Для справки - это умеет даже PHP 4. Единственный доступный маневр - instanceof. Не typeof, заметьте, поскольку для ECMAScript все бангалорские обьектные танцы называются просто и по-советски - Object. А instanceof - мало того что ключевое слово (а не метод) так еще и строгий предикат - то есть можно проверить, “собака ли собака”, но спросить “что это за животное” нельзя.

На это, в свою очередь, надет рендеринговый движок. Ну не то чтобы плохой движок, нет… ему только Много Лет. Единственное добавление к Движку за последние несколько лет - BitmapData, фактичеси запоздавший (надолго) перенос битмепных API из Директора. Позволяет… ура! блитить пиксели на экран без рисования кривых! Для 2004 года (или когда там вышел 8-й флеш) это просто победа, господа. При этом несколько забывается что

  • …кеширование отрендеренных кадров
  • …гарантированный плейбек хоть на какой-нибудь скорости
  • …контроль за скоростью проигрывания, каким бы неточным он ни был
  • …хотя-бы один знак после запятой в геометрии
  • …удобные (но - ах - медленнее просчитываемые) кривые
  • …встроенный твининг параметров

у движка отсутствуют напрочь, потому что он был создан для компьютеров, которые этого Не Могли. Много лет назад. И воз и ныне там.


Движок дополняет прекрасная авторинговая среда, отличительными свойствами которой являются:

  • …сотни багов
  • …невозможность рендеринга параметрической анимации
  • …кривой дебаггер и ужасный редактор кода
  • …неудобные инструменты точного рисования (не в последнюю очередь обязанные своей кривизной целочисленным координатам)
  • …невозможность рендеринга параметрической анимации

Тенденцию улавливаете? Я не говорю про то, что Flash может как платформа - сам пользуюсь. Двигаемся вверх по дереву…


На авторинговую среду надет набор компонентов (те самые Macromedia Components). Рассмотрим компоненты для создания пользовательских интерфейсов (про видео будет отдельный bile). Компоненты Macromedia отличаются следующим:

  • …не соответствуют по поведению НИ ОДНОЙ графической среде внутри которой Flash будет работать
  • …и визуально тоже не соответствуют
  • …имеют относительно цельный, но очень странный API
  • …и невнятные возможности по наложению Как-бы CSS-стилей. Которые Как-бы работают.
  • …неадекватно ведут себя в геометрии и стеке клипа (поскольку ресайзинг элементов напялен на указанные выше уровни как пятое колесо на телегу)
  • …и спокойно нарушают поведение друг друга

Большое их достинство - их код можно прочитать, и восхититься бангалорством.

С точки зрения графического интерфейса компоненты эти весьма знаменательны, поскольку:

  • …стилизованы под формы но ведут себя несколько иначе
  • …никаких задач кроме датагридов и виджетов форм не решают

То есть, в переводе на понятный язык - пригодны для создания тупых тикерообразных бюрократских апплетов, с которыми между прочим и HTML справляется неплохо. Точнее - выполняют то, что НЕ является сильной стороной платформы в принципе.

Идем выше. На все это напялен (будем называть вещи своими именами) Flex, как Некое Нечто. К сожалению переубедить меня в том что Flex это Некое Нечто фанатам не удастся, потому что Flex - маркетинг. К примеру:

  • …большинство Флексовских контролов имеют те же проблемы, что и описанные выше Макромедиевские
  • …90 процентов виденных мною Flex-демок рисуют графики. В дополнение к бюрократским виджетам и датагридам. В панельках правда.
  • …MXML - псевдокод, призванный замаскировать кривизну Flash runtime. По сути то-же самое что и в Java (ну не можем мы компилировать на лету - ну так давайте дескрипторы писать), только помноженный на трабант (ECMAScript) и Бангалор
  • …а еще это попытка скрыть временную диаграмму - которая все равно выползет и укусит, хоть ты обдескриптись

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


А над этим всем висит еще и потоковое видео. Которое в общем-то интересный зверь – продукт синдрома NIH (Not Invented Here). Что это значит? При наличии 3 видов потокового видео, принадлежащих другим Корпорациям (и имеющим приличные кодеки, транспорты и беплатные стрим-серверы) Макромедиа сделали следующее:

  • …решили сделать свое стриминговое видео, не совместимое ни с каким другим - ни по формату контейнера, ни по кодеку
  • …отчасти потому что рендеринговый движок не в состоянии обеспечить постоянную частоту кадров
  • …купили для него два кодека, один отвратительнее другого (Sorenson Spark и On2 V6)
  • …второй из них лишь потому, что он допускает альфа-каналы
  • …сделали платный стрим-сервер за совершенно неприличное количество денег

Что создало в общем интересный разультат. Google Video и YouTube выбрали именно его - не потому что он качественный или удобный, а из-за популярности проигрывателя. Но в качестве оборотной стороны медали получили отвратнейшее изображениe и крайне странное поведение проигрывателя в зависимости от фаз луны (например - Flash Video скипит кадры и звук, если окно, содержащее плеер, не содержит фокус).


Причем тут Windows, спросит читатель?

Слон на спичечном коробке, дом на слоне, а на доме - аэродром. И с аэродрома Боеинг взлетает.

Именно так выглядит в данный момент Flash-платформа. И все по-настоящему интересные вещи, которые я видел даже на flashconference’06, работали совершенно “непартийным” образом - against the grain, в обход и объезд всего этого нонсенса. И большая часть OSFlash, которая вызывает интерес (типа ActionStep) туда же. И Quasimondo подтвердил, что Макромедиевские контролы для его приложения совершенно не годятся, а были туда шлепнуты потому что “другого не было”. Мой опыт создания небольшого блока Flash-компонентов подтверждает что мне с таким мейнстримом тоже не по пути.

Пример: при всей расширенности ActionScript человек, использовавший Flash для самой что ни на есть традиционной анимации, не может сделать элементарные параметрические прыжки шарика по синусойде, потому что до-сих пор единственный способ хоть как-то отрастрировать параметрическую флеш-анимацию - это снять ее с экрана (ну не убожество ли) или отрастрировать через Director (!!) по два кадра в минуту.

Я буду сильно смеяться когда Макродобы выпустят HIG для флексовых приложений. Все это я пишу не потому что “макинтошнечег и флекс билдера не дали”, как может быть заязвит Клишин (ну не дали, с нами так часто поступают). И не потому что ненавижу Flash (я его использую для конкретных хороших вещей). А потому, что опасно быть фанатом, тем более - фанатом Линии Партии.

Знаю, поскольку сам грешен.