Показаны сообщения с ярлыком Flash. Показать все сообщения
Показаны сообщения с ярлыком Flash. Показать все сообщения

2 мая 2012 г.

ActionLinq имплементация языка запросов LINQ для ActionScript.

Многие наверно читали или слышали про язык запросов LINQ.
Это чрезвычайно удобное средства обработки данных. По удобству использование не уступающий и иногда даже немного превосходящий старый добрый SQL. Собственно, почему я это пишу.
Несколько месяцев назад мне нужно было, как то сгруппировать и обработать данные в массиве внутри Flex ActionScript приложения. Но я не хотел обрабатывать объекты просто перебирая их в цикле. И я тогда нашел ActionLinq.
Итак, ActionLinq это практически полная имплементация языка запросов LINQ для ActionScript.
Вот простой пример
package
{
 import flash.display.Sprite;
 import System.Collection.Generic.IGrouping;
 import System.Linq.Enumerable;
 
 /**
  * ...
  * @author ami...[at]mail.ru
  */
 public class AcLinq extends Sprite
 {
  
  public function AcLinq()
  {
   var data:Array = [ { name: "Сергей", age: 20, city: "Москва" }, 
          { name: "Максим", age: 21, city: "Москва" }, 
          { name: "Володя", age: 25, city: "Минск" }, 
          { name: "Сергей", age: 19, city: "Минск" } ];
   
   var new_data:Array = Enumerable.from(data).groupBy(function(name:Object):String
    {
     return name.name;
    }, 
    function(values:Object):Object
    {
     return {age: values.age, city: values.city};
    }, 
    function(name:String, vals:IGrouping):Object
    {
     return { name: name, count:vals.count() };
    }).toArray();
    
    /*
     * А получаем мы в итоге нечто вроде
     * Сергей, 2
     * Володя, 1 
     * Максим, 1*/
    
    trace(new_data);
     
  }
 
 }

}
А самым удобным является что внутри конструкций function() можно определять любые стандартные операторы и конструкции ActionScript и возвращать нужные значения.
На странице wiki  ActionLinq можно прочитать, что поддерживаются многие операторы LINQ. Там же есть кое какие примеры . Так же если хотите больше примеров рекомендую посмотреть на юнит тесты проекта.

6 июля 2011 г.

Adobe Flash Player ActiveX + IronPython с использованием SharpDevelop

Для многих программистов это тривиальная задача но думаю для начинающих этот топик будет полезен.
Наша задача запустить приложение написанное на IronPython использующее Adobe Flash Player ActiveX c применением среды SharpDevelop.

Понадобится: SharpDevelop и любая версия .Net Framework SDK.

Нам нужно создать компонент для палитры компонентов SharpDevelop. Для этого его надо сгенерировать его с помощью утилиты aximp.exe входящей в состав Net Framework SDK. Команда для генерации довольно таки проста

aximp.exe [имя файла ActiveX]

при этом будет сгенерированно [имякласса]s.dll Ax[имякласса]s.dll. aximp.exe обычно расположена в папке C:\Program files\Microsoft.NET\SDK\*версия*\Bin\ а файл ActiveX %windir%\system32\Macromed\Flash\.

Теперь запускаем SharpDevelop и начинаем новый проект "File">"New">"Solution…", в открывшемся окне выбираем "Python">"Windows Application" указываем имя проекта и нажимаем "Create".

Переходим в режим дизайнера форм нажав кнопку "Design". Переходим к панели "Tools" и вызываем контекстное меню панели, выбираем пункт "Configure Sidebar".

В открывшемся окне добавим новую категорию для нового компонента, нажав кнопку "New", и назовем его "ActiveX". После выберем нашу новую категорию и жмем кнопку "Add Components".

В новом окне переходим во вкладку "Custom" и указываем имя на файл сгенерированный утилитой aximp.exe а именно на тот где имя файла начинается с Ax. Жмем "ok" и еше раз "ok".

Теперь бросаем в окно программы компонент "AxShockwaveFlashObjects" из палитры компонентов и устанавливаем свойство "Movie" объекта равным имени файла нашей флешки. Жмем кнопку "Run". Тут у нас может поджидать ошибка

IronPython.Runtime.UnboundNameException: global name 
'AxShockwaveFlashObjects' is not defined
   at Caller.Call
   at BuiltinFunctionCaller.Call5
   at System.Dynamic.UpdateDelegates.UpdateAndExecute7
   at IronPython.Runtime.Importer.Import
   at IronPython.Runtime.Operations.PythonOps.InitializeModule
   at PythonMain.Main

для его устранения нужно добавить в исходный код программы строку.

import AxShockwaveFlashObjects

снова жмем кнопку "Run" и видим результат

С таким же успехом можно добавить и использовать в среде SharpDevelop любой компонент ActiveX.

11 июня 2011 г.

Прикручиваем Adobe Flex к приложению на Delphi.



Adobe Flex предоставляет весьма удобные и наглядные средства визуализации данных такие как OLAP кубы разного рода диаграммы с красивыми эффектами. Мне как то захотелось использовать такую диаграмму в своем приложении написанном на Delphi. Например.
Alternative content
Get Adobe Flash player
Конечно я знаю что Delphi имеется аналогичные компоненты но они как мне кажется в смысле дизайна более «серым»и на фоне «Flex»cовых компонентов. Попробуем встроить Flex приложение в Delphi и передать в него данные для вывода графика.
Поскольку FlashDevelop написан на C# он требует .NET Framework и JRE чтобы скомпилировать Flex приложение. Можно скачать Beta 4-ой версии или стабильную 3-ю при установке нужно отметить «Install Flex SDK» при этом установщик скачает и распакует Adobe Flex SDK. Я использовал бету.
Пишем наше Flex приложение.
Запускаем FlashDevelop. Переходим меню Project > New Project, выбираем Flex 4 Project, жмем OK. Пишем имя нашего приложения(у меня «Flex»).
Вот код нашего приложения.
<?xml version="1.0" encoding="utf-8"?>
<!-- Пример диаграммы встраиваемой в программу Delphi-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:s="library://ns.adobe.com/flex/spark"
               initialize="init()">

    <fx:Declarations>
        <!--Небольшой Эффект -->
        <mx:SeriesSlide id="slideIn"
                        duration="1500"
                        direction="up" />
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import flash.external.ExternalInterface;
            import mx.collections.ArrayCollection;
            
            [Bindable]
            public var danniye:ArrayCollection = new ArrayCollection;
            
            public function fromDelphi(massiv:Array):void
            {
                //Записиваваем полученные данные в массив для Графика
                danniye = new ArrayCollection(massiv);
            }            
            //Эта функция вызывается при инициазизации флекс приложения
            public function init():void
            {
                //Регистрируем внешную функцию
                ExternalInterface.addCallback("fromDelphi", fromDelphi);
            }
        ]]>
    </fx:Script>
    <s:layout>
        <s:VerticalLayout />
    </s:layout>
    <s:Panel title='Пример "нереального" бизнесса'>
        <s:layout>
            <s:VerticalLayout />
        </s:layout>
        <mx:ColumnChart id="myChart"
                        dataProvider="{danniye}"
                        showDataTips="true">
            <mx:horizontalAxis>
                <mx:CategoryAxis dataProvider="{danniye}"
                                 categoryField="MONTH" />
            </mx:horizontalAxis>
            <mx:series>
                <mx:ColumnSeries xField="MONTH"
                                 yField="DOHOD"
                                 displayName="Доходы"
                                 showDataEffect="slideIn" />
                <mx:ColumnSeries xField="MONTH"
                                 yField="RASHOD"
                                 displayName="Расход"
                                 showDataEffect="slideIn" />
                <mx:ColumnSeries xField="MONTH"
                                 yField="PRIB"
                                 displayName="Прибыль"
                                 showDataEffect="slideIn" />
            </mx:series>
        </mx:ColumnChart>
        <mx:Legend dataProvider="{myChart}" />
    </s:Panel>
</s:Application>
Для компиляции и запуска жмем F5.
Delphi приложение.
И так запустим Delphi и начнем новый проект. Свяжем наше приложение с базой данных. Для простоты я использовал ClientDataSet а данные беру из XML файл в формате cds-xml. Бросаем компонент форму указываем путь к XML файлу. Бросаем DataSource свойство DataSet устанавливаем равным ClientDataSet.
Теперь добавляем идем меню Component > Import Active X Control

В появившемся окне выбираем Shockwave Flash и нажимаем кнопку Install. В следующих окнах нажимаем OK и Yes.
Бросаем в окно программы компонент ShockwaveFlash из набора Active X. Добавим в uses XMLIntf, XMLDoc, StdCtrls и напишем процедуру для вызова функции которая будет находится внутри нашей флешки.
procedure TForm1.CdsToXml(datset:TDataSource; flash:TShockwaveFlash);
var i, j : integer;
    filNode, recNode, obNode, arNode, iNode, inNode:IXMLNode;
    xmldoc:TXMLDocument;
begin
try
    //создем Xml документ
    xmldoc:=TXMLDocument.Create(nil);
    xmldoc.Active:=True;

    //Главный тег
    inNode:=xmldoc.AddChild('invoke');
    xmldoc.Encoding:='windows-1251';

    inNode.Attributes['name']:='fromDelphi';        
    iNode:=inNode.AddChild('arguments');    
    arNode:=iNode.AddChild('array');
        
    with datset.DataSet do begin
    {пребираем все записи поля таблыци и взависимосьти от типа поля
    зеркалируем каждое значение в нужные теги}
    first;
        for I := 1 to RecordCount do begin
            obNode:=arNode.AddChild('property');
            obNode.Attributes['id']:=IntToStr(I-1);
            recNode:=obNode.AddChild('object');
            for j := 0 to FieldCount-1  do begin
                filNode:=recNode.AddChild('property');
                filNode.Attributes['id']:=FieldDefs.Items[j].Name;
                
                case Fields[j].DataType of
                    ftString:
                    begin
                        iNode:=filNode.AddChild('string');
                        iNode.Text:=Fields[J].Value;
                    end;
                    ftBoolean:
                    if Fields[J].AsBoolean then
                        iNode:=filNode.AddChild('true')
                    else
                        iNode:=filNode.AddChild('false');
                    ftCurrency:
                    begin
                        iNode:=filNode.AddChild('number');
                        iNode.Text:=FloatToStr(Fields[J].AsFloat);
                    end;
                    ftBCD:
                    begin
                        iNode:=filNode.AddChild('number');
                        iNode.Text:=FloatToStr(Fields[J].AsFloat);
                    end;
                    ftInteger:
                    begin
                        iNode:=filNode.AddChild('number');
                        iNode.Text:=Fields[J].Value;
                    end;
                    ftFloat:
                    begin
                        iNode:=filNode.AddChild('number');
                        iNode.Text:=Fields[J].Value;
                    end;
                    ftDate:
                    begin
                        iNode:=filNode.AddChild('string');
                        iNode.Text:=Fields[J].Value;
                    end;
                    ftDateTime:
                    begin
                        iNode:=filNode.AddChild('string');
                        iNode.Text:=Fields[J].Value;
                    end;
                    ftSmallint:
                    begin
                        iNode:=filNode.AddChild('number');
                        iNode.Text:=Fields[J].Value
                    end;
                    else iNode:=filNode.AddChild('null');
                end;
            end;
            Next;
            end;
        end;
finally
    //Вызаваем фукцию во флешке
    flash.CallFunction(inNode.XML);
    xmldoc:=nil;
end;
end;
Эта процедура будет создаст XML документ в котором будет указанно имя вызываемой функции и ее параметры. Которая будет иметь вид типа. 
<invoke name="fromDelphi">
    <arguments>
        <array>
            <property id="0">
                <object>
                    <property id="MONTH">
                        <string>Январь</string>
                    </property>
                    <property id="DOHOD">
                        <number>1500</number>
                    </property>
                    <property id="RASHOD">
                        <number>700</number>
                    </property>
                    <property id="PRIB">
                        <number>800</number>
                    </property>
                </object>
            </property>
            <property id="1">
                <object>
                    <property id="MONTH">
                        <string>Февраль</string>
                    </property>
                    <property id="DOHOD">
                        <number>2500</number>
                    </property>
                    <property id="RASHOD">
                        <number>1340</number>
                    </property>
                    <property id="PRIB">
                        <number>1160</number>
                    </property>
                </object>
            </property>
            <property id="2">
                <object>
                    <property id="MONTH">
                        <string>Март</string>
                    </property>
                    <property id="DOHOD">
                        <number>1100</number>
                    </property>
                    <property id="RASHOD">
                        <number>820</number>
                    </property>
                    <property id="PRIB">
                        <number>280</number>
                    </property>
                </object>
            </property>
    </arguments>
</invoke>
Пишем в обработчике onCreate нашей формы.
procedure TForm1.FormCreate(Sender: TObject);
begin
//Разделитель точка 
DecimalSeparator:='.';
//Указаваем путь к нашей флешки, здесь она рядом с экзешником
ShockwaveFlash1.LoadMovie(0, ExtractFilePath(Application.ExeName)+'flex.swf');
end;
Бросаем на нашу форму кнопку и вызываем процедуру приготовления XML пакета в котором указанны названия функции нашей флешки и параметры к ней.
procedure TForm1.btn1Click(Sender: TObject);
begin
ClientDataSet.Open;
CdsToXml(DataSet, ShockwaveFlash1);
end;
Компилируем Delphi приложение, находим swf файл скомпилированный на FlashDevelop и кидаем его рядом с экзешником Delphi приложения и запускаем его. Как только флешка загрузится жмем нашу единственную кнопку и радуемся результату :).

Архив с исходниками.