sobota, 1 września 2007

Cairngorm 2.2 - czytnik RSS

Framework aplikacyjny pozwala na tworzenie aplikacji, koncentruje się także na interfejsie użytkownika. Natomiast frameworki architektoniczne służą do opisywania i organizowania struktury powstającej aplikacji. Są wewnętrzna częścią aplikacji. Często bazują na wzorcach projektowych. Różnicą w projektowaniu aplikacji internetowych opartych na architekturze klient-serwer a aplikacjami internetowymi z bogatym interfejsem użytkownika jest to, że te pierwsze wymuszają obsługę stanów aplikacji i jak zarówno interakcję użytkownika na serwerze, natomiast te drugie aplikacje ograniczają się do obsługi danych z serwera ale cała interakcja użytkownika spoczywa na kliencie.

Wzorzec ValueObject – obiekty danych
Trzeba zaprojektować klasę, której obiekt będzie przechowywał dane. Co oznacza, że dane będą miały reprezentację obiektową. Dane zostaną dostarczone z zewnątrz. Takie dostarczone dane muszą załadowane do obiektu. Dzięki takiemu podejściu unika się operowania bezpośrednio na strukturze danych. Dane mogą być dostarczone w równy sposób i przyjmować różną strukturę na przykład dokumentu XML czy zestawu danych binarnych. Drugą zaletą stosowania obiektów do przechowywania danych jest lepsza kontrola typów danych w aplikacji. W Cairngormie tworzenie obiektów danych wymaga implementacji interfejsu IValueObject:


package info.malaj.readerrss.vo
{
import com.adobe.cairngorm.vo.IValueObject;
[Bindable]
public var title:String;
public var link:String;
public var description:String;

public class ItemVO implements IValueObject
{ }
}

Klasa ItemVO posiada zbiór składowych dzięki któremu obiekty mogą opisywać wpis z bloga. Gdy dane zostaną pobrane z tej klasy tworzy się obiekty klasy ItemVO. Następnie te obiekty zostają zarejestrowane w modelu aplikacji. To pozwala na dostęp do tych obiektów z danymi z dowolnego miejsca aplikacji.

Wzorzec ModelLocator
Model jest singletonem to oznacza, że może być tylko jeden obiekt tego typu w aplikacji. Model przechowuje informacje o obiektach danych. Jest jakby centrum zarządzania danym

package info.malaj.readerrss.model
{
import com.adobe.cairngorm.model.IModelLocator;
import com.adobe.cairngorm.CairngormError;
import com.adobe.cairngorm.CairngormMessageCodes;
import info.malaj.readerrss.vo.ItemVO;
import mx.collections.ArrayCollection;

[Bindable]
public class Model implements IModelLocator
{
private static var instance:Model;
public var feedVOList:ArrayCollection;
public var itemVO:ItemVO;
public var feedURI:String;
public var feedTitle:String = "Czytnik RSS";
public var feedTitleLink:String;
public var syndicate:String;

public function Model(access:Private)
{
if (access != null)
{
if (instance == null)
{
instance = this;
}
}
else
{
throw new CairngormError(CairngormMessageCodes.SINGLETON_EXCEPTION, "Model" );
}
}

public static function getInstance():Model
{
if (instance == null)
{
instance = new Model( new Private );
}
return instance;
}
}
}
internal class Private {}

Z tego kodu można się nauczyć obsługi kilku rzeczy. Jak tworzy się singletona, wywoływanie wyjątków Cairngorm. Rejestrujemy w nim obiekt danych typu ItemVO i jak listę wpisów z bloga jako typ ArrayCollection .Pozostałe dane służą widokom i poleceniom To oznacza że widok korzysta z danych zarejestrowanych przez Model. A polecenia mogą zmieniać dane zarejestrowane w tym Modelu. Zmiana danych w obiekcie danych typu ItemVO przez polecanie zostanie automatycznie przekazana do obiektu widoku typu DetailView.

Service Locator – delegacje usług sieciowych.
ServiceLocator to miejsce w którym są wywoływane różnego rodzaju połączenia z zewnętrznym światem za pomocą żądań HTTP czy usług sieciowych WebService bądź Flash Remoting. ServiceLocator jest centralnym miejscem gdzie trzeba wstawiać informacje dotyczące obsługi połączeń. Ponieważ opiera sie to komponentach RPC więc programista nie musi znać szczegółów implementacji wywołań. ServiceLocator jest singletonem więc można rozszerzyć tą klasę Services w kodzie MXML

<?xml version="1.0" encoding="utf-8"?>
<cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:cairngorm="com.adobe.cairngorm.business.*">
<mx:Script>
<![CDATA[
import info.malaj.readerrss.model.Model;

public static const SERVICE:String = "service";
[Bindable]
public var model:Model = Model.getInstance();
]]>
</mx:Script>
<mx:HTTPService id="rss" url="{model.feedURI}" />
</cairngorm:ServiceLocator>


Delegaty są to metody, które odpowiadają za wykonanie pobrania danych i ewentualnie wywoływania zdalnych metod usług przez żądań internetowych do serwisów w celu pobrania tych danych. W tej aplikacji żądanie polega na pobraniu wpisów z bloga z kanałów RSS. Metody delegata są wywoływane przez odpowiedni obiekt polecenia.
Kod klasy GetFeedDelegate.as:

package info.malaj.readerrss.business
{
import mx.rpc.IResponder;
import mx.rpc.http.HTTPService;
import com.adobe.cairngorm.business.ServiceLocator;
import mx.rpc.AsyncToken;
import mx.rpc.events.ResultEvent;

public class GetFeedDelegate implements IResponder
{
private var responder:IResponder;
private var service:HTTPService;
private var token:AsyncToken;

public function GetFeedDelegate(responder:IResponder):void
{
this.responder = responder;
this.service = ServiceLocator.getInstance().getHTTPService("rss");
}

public function getFeed() : void
{
this.token = this.service.send();
this.token.addResponder(this);
}

public function result(data:Object):void
{
this.responder.result(data);
}

public function fault(info:Object):void
{
this.responder.fault(info);
}
}
}

Zdarzenia

Klasy zdarzeń rozszerzają klasę bazowa CairngormEvent. Ta klasa bazowa pozwala na tworzenie specyficznych zdarzeń dla aplikacji. W naszej aplikacji mamy 3 zdarzenia i odpowiadające im klasy ShowPageEvent, SelectItemEvent, GetFeedEvent. Każda z tych klas musi być zarejestrowana w kontrolerze. Kiedy obiekt zdarzenia jest wyzwalany to składowe są przekazywane do konstruktora. Zdarzenie jest przekazywane z widoku za pomocą metody dispatch. Kod klasy GetFeedEvent.

package info.malaj.readerrss.events
{
import com.adobe.cairngorm.control.CairngormEvent;
import info.malaj.readerrss.control.ApplicationController;
public class GetFeedEvent extends CairngormEvent
{
public var selecteduri : String;

public function GetFeedEvent(type:String)
{
super(ApplicationController.GET_FEED);
this.selecteduri = type;
}
}
}

Kod klasy SelectItemEven

package info.malaj.readerrss.events
{
import com.adobe.cairngorm.control.CairngormEvent;
import info.malaj.readerrss.control.ApplicationController;

public class SelectItemEvent extends CairngormEvent
{
public var selectedItem : Object;

public function SelectItemEvent(selectedItem:Object)
{
super(ApplicationController.SELECT_ITEM);
this.selectedItem = selectedItem;
}
}
}

Kod klasy ShowPageEvent

package info.malaj.readerrss.events
{
import com.adobe.cairngorm.control.CairngormEvent;
import info.malaj.readerrss.control.ApplicationController;

public class ShowPageEvent extends CairngormEvent
{
public var link:String;

public function ShowPageEvent()
{
super(ApplicationController.SHOW_PAGE);
this.link = link;
}
}
}

Wzorzec Command - polecenia
W tej aplikacji są tylko 3 interakcje – pobranie RSS, wyświetlenie listy wpisów i wyświetlenie wpisu. Trzeba napisać klasy do obsługi tych interakcji. Każda funkcjonalność wymaga napisania klasy bazującej na klasie Command. Z funkcjonalnościami powiązane są zdarzenia. Każdy obiekt typu Command ma metodę execute(). Użytkownik poprzez swoją interakcję może wywołać zdarzenie, a ono wykona tą metodę. Każda wywołana metoda execute() w obiekcie typu Command wymaga podania jako argumentu zdarzenia typu CairngormEvent, którego można rzutować na typ własnego zdarzenia. Każdy typ zdarzenia ma odpowiednik w typie klas Command. Metody result i jak fault są wymagane przez interfejs IResponder te metody służą do obsługi asynchronicznego przekazywania wyników z serwera. Metoda result zadziała w przypadku gdy wywołanie się uda a fault w przypadku gdy się nie uda. W tej aplikacji jest klasa GetFeedCommand odpowiedzialną za pobranie RSS. Klasa ta korzysta z delegacji, która obsługuje sam proces pobierania danych RSS, natomiast sama zajmuje się wypełnianiem danych obiektu Model

package info.malaj.readerrss.commands
{
import com.adobe.cairngorm.control.CairngormEvent;
import mx.rpc.IResponder;
import com.adobe.cairngorm.commands.ICommand;
import info.malaj.readerrss.business.GetFeedDelegate;
import info.malaj.readerrss.model.Model;
import info.malaj.readerrss.events.GetFeedEvent;
import mx.collections.ArrayCollection;
import mx.utils.StringUtil;
import mx.controls.Alert;

public class GetFeedCommand implements ICommand, IResponder
{
private var delegate:GetFeedDelegate;
private var model:Model;
private var feedEvent:GetFeedEvent;
private var feedFactory:FeedFactory;

public function GetFeedCommand()
{
this.delegate = new GetFeedDelegate(this);
this.model = Model.getInstance();
}

public function execute(event:CairngormEvent):void
{
this.feedEvent = GetFeedEvent(event);
this.model.feedURI = this.feedEvent.selecteduri;
this.delegate.getFeed();
}

public function result(data:Object):void
{
if(data.result.rss)
{
this.model.syndicate = "RSS";
this.model.feedVOList = data.result.rss.channel.item as ArrayCollection;
this.model.feedTitle = StringUtil.trim(data.result.rss.channel.title);
this.model.feedTitleLink = StringUtil.trim(data.result.rss.channel.link);
}
if(data.result.feed)
{
this.model.syndicate = "Atom";
this.model.feedVOList = data.result.feed.entry as ArrayCollection;
this.model.feedTitle = StringUtil.trim(data.result.feed.title);
this.model.feedTitleLink = StringUtil.trim(data.result.feed.link[0].href);
}
}

public function fault(info:Object):void
{
Alert.show("wystąpił bład " + info.message);
}
}
}

Podobnie rzecz się ma z klasą SelectItemCommand odpowiedzialną za pobranie informacji o wpisie

package info.malaj.readerrss.commands
{
import com.adobe.cairngorm.control.CairngormEvent;
import mx.rpc.IResponder;
import com.adobe.cairngorm.commands.ICommand;
import info.malaj.readerrss.model.Model;
import info.malaj.readerrss.vo.ItemVO;
import info.malaj.readerrss.events.SelectItemEvent;

public class SelectItemCommand implements ICommand, IResponder
{
private var model:Model;
private var newItemVO:ItemVO;
private var feed:SelectItemEvent;

public function SelectItemCommand():void
{
this.model = Model.getInstance();
}

public function execute(event:CairngormEvent):void
{
this.newItemVO = new ItemVO;
this.feed = SelectItemEvent(event);
this.newItemVO.title = this.feed.selectedItem.title;
if(this.model.syndicate=="RSS")
{
this.newItemVO.description = this.feed.selectedItem.description;
}
if(this.model.syndicate=="Atom")
{
this.newItemVO.description = this.feed.selectedItem.content;
}

if(this.model.syndicate=="RSS")
{
this.newItemVO.link = this.feed.selectedItem.link;
}
if(this.model.syndicate=="Atom")
{
this.newItemVO.link = this.feed.selectedItem.link[0].href;
}

this.model.itemVO = this.newItemVO;
}

public function result(data:Object):void
{}

public function fault(info:Object):void
{}
}
}

Kod klasy ShowPageCommand odpowiedzialnej za otwarcie strony internetowej ze wpisem.

package info.malaj.readerrss.commands
{
import com.adobe.cairngorm.control.CairngormEvent;
import com.adobe.cairngorm.commands.ICommand;
import info.malaj.readerrss.model.Model;
import info.malaj.readerrss.events.ShowPageEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;

public class ShowPageCommand implements ICommand
{
private var model:Model;
private var showPageEvent:ShowPageEvent;
private var link:String = "http://flex2.blogspot.com";

public function ShowPageCommand()
{
this.model = Model.getInstance();
}

public function execute(event:CairngormEvent):void
{
this.showPageEvent = ShowPageEvent(event);
try
{
var v:URLRequest = new URLRequest(this.model.itemVO.link);
navigateToURL(v,"_blank");
}
catch(err:Error)
{
var u:URLRequest = new URLRequest(this.link);
navigateToURL(u,"_blank");
}
}
}
}

Wzorzec Controller – kontrolera
Kontroler jest miejscem gdzie obiekty poleceń są powiązane z odpowiadającymi im zdarzeniami. Gdy zdarzenie jest wywołane to kontroler przekonuje je odpowiedniemu obiektowi polecenia.

package info.malaj.readerrss.control
{
import com.adobe.cairngorm.control.FrontController;
import info.malaj.readerrss.commands.GetFeedCommand;
import info.malaj.readerrss.commands.SelectItemCommand;
import info.malaj.readerrss.commands.ShowPageCommand;
public class ApplicationController extends FrontController
{
public static const GET_FEED : String = "getFeed";
public static const SELECT_ITEM : String = "selectItem";
public static const SHOW_PAGE : String = "showPage";

public function ApplicationController()
{
this.addCommand(ApplicationController.GET_FEED, GetFeedCommand);
this.addCommand(ApplicationController.SELECT_ITEM, SelectItemCommand);
this.addCommand(ApplicationController.SHOW_PAGE, ShowPageCommand);
}
}
}

Po pierwsze wszystkie zdarzenia murzą być zarejestrowane jako stałe w obiekcie kontrolera, pozwala to na uniknięcie problemów podczas kompilacji. W konstruktorze kontrolera dodaje sie klasy poleceń do powiązanych z nimi zdarzeń. Taka klasa może być bardzo duża w przypadku jak doda się wiele poleceń i zarejestruje sie wiele zdarzeń. Metoda addCommand () wymaga podania jako argumentu nazwy zdarzenia i nazwy klasy polecenia. Jak można zauważyć klasa ApplicationController rozszerza klasę FrontController. Poprzez rozszerzenie ma się dostęp do wszystkich dodanych poleceń i powiązanych z nimi zarejestrowanymi zdarzeniami. Obiekt kontrolera tworzy sie w głównym pliku aplikacji. To oznacza że aplikacja ma FrontController który odpowiada na zdarzenia i wywołuje wszystkie polecania które są powiązane z tymi zdarzeniami.

Wzorzec View - widoku
Widok jest częścią aplikacji, która odpowiada za interfejs użytkownika i jak jego interakcję. Dzięki wbudowanej w Flex obsłudze wiązania danych. obiekt Model aktualizuje dane w obiektach widoku. Użycie wiązania danych wymaga wskazania źródła i celu dla danych . Źródłem jest obiekt danych a celem jest obiekt widoku który potrzebuje tych danych.

Główny plik aplikacji RSS.mxml zawiera informacje o widokach, kontrolerze i jak o usłudze sieciowej wymaganej przez delegata w celu pobrania danych.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
xmlns:view="info.malaj.readerrss.views.*"
xmlns:business="info.malaj.readerrss.business.*"
xmlns:control="info.malaj.readerrss.control.*">
<business:Services id="rss" />
<control:ApplicationController id="control" />
<view:MainPanelView id="mainPanel" width="800" height="500" layout="vertical" horizontalAlign="center">
<view:URIView id="uriTextinput" paddingTop="10"/>
<view:ListView id="listDatagrid" width="750"/>
<view:DetailView id="detailTextarea" width="750" height="100%"/>
</view:MainPanelView>
</mx:Application>
Kod MainPanelView.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" title="{model.feedTitle}">
<mx:Script>
<![CDATA[
import info.malaj.readerrss.model.Model;
[Bindable]
private var model:Model = Model.getInstance();
]]>
</mx:Script>
</mx:Panel>

Kod ListView.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml"
dataProvider="{model.feedVOList}"
itemClick="handleItemClick(event.currentTarget.selectedItem)"
fontSize="12"
>
<mx:Script>
<![CDATA[
import info.malaj.readerrss.model.Model;
import info.malaj.readerrss.events.SelectItemEvent;

[Bindable]
private var model:Model = Model.getInstance();
private var event:SelectItemEvent;
private function handleItemClick(feed:Object):void{
event = new SelectItemEvent(feed);
event.dispatch();
}
]]>
</mx:Script>
<mx:columns>
<mx:DataGridColumn headerText="Tytuł wpisu na blogu" dataField="title" width="450" />
</mx:columns>
</mx:DataGrid>
Kod URIView.mxm
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="handleCreationComplete()">
<mx:Script>
<![CDATA[
import info.malaj.readerrss.events.GetFeedEvent;
import info.malaj.readerrss.model.Model;

[Bindable]
private var model:Model = Model.getInstance();
private var event:GetFeedEvent;
private function geturi(selecteduri:String):void{
event = new GetFeedEvent(selecteduri);
event.dispatch();
}

private function handleCreationComplete():void{
model.feedURI = "http://flex2.blogspot.com/feeds/posts/default";
geturi(model.feedURI);
}
]]>
</mx:Script>
<mx:Label text="Wprowadz adres RSS lub Atom" fontSize="12" paddingTop="4" fontWeight="bold"/>
<mx:TextInput id="uritext" width="400" text="{model.feedURI}" fontSize="12"/>
<mx:Button id="uributton" label="Pobierz" click="geturi(uritext.text)" fontSize="12"/>
</mx:HBox>
Kod DetailView.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="right">
<mx:Script>
<![CDATA[
import info.malaj.readerrss.model.Model;
import info.malaj.readerrss.events.ShowPageEvent;
[Bindable]
private var model:Model = Model.getInstance();
private var event:ShowPageEvent;

private function handleShowPage():void
{
event = new ShowPageEvent();
event.dispatch();
}
]]>
</mx:Script>
<mx:TextArea id="details" htmlText="{model.itemVO.description}" fontSize="12" width="100%" height="80%"/>
<mx:LinkButton id="goToStory" label="Pokaż stronę wpisu" click="handleShowPage();"/>
</mx:VBox>

Przyzwyczaiłem się do dość wygodnego pisania aplikacji opartych na frameworku Cairngorm między innymi na mechanizmy auto uzupełniania kodu. w edytorach kodu.

Najpierw pisze klasy dla danych w folderze vo, następnie piszę klasę Model w folderze model. Potem piszę w folderze business plik ServiceLocator.mxml i klasy delegatów. Kolejnym krokiem jest utworzenie szablonu klasy ApplicationControl w folderze control. W tej klasie wpisuję nazwę funkcjonalności, potem odpowiednio w folderach commands i events tworzę odpowiednie klasy zdarzeń i poleceń a w końcu uzupełniam klasę ApplicationControl Ostatnim etapem jest pisanie klas czy komponentów widoków w folderze views i klasy głównej aplikacji.

czwartek, 16 sierpnia 2007

Syntezatory mowy czy telefonia VoIP

Od pewnego czasu śledzę ze zdziwieniem rozwój usług internetowych opartych na komunikacji dźwiękowej pomiędzy użytkownikami.

1 kierunek: telofonia VOIP - pewna firma Ribbit zaproponowała programistom rozwój swojego komponentu RibbitPhone Component

2 kierunek to: obsługa generowanego dźwięku po stronie serwera (przykład po japońsku) na blogu pewnej pięknej japońskiej programistki Yo-suke (jej zdjęcie)

3 kierunek to napisanie własnego syntezatora mowy na przykładzie istniejących bibliotek
do obsługi dźwięku Tymi bibliotekami są syntezator Andre Michelle (kod źródłowy biblioteki BitBoy wraz z przykładami) czy symulator chwytów gitarowych czy bibliotekę PCMAudio.
Dla programistów HaXe tez jest fajne demo oscylatora. Warto zobaczyć wpisy Andre Michelle czy o generowaniu dźwięku, przykład jest też tutaj na japońskim blogu

Interesująco zaczyna być prawda?

poniedziałek, 13 sierpnia 2007

Kolekcja bibliotek Action Script 3

Od pewnego czasu w internecie chodzi po blogach lista bibliotek ActionScript 3

Możemy spróbować dokonać pewnej klasyfikacji

Frameworki architektoniczne AS3
Cairngorm
PureMVC
Guasax
Riavawe
Flest
currents

VEGAS
Indigo

ARP - framework tworzony przez Aral Balkan. Warto przeczytać wpis na jego blogu o stosowaniu tego frameworka pod Flex 2 (na razie jego rozwój jest wstrzymany co można stwierdzić o ilości postów na liście mailingowej)
lowra - Low-level Rework on Actionscript 3.0 - francuski framework tworzony przez Francis Bourre (bazuje na IoC) przy wsparciu firmy Prizee Warto przejrzeć slajdy i materiał video z konferencji w Toronto o tym frameworku.

Frameworki GUI
ASWing
uicomponents-as3 - Lightweight AS3 UI component library

2D
ImageProcessing - biblioteka filtrów graficznych
Springgraph - biblioteka do wizualizacji grafów
Distortion Effect - iluzja trójwymiarowego przejścia
Singularity
Draw Primitive
Fraktal


3D
Papervision 3D
Sandy
Away3D -
ASCollada -

Animacja
asinmotion - Animation Library for AS3
Tweener - Full featured animation library

Fizyka
APE ActionScript Physics Engine


API do serwisów Web 2.0
as3awss3lib - AS3.0 API dla Amazon S3 - usługi składowania danych dla e-biznesu napisana przez Christian Canrtell
mappr - AS3 API dla Mappr usługi zapewniającej geolokalizację grafiki na Flickr
youtube - AS3 API dla YouTube pozwalające na wyszukiwanie filmów na YouTube.
flickr - AS3 API dla Flickr serwisu internetowego pozwalającego na udostępnianie zdjęć przez internet - można przeczytać dokumentacje API z korzystania usług na Flickr
eBay - AS3 API dla eBay serwisu aukcyjnego warto przyjrzeć się ofercie dla programistów do korzystania z usług słynnego serwisu aukcyjnego.
facebook - AS3 API dla Facebook jednego z najbardziej popularnych serwisów społecznościowych Ten serwis ma bogatą platformę programistyczną umożliwiając w różny sposób (bazując na REST, FQL czy FBML) wykorzystanie potencjału takiego serwisu
last.fm AS3 API dla Last.fm pozwalającego na wyszukiwanie muzyki
Salesforce Flex Toolkit - AS3 API narzędzie do tworzenia własnych sklepów online na platformie Salesforce
Odeo AS3 API - narzędzie do wyszukiwania i odsłuchiwania podcastów z Odeo
Yahoo! Answers AS3 API - narzędzie do obsługi zapytań do Yahoo! Answers można obejrzeć przykład jako przykład dawania odpowiedzi na jakieś zagadnienia, jest to serwis w którym ludzie dzielą się wiedzą udzielając odpowiedzi na pytania
Yahoo! Weather AS3 API narzędzie do obsługi zapytań do Yahoo! Weather gdzie można otrzymać informację o pogodzie na dowolnym miejscu na Ziemi Można zobaczyć przykład wykorzystania (uwzględniając kody pocztowe USA) tej biblioteki wraz z wyjaśnieniem
Yahoo! Search AS3 API
Yahoo! Upcoming.org AS3 API
Twitter AS3 API
Digg AS3 API
Box.net AS3 API - http://www.box.net/api/

Mapy
MapQuest
Yahoo! Maps AS3 Communication Kit
Modest Maps http://www.modestmaps.com

Games
as3ds
AS3 Data Structures For Game Developers - biblioteki napisane przez Michael Baczynski który, prowadzi interesującego bloga poświęconego problemom algorytmicznym w Action Script 3
mecheye-as3-libraries - biblioteka napisana dla programistów gier w Flash CS3 udostępniona przez Mecheye Independent Studio
as3card - biblioteka napisana przez Darron Schall do programowania gier karcianych, więcej o tej bibliotece informacji można przeczytać w wpisie na jego blogu
hexagon - zbiór bibliotek dla programistów gier, twórca Sascha Balkau ma bloga poświęconego tej bibliotece

Utils
corelib - MD5 hashing, JSON serialization, advanced string and date parsing,

XML Syndication Library - biblioteka od programistów Adobe umożliwiająca wykorzystanie i pasowanie dokumentów Atom czy wersji RSS od blogów
AS3Crypto - ActionScript 3 Cryptography Library - biblioteka autorstwa Metal Hurlant, która zapewnia wykorzystanie algorytmów kryptograficznych w aplikacjach RIA takich jak RSA, AES, DES, 3DES, BlowFish, XTEA, RC4 czy algorytmów haszujących MD2, MD5, SHA-1, SHA-224, SHA-256 Można zobaczyć demo wraz z kodem źródłowym przedstawiające możliwości tej biblioteki.
FZip - Actionscript 3 class library to load standard ZIP archives and extract/decompress contained files.
XIFF - XMPP client library
flexircclient - klient IRCa
WiiFlash
asSQL Connect from ActionScript directly to mySQL
as3soundeditorlib Actionscript 3.0 library for sound editing

Prana
framework z IoC
di-as3 depedency injection


as3-rpclib - boblioteka do wywoływania procedur zdalnie: AMF0, XML-RPC



Debug
Alcon
Xray
With Firebug http://www.marcosweskamp.com/blog/docs/Console.as
http://osflash.org/luminicbox.log
http://osflash.org/debugit
http://osflash.org/printrdebugger
http://www.senocular.com/flash/actionscript.php?file=ActionScript_3.0/com/senocular/utils/Output.as

Testy jednostkowe
FlexUnit - is a unit testing framework for Flex and ActionScript 3.0 applications
asunit
Sprouts



Komponenty
FlexLib zbiór kontrolek i rozbudowanych komponentów: AdvancedForm, Base64Image, EnhancedButtonSkin, CanvasButton, ConvertibleTreeList, Draggable Slider, Fire, Highlighter, HorizontalAxisDataSelector ImageMap, PromptingTextInput, Scrollable Menu Controls, SuperTabNavigator, Alternative Scrolling Canvases, Horizontal Accordion, TreeGrid, FlowBox, Docking ToolBar, Flex Scheduling Framework

Kompomenty
Animated DragTile Component 0.1
Fisheye Component v0.3
FlexBook
Flickr Roulette
Interactive Calendar
IPE Controls
Landscape Zoomer
RandomWalk component
DisplayShelf Component

Biblioteki z ByteArray.org
Raster
is an open source bitmap drawing class.
MouseGesture is an open source class to perform some Mouse Gesture recognition.
Live JPEG Encoder Class to capture any content into a JPEG file (JPEG Encoding corelib class).
PageFlip is simple low-level class to perform some pageflip drawing. It's supports the 4 corners flip and vertical / horizontal mode.
SMTP Mailer
lets you send HTML e-mails with attached files.
AS3 GIFAnimation Encoder is a GIF encoding class to generate animated GIF from Flash.
AS3 GIFPlayer
is a GIFPlayer class to play animated GIF in AS3.
ASZip
lets you generate Zip files from scratch with AS3.

Biblioteki AS3
od Bena Stucki`ego
com.fusiox.media.ID3Reader
com.fusiox.media.ID3Stream
com.fusiox.skins.CSS3Box
com.fusiox.styles.CSSManager
com.fusiox.ui.Bitmap3D
com.fusiox.ui.Image
com.fusiox.ui.Pixel3D
com.fusiox.ui.Reflection
com.fusiox.ui.Scroller
com.fusiox.ui.Visualization

Komponenty od Alessandro Crugnola
CheckBox 3 state

Advanced ColorPicker
Tree CheckBox

ResizeTool
Labelled Box


Co jeszcze by dopisać?

Flash Remoting
WebOrb
AMFPHP
Fluorine
Saaser
http://as3lrf.riaforge.org/

Dynamiczne tworzenie instancji

Pracując nad przeglądarką multimediów zauważyłem że trzeba wywoływać dynamicznie klasy i ich instancje. Pomyślałem że trzeba całkiem odejść od myślenia i pisania tradycyjnego kodu ActionScript 1.0 czy 2.0. W tym momencie trafiłem na fajny wpis na blogu Kelly Brown z jej przykładem

import flash.utils.getDefinitionByName;

private function addButton():void{
var className:String="mx.controls.Button";
var ClassReference:Class = getDefinitionByName(className) as Class;
var instance:Object = new ClassReference();

instance.label="Test"
this.addChild(DisplayObject(instance));
}


Jest więcej pisania kodu, ale kod jest bardziej elastyczny.
Podobnie rzecz sie ma z inspekcja kodu o czym pisze Eric Cancil
jego introspekcją czy refleksją za pomocą takiego kodu

import flash.utils.describeType;
var simpleInstance = new SimpleClass();
trace(describeType(simpleInstance));


Czasami też przydają się dynamiczne klasy. Są to klasy do których można dodawać nowe pola i metody po utworzeniu ich instancji.

dynamic class Person {
var name:String;
}
Person p= new Person();
p.name=”Joe”;
p.age=25;
p.printMe = function () {
trace (p.name, p.age);
}
p.printMe(); // Joe 25

Nie polecam jednak częstego stosowania dynamicznych klas. Są one bardzo mało wydajne.

Jak zrobić identyczny klon obiektu zamiast jego na nowo wywoływania ? Nie obejdzie sie z jego "zripowaniem" jak to pokazał niko na swoim blogu

piątek, 10 sierpnia 2007

Zabezpieczenia formularzy MXML

Często może być taka sytuacja, że trzeba zabezpieczyć formularz MXML (np: kalkulator kredytowy) przed nieautoryzowanym wykorzystaniem na innych serwisach internetowych. W tej sytuacji wystarczy sprawdzić domenę z której formularz MXML korzysta

Oto kod:

import mx.utils.URLUtil;
import mx.controls.Alert;
private function init():void
{
var name:String = URLUtil.getServerName(Application.application.loaderInfo.url);
if(name != "www.jakisbank.pl")
{
Alert.show("Proszę skorzystać z kalkulatora kredytowego na stronie Banku");
}
}


Innym sposobem ochrony przed nieuczciwymi klientami jest zamieszczenie "bomb czasowych" . Polega to na tym, że klient jak zechce używać aplikacji RIA z formularzem MXML po upływie jakiegoś czasu to wprowadzamy jakieś utrudnienie dla użytkowników. A to jest bardzo proste:

private function initTimer():void
{
var now:Date = new Date();
var end:Date = new Date(2007, 6, 30);
if (end < now)
{
sabotage();
}
}


To są najprostsze zabezpieczenia. Ale dzięki możliwościom ActionScript 3 i samego Flash Playera 9 mamy możliwość tworzenia bardziej zaawansowanych sposobów zabezpieczeń przy pomocy szyfrowania i kryptografii. A także bardziej zmyślnych sposobów dostarczania treści i multimediów w zależności od ich jakości.

poniedziałek, 6 sierpnia 2007

ActionScript językiem robotyki?

Możecie obejrzeć jak ActionScript 3 wkracza tam gdzie nikt się nie spodziewał - w komunikację pomiędzy urządzeniami. W Japonii jak wiadomo robotyka stoi na bardzo wysokim poziomie. Do tego stopnia że nawet rozwinął się ruch OpenSource w wykorzystywaniu pewnych rozwiązań na poziomie elektroniki. Otóż powstała platforma sprzętowa - programistyczna dzięki której można zacząć programować swoje układy scalone w ActionScript. Niewiarygodnie? No chyba że obejrzy sie stronę internetową platformy Gainer Można się zapoznać ze tutorialem a szczególnie z wykorzystaniem ActionScript 2 i Flash 8 Jednak takie zastosowanie może wyglądać bardzo intrygująco. Na tej stronie pokazano że można sobie zaprogramować stół. Jeden programista japoński nawet napisał bibliotekę ActionScript 3 do Gainera.



Oto przykład jak to może wyglądać w praktyce. Na tym japońskim blogu możemy znaleźć informacje i zdjęcia Gainera.




Na tym filmie możemy zobaczyć jak można sterować zabawką z poziomu aplikacji napisanej w ActionScripcie.

Podobnie można dojść jeżeli chodzi o używanie konsoli Wii do sterowania komunikacją z komputerem a szczególnie w grach wieloosobowych



Odo serwis który ma do zaoferowania gry flash pod Wii

Inną koncepcję maja twórcy Chumby tworząc zabawkę z Linuksem którego interfejs graficzny jest w całości plikiem SWF



Czy też ten przykład



Ciekawie zaczyna być w świecie programistów ActionScript

czwartek, 2 sierpnia 2007

Przeglądarka multimediów

Ostatnio zajmuję sie pisaniem odtwarzaczy mp3 i jak video w ActionScript 3 dla serwisu społecznościowego weblisko.com. W tym czasie firma Adobe wypuściła Flash Ajax Video Compoment Koncepcja mi się spodobała. Pomyślałem, że wśród rozwiązań Open Source brakuje rozwiązania, które byłoby podobne do Lightboxa.js ale dawało możliwość odtwarzania plików video, dźwiękowych (koniecznie z jakaś wizualizacją), plików SWF (ze skalowaniem) także i plików graficznych. W przyszłości dodałbym jeszcze obsługę plików obsługiwanych przez Papervision3D. Zastanawiam się, które rozwiązanie wybrać oparte na FlashVars czy na Flex-Ajax Bridge. Do funkcjonalności należałoby też zmienianie wyglądu takiej przeglądarki multimediów za pomocą skompilowanych plików CSS. Całość będzie dostępna na Google Code na licencji GPL. Na razie Rafał Nagrodzki nick:burzaone zaoferował mi pomoc w pisaniu wizualizacji do plików audio. Czekam na propozycje współpracy w pisaniu takiej przeglądarki multimedialnej. W komentarzach proszę wpisywać propozycje nazw dla takiej przeglądarki.