外部SWFからのクラス定義の取り出し
fetch class definition from external swf
author: motoki matsumoto
email: mtmotoki(at)gmail.com
/*
fetch class definition from external swf
author: motoki matsumoto
email: mtmotoki(at)gmail.com
*/
package
{
import flash.text.TextField;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.utils.getQualifiedClassName;
[SWF(width="465", height="465", backgroundColor="0xffffff", frameRate="0")]
public class DynamicClassLoading extends Sprite
{
private var output:TextField;
public function DynamicClassLoading()
{
initOutput();
println('Construct ' + getQualifiedClassName(this));
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
println("外部SWFからクラス定義を読みだすサンプルプログラムです。");
}
public function init():void {
var cl:ClassLoader = new ClassLoader(new ApplicationDomain(null));
var req:URLRequest = new URLRequest("http://www.matzmtok.com/wonderfl/lib/TextLayoutLib.swf");
cl.loadSWF(req);
cl.addEventListener(Event.COMPLETE, completeHandler);
}
private function completeHandler(e:Event):void
{
var cl:ClassLoader = e.target as ClassLoader;
var cls:Class = cl.getClass("flashx.textLayout.elements.TextFlow");
var instance:* = new cls();
println("Loaded class is ", getQualifiedClassName(instance));
}
private function addedToStage(e:Event):void
{
removeEventListener(e.type, arguments.callee);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
init();
}
////////////////
// 出力
///////////////
private function initOutput():void {
var margin:Number = 10;
addChild(output = new TextField());
output.selectable = false;
output.multiline = true;
output.width = stage.stageWidth - margin * 2;
output.height = stage.stageHeight - margin * 2;
}
public function print(... args):void {
output.appendText(args.join(", "));
}
public function println(... args):void {
output.appendText(args.join(", "));
output.appendText("\n");
}
}
}
/*
書いてみたもののあんまり役に立たなそう(笑)
*/
import flash.events.Event;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.EventDispatcher;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.ProgressEvent;
import flash.system.LoaderContext;
import flash.net.URLRequest;
import flash.utils.getQualifiedClassName;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
class ClassLoader extends EventDispatcher {
private var _applicationDomain:ApplicationDomain;
public function ClassLoader(applicationDomain:ApplicationDomain) {
if (applicationDomain == null) {
throw new ArgumentError("applicationDomain is null");
}
_applicationDomain = applicationDomain;
}
public function loadSWF(req:URLRequest):void {
var l:Loader = new Loader();
var context:LoaderContext = new LoaderContext(true, _applicationDomain, SecurityDomain.currentDomain);
l.load(req, context);
l.contentLoaderInfo.addEventListener(Event.COMPLETE, redirectEvent);
l.contentLoaderInfo.addEventListener(Event.OPEN, redirectEvent);
l.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusEventHandler);
l.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
}
private function redirectEvent(e:Event):void {
var event:Event = new Event(e.type);
dispatchEvent(event);
EventDispatcher(e.target).removeEventListener(e.type, arguments.callee);
}
private function httpStatusEventHandler(e:HTTPStatusEvent):void
{
var event:HTTPStatusEvent = new HTTPStatusEvent(e.type, false, false, e.status);
dispatchEvent(event);
EventDispatcher(e.target).removeEventListener(e.type, arguments.callee);
}
private function securityErrorHandler(e:SecurityErrorEvent):void
{
var event:SecurityErrorEvent = new SecurityErrorEvent(e.type, false, false, e.text);
dispatchEvent(event);
EventDispatcher(e.target).removeEventListener(e.type, arguments.callee);
}
private function progressHandler(e:ProgressEvent):void
{
var event:ProgressEvent = new ProgressEvent(e.type, false, false, e.bytesLoaded, e.bytesTotal);
dispatchEvent(event);
EventDispatcher(e.target).removeEventListener(e.type, arguments.callee);
}
public function getClass(name:String):Class {
var cls:Class = _applicationDomain.getDefinition(name) as Class;
if (cls == null) {
throw new Error("Can't find class definition");
}
return cls;
}
public function get applicationDomain():ApplicationDomain {
return _applicationDomain;
}
}