Sonicjam 社歌~

0 意見

2009-03-31_130543.jpg

sonicjam的官方網站,兩個有趣的角色在唱歌,對話十分搞笑,網站由3D呈現,效果不錯

網站:http://www.sonicjam.co.jp/special/v1/



Flex 4 Gumbo

0 意見

官方網站目前己可下載Milestone的SDK,雖然沒有IDE可用,但還是可體驗一下Flex4 Gumbo的新語法,比較特殊的是FXG跟State吧,其它的還在看

SDK下載頁面:http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4

官方介紹頁:http://opensource.adobe.com/wiki/display/flexsdk/Gumbo

範例教學:http://blog.flexexamples.com/



[PureMVC] 使用Pipes Util 實現Module間溝通

1 意見

之前在Micro Architecture PureMVC一篇有介紹到多核版的PureMVC架構,所謂的多核,指的是同一專案能出現多個實做PureMVC的模塊,在Flex是以Module的方式實現,讓每個Module都有各自的Facade,功能獨立。但PureMVC本身未提供Module間彼此溝通的方法,雖然我們可以用Interface等方法來管理每個Module,但這會使程式的關聯太高,失去MVC的好處,所幸己有高手解決了這個問題,官方網站的Pipes Util就是用來處理Module的問題,他能在Module間再架一層溝通架構,能每個Module都能像送Notification的方式彼此溝通,下面寫個簡單的範例說明

程式為Shell跟Module互傳訊息,Shell是讀入Module的主程式,Module是獨立的PureMVC架構

2009-03-21_210435.jpg

PipeUtil主要是靠JunctionMediator跟其它Module溝通,由於JunctionMediator是繼承自Mediator,所以可再收發Notification,使Module間的訊息可走回原本的PureMVC架構

package idv.gd.hellopipes.shell.view
{
import idv.gd.hellopipes.common.PipeAwareModule;
import idv.gd.hellopipes.shell.ApplicationFacade;

import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.utilities.pipes.interfaces.IPipeAware;
import org.puremvc.as3.multicore.utilities.pipes.interfaces.IPipeMessage;
import org.puremvc.as3.multicore.utilities.pipes.messages.Message;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.Junction;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.JunctionMediator;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.Pipe;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.TeeMerge;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.TeeSplit;

/**
* junction是實際拿來連結的實體,架構在原本的puremvc內(mediator)
*/
public class ShellJunctionMediator extends JunctionMediator
{
public static const NAME:String = "AppJunctionMediator";

public function ShellJunctionMediator()
{
//Junction為不可見的連結實體,用來管理 shell跟module的關係
super(NAME, new Junction());
}

override public function listNotificationInterests():Array
{
return [ApplicationFacade.MODULE_ADDED, ApplicationFacade.SEND_MESSAGE];
}

override public function handleNotification(note:INotification):void
{
switch (note.getName())
{
case ApplicationFacade.MODULE_ADDED:
{
var module:IPipeAware = IPipeAware(note.getBody());
connectPipe(module);
break;
}
case ApplicationFacade.SEND_MESSAGE:
{
var message:Message = new Message(PipeAwareModule.SHELL_MESSAGE, null, note.getBody());
junction.sendMessage(PipeAwareModule.SHELL_TO_MODULE, message);

break;
}
}
}

/**
* 連結pipe跟接口
*/
private function connectPipe(module:IPipeAware):void
{
//註冊pipe及產生接口
junction.registerPipe(PipeAwareModule.SHELL_TO_MODULE, Junction.OUTPUT, new TeeSplit());
junction.registerPipe(PipeAwareModule.MODULE_TO_SHELL, Junction.INPUT, new TeeMerge());

//監聽訊息
junction.addPipeListener(PipeAwareModule.MODULE_TO_SHELL, this, handlePipeMessage);

//連結 module跟shell
var moduleToShell:Pipe = new Pipe();
module.acceptOutputPipe(PipeAwareModule.MODULE_TO_SHELL, moduleToShell);

var shellInFitting:TeeMerge = junction.retrievePipe(PipeAwareModule.MODULE_TO_SHELL) as TeeMerge;
shellInFitting.connectInput(moduleToShell);

//連結shell跟module
var shellToModule:Pipe = new Pipe();
module.acceptInputPipe(PipeAwareModule.SHELL_TO_MODULE, shellToModule);

var shellOutFitting:TeeSplit = junction.retrievePipe(PipeAwareModule.SHELL_TO_MODULE) as TeeSplit;
shellOutFitting.connect(shellToModule);
trace("connected");
}

override public function handlePipeMessage(message:IPipeMessage):void
{
switch (message.getType())
{
case PipeAwareModule.MODULE_MESSAGE:
{
sendNotification(ApplicationFacade.GET_MESSAGE, message.getBody());
break;
}
}
}

}
}

連結是透過Pipe監聽訊息,這部分寫起來比較麻煩,但可限制那些Module之間可以溝通,以及要監聽的訊息

原始檔下載



Micro Architecture ─ PureMVC Part2

0 意見

把之前的補完,先介紹一下Mediator

Mediator用來管理可見元件,讓原本UI能與PureMVC溝通,主要負責觸發跟反應Notification

ApplicationMediator


package idv.gd.pureMVCTest.view
{
import flash.events.MouseEvent;

import idv.gd.pureMVCTest.ApplicationFacade;

import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.mediator.Mediator;

public class ApplicationMediator extends Mediator
{
public static const NAME:String = "ApplicationMediator";

public function ApplicationMediator(viewComponent:Main)
{
super(NAME, viewComponent);
}

/**
* view內所有的元件註冊在此
*/
override public function onRegister():void
{
super.onRegister();

facade.registerMediator(new RSSReaderMediator(main.reader));

main.newsBtn.addEventListener(MouseEvent.CLICK, getNewsHandler);
main.techBtn.addEventListener(MouseEvent.CLICK, getTechHandler);
}

private function getNewsHandler(event:MouseEvent):void
{
facade.sendNotification(ApplicationFacade.READ_NEWS);
}

private function getTechHandler(event:MouseEvent):void
{
facade.sendNotification(ApplicationFacade.READ_TECH);
}

protected function get main():Main
{
return viewComponent as Main;
}
}
}

Mediator會對應到一個名稱,寫法上以常數宣告,讓Facade可取用對象,若Mediator所管理的UI有子元件,每個子元件都可在此註冊,在寫法上為了避免管理的子元件尚未生成,註冊元件時應盡量寫在onRegister裡,Constructor有時會出現問題

雖然Mediator可取得Proxy跟其它的Mediator,但會耦合性會過高,以Notification通知Command,再以Command操作Proxy的方式比較妥當,而Mediator去操作其它的Mediator是絕對不允許的

Proxy同Mediator要有一個識別名,用來管理資料及封裝操作的方法,實現Domain Logic,在官方文件還有一種RemoteProxy,不過我個人比較喜歡拆成Delegate跟Proxy,讓Delegate管遠端要值的方法,方便之後抽換

RSSProxy


package idv.gd.pureMVCTest.model
{
import idv.gd.pureMVCTest.ApplicationFacade;
import idv.gd.pureMVCTest.model.business.RSSDelegate;
import idv.gd.pureMVCTest.model.vo.InfoVO;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.rpc.IResponder;

import org.puremvc.as3.patterns.proxy.Proxy;

/**
* proxy用來維護資料,保有原始資料及操作方法
*/
public class RSSProxy extends Proxy implements IResponder
{
public static const NAME:String = "DataProxy";

public function RSSProxy(data:Object = null)
{
super(NAME, data);
}

/**
* 使用 delegate來取得內容,使用 delegate才方便抽換取得來源
*/
public function getRealNews():void
{
var delegate:RSSDelegate = new RSSDelegate(this);

delegate.getNews();
}

public function getTech3c():void
{
var delegate:RSSDelegate = new RSSDelegate(this);

delegate.getTech3c();
}

public function removeItemAt(index:uint):void
{
if (infoVO)
{
infoVO.content.removeItemAt(index);
}
}

public function removeAll():void
{
infoVO.content.removeAll();
}

public function result(resultEvent:Object):void
{
var data:Object = resultEvent.result;
var title:String = data.rss.channel.title;
var lastBuildDate:String = data.rss.channel.lastBuildDate;
var content:ArrayCollection = data.rss.channel.item;

var vo:InfoVO = new InfoVO(title, lastBuildDate, content);

this.data = vo;

this.facade.sendNotification(ApplicationFacade.RSS_LOAD_COMPLETE, infoVO);
}

public function fault(data:Object):void
{
this.facade.sendNotification(ApplicationFacade.RSS_LOAD_FAULT);
}

protected function get infoVO():InfoVO
{
return data as InfoVO;
}

}
}

在多核心的版本,其實只是多了一組管理Facade的Map,跟Mediator及Proxy一樣,生成時要有個識別的名字,其它用法一樣

Main.mxml



//進入點要有識別名,用來識別 facade instance
public const NAME:String = "Main";
private var facade:ApplicationFacade = ApplicationFacade.getInstance(NAME);

ApplicationFacade



public function ApplicationFacade (key:String)
{
super(key);
}

原始檔下載(Flex專案檔,附PureMVC Standard)



iPhone os 3.0 即將登場,仍不支援Flash

0 意見

appleiphone3_013500x375.jpg

今天看到iPhone OS 3.0的新聞,雖然增加了許多功能,但最關心的Flash還是不支援 (="=),Adobe從去年10月就說Flash Player要登上iPhone,但至今仍無消息,我相信Adobe一定能解決Flash在iPhone上執行的問題,畢竟iPhone都可以放youTube了,剩下只看Apple肯不肯點頭

新聞頁面 http://www.techcrunch.com/2009/03/17/live-from-apples-iphone-30-press-conference/