AS3: Handle BulkLoader.COMPLETE event on AS3 Preloader - actionscript-3

I am trying to use BulkLoader (https://github.com/arthur-debert/BulkLoader) to preload all assets of my AS3/Flex application. Right now it is working and I am able to access the contents everywhere on my Main module (where my BulkLoader instance lives).
My problem: I need to handle the BulkLoader.COMPLETE event from my preloader (pre.as living next to Main.mxml on src/), to allow the user to exit the preloader and enter the application ONLY after BulkLoader.COMPLETE was fired.
Thanks!

Why not pass the reference to the BulkLoader instance?
Somethinglike this:
preloader.setLoader(_bulkLoaderInstance or name)
or
var preloader:Preloader = new Preloder(_bulkLoaderInstance or name)
BTW, the LoaderMax from Greensock is better (fewer bugs, more reliable events, nicer API).

Related

Libgdx Skin dispose behavior

I've a question about the libgdx Skin behavior.
the game I'm developing has a global AssetsManager (from the libgdx suite) that every class can access.
I load different TextureAtlas inside this assets manage
I know that assetManager.dispose() disposes all the resources loaded inside the assets manager.
Now, I would like also to have a Skin (for the GUI) loaded inside the assets manager.
The skin is gonna use several TextureAtlas...
Here's the question: since I'm gonna use skin.addRegion() and since the online API reference about the skin class says "The atlas will not be automatically disposed when the skin is disposed" is it a good idea to load all the TextureAtlasof the skin in the global assets manager?
I'm fearing about the dispose action. Because when I call the assetManager.dispose() both the TextureAtlas and the Skin will be called on the dispose method...but what if the TextureAtlas are disposed before the skin?
Could actually happen any problem about it?
The skin behavior is not so well-defined, I mean...what does the dispose method do?
Thank in advance,
Luca
skin.dispose() calls dispose on any specific resources that are Disposable. But the TextureAtlas itself is not one of the "resources" so it must be manually disposed of separately from the skin.
The only example of a disposable skin resource I can think of is a BitmapFont that does not use the TextureAtlas that you're using with the Skin.
Note that you should never call dispose on something that you loaded with the AssetManager. Instead, you should call manager.unload() on that resource so the AssetManager can properly manage dependencies.
The nice thing about manager.unload() is that it keeps track of how many other resources are dependent on the object and only disposes it when it's clear of dependencies. So if you also load your Skin with the AssetManager, you only ever need to worry about calling manager.unload("mySkin") and it will correctly determine whether the associated TextureAtlas should also be disposed.
But be sure to only call unload() on a resource once per time you called load() on the same resource. AssetManager's internal dependency counting does rely on all your load() and unload() calls mirroring each other one-to-one.
I didn't want to post an anwser but I wasn't able to post a comment with code -_-.
Ok, so if the situtation is this below:
`
assetManager.load("images/guiTextureAtlas", TextureAtlas.class);
assetsManager.load("skin/uiSkin.json", Skin.class)";
assetsManager.finishLoading();
Skin uiSkin = assetManager.get("skin/uiSkin.json");
uiSkin.addRegion(assetManager.get("images/guiTextureAtlas");
`
Is it all fine if I call assetManager.dispose() for disposing all the resources?

Modifying the domain memory of a loaded SWF to control behavior

I have several flash games that cannot be paused from within the games. I would like to write a wrapper swf that allows me to pause them. It is not feasible to recompile the games, so no functionality can be added to them.
What I would probably need to do is control when the loaded swf gets ENTER_FRAME events and redirect calls to flash.utils.getTimer to a function defined in the wrapper. Can this be done by modifying the domainMemory ByteArray of the loaded ApplicationDomain object?
domainMemory is definitely doesn't help you, it's just the API to access to the fast memory.
What you can try to do is to decompile the game swf and find the dispatcher of main EnterFrame event (and after loading game swf you have to find this dispatcher through the display list for example if it doesn't turned out to be the stage or root), that is used as the game tick dispatcher, than you will be able to intercept the default EnterFrame event for this dispatcher. For interception just add your own listener with the higher priority:
//pause the game
dispatcher.addEventListener(Event.ENTER_FRAME, onGameEnterFrame, false, 1);
//resume the game
dispatcher.removeEventListener(Event.ENTER_FRAME, onGameEnterFrame);
protected function onGameEnterFrame(event:Event):void
{
event.stopImmediatePropagation();
}

How do I attach a global event listener?

I am working on an AIR application:
The main window is like a dashboard. With the menu bar, I can open other windows with dashboard details. When I close these, I'd like to refresh the main window.
I tried to use an event listener, but the result is not good. If I open detail windows directly from the main window, I know how to add an event listener - and it works - but I don't know how to do it, if the detail window is opening from the menubar!
Thanks for helping me.
A Singleton is what you are looking for. Just put an event dispatcher inside and you will be able to listen from everywhere in the application.
A Singleton is like having a unique instance of an object in memory, so anyone modifying a variable inside that object ( or sending events throught ) will be modified for everyone.
Here is an example of code on how to use it.
http://life.neophi.com/danielr/2006/10/singleton_pattern_in_as3.html
Note: Singletons are powerful and dangerous at the same time, there is a lot of talk about how to use them, please read a little more about that if you are considering building a big project.
Hope it helps!
The issue is that you're performing business logic from a View. Don't do this. Instead, dispatch an event from each menu rather than directly opening the window from within it. Listen for those events at a higher level, and then you can either directly listen to the new windows you have opened, or you can create a base window Class that exposes a variable of type IEventDispatcher. If you populate that variable with the same event dispatcher, what you wind up with is called an "event bus," and you can listen on that for events.
This architecture requires a little more thought than using a Singleton, but it avoids the tight coupling and other issues you'll run into by introducing one into your project.
You can listen to an object (EventDispatcher) directly by adding an event listener to it, or if the dispatcher object is on the displaylist, such as a Sprite, you could listen at the stage level with the capture parameter set to true.
But the main caveat is that the dispatcher must be on stage for you to catch this event.
Your main window listens to stage (with capture = true):
stage.addEventListener("MY_CUSTOM_EVENT", handle_custom_event, true);
private function handle_custom_event(e:Event):void
{
var sub_window:Object = e.target;
// do something to your sub_window
}
Your sub window can dispatch events like this:
dispatchEvent(new Event("MY_CUSTOM_EVENT"));
But (ab)using the stage as a message passing infrastructure for custom events in this way is a little messy. You could consider a more formal message passing architecture if you really want this kind of communication. Even a static MessageBus class would at least quickly help you identify where you use this in your codebase. Either way, you'll have to be careful about references and memory leaks.

referencing existing sound objects on the timeline via actionscript 3

In Actionscript 3 / Flash 10, is it possible to programmatically reference a sound object that exists on the timeline? I've found lots of examples for referencing DisplayObjects via the following sytax:
var m:MovieClip = stage.getChildByName("SomeMovieClipClass");
var n:MovieClip = stage.getChildByIndex(1);
But this doesn't seem to include sound objects. Similarly, it seems straightforward to instantiate and play a sound that exists in the Library via Actionscript:
var s:SoundClip1 = new SoundClip1(); // exported in first frame via properties
s.play();
For my purposes, though, I'd like to reference sound clips (ideally in a specific layer, although that seems to be a design-time element) that designers have adjusted and arranged on the timeline, so that I can inspect their waveforms via code, at runtime. Something like this:
// Imaginary Code
sc = timeline.getSoundClipByName("SoundClip1");
sc.extract(waveform,sc.length/1000 * bitrate);
Is this possible? Thanks!
As of this date, no it is not possible to access the soundChannel generated by a timeline sound. It's a feature I would love to see implemented.
I was going to try to test the feasibility of using computeSpectrum to get the waveform of a timeline sound but I'm having problems importing mp3s right now. In absence of firsthand proof of concept, I searched around and found this thread:
http://www.kirupa.com/forum/showthread.php?t=329632
Which links to this solution
http://www.mail-archive.com/flashcoders#chattyfig.figleaf.com/msg43157.html
But of course this doesn't allow you to disambiguate between different timeline sounds. I'm pretty sure you won't be able to do that at all.
I have not ever used Sound.extract(), but if the sounds exist in the fla library this indicates to me that you can simply give them a Class name and at runtime use extract() to gather the waveform for your own purposes, yes? Then whenever the appropriate timeline sound plays, you can tap into the waveform from the Sound object. Perhaps a timeline callback or event would suffice for this?

AS3 Wrapper Accessing AS1 Variables

Okay, so I have a Flash CS3 (+ AS3) program which is loading another flash program (called "pacman_main.swf" in this example). I've determined this is a rather old SWF, as it is made in Flash 5 and AS1 (yippee!).
I want the parent SWF (a.k.a. the wrapper) to be able to access the variables, specifically the score, of the child SWFG (a.k.a. "pacman_main.swf"). This is so I can submit the score to a 3rd party PHP/mySQL db blah blah.
function checkScore() {
// Get the score and submit it
}
submitScore.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(event:MouseEvent):void {
checkScore();
}
var loader:Loader = new Loader();
loader.load(new URLRequest("pacman_main.swf"));
addChildAt(loader, 0);
I know the variable name of the score, using the Debug > List Variables after building the wrapper. The score is a variable listed as "Variable _level0.instance5.instance6.score = 180" after getting 18 pac-dots in the game. How would I access that in my "checkScore" function?
Thanks!
The latest flash players have two virtual machines packaged in them, the AVM2 for as3, and AVM1 for as2/as1. Because of this, when you load an as1/as2 swf into flash it is of the type AVM1Movie, which will be run by the AVM1. Unfortunately, the AVM2 has little access to the objects running on AVM1, in fact, "no interoperability (such as calling methods or using parameters) between the AVM1Movie object and AVM2 objects is allowed".
Do you have access to the as1 source code? If you do I suggest firing off events every time the score changes, you can listen for these events in your wrapper class and not have to worry about accessing the score variable directly.
You can read more about AVM1Movie here