Skip to main content

[AS3] pureMVC Utility - WidgetsConsole 1.0.0


Project Name: pureMVC Utility - WidgetsConsole
Version: 1.0.0
Project Owner: Erin Lin
Description: An utility is under pureMVC Multicore that has Flex only and AS3 two versions.
Demo: WidgetsConsole Live Demo with source code
Demo source code
Download: WidgetsConsole Open Source Project Home
pureMVC website: http://puremvc.org/



沒想到我第一個 google code open source project 就獻給 pureMVC 了...

套用 pureMVC 到 Flex 專案第一個遇到的問題就是 view components 的控制,Flex 專案的 view 總類太多:有 Modules, UIComponent, external swf and pop-up view...etc. 整個專案作下來光 view 就可能換上幾十個頁面,先前分享了運用 StateMachine 來處理 view 的轉換,中大型專案作下來 code 的複雜度也是非常可觀。我在今年二月分享了 [Flex] pureMVC MultiCore with Modules 就開始著手將其概念包裝成 pureMVC 的工具包,使用到目前為止整個架構還是挺完善,所以在這邊與大家分享。

WdigetConsole 顧名思義是「 相同目的 views 組合 = Widget 」 的中央控制中心,將程式內加入 WidgetsConsole 的 widget 統一控管,最終只需要 sendNotification 就可以達到 view 的新增跟刪除(因為我是懶人工具的愛好者,懶人工具的定義就是以最低的限度達到所需要的效果,所以這個工具包的自由度很高!)

以下是簡單講解 WidgetsConsole 是什麼:

Widget 的定義: View component(s) + WidgetMediator + WidgetCommand
實作的 WidgetCommand:SimpleCommand 會掌控相關 views, proxies, commands 的註冊與移除。你可以發現上次在 pureMVC + StateMachine 文章中,Erin 建議將一個 view 的相關 Mediators, Proxies , Commands 都用一個 Command 來控制建立與刪除,其重點就是"只"讓一個 Command 掌握一個 views 組合的所有細節。

Interfaces: 想要自動化,介面是不可缺少的
  1. IWidgetShell:所有放置 Widget 的 DisplayObjectContainder 都需要實作。
  2. IWidget:view component or modules 只要需要被中央控管的 views 都要實作 IWidget
  3. IWidgetInfo:定義傳遞的 Value Object 介面


IWidgetShell 的實作
可以 extends 任何的 DisplayObjectContainder Class 來實作 IWidgetShell 介面,當然也可以參考 Live Demo 內的 AssignShell 寫法製作。如果你很在意巢狀容器的話,請避免使用 DisplayObjectContainder Class 來實作 IWidgetShell 介面。

WidgetCommand:SimpleCommand
寫法跟一般寫 Command 沒兩樣,差別在 execute 中只處理 WidgetsConsole.CREATE_WIDGET and WidgetsConsole.DESTROY_WIDGET。
  1. WidgetsConsole.CREATE_WIDGET:處理所有相關 View, mediator, proxies 的註冊,統一在此處理 view component 的 WidgetsConsole.ADD_WIDGET_TO_SHELL

    sendNotification(
    WidgetsConsole.ADD_WIDGET_TO_SHELL,
    widget:IWidget,
    ShellName:String
    );

  2. WidgetsConsole.DESTROY_WIDGET:處理所有相關 View, mediator, proxies 的刪除
    需要在此處理 view component 的 WidgetsConsole.REMOVE_WIDGET_FROM_SHELL

    sendNotification(
    WidgetsConsole.REMOVE_WIDGET_FROM_SHELL,
    widget:IWidget,
    ShellName:String
    );



How to Inject WidgetsConsole?
inject 函式的命名寫法參考自 pureMVC Utility - StateMachine

var wc:WidgetsConsole = new WidgetsConsole();
wc.inject( this.multitonKey );
wc.registerWidget( widgetName:String, command:Class );
//在這邊將做好的 WidgetCommand 註冊
wc.registerShell(name:String, shell:IWidgetShell);
//註冊 shell,由於 shell 是一個 IWidgetShell 實體,所以在實體被移除前一定要執行 removeShell


Widget 的呼叫:

sendNotification(
WidgetsConsole.CREATE_WIDGET,
new WidgetInfo( widgetName:String , mediatorName:String , targetShellName:String , moduleURL:String = null, attachment:Object = null )
);

mediatorName 由外部指定才能讓同一個 Widget 有不同的 Instances, 也可以將之 push 到不同的 shell 內。請參考 Live Demo

這邊的 moduleURL:String 欄位請自由運用,在 WidgetCommand 內可以藉由 IWidgetInfo.getURL() 取得,由於一開始 Erin 就是針對 Flex 開發出這個工具包,所以 IWidgetInfo 並沒有分版本;AS3 版本只是將 Module 相關拿掉而已。
*Edit:10.26,2009 筆誤... moduleURL:String 寫成 targetShellName:String...

LazyWidget 的呼叫:懶人 widget,WidgetMediator and WidgetCommand 已由 WidgetsConsole 提供
只有 ViewUI 的 Widget,單純展示畫面,多為測試用。 inject WidgetsConsole 的時候 registerLazyWidget(),才可以使用。

sendNotification(
WidgetsConsole.CREATE_WIDGET,
new WidgetInfo( WidgetsConsole.LAZY_WIDGET , mediatorName:String , targetShellName:String , moduleURL:String =null, viewUIInstance:IWidget )
);
//*Edit:10.26,2009 筆誤... moduleURL:String 寫成 targetShellName:String...
//attachment 欄位直接帶入 IWidget


Widget 的刪除

//刪除全部 Widgets
sendNotification(WidgetsConsole.DESTROY_ALL_WIDGETS);

//刪除指定 shell 內所有的 Widgets
sendNotification(WidgetsConsole.DESTROY_WIDGETS_BY_SHELL, shellName:String );

sendNotification(WidgetsConsole.DESTROY_WIDGET, mediatorName:String );
//刪除特定 Widget


Module 專區 - Flex only version

ModuleWidget 的呼叫:外部 ModuleWidget 共用,WidgetMediator and WidgetCommand 已由 WidgetsConsole 提供
需要在 inject WidgetsConsole 的時候順便 registerModuleWidget(),才可以使用。

sendNotification(
WidgetsConsole.CREATE_WIDGET,
new WidgetInfo( WidgetsConsole.MODULE_WIDGET , mediatorName:String , targetShellName:String , moduleURL:String , attachment:Object = null )
);
//WidgetsConsole 會將 attachment:Object 送到 Module.data,所以需要直接寄到 Module 的參數可以利用 attachment 傳送。



Module 專用的 broadcast to Global Notification:WidgetsConsole.MODULE_SENDER
發出通知後會自動轉變成 「WidgetsConsole.BROADCASTING 」到 System facade ,也會順便轉發出 「WidgetsConsole.MODULE_RECEIVER」 送進"其他"的 ModuleWidget(自己發送的 Notification 就不會接收),所以 WidgetsConsole.BROADCASTING 請謹慎使用...

sendNotification( WidgetsConsole.MODULE_SENDER , body:Object , type:String );
//body is an Object...可以放任何你想要傳出去的物件~~萬物皆物件啊!


Module 外部資料接收器:WidgetsConsole.MODULE_RECEIVER

override public function listNotificationInterests():Array
{
return [
WidgetsConsole.MODULE_RECEIVER
];
}
override public function handleNotification(notification:INotification):void
{
//就是處理你要的東西
}


Module remove Notification:WidgetsConsole.MODULE_REMOVE
不管是由 Module 發出 WidgetsConsole.MODULE_REMOVE,又或者從 System facade 發出 WidgetsConsole.DESTROY_WIDGET 都會送出 WidgetsConsole.MODULE_REMOVE 讓 Module facade 收聽,所以請記得在 Module's ApplicationFacade 內註冊 WidgetsConsole.MODULE_REMOVE Command,並將此 Module 在移除時需要清除的東西寫在此 Command 內。

sendNotification( WidgetsConsole.MODULE_REMOVE );
// remove self



其實目前 mx.modules.ModuleManager 有要命的 memory leak bug...建議現階段還是少用 Module 比較安全。這也是我使用 RSL(Runtime Shared Library) 來處理專案的主要原因,Module 只用來實作非主要的 view componet。

想要取得你所載入的 Module's ModuleInfo 去執行 unload() 的話,請利用 ModuleManager.getModule(url):IModuleInfo 來取得,關於這點我沒有在 WidgetsConsole 內處理的原因是:不管 ModuleInfo 有沒有執行 unload,其 ModuleInfo 還是會剩下一個實體不被回收,可能的原因是 ModuleManager 內的 inner class ModuleManagerImpl 有個 moduleList 在 ModuleInfo.unload 的時候並沒有順便清掉其 reference,當然也可能還有其他的因素。既然有沒有 unload 都沒差別那就不需要特別處理它了...=)

Comments

  1. 還能說什麼呢...這真的太有大愛了!

    ReplyDelete
  2. 我在live demo with source code連結找不到source code呀~

    ReplyDelete
  3. 有阿....滑鼠按右鍵不是有 view source...

    ReplyDelete
  4. 報告^^
    沒有看到view source捏~~~

    ReplyDelete
  5. 看情況好像被 Hinet 的垃圾廣告 JS 擋起來了....等我有空的時候再去查解法來解決~~- -....

    ReplyDelete
  6. 阿咧...今天看的時候 online Demo 的 View source 又可以開了...= =

    ReplyDelete

Post a Comment

Popular posts from this blog

[AIR] JoSiResize - Mobile 開發小工具

JoSiResizev0.6.0,Adobe AIR 3 runtime之前開發 tool app 的時候並沒有很深刻的體認到圖片素材的 resize 是一個很麻煩的事情...畢竟圖片使用量並不大,等到開發遊戲類的 app 才發現光處理不同螢幕尺寸的圖片素材是一個相當折磨人的工作。
因此 JoSiResize app 誕生了~~~原理是採用最小 scale 長寬比例不變的方式進行放大縮小。使用方法非常簡單,設定好變更的尺寸,接下來,將需要處理的圖片檔案全選直接拖曳到視窗內,畫面即會跳出預備儲存的檔案夾選擇畫面,確認後即開始轉檔。

PureMVC for Titanium Mobile

為了秉持著哪裡都要用 PureMVC 的想法,試著修改 PureMVC 官網上提供的 Javascript 版本給 Titanium 使用。
**source code**
有任何問題請上:Titanium Mobile 中文開發者論壇

建立 instance 的方法:使用 Puremvc 為 namespace
Ti.include('puremvc-js-1.0.js');
var c = Puremvc.clone( Puremvc.SimpleCommand );
var p = Puremvc.clone( Puremvc.Proxy, "TestProxy", "This is TestProxy's data" );
var m = Puremvc.clone( Puremvc.Mediator , "MainMediator" );

[Unity] erinylin.lazylib - Cookie for PlayerPrefs

有鑑於 PlayerPrefs 測試與版本更新問題,將大家都愛用的 PreviewLabs.PlayerPrefs 打包起來,製作重點還是以懶人為主,基本上 PlayerPrefs 資料更新與數量並不可能會有強烈衝擊效能的狀況產生,所以為了方便開發,就弄了一個視覺化工具,方便除錯用。

雖然 PreviewLabs.PlayerPrefs 作者都宣告放棄他們的版權,不過為了尊重程式,僅僅加入了兩個公用函式,其他並無更改。

內有:
Cookie ManagerCookie 用 DataObject 混合編輯 ScriptableObject執行階段除錯視窗工具當然還是有懶人常數檔案輸出資料版本控制,方便更新版後儲存資料更新功能其實很多,有興趣的請自行到 Github 下載並參考範例吧!