ActionScript

关于Flash Player的“跑道/切片模型”

Posted in ActionScript, Flash Player on February 24th, 2010 by Jinni – 1 Comment

早前的一篇文章中我曾经提到过:“Flash Player的“跑道”模型最早由Ted Patrick提出,而Sean Christmann将这个理论进一步扩展成了“切片”模型,但是我对这个模型的结论抱有很大的质疑,这个模型和我的实验结果有很大的出入,有时间我会专门来撰写文章和大家分享讨论。”

正巧最近天地会论坛上有一篇针对切片模型的翻译,我借机将我的质疑提出来,并引发了一些讨论。我的质疑主要针对于原文中的以下论述:

Additionally, if you choose, you can render to the screen sooner then the compiled framerate by calling updateAfterEvent() , but only within a Mouse, Timer, or Keyboard event handler. In this instance though, the Marshal will consider that the end of the frame and start a new frame on the next slice.

根据我的实验结果,调用updateAfterEvent()会触发RENDER事件并进行实际的重绘,但并不会造成“当前帧结束并开始下一帧”。也就是说,你可以在同一帧之内,多次触发RENDER事件及其关联的处理函数,并对对屏幕进行多次重绘,并不会对帧进行“打断”。进一步来说,原文中的模型所基于“用户事件代码可以执行多次,而渲染事件代码和真正的渲染操作只在最后一个Slice执行”的假设并不成立,或者说,该假设只能说明某种情况,而不绝对成立。

为此,我特地咨询了我的同事,也是“跑道”模型的最初提出者Ted。他非常迅速的给了我回复,内容如下:

Yes you can call updateAfterEvent over and over between standard renders. You basically inject a partial render in the code execution side of the racetrack and elongate it.

翻译如下:

是的,你可以在每次标准RENDER(即原文中的Last slice’s render)之间调用多次updateAfterEvent(并进行重绘),相当于你在跑道一圈中代码执行的阶段”注入”了部分渲染过程并延长了整个跑道。

至此,我想这一问题应该是比较清晰了,跑道模型并不绝对,由于updateAfterEvent和Flash Player内部强制重绘需求的存在,我们可以在一帧的用户代码时间插入渲染事件代码,并进行多次重绘。也就是说,在一帧中,用户代码并不总是先于渲染代码而执行,它们是有可能交替进行的。

另外,Ted还提到:

I would love to see AS have full render control as a playermode in FP11. If set there are no automatic renders and the developer must call render for all visual changes to occur.

翻译:

其实我很希望看到Flash Player 11可以在某种模式下给开发者完整的渲染控制。在这种情况下开发者必须主动调用API来实现屏幕重绘。

的确,如果能够实现完整的渲染控制,将会给开发者对性能优化带来更大的提升空间~。

基于NetGroup的P2P多人聊天室

Posted in ActionScript, Flex, My Tutorials, P2P / Stratus on January 26th, 2010 by Jinni – 22 Comments

Stratus Beta2上线后,有很多朋友表示不知道如何基于NetGroup进行开发。事实上,NetGroup是一个非常强大的类,可以实现诸如Direct Routing, Posting和Object Replication等功能。为此,我花了20分钟时间写了一个简单的Demo:基于NetGroup的P2P多人聊天室,其中主要使用了Posting功能。其他NetGroup功能的使用方法大同小异,请各位自行发掘。

要运行这个Demo,你需要一个Stratus Developer Key,并确保你的Flash Player版本为10.1

点击下图运行Demo

时间仓促,界面使用FB4的Design模式胡乱搭的:

	 ....

Script标签内的代码如下:

import mx.utils.StringUtil;
[Bindable]
private var developerKey:String = "Your Developer Key";
[Bindable]
private var yourName:String = "no name";
private const SERVER_URL:String = "rtmfp://stratus.adobe.com/";
[Bindable]
private var logText:String = "";
[Bindable]
private var chatMsg:String = "";
 
private var netConn:NetConnection;
private var netGroup:NetGroup;
 
private function connectBtn_onClick():void {
	if(!netConn) {
		netConn = new NetConnection();
		netConn.addEventListener(NetStatusEvent.NET_STATUS, netConn_onNetStatus);
	}
        netConn.connect(SERVER_URL+developerKey);
}
 
private function sendBtn_onClick():void {
	if(StringUtil.trim(chatMsgInput.text).length) {
		var msg:Object = {
			text: chatMsgInput.text,
			sender: yourName
		};
		netGroup.post(msg);
		msgRecieved(msg);
		chatMsgInput.text = "";
	}
}
 
private function netConn_onNetStatus(event:NetStatusEvent):void {
	log(event.info.code);
	if(event.info.code == "NetConnection.Connect.Success") {
		connectBtn.enabled = false;
		developerKeyInput.enabled = false;
		yourNameInput.enabled = false;
		log("My Peer Id = "+netConn.nearID);
		var groupSpec:GroupSpecifier = new GroupSpecifier("swfever");
		groupSpec.serverChannelEnabled = true;
		groupSpec.ipMulticastMemberUpdatesEnabled = true;
		groupSpec.multicastEnabled = true;
		groupSpec.postingEnabled = true;
		var groupId:String = groupSpec.groupspecWithAuthorizations();
		log("Group Id = "+groupId);
		netGroup = new NetGroup(netConn,groupId);
		netGroup.addEventListener(NetStatusEvent.NET_STATUS, netGroup_onNetStatus);
	} else
	if(event.info.code == "NetGroup.Connect.Success") {
		sendButton.enabled = true;
	}
}
 
private function netGroup_onNetStatus(event:NetStatusEvent):void {
	log(event.info.code);
	if(event.info.code == "NetGroup.Neighbor.Connect") {
		log("NetGroup Neighbor Count = "+netGroup.neighborCount);
		userList_ac.addItem(event.info.neighbor);
	} else
	if(event.info.code == "NetGroup.Neighbor.Disconnect") {
		log("NetGroup Neighbor Count = "+netGroup.neighborCount);
		userList_ac.removeItemAt(userList_ac.getItemIndex(event.info.neighbor));
	} else
	if(event.info.code == "NetGroup.Posting.Notify") {
		msgRecieved(event.info.message);
	}
}
 
private function log(msg:String):void {
	logText+=msg+"\n";
}
 
private function msgRecieved(msg:Object):void {
	chatMsg+=msg.sender+" : "+msg.text+"\n";
}

源代码下载

  NetGroup_Posting_Demo_src (1.4 KiB, 3,192 hits)

2万行ActionScript代码打造Adobe ROME

Posted in ActionScript, AIR, Flex on October 10th, 2009 by Jinni – 6 Comments

Adobe ROME是一款完全由ActionScript编写,基于Flex框架,可运行在浏览器和桌面(AIR)的跨平台多功能出版工具。
使用Adobe ROME可以创建和发布动画,Flash网站,名片,演示稿,唱片封面等等。
这届的Adobe MAX大会上演示了部分ROME的功能,包括:

  • 矢量图形绘制
  • PSD图形导入和解析(对PS图层的完美识别)
  • 补间动画
  • 魔术棒工具
  • 视频支持
  • 导出到PDF或上传到网站

下面是一些Twitter们在看过这个Sneak Peek后的评论:

Adobe ROME简直就是所有CS4软件的合体!

如果你正在使用Adobe的任一款软件,就一定要来看看Adobe ROME,有史以来最好的AIR应用,2万行的AS代码!

更多评论可以看这里

除去这个项目本身的价值,我想它也再次证明了ActionScript/Flex足以胜任商业级应用程序的开发。

Gravity:OSGi的ActionScript实现!

Posted in ActionScript, Utilities on October 3rd, 2009 by Jinni – Be the first to comment

Adobe Labs不久后将放出基于ActionScript实现的OSGi框架,代号为Gravity。目前关于该项目的公开消息并不多,但是Stacy Young确认该项目将于2-3周内在Labs上放出,敬请关注。

也许你不知道什么是OSGi,但你一定知道Eclipse。这个迄今为止最成功的IDE就是基于OSGi模型的。
简言之,OSGi定义了一个基于插件模型的运行时框架,所有运行在上面的模块(Bundle)都作为对其的扩展而存在。
下面是经典的OSGi架构图示:
OSGi

Flash开发者利器:FlashBug

Posted in ActionScript on October 3rd, 2009 by Jinni – 5 Comments

Flash开发工具阵营又有新成员,FlashBug作为对FireBug插件的扩展,是专门为Flash/Flex开发者设计的。你再不需要通过调用JavaScript来利用FireBug的Console功能,FlashBug可以自动捕捉SWF中的trace()及警告信息。唯一的要求是你的Firefox需要安装有Debugger版本的Flash Player

FlashBug

安装和更多介绍请访问这里