Loading .swc assets into array, in pure Actionscript 3 project - actionscript-3

I know how to get Flash CS4 symbols into Flash Builder via .swc.
The class names become available in the main class, but I can only instantiate those one by one, writing each name into the code.
How can I loop through the .swc and load its assets in an array without mentioning their name, then obtain and use these names for instantiation? ideally, something like (half-assed pseudocode):
the_instances: = new Array
for(i=0; i<the_SWC.length; i++)
{
tmp = new eval( the_SWC[i].name + '\(\)' )
the_instances.push( tmp )
}
or anything else to get those names in a loop.

You have at least 2 options.
Option1:
Given the fact that a SWC file is a zip file that contains a swf with the embedded assets and an xml file describing the contents, you can load the swc as a zip, get the xml and parse it.
var swcLoader:URLLoader = new URLLoader(new URLRequest('assets/assetsLib.swc'));
swcLoader.dataFormat = URLLoaderDataFormat.BINARY;
swcLoader.addEventListener(Event.COMPLETE, swcLoaded);
function swcLoaded(event:Event):void{
var zipFile:ZipFile = new ZipFile(event.target.data);
for(var i:int = 0; i < zipFile.entries.length; i++) {
var entry:ZipEntry = zipFile.entries[i];
if(entry.name == 'catalog.xml'){
var data:ByteArray = zipFile.getInput(entry);
var list:XML = new XML(zipFile.getInput(entry));
var nodes:XMLList = list.children();
for (var j:int = 0; j < nodes.length(); j++) {
if (nodes[j].name().localName == "libraries") {
var libraries:XML = nodes[j];
var libList:XMLList = libraries.children();
for(var k:int = 0 ; k < libList.length(); k++){
var library:XML = libList[k];
var classList:XMLList = library.children();
for(var l:int = 0 ; l < classList.length(); l++){
var classDef:XML = classList[l];
trace('class name: ' + classDef.#name);
//var LibClass:Class = this.loaderInfo.applicationDomain.getDefinition(classDef.#name) as Class;
}
}
}
}
}
}
}
I am using the nochump library.
Option2:
Since you only need the class names to make your like easier and you mentioned using Flash CS4(which makes me assume you have access to the .fla file generating the swc), you can write a simple jsfl script that will write that line of code for you.
var doc = fl.getDocumentDOM();
var libItems = doc.library.items;
var libItemsNum = libItems.length;
var classesString = 'var '+doc.name.substr(0,doc.name.length-4)+'Classes = [';
var classesNum = 0;
var classes = [];
fl.outputPanel.clear();
for(var i = 0 ; i < libItemsNum; i++){
if(libItems[i].linkageExportForAS){
classes[classesNum] = libItems[i].linkageClassName;
classesNum++;
}
}
for(i = 0; i < classesNum; i++){
if(i < classesNum-1) classesString += '"'+classes[i]+'",';
else classesString += '"'+classes[i]+'"];';
}
fl.clipCopyString(classesString);
fl.trace(classesString);
All you need to do is:
File > New > Flash Javascript File and paste the code.
Save it in the Commands folder with a descriptive name, like: listExportClasses.
Since it's in the Commands menu, if you use this often enough you could add a keyboard shortcut.
What the command will is generate an array with the name of the fla file and contain the exported classes' names and conveniently place it in your clipboard.
e.g
var assetsLibClasses = ["Start1","Start2","Start3","Button","ColorBox","GameBackground","MenuBackground"];

Related

XMP data encrypted on Canon EOD D1000

I have a question regarding encryption, once again this relates to reading serial numbers from the aux:SerialNumber namespace.
When I open my file in AS3 from photos of the Canon EOS D1000, it can't read this bit in the ByteArray var i:int = p.search('<x:xmpmeta xmlns:x="\'dobe:ns:meta/\''); because well its encrypted.
What makes this interesting is, if I open the file in Photoshop then save it and close it the XMP data is correct and my app can read it.
My question would be how would I decrypt the XMP data from within AS3? Is there a way to do it. Or another way to read it?
This is the method I use:
private function getXMP(ba:ByteArray):XML
{
var LP:ByteArray = new ByteArray();
var PACKET:ByteArray = new ByteArray();
var l:int;
ba.readBytes(LP, 2, 2);
//http://www.adobe.com/devnet/xmp.html read part 3: Storage in Files.
//that will explain the -2 -29 and other things you see here.
l = LP.readInt() - 2 -29;
ba.readBytes(PACKET, 33, l);
var p:String = trim(""+PACKET);
var i:int = p.search('<x:xmpmeta xmlns:x="adobe:ns:meta/"');
//Delete all in front of the XMP XML
p = p.substr(i);
//For some reason this left some rubbish in front, so I'll hardcode it out for now
var ar:Array = p.split('<');
var s:String = "";
var q:int;
var j:int = ar.length;
for(q=1;q<j;q++)
{
s += '<'+ar[q];
}
i = s.search('</x:xmpmeta>');
i += ('</x:xmpmeta>').length;
s = s.slice(0,i);
//Delete all behind the XMP XML
//trace(s);
return XML(s);
}

how to change shared object path when I save data in it

how to change sharedObject save location,I want to save shared object on server for particular user, what I do for this?
You can look at SharedObject.getRemote() if you have a Flash Media server. Alternatively you can encode the data associated with your SharedObject as JSON and store it in a database.
Bad way, but it works
var src:ByteArray = your byteArray;
var arr:Array = new Array();
for (var i:int = 0; i < src.length; i++)
{
arr.push(src.readByte());
}
var jsonStr:String = arr.join("|");
and conversely...
var retArr:Array = jsonStr.split("|");
var ba:ByteArray = new ByteArray();
for (var j:int = 0; j < retArr.length; j++)
{
ba.writeByte(retArr[j]);
}
var ldr:Loader = new Loader();
ldr.loadBytes(ba);
addChild(ldr);

AS3 AIR - "list / count" dictory contents

Using AS3 Air for Android, What code can I use to list all or count the files from a chosen directory on local machine? In this case I am using Air For Android.
Then I would like to put them in an array
I am willing to give 50 pts for this answer. As you can see for my rep it's a lot but this question is HUGE for me. I would like it if possible if we don't use a Class Package.
The following code outputs a list of files and directories contained in the user's desktop directory.
import flash.filesystem.File;
var desktop:File = File.applicationDirectory.resolvePath("images");
var files:Array = desktop.getDirectoryListing();
for (var i:uint = 0; i < files.length; i++)
{
trace(files[i].nativePath); // gets the path of the files
trace(files[i].name);// gets the name
/// PUT ARRAY CODE HERE to add each "files[i].name" into an array for later use.
}
You can recurse through directories by checking if each File in the directory listing is a directory. The following function will return the count of all files recursively (excluding directories).
function recursiveDirectoryListing( directory:File ):int
{
var count:int = 0;
if (directory.isDirectory)
{
var files:Array = directory.getDirectoryListing();
for (var i:int = 0; i < files.length; i++)
{
if (files[i].isDirectory)
{
count += recursiveDirectoryListing( files[i] );
}
else
{
trace("file found: " + files[i].nativePath );
count += 1;
}
}
}
return count;
}
Then you can just call this function on whatever location you require to list:
recursiveDirectoryListing( File.applicationStorageDirectory );

How to create a series of class instances in a for loop, as3

In my library I have a bunch of classes named tip1, tip2, tip3, tip4...and so on. Is it possible to create one instance of each on the stage using a for loop? I tried this but it didn't seem to work.
var tips:int = 12;
for(var i:int = 1; i<=tips; i++){
var tipName:String = "tip"+i
var tip:MovieClip = new tipName();
tip.name = "tip" + i
tip.x = stage.width;
tip.y = 0;
addChild(tip);
}
Any help would be appreciated. Thanks!
You were missing the "getDefinitionByName" part.
// Up top
import flash.utils.getDefinitionByName;
// Down below
var tips:int = 12;
for (var i:int = 1; i < tips; ++i ) {
var myClass:Class = getDefinitionByName('tip' + i) as Class;
var tip:Object = new myClass();
tip.name = "tip" + i;
....
}
Instead of
var tip:MovieClip = new tipName();
Try (written from memory)
var clazz:Class = getDefinitionByName(tipName) as Class;
var tip:MovieClip = new clazz();
Also, you generally want to use stage.stageWidth instead of stage.width, since the latter will return the stage bounding box width (which might not be the same as the area the swf file covers).

I cant remove child of this movie clip upon clicking the back button to go function goHomePage (evt:Event):void{

Help. I need to remove the newContainer(this is a movie clip) after clicking the back button to go back to homepage.
But it just loads the homepage and the newContainer is still there. :( where did i go wrong?
import flash.events.MouseEvent;
import flash.events.Event;
import fl.motion.MotionEvent;
import flash.net.URLVariables;
import flash.display.MovieClip;
import flashx.textLayout.elements.Configuration;
var ctr:int = 0;
var now:Date = new Date();
var myurl:String = "http://localhost:8888/eventspictures/getdata.php";
var scriptLoader:URLLoader = new URLLoader();
var scriptRequest:URLRequest = new URLRequest();
var newContainer:MovieClip;
scriptRequest.url = myurl + "?ck=" + now.getTime();
scriptLoader.addEventListener(Event.COMPLETE, handleLoadSuccess);
scriptLoader.addEventListener(IOErrorEvent.IO_ERROR, handleError);
scriptRequest.method = URLRequestMethod.POST;
scriptLoader.load(scriptRequest);
function handleLoadSuccess(evt:Event):void
{
for (var j:Number = 0; j <4; j++)
{
var newContainer:MovieClip = new con();
newContainer.name = String(ctr);
newContainer.y = j*80 +65;
newContainer.x= 16;
stage.addChild(newContainer);
var variables:URLVariables = new URLVariables(evt.target.data);
trace(variables.output);
var parse:String = variables.output;
var parsed:Array = parse.split("<|>");
var tab:String = ' ';
var eventname:String = '';
var date:String='';
var slotsleft:String='';
// different variable names to assign to different column names(etc; eventname, date, slotsleft)
// loop through.. start from O
for (var i:Number = 0; i<parsed.length-1; i++)
{
trace(parsed[i]);
var item:String = parsed[i];
var itemarray:Array = item.split(",");
eventname += itemarray[2] + tab + "<br>";
date += itemarray[3] + tab;
slotsleft += itemarray[4] + tab;
trace(eventname);
newContainer.eventname_txt.htmlText = eventname;
newContainer.date_txt.htmlText= date;
newContainer.slotsleft_txt.htmlText=slotsleft;
}
}
//slotsleft_txt.x = 270;
}
function handleError(evt:IOErrorEvent):void
{
}
backbutton_mc.addEventListener(MouseEvent.CLICK, goHomePage);
function goHomePage (evt:Event):void{
gotoAndPlay("dashboard");
removeChild(newContainer);
}
stop();
In your function handleLoadSuccess() you have a loop that creates 4 MovieClip's and adds them to the stage.
But in your goHomePage() function you only try to remove one object from the stage. It turns out this object is probably null in your example (trying to remove an object that is null should generate an error if you are using the debug Flash player).
The reason it is probably null is because you have defined two variables named newContainer in your code: one is declared at the beginning of the script, and the second one inside the function handleLoadSuccess() (because you are using the keyword var on each line).
The variable created inside the function only exists while that function is executing. The variable created outside the function never seems to receive a value.
Two approaches you can use:
Keep track of the things you add to the stage, by putting them in an Array:
Replace the newContainer variable that is outside the function with an Array called containers:
var containers:Array = [];
In the function handleLoadSuccess(), when you add each MovieClip to the stage, also add them to the containers array:
stage.addChild(newContainer);
containers.push(newContainer);
Finally in the function goHomePage() iterate over the containers array to remove each MovieClip:
for (var j:int = 0; j < containers.length; j++)
{
stage.removeChild( containers[j] );
}
// reset the containers array so it's empty for the next time
// and to remove the references to the MovieClips (to prevent a memory leak)
containers=[];
Blindly remove everything from the stage
If this is accetpable, it is much easier. Just iterate backwards over the children of the stage in your goHomePage() function:
for (var j:int = stage.numChildren; j >= 1; j--)
{
stage.removeChildAt(j - 1);
}