简介
多年的AS3经验,让自己再工作中需要开发一些便利性的方便偷懒的工具时,习惯性把这项技术再拿出来,让其继续发光发热。本次实现的是一个简单的本地地图编辑器,但是抛砖引玉,为了日后再需要开发一些小工具的方便,我对PurMVC进行了简单的重写和封装,借助MornUI(Flash轻量级,高性能,可视化UI解决方案,真的很好用),让moudle与moudle,moudle内部及moudle之间的通信,都更加清晰和便于管理,让我以后的工具皆可moudle。(Flex SDK版本为 Flex 4.6.0,ActionScript项目为桌面在Adobe AIR中运行)
Command
FacadePurMVC的大门,所有的Proxy和Mediator要想有名有姓,自然都要在这里注册啦,我们将每一个moudle中涉及的Proxy和Mediator放入一个Command中单独进行管理。
public class MapPage_StartupCommand extends SimpleCommand
{
public function MapPage_StartupCommand()
{
super();
}
override public function execute( $note:INotification ):void
{
//register proxy and mediator
facade.registerProxy( new MapPage_MsgReceivedProxy() );
facade.registerProxy( new MapPage_MsgSenderProxy() );
facade.registerMediator( new MapPage_Mediator() );
}
}
Proxy
Proxy主要分MsgReceivedProxy和MsgSenderProxy,分别通过NetWorkManager实现前后端消息得接收和发送。
MsgReceivedProxy接受到消息后第一时间传入Mediator,做后续处理。
override public function onRegister():void
{
NetWorkManager.registerMsgs([
10000
],receivedMsgHandle, NAME);
}
override public function onRemove():void
{
NetWorkManager.removeMsgs([
10000
], NAME);
}
/**
* 处理管道信息
* @param $notification
*/
private function receivedMsgHandle( $notification:Notification):void
{
var name:* = $notification.name;
var data:ByteArray = $notification.body as ByteArray;
if(this.hasOwnProperty("received_"+name))
{
this["received_"+name](data);
}
else
{
// Trace("协议号"+name+"不存在");
}
return;
}
/**
* 返回面板信息)
* @param $data
*/
public function received_10000($data:ByteArray):void
{
var buf:ByteArray = $data;
}
MsgSenderProxy则直接将消息传输与服务器。
public static const NAME:String = 'MapPage_MsgSenderProxy';
public function MapPage_MsgSenderProxy(proxyName:String=null, data:Object=null)
{
super(NAME, data);
}
public function send_10000($data:*=null):void
{
var buf:ByteArray = new ByteArray();
NetWorkManager.sendMsg(10000,buf);
}
Mediator
Mediator主要处理通过侦听事件实现view的内部交互,以及通过数据对view做出显示改变。
override public function listNotificationInterests():Array
{
return [
PipeConstants.SHOW_MAPEDITOR_PANEL
];
}
override public function handleNotification(note:INotification):void
{
switch (note.getName())
{
case PipeConstants.SHOW_MAPEDITOR_PANEL:
GameInstance.instance.main.addChild(panel);
loadRes();
panel.mapList.array = [];
if(MapPageSharedObject.instance && MapPageSharedObject.instance.data.nativePath)
{
mapPageModel.nativePath = MapPageSharedObject.instance.data.nativePath;
var list:Array = FileManager.getAllFiles(new File(mapPageModel.nativePath), [".json"]);
var vec:Array = DataCreater.getgetFilesVector(list);
if(vec.length > 0)
{
mapPageModel.mapList = vec;
mapPageModel.mapListSelectedItem = vec[0];
}
mapPageModel.sceneModel = true;
}
break;
}
}
对于view内部的事件侦听,我做了UIEventsRegisterManager,在view显示的时候侦听,关闭的时候移除,提高效率。
override public function onRegister():void
{
//注册事件
initEvents();
}
/**
* 注册事件
*/
private function initEvents():void
{
UIEventsRegisterManager.addUIRegisterEvent(MapPage,function():void{
panel.addEventListener(Event.ADDED_TO_STAGE, handler);
});
UIEventsRegisterManager.addUIRemovedEvent(MapPage,function():void{
panel.removeEventListener(Event.ADDED_TO_STAGE, handler);
});
}
Facade
Facade这里通过PipeManager管理moudle的启动,并且接收其他moudle传输过来的管道消息传输到Mediator
public static const NAME:String = "game.moudle.mappage.MapPage_ApplicationFacade";
public static const STARTUP:String = "STARTUP";
public function MapPage_ApplicationFacade(key:String)
{
super(key);
PipeManager.registerMsgs( [
PipeConstants.STARTUP_MAPEDITOR,
PipeConstants.SHOW_MAPEDITOR_PANEL
],
handlePipeMessage,
MapPage_ApplicationFacade
);
}
public static function getInstance() : MapPage_ApplicationFacade
{
if ( instanceMap[ NAME ] == null )
instanceMap[ NAME ] = new MapPage_ApplicationFacade( NAME );
return instanceMap[ NAME ] as MapPage_ApplicationFacade;
}
override protected function initializeController():void
{
super.initializeController();
registerCommand( STARTUP, MapPage_StartupCommand );
}
/**
* 处理管道消息
* @param $notification
*/
public function handlePipeMessage( $notification:Notification ):void
{
var key:String = $notification.name;
var data:Object = $notification.body;
switch ( key )
{
//启动此facade
case PipeConstants.STARTUP_MAPEDITOR:
startup();
break;
case PipeConstants.SHOW_MAPEDITOR_PANEL:
sendNotification(key, data);
break;
}
}
/**
* 启动
*/
public function startup():void
{
sendNotification( STARTUP );
}