PDA

View Full Version : [Flex2] How to control symbols from flash?


aerosoul
05-09-2007, 11:32 AM
Hello,
I have a question about flex2.
Is there any way to control symbols from flash and keep their script?

In an actionscript project, I use [embed] to access symbols from fla files.
However the scripts of embeded symbols are ignored this way (even they are written in as3).

The embeded symbols are movieclips that contain sub-movieclips.
For example, I need a sub-movieclip to do a callback function at its last frame.

embededMC.subMC.addFrameScript() doesn't work this way.

Is there any way to control symbols from flash and keep their script?
Thanks.

miramax
05-09-2007, 11:52 AM
Flex lets you reference exported symbols in an embedded SWF file.
Use embed tag as follow:

[Embed(source='SWFFileName.swf', symbol='symbolName')]

aerosoul
05-09-2007, 01:59 PM
Yes, I use [Embed] tag to embed symbols.
However the scripts of embeded symbols are ignored this way (even they are written in as3).

Is there any way to control symbols from flash and keep their script?

miramax
05-09-2007, 02:28 PM
You can export simbols to classes, and load them from an external .swf in runtime.

aerosoul
05-09-2007, 03:56 PM
You can export simbols to classes, and load them from an external .swf in runtime.

So will the scripts of the symbol (for example, scripts in timeline) work after loaded this way?

I tried to export symbols to classes, but embeded symbols ignore all scripts anyway.

Do you mean not to use [Embed] but load them by swfLoader instead?
Can you tell me more details about how to do this please?
Thanks.

miramax
05-09-2007, 05:19 PM
I propose to load external classes in runtime.
You should write something like ClassLoader...
I use this:
package ru.as3.net
{
import flash.events.EventDispatcher;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
import flash.system.LoaderContext;
import flash.errors.IllegalOperationError;

public class ClassLoader extends EventDispatcher
{
private static var urls:Array = [];
private var loader:ALoader;
private var className:String;
private var classURL:String;
private var __class:Class;

public function ClassLoader(classURL:String, className:String)
{
this.classURL = classURL;
this.className = className;

if( urls[classURL] ) loader = urls[classURL];
else
{
loader = new ALoader();
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain() ;
loader.load(new URLRequest(classURL), context);
urls[classURL] = loader;
}

if(loader.completed) completeHandler();
else
{
loader.contentLoaderInfo.addEventListener(Event.CO MPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(IOErrorE vent.IO_ERROR, ioErrorHandler);
}
}

public function getClass():Class
{
return __class;
}

private function completeHandler(e:Event = null):void
{
var applicationDomain:ApplicationDomain = ApplicationDomain(loader.contentLoaderInfo.applica tionDomain)
try
{
__class = applicationDomain.getDefinition(className) as Class;
dispatchEvent(new Event(Event.COMPLETE));
}
catch(e:Error)
{
throw new IllegalOperationError(className + " definition not found in " + classURL);
}
}

private function ioErrorHandler(e:IOErrorEvent):void
{
trace("ERROR: " + e);
}
}
}
And class-helper:
package ru.as3.net
{
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.events.Event;

class ALoader extends Loader
{
private var __completed:Boolean = false;

public function ALoader()
{
this.contentLoaderInfo.addEventListener(Event.COMP LETE, completeHandler)
}
// bytesTotal == bytesLoaded ???
public function get completed():Boolean
{
return __completed;
}

override public function load(urlRequest:URLRequest, context:LoaderContext=null):void
{
__completed = false;
super.load(urlRequest, context);
}
function completeHandler(e:Event):void
{
__completed = true;
}
}
}
Usage:
Create a swf library with classes what you need.
And create a new fla. Then type in first frame:

import ru.as3.net.*;

var classLoader:ClassLoader = new ClassLoader('library.swf', 'MyMovieClass');
classLoader.addEventListener(Event.COMPLETE, create);

function create(e:Event):void
{
var cl:Class = l.getClass();
addChild(new cl());
}

Sorry for comments missing. I can explain if something unclear.

ClassLoader interface is simple. You create new instance of ClassLoader. First argument in constructor - path to library swf file, second - class name.
ClassLoader dispatches Event.COMPLETE event after loading.
You can get loaded Class by getClass() method.
Weakness - your code depends from an external file. And you can not controll types in external library.

aerosoul
05-10-2007, 09:51 AM
import ru.as3.net.*;

var classLoader:ClassLoader = new ClassLoader('library.swf', 'MyMovieClass');
classLoader.addEventListener(Event.COMPLETE, create);

function create(e:Event):void
{
var cl:Class = l.getClass();
addChild(new cl());
}



Thank you so much!

I use your code and I got an error.

var cl:Class = l.getClass();

I think you mean :
var cl:Class = classLoader.getClass();

Then it works.
Thanks a lot but I have one more question.:p
If I want to load symbols without accessing external files for some reasons.
The only way I know so far is using [Embed] tag, but the scripts of the embedded symbols are stripped.

Is there any way to solve it?
Thanks.

miramax
05-10-2007, 10:32 AM
If I want to load symbols without accessing external files for some reasons.
The only way I know so far is using [Embed] tag, but the scripts of the embedded symbols are stripped.

Is there any way to solve it?
Thanks.I think there is no way to extract code from compiled .swf file. Graphics only.

aerosoul
05-10-2007, 11:10 AM
I think there is no way to extract code from compiled .swf file. Graphics only.

If I embed the whole swf instead of the symbols only, can I create some instances of the symbols and keep their scripts from flash?

miramax
05-10-2007, 11:31 AM
If I embed the whole swf instead of the symbols only, can I create some instances of the symbols and keep their scripts from flash?
Anyway with [Embed] tag you can't interact a code in embeded source.
From help:
> "You can embed SWF files created for Flash Player 8 and earlier. When embedded, your Flex 2 application cannot interact with the embedded SWF file. "
> "You typically embed a Flex 2 application when you do not require the embedding application to interact with the embedded application. If the embedded application requires interactivity with the embedded application, you might consider implementing it as a custom component, rather than as a separate application."

Last applies to compiled flash projects.

dr_zeus
05-10-2007, 05:49 PM
If I embed the whole swf instead of the symbols only, can I create some instances of the symbols and keep their scripts from flash?

Grant Skinner posted a method (http://www.gskinner.com/blog/archives/2007/03/using_flash_sym.html) to embed a SWF using a binary format, and "load" it from a ByteArray.

miramax
05-10-2007, 11:25 PM
Grant Skinner posted a method (http://www.gskinner.com/blog/archives/2007/03/using_flash_sym.html) to embed a SWF using a binary format, and "load" it from a ByteArray.
Yeah great !
loading classes with out external files =)

aerosoul
05-11-2007, 07:42 AM
Can I export my movieclips to swc files, and use them in flex?

aerosoul
05-11-2007, 11:38 AM
I found an easy way to accomplish this.
It's Adobe's prerelease "Flex Component Kit for Flash CS3".
You can export symbols for flex easily.
But the classes are forced to be auto-generated since it only accept classes that extends mx.flash.UIMovieClip.
Maybe the public release will improve this.

dr_zeus
05-11-2007, 11:46 PM
Can I export my movieclips to swc files, and use them in flex?

Yes. If you right-click on symbol in the library and choose "Export SWC", that SWC will work in Flex Builder.

Edit: One more thing... you'll need to make some special changes if you want to use them within the Flex framework, since they won't be compatible with Flex's UIComponent architecture. No changes needed in an ActionScript project, though.

pimpofpixels
06-13-2007, 12:27 PM
This thread helped me out BIG TIME!.

I'll just add one last thing to help out anyone who is as confused as I was.

The last bit that is not mentioned here is that you have to point your Flex Builder Project to the SWC file.

This is done in Eclipse (with flex builder plugin installed) by:
-->Right clicking on the root of the project in the Navigator view.
-->going to properties.
-->Going to library path. (2nd tab)
-->and pressing the "Add SWC" button

This is equivalent to importing the SWC file as a class library, and you can now instantiate classes from that library as easily as you could say new MovieClip()

Thanks to all for their intelligent comments.