Difference between getDefinition and getDefinitionByName in AS3 - actionscript-3

Can somebody explain what is the difference between getDefinitionByName and getDefinition inA AS3?
When I load an external SWF I can't use getDefinitionByName because I get an Error #1065.
But using externalSWF_ContentLoaderInfo.applicationDomain.getDefinition works OK.
So, why getDefinitionByName doesn't find the className?
I mean, if the definition is inside the applicationDomain of the loaded SWF, why is not in the main SWF too? (I'm using Flex).
Offtopic: I can't create new tags so I can't add the tags getDefinition and getDefinitionByName :(

getDefinition is a method of an ApplicationDomain which returns a definition of a class, namespace or function.
getDefinitionByName is a package-level function from flash.utils which returns a Class object that you can use to instantiate new Objects. The definition must already be loaded somewhere in your ApplicationDomain.
The reason you can't make getDefinitionByName with an external SWF is that it is loaded into a separate ApplicationDomain. Your second example works because you are targeting the correct ApplicationDomain. To make your first example work you must load the external SWF into your current ApplicationDomain like this:
var request:URLRequest = new URLRequest("externalSWF.swf");
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
var loader:Loader = new Loader();
loader.load(request,context);
This works because it passes the current ApplicationDomain as a property of the loader context.

Related

Accessing multiple bitmap images in a swc file by using getdefinitionbyname

I received from my client a SWC file with hundreds of png images that all have AS Linkage such as image1_1_1, image1_1_2, image1_2_1, image2_1_3 and so on. I have these same linkage names in an XML file that i'm loading.
All the images are linked with the BitmapData class as base class.
The problem is that when i try to dynamically create new bitmaps from the xml file and the linkage names by using getDefinitionByName i get the following error:
ReferenceError: Error #1065: Variable image1_1_1 is not defined.
My code for creating the bitmaps is as follows:
var BmDataClass:Class = getDefinitionByName(xmlImage) as Class;
var image:Bitmap = new Bitmap(new BmDataClass());
where xmlImage is the variable in a for each loop, looping through the xml file.
I trace xmlImage so i know it coresponds to the correct name in the SWC file.
Does anyone have any idea why i get this error?
Would appreciate any hints or solutions :-)
try this:
var imageName:String = "xxx";
var myClass:Class = getDefinitionByName(imageName) as Class;
var bmp:BitmapData = new myClass(0, 0) as BitmapData;
var img:Bitmap = new Bitmap(bmp);
The answer seems to have been as described in the accepted Answer to this thread
Instantiate a class from a string in ActionScript 3
And also slightly explained on this page
http://producerism.com/blog/flashpunk-dame-and-lua-tutorial-part-6/
under the paragraph titled getDefinitionByName
Which for me sadly messed up a large part of the project. Ah well... new solutions presents themselves every day :-)

Referencing flash instance names in actionscript 3

I am trying to reference a movie clip through its instance name which I have called "mc_mycursor" inside flash.
I want to access this movie clip inside my main document class which runs the entire application. Till now I have been exporting all objects on my stage to classes and then adding them as child objects to my stage which works fine but I would like to know how to directly refer to an object inside stage in AS3 just by using its instance name.
I have declared the variable in my main doc as follows
private var mc_mycursor:MovieClip;
but when i try to do something like mc_mycursor.x = 500, it throws an error. I am new to Flash so some help would be appreciated.
You first need to instantiate it like:
mc_mycursor = new MovieClip();
addChild(mc_mycursor);
You can do this in the constructor or at least before you try to modify properties.

AS3: How to instantiate the generic 'Document Class' (MainTimeline?) of a loaded SWF?

I have "Question.swf", which was created from "Question.fla". Note that Question.fla has no Document Class associated with it. (Note that this is legacy content, and there are over 14,000 variants of "Question.swf"; changing all these is not a viable option.)
Now I have my main Flash application, which loads in Question.swf at runtime. I know that Question.swf has a "Document Class" automatically created which represents the entire "stage" of the SWF (and that it's named "MainTimeline"). I want this application to be able to instantiate multiple instances of that Question.swf Document class... how can I?
I've been working with Flash/AS3 since 2006 (I'm very familiar with loading/using external content, the ApplicationDomain, etc.), but I find that I have no idea how to do this!
Things I've tried which haven't worked include querying the relevant ApplicationDomain with hasDefinition( "Question_fla.MainTimeline" ) - this returns false - as well as running getQualifiedClassName() on my loader.content object - this just returns MovieClip.
I'm not sure how to duplicate the main content of the Loader. However, a reasonable workaround might be to load the SWF bytes once and create multiple Loaders from those bytes:
Load your SWF bytes with a URLLoader:
var urlloader : URLLoader = new URLLoader();
urlloader.load(new URLRequest("your url here"));
Once it is loaded, use the bytes to instantiate new display objects:
var loader : Loader = new Loader();
loader.loadBytes(urlloader.bytes);
Use your loaded loader's loader.content display object on the display list (or the loader itself).

AS3 Loader Class best practice

Recently in a project I configured a custom Loader class as follows
First I define my Loader as a private variabel
private var _myLdr:Loader
//Then in the constructor
_myLdr = new Loader();
_myLdr.contentLoaderInfo.addEventListener( Event.COMPLETE, doneImgLoad );
_myLdr.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, loadProgress );
_myLdr.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, ioError );
And then finally when I need to load a new asset I call my Loader instance via a public method
_myLdr.load(new URLRequest ('myswftoLoad.swf') );
So far so good....UNLESS you happen to view your page using the debug version of FlashPlayer 9.024 in which case you get
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::Loader/_load()
WTF???!!
So to correct I need to instantiate a new loader EVERY time I load a new asset.
Can someone tell me which method would be considered a 'best practice'?
A Loader instance can have utmost one child at a time. Call _myLdr.unload(); before issuing subsequent load() requests with same Loader instance.
That being said, I would rather create a new Loader instance for each loads (and make sure that previous instances are properly unloaded when they are no longer needed).

Can an AS2 swf be loaded into an AS3 swf? How can I add this to the stage and interact with it from As3 swf?

I am trying to load a swf written in AS2 into an AS3 swf - using Loader class and listening for Event.COMPLETE. in my onCompleteHandler function i want to add this to the stage so Im trying -
addChild(evt.currentTarget.content)
... but I get the following error message:
Error #2180: It is illegal to move AVM1 content (AS1 or AS2) to a different part of the displayList when it has been loaded into AVM2 (AS3) content.
The AS2 swwf has a lot of code and I really dont want to have to migrate to AS3 if I can avoid it. Anybody know if this is possible or know of a differnt way to add the loaded swf to the stage. How do I then go about calling functions in the loaded swf?
Here is a code snippet -
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
var request:URLRequest = new URLRequest("testLoadSwf.swf");
loader.load(request);
function onCompleteHandler(evt:Event) {
addChild(evt.currentTarget.content);
}
Thanks all.
The only really effective way to do this is by using LocalConnection. AS2 and AS3 can't communicate much with each other. If you still have access to the AS2 file's source, you can expose some functions with LocalConnection. There's also a neat helper class by Grant Skinner called SWFBridge that takes some of the groundwork out of doing this, it's available here: http://www.gskinner.com/blog/archives/2007/07/swfbridge_easie.html
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
var request:URLRequest = new URLRequest("testLoadSwf.swf");
loader.load(request);
function onCompleteHandler(evt:Event) {
//addChild(evt.currentTarget.content);
}
addChild(loader)