среда, 20 мая 2009 г.

Интеграция Adobe Flex и IBM WebSphere Portal

Integrating Adobe Flex and IBM WebSphere Portal - статья под таким названием была недавно опубликована на сайте компании IBM в разделе developerWorks инженерами подразделения IBM China.

Статья представляет собой подробную инструкцию по созданию клиент-серверного приложения на базе Adobe Flex и IBM WebSphere Portal. В ней рассматриваются такие моменты как создание проектов в Adobe Flex Builder и IBM Rational Software Architecture. Особое внимание уделяется процедуре упаковки Flex-приложения, Web-компилятора, пакета BlazeDS и Java-классов удаленного сервиса в один портлет и развертыванию его на сервере приложений IBM WebSphere. Вскользь упоминается возможность сокращения размера конечного WAR-файла за счет использования разделяемых библиотек.

Не вижу смысла разбирать эту статью более подробно. При желании вы можете сами с ней ознакомиться. Материал там подается достаточно доходчиво и сопровождается примерами. Примечательным же, на мой взгляд, является сам факт появления такой статьи на сайте компании IBM. Я склонен рассматривать это как сигнал партнерам и клиентам IBM о том, что Adobe Flex можно и нужно использовать в проектах на базе продуктов семейства IBM WebSphere. Если учесть, что основными потребителями продуктов такого класса в России являются такие гиганты как Центральный банк РФ, ОАО "РЖД", РАО "ЕЭС России", Альфа-банк и подобные им, то можно предположить, что Flash-платформу ждет большое будущее уровня enterprise.

P.S. В августе 2008 года в беседе с Константином Ковалёвым я предположил что-то подобное. Это была всего лишь ироничная шутка, но ирония оказалась глубже.

пятница, 30 января 2009 г.

Очередь асинхронных ShaderJob не работает никак, потому что она не существует.

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

Задача оказалась довольно простой.

Вот пример класса, реализующего очередь:

package ru.dmitrykrasnov.service.shader {
  import flash.display.ShaderJob;
  import flash.events.ShaderEvent;

  public class ShaderJobQueue {
      public static const INSTANCE:ShaderJobQueue = new ShaderJobQueue();

      private var queue:Vector.<ShaderJob>;
      private var inProgress:Boolean;

      public function ShaderJobQueue() {
          if (INSTANCE != null) throw new Error("Сonstructor is locked.");
          queue = new Vector.<ShaderJob>();
      }

      public function addToQueue(shaderJob:ShaderJob):void {
          queue.push(shaderJob);
          if (!inProgress) {
              inProgress = true;
              run();
          }
      }

      private function run():void {
          var shaderJob:ShaderJob = queue.shift();
          shaderJob.addEventListener(ShaderEvent.COMPLETE, shaderJobCompleteHandler);
          shaderJob.start();
      }

      private function shaderJobCompleteHandler(event:ShaderEvent):void {
          event.target.removeEventListener(ShaderEvent.COMPLETE, shaderJobCompleteHandler);
          if (queue.length > 0) {
              run();
          } else {
              inProgress = false;
          }
      }
  }
}

При необходимости, этот класс можно использовать самостоятельно, вставив в свой код строку:

ShaderJobQueue.INSTANCE.addToQueue(shaderJob);

Но это некрасиво. Эстетики ради, можно немного усовершенствовать класс ShaderJob:

package ru.dmitrykrasnov.service.shader {
  import flash.display.Shader;
  import flash.display.ShaderJob;

  public class ShaderJobEnhanced extends ShaderJob{
      private var addedToQueue:Boolean;

      public function ShaderJobEnhanced(shader:Shader = null, target:Object = null, width:int = 0, height:int = 0) {
          super(shader, target, width, height);
      }

      public override function start(waitForCompletion:Boolean = false):void {
          if (waitForCompletion || addedToQueue) {
              super.start(waitForCompletion);
          } else {
              addedToQueue = true;
              ShaderJobQueue.INSTANCE.addToQueue(this);
          }
      }
  }
}

Тогда метод ShaderJobEnhanced.start() будет полностью соответствовать документации метода ShaderJob.start().

Честно говоря, сейчас я даже рад, что Adobe не предоставила готовую реализацию очереди т.к. у нас есть возможность сделать эту реализацию сколь угодно специфичной (например, сейчас мне нужна очередь с динамической сортировкой). Только надо было как-то более адекватно отразить это в документации.

среда, 14 января 2009 г.

Как работает очередь асинхронных ShaderJob?

То ли  я недостаточно сообразителен, то ли документация не совсем соответствует действительности. Вобщем, суть проблемы такова:

В документации по ShaderJob.start() сказано:

Русская версия: "Одновременно может выполняться только одна фоновая операция ShaderJob. Все операции затенения помещаются в очередь и выполняются последовательно. При вызове метода start() во время выполнения операции затенения еще одна операция добавляется в конец очереди. Впоследствии, когда наступает очередь, она выполняется."

Английская версия: "Only one background ShaderJob operation executes at a time. Shader operations are held in a queue until they execute. If you call the start() method while a shader operation is executing, the additional operation is added to the end of the queue. Later, when its turn comes, it executes."

Но в реальности, при запуске нескольких ShaderJob...

shaderJob1.start();
shaderJob2.start();
shaderJob3.start();

...выполняется только shaderJob1 и все. Никакой очереди и последовательного выполнения.

В чем дело? Что может быть не так?

Буду весьма признателен вам за любую помощь.