Tag Archive: actionscript


as3signals: new approach for AS3 Events

There are times you may find that the built-in events of AS3 are limited and even troublesome. Here are some circumstances that EventDispatchers turn against developers:

  1. Objects MUST extend EventDispatcher in order to be able to dispatch events. Implementing IEventDispatcher alone is impossible because the event target is read-only and you cannot change it from outside of EventDispatcher.
  2. It’s difficult to manage events. There’s no way you can remove all event handlers attached to an event dispatcher at once. So in some cases, you don’t remove them properly and they start causing bugs. (BTW, using weak references is not reliable and not recommended.)
  3. You cannot pass extra data to you listener unless you extends a new Event object
  4. You cannot set up your interface in a way that it can enforce implementing classes to dispatch the required events.
  5. On performance perspective, creating objects is one of the most evil things. That’s why any advanced programmers must know and practically use objects pool. However, we are still wasting a lot of resources creating event objects, especially repetitive events like mouse move or enter frame.
  6. Read here for more critiques on AS3 events

Continue reading “as3signals: new approach for AS3 Events” »

New Tools in AS3

This one took a little longer than I’d hoped – life’s too busy right now! In this third part of my series on resource management in ActionScript 3 I will be focusing on a few new tools in AS3 / Flex2 that let you track and manage memory more effectively. There are only a couple new “official” features that are specifically geared towards resource management, but they are very useful. These are supplemented by a handy unofficial feature, and of course there are lots of language features that can help you in more generic ways.

System.totalMemory
This is simple tool, but it’s important because it marks the first run-time profiling tool developers have had in Flash. It allows you to monitor how much memory is in use by the Flash player at run-time. This gives you some ability to profile your own work during development without a system monitor. More importantly, it let’s you preemptively deal with major memory leaks in your content before it causes a serious issue for your user. It’s better to throw an error, and abort your application, than bog down the user’s system or even stall it completely.

Here’s a simple example of what this could look like:

import flash.system.System;
import flash.net.navigateToURL;
import flash.net.URLRequest;

// check our memory every 1 second:
var checkMemoryIntervalID:uint = setInterval(checkMemoryUsage,1000);

var showWarning:Boolean = true;
var warningMemory:uint = 1000*1000*500;
var abortMemory:uint = 1000*1000*625;

function checkMemoryUsage() {
if (System.totalMemory > warningMemory && showWarning) {
// show an error to the user warning them that we’re running out of memory and might quit
// try to free up memory if possible
showWarning = false; // so we don’t show an error every second
} else if (System.totalMemory > abortMemory) {
// save current user data to an LSO for recovery later?
abort();
}
}
function abort() {
// send the user to a page explaining what happpened:
navigateToURL(new URLRequest(“memoryError.html”));
}

This could obviously be enhanced in a number of ways, but hopefully demonstrates the basic concept well.

It is important to note that totalMemory is a shared value within a single process. A single process may be just one browser window, or all open browser windows, depending on the browser, the OS, and how the windows were opened (ex. in OSX all Safari windows share a single process and totalMemory value, whereas it is much more convoluted in Windows).

Weak References
One of the features I’m really happy to see implemented in AS3 is weak references. These are references to objects that are not counted by the Garbage Collector in determining an object’s availability for collection. That is, if the only references remaining to an object are weak, that object will be removed by the GC on its next pass. Unfortunately, weak references are only supported in two contexts. The first is event listeners, which is great because event listeners are one of the most common references that cause problems with garbage collection. I strongly recommend alwaysusing weak references with listeners by passing true as the fifth parameter of your addEventListener calls:

someObj.addEventListener(“eventName”,listenerFunction,useCapture,priority,weakReference);
stage.addEventListener(Event.CLICK,handleClick,false,0,true);
// the reference back to handleClick (and this object) will be weak.

To learn more, read my article on weakly referenced listeners.

The other place that weak references are supported is in the Dictionary object. Simply pass true as the first parameter when you instantiate a new Dictionary to have it use weak references as its keys:

var dict:Dictionary = new Dictionary(true);
dict[myObj] = myOtherObj;
// the reference to myObj is weak, the reference to myOtherObj is strong

To learn more about using dictionaries in ActionScript 3, read my article about the Dictionary Object in AS3. One of the cool things about having weak reference support in Dictionary is that we can hook into it to use weak references in other contexts. For example, I used Dictionary to create WeakReference and WeakProxyReference classes that can be used to create weak references anywhere.

WeakReference class
WeakReference takes advantage of Dictionary to allow you to hold a weak reference to any object within any context. It has a small amount of overhead for instantiation and access, so I would only recommend using it for potentially large objects that may not be properly freed. This should notreplace writing code that cleans up properly after itself, but it can help you to ensure large data objects are freed properly for garbage collection.

I based the ActionScript 3 WeakReference class on the WeakReference class for Java. To use it, you simply instantiate a new WeakReference, passing the referent (object you wish to reference) as the first parameter. You then store a strong reference to the instance of WeakReference, not the referent, and access the referent via the get() method of WeakReference.

import com.gskinner.utils.WeakReference;
var dataModelReference:WeakReference;
function registerModel(data:BigDataObject):void {
   dataModelReference = new WeakReference(data);
}
...
function doSomething():void {
   // get a local, typed reference to the data:
   var dataModel:BigDataObject = dataModelReference.get() as BigDataObject;
   // call methods, or access properties of the data object:
   dataModel.doSomethingElse();
}

For well architected code, this is a good solution, because it lets you maintain type safety, and is non-ambiguous. For those who just want to hack code together quickly, I also put together the WeakProxyReference class (which was a great learning experience for the new Proxy object).

WeakProxyReference class
WeakProxyReference uses the new Proxy class to transparently wrap a weakly referenced object. It works the same as WeakReference, except that you can call methods on the weak reference object directly and have them passed to the referent. The main issues are the loss of type safety, and slightly more ambiguous code. Note that it will still throw appropriate run-time errors (ex. if you try to access a non-existent property on the object), but not compile-time errors.

import com.gskinner.utils.WeakProxyReference;
var dataModel:Object; // note that it is untyped, and not named as a reference
function registerModel(data:BigDataObject):void {
   dataModel = new WeakProxyReference(data);
}
function doSomething():void {
   // don't need to get() the referent, you can access members directly on the reference:
   dataModel.doSomethingElse();
   dataModel.length++;
   delete(dataModel.someProperty);

   // if you do need access to the referent, you need to use the weak_proxy_reference namespace:
   var bdo:BigDataObject = dataModel.weak_proxy_reference::get() as BigDataObject;
}

You can download WeakReference and WeakProxyReference at the end of this article.

Unsupported Way to Force GC
In my previous article on Garbage Collection in AS3 I said that the GC is indeterminate – that there is no way to know when it will run. That is not entirely true, there is a trick that will let you force the Flash player to carry out a full GC pass. This trick can be really handy for exploring Garbage Collection, and testing your applications during development, but it should never be deployed in production code because it can wreak havoc with processor load. It is also officially unsupported, so you cannot rely on it to work in updated versions of the player.

To force an immediate GC mark/sweep, all you have to do is call connect() on two LocalConnections with the same name. This will throw an error, so you’ll have to wrap it in a try/catch block.

try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}
// the GC will perform a full mark/sweep on the second call.

Again, this should only be used as a development aid. It should never be used in production code! There is an example of this in use in the demo FLAs for the WeakReference class, which you can download at the end of this article.

Summary
ActionScript 3 has substantially increased the amount of work developers must do to manage resources in their applications. While we have only been provided with a few new tools to help us with this, they are better than nothing and signify that Adobe is at least aware of the issue. Pairing these new tools with effective strategies and approaches (the subject of my next article) should allow you to successfully manage resources in Flash 9 and Flex 2 projects.

Download WeakReference and WeakProxyReference.

A big thank you to Thomas Reilly for proofreading this article, and ensuring I’m not misleading the rest of the Flash world too badly. Any errors are mine, not his.

3 cách viết code trong Flex

Giống như Flash có cách viết code trên frame, trên đối tượng (AS2), hoặc dùng linkage với file bên ngoài.

Flex có những cách code tương tự như sau :

1. Code trực tiếp trên file mxml với thẻ scritp:

Code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="helloWorld();">
	<mx:Script>
		<![CDATA[
			public function helloWorld(): void {
				labelHello.text = "Hello World";
			}
		]]>
	</mx:Script>
	<mx:Label id="labelHello"  color="#FFFFFF" width="150"/>
</mx:Application>

2. Code trên file as rồi include vào :

File myscript.as (tạo = New ActionScript File)

Code:
// ActionScript file
public function helloWorld(): void {
	labelHello.text = "Hello World";
}

File mxml:

Code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="helloWorld();">
	<mx:Script>
		<![CDATA[
			include "myscript.as";
		]]>
	</mx:Script>
	<mx:Label id="labelHello"  color="#FFFFFF" width="150"/>
</mx:Application>

3. Dùng class (code behind): đây là cách tốt nhất. Code 1 nơi, layout 1 nơi, rõ ràng, dễ đọc.

MyVBox class (tạo = New AS Class) :

Code:
package
{
	import mx.controls.Label;
	import mx.containers.VBox;
	import mx.events.FlexEvent;

	public class MyVBox extends VBox
	{
		public var labelHello: Label;

		public function MyVBox()
		{
			super();
			this.addEventListener(FlexEvent.CREATION_COMPLETE, helloWorld);
		}

		public function helloWorld(event: FlexEvent): void {
			labelHello.text = "Hello World";
		}

	}
}

File MyVBoxComp.mxml:

Code:
<?xml version="1.0" encoding="utf-8"?>
<MyVBox xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
	<mx:Label id="labelHello"  color="#FFFFFF" width="150"/>
</MyVBox >

File TestApplication.mxml:

Code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*">
	<local:MyVBoxComp />
</mx:Application>

Tùy từng trường hợp mà chúng ta đặt code cho thích hợp. Nếu code đơn giản thì xài cách 1 hoặc 2, còn ko xài cách 3 để pro hơn 1 chút.

Copyright: http://vnfx.com/vb/showthread.php?t=3973

Powered by WordPress | Theme: by 85ideas. Editor by Khoanguyen