Actionscript 3, read file text at compile time? - actionscript-3

There is some way to make the flash put the content of one text file in a string, or at least put it in the .swf, so the user don't need to download it?

Solution:
[Embed(source = "ExampleText.txt", mimeType = "application/octet-stream")]
protected var pscene:Class;
var tmp:ByteArray = new pscene();
result = tmp.readMultiByte(tmp.bytesAvailable, tmp.endian);
It took me a while to understand how to read the data from the Byte Array.

I've always used a pre-compile step to populate a template. It's pretty easy to make a class that has a string to be populated before compilation.
Ant can do this pretty easily. Check out the replace task.

Related

Animate CC AS3 how to manage data when writing to a file

I am building a program on Animate CC 2019 which needs to access a text file where it can read from and write to.
I want to store strings and numbers, from Input Texts, then write them in the file, in addition to the already existent contents.
I also need to be able to manage how the data is written in the file. So, for example, I want to have 2 arrays: Array1 stores names and Array2 stores numbers. So when the program writes to the file, it needs to write on each line the corresponding values of a specific index in the arrays. So if Array1(0) = name1 & Array2(0) = 52, in the file it should be written:
name1 52
If not exactly like this, a way which data can be written in a manageable way.
I am trying this on Windows 10/AIR.
My questions:
How can I manage how data are written in a file?
Which code should I use? I find info on two ways to approach this:
a. Code using “File” and “FileStream” which does NOT work! I get error messages: “Type was not found or was not a compile-time constant” for both, like the system does not recognize the commands. Are these commands still usable on the current version of Animate CC?
b. The code snipets/AIR code which does work, however, I cannot find a way to manage how data are written in the file, as explained above. Everytime something is written in the file, the previous data are overwritten.
Below the codesnipets code which works.
/* Click to Write to a Text File
Clicking on the specified object will prompt the user to select a location and file name and save a text string to it.
Instructions:
To set what data is saved to the file change "Text to save to file." to the data you wish to save.
*/
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
movieClip_1.addEventListener(MouseEvent.CLICK, fl_SaveFile);
var fl_FileDataToSave:String = "Text to save to file.";
var fl_SaveFileStream:FileStream = new FileStream(); // FileStream used to write to the file
var fl_SaveFileChooser:File = File.documentsDirectory; // Default to the documents directory
fl_SaveFileChooser.addEventListener(Event.SELECT, fl_WriteFileHandler);
// Opens a Save As dialog box for user to specify a file name
function fl_SaveFile(event:MouseEvent):void
{
fl_SaveFileChooser.browseForSave("Save As:");
}
// Write data in fl_FileDataToSave variable
function fl_WriteFileHandler(event:Event):void
{
fl_SaveFileChooser = event.target as File;
fl_SaveFileStream = new FileStream();
fl_SaveFileStream.openAsync(fl_SaveFileChooser, FileMode.WRITE);
fl_SaveFileStream.writeMultiByte(fl_FileDataToSave, File.systemCharset);
fl_SaveFileStream.close();
}

How can I reference a Flash file's own filename from actionscript?

In our pipeline, we ultimately publish HTML5 using Toolkit for CreateJS. However one of the steps to get us to that HTML5 includes publishing an SWF that outputs some Javascript code. I've mostly managed to automate this using JSFL. However, at present there is one line of AS3 that our artists have to find on the timeline and change manually, but it interrupts their workflow, and if they miss it or mess it up it is hard to catch, so I would like to automate it too:
Object(root).log.text += " root.skillAnime189 = factory();\n";
From the above, "skillAnime189.fla" is the name of the .fla file which contains this code. This is the case if the artist is working on Skill Animation #189, but if he is doing #304 or #6 or #1022 (no padding) the number changes accordingly, and he has to update that line accordingly.
So, I would like to change that line to something like:
var flaName:String = getThisFlashFileName().split(".")[0];
Object(root).log.text += " root." + flaName + " = factory();\n";
but I am at a loss as to how to access the name of the .fla file containing the code.
The common way to get the swf name is to parse stage.loaderInfo.url parameter:
var url:String = stage.loaderInfo.url;
url = url.split("?")[0]; //remove query string after "?"
var swfname:String = url.substring(url.lastIndexOf("/")+1);
trace(swfname);
output:
astest.swf
But this code gives swf but, rather than fla, so you need to maintain the same names for flas and published swfs (any case usually they are the same, so it shouldn't be the problem)

Actionscript add strings to embedded images?

Say I have something like this:
[Embed(source='../lib/images/image01.png')] var Image:Class
But I want to change that images based on another string like so:`
var StringData:String
StringData = "02";
[Embed(source='../lib/images/image'+ StringData +'.png')] var Image:Class
But this gives me an error, is there another way to do something like this?
Embedded resources are evaluated at compiling time so you can't set a dynamic path.
If you want a unique path by compile type (debug / release for exemple), you can use compiler variables :
[Embed(source=CONFIG::ICON_PATH)]
var Image:Class;
And add compiler args:
-define+=CONFIG::ICON_PATH,'../lib/images/image01.png'
or
-define+=CONFIG::ICON_PATH,'../lib/images/image02.png'

ActionScript Substituting Lengthy Display List Paths In Code?

i would like to make my code easier to read by replacing long paths with variables, or something similar.
in my code, i can target an instance many times, but the instance can have a lengthy path deep within the display list. for example: myButton instance could be located at myButtonsPanel.section2.redArea.myButton, or something like that.
is it possible to substitue this long path as a variable or constant? something like:
var myPath = myButtonsPanel.section2.redArea;
therefore, calling the instance would be:
myPath.myButton;
Not the path , but the actual Button
var myButton:MovieClip = myButtonsPanel.section2.redArea.myButton;
although you could also do this:
var myContainer:MovieClip = myButtonsPanel.section2.redArea;
//then access your button like this
myContainer.myButton
It really depends on what you need to do, but the idea is that instead of storing a path, you're actually referencing a MovieClip directly, then using that variable to access this MovieClip

AS3 Object Filtering

Ok. so I'm working on an app that retrieves items from a db and builds a gallery. I've done this a ton of times, and it should be simple.
I'm running into problems, because in this gallery, I get results from a db that includes both image files, and other files. Let's just say I can't change anything but the flash, so I need to detect if it's an image, and only display it if it is.
My question is: How the hell can I delete a property from an object without the object staying the same size? I use a count() function to generate pagination data, so I can't just 'null' them, and as I understand it, delete() is not an option either.
My solution for this was to just create another object, filter the good items with a for in loop, then pop them in to another object, but each item in the object is an object, and I have no push() function for objects.
So, in desperation, I am using an increment to add the objects to the new object using an index (goodItemsObject[index] = allItemsObject[object]), but that seems like a really gruesome way of getting around this problem.
Here's some code:
var filteredMO = new Object();
var newFile = 0;
for each(var file in mediaObject){
if(check_file(file)){
filteredMO[newFile] = file;
newFile++;
}
}
mediaObject = filteredMO;
check_file() just returns true or false, mediaObject is all full of objects.
I'd much prefer to be doing this:
for each(var file in mediaObject){
if(check_file(file)){
//remove_from_object_for_reals(mediaObject[file]);
}
}
I realize that might not be possible (would it throw off the for loop?), but something similar would be sweet. I'd love to be able to let the gc grab all these useless objects hanging out.
any ideas?
thanks,
Jesse
What you are using to store your object now is called an associative array. You cannot remove a key-value from an associative array. What you need is a dictionary (which as3 has a build-in one http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Dictionary.html).
import flash.utils.Dictionary;
var dict:Dictionary = new Dictionary();
then you can remove a key from your dictionary by calling
delete dict["myKey"]