Bindable(event="...") public static function - actionscript-3

I am trying to bind to a static function, I designate a binding event name and then fire the event from another static function.
[Bindable(event="dataUpdated")]
public static function string(path:String) :String
{
...
}
private static function updateData() :void
{
//doSomthing;
staticEventDispatcher.dispatchEvent(new Event('dataUpdated'));
}
private static var staticEventDispatcher:EventDispatcher = new EventDispatcher();
My view is not updating when the event is fired, is there a better way to do this?
I have also tried dispatching the event from an instance of the class, I added this staticEventDispatcher as a last resort, but it didn't work.
The point in this if for language translations within the app, MyClass.string('stringPath') will return the translated component text. I need the app text to be updated when the user changes their language.

Binding doesn't work with static properties and methods (see this question for details Binding to static property).
In your case it's better to use the singleton pattern for resource manager and remove static from string and updateData:
MyClass.instance.string('stringPath')
and MyClass:
public static const instance:MyClass = new MyClass();

Related

AS3 Access stage object in singleton returns null

I know singletons are sensitive subjects, but I really don't want to hear anything about that, or what you think about this implementation. This question is not about that.
So, I have implemented a singleton using a static var with the instance.
private static var instance:SomeClass = new SomeClass();
public static function getInstance():SomeClass {
return instance;
}
SomeClass is a class in the library, and inside that one there some instance called someSymbol.
For some reason, when I use SomeClass as a singleton, every time I want to access someSymbol I get Cannot access a property or method of a null object reference. But if I implement SomeClass with regular instantiation the error disappears.
I've tried accessing someSymbol in different ways but I always get the error.
someSymbol.rotation = 0;
and also
var aSymbol = getChildByName("someSymbol");
aSymbol.rotation = 0;
and also
trace(someSymbol); // null
trace(this['someSymbol']); // null
trace(SomeClass.instance.someSymbol); // throws error
So why do I get null when using this singleton implementation, and not when instantiating the class as usual?
Edit:
Thanks to #Marty Wallace answer, I changed my singleton implementation and now it works.
So, instead of instantiating the instance this way:
private static var instance:SomeClass = new SomeClass();
I instead instantiate it the first time getInstance() is called, as #Marty does it.
I don't know exactly what is going on behind the curtains, but it seems as if SomeClass wasn't fully exported when instantiating before the document class is running.
Your example is working fine for me:
public class Singleton
{
private static var _instance:TestClip;
public static function get instance():TestClip
{
if(_instance === null) _instance = new TestClip();
return _instance;
}
}
And TestClip has an inner MovieClip with the instance name inner:
trace(Singleton.instance.inner); // [object MovieClip]
Do you have any luck if you make a class for SomeClass and make a getter for someSymbol like this?
public function get someSymbol():MovieClip
{
return this["someSymbol"];
}

AS3 How to extends Event class without keeping any existing event types?

I would like to extends the Event class to add some events I am using in game.
But I don't want the new Event Class to have the old public static types..
For instance I don't want to have:
NewEventClass.ENTER_FRAME
How do you go about extending the Event class without getting the old types mixed in?
Is there any way to outsmart AS3 to leave out the uneeded types?
Or should I avoid creating a new Event type altogether and just add the new strings?
Extending Event is only really necessary if you want to add some extra properties to it, for example:
public class EnemyEvent extends Event
{
// Constants used to represent event type
public static const ENEMY_KILLED:String = "killed";
// Event properties
public var score:int = 0;
/**
* Constructor
* Retain Event behaviours
*/
public function EnemyEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
So that when you dispatch this event from an enemy you can go:
var evt:EnemyEvent = new EnemyEvent(EnemyEvent.ENEMY_KILLED);
evt.score = myScoreValue;
dispatchEvent(evt);
And then make use of the score property from the listening method within the game engine:
enemy.addEventListener(EnemyEvent.ENEMY_KILLED, _countKill);
function _countKill(e:EnemyEvent):void
{
gameTotalScore += e.score;
if(gameTotalScore > 100) getAchievement();
e.target.removeEventListener(e.type, _countKill); // <-- woudn't work without extending event either
}
If you just need to store constants to use in addEventListener(x, ..), new Event(x), etc then you can just make a class that holds these and doesn't have anything to do with Event:
public class CustomEvents
{
public static const MY_CUSTOM_EVENT:String = "myCustomEvent";
}
So that you can just use these as needed:
new Event(CustomEvents.MY_CUSTOM_EVENT);
addEventListener(CustomEvents.MY_CUSTOM_EVENT, _listener);
The former method is still preferable as it's tidier and more logical.
Additionally; your note about your custom event having constants such as ENTER_FRAME isn't the case anyway, because they are static and belong to Event. You'll get this error if you try access ENTER_FRAME through the example in your answer:
1119: Access of possibly undefined property ENTER_FRAME through a
reference with static type Class.

How to call some mxml function from class?

I have 2 files: Main.mxml with application and one MyObject.as.
I create the instance of MyObject in mxml and can call its every public function from mxml. But what if for some reason I need to call some function declared in mxml from MyObject class? How to do that? I thought that I could pass the reference to main.mxml class into this object but I couldn't figure out what exact class is it (it inherits Application, right, but what exact class is it?)
Thanks
It is of type Main (it takes on the name of the mxml file). You can add a static variable and getter method to it:
private static var _instance : Main;
public static function get instance () : Main {
return _instance;
}
Then let instance refer to this after the application is complete:
private function applicationCompleteHandler():void
{
_instance = this;
}
Don't forget to set applicationComplete="applicationCompleteHandler" in your <mx:Application> tag.
After that you can call Main.instance from anywhere in your program to access the methods and variables.
If you are instantiating the MyObject class in your Main.mxml, you could also accomplish access to a method in Main by passing the method as a Function into the object.
Suppose you have in Main.mxml the function:
private function doSomething():*{
...
}
With an appropriate setter in MyObject.as:
private var _mainFunction:Function;
public function set mainFunction(f:Function):void
{
_mainFunction = f;
}
Then you can pass the method when you instantiate the MyObject class in the mxml:
<*:MyObject mainFunction='doSomething'/>
And now you just call _mainFunction in the MyObject.as code whenever you need it.
Of course, Weltraumpirat's suggestion would be more efficient if you needed to access more than one method and/or variable on your Application.

Calling private function from external ActionScript3 File

How do I call a private function from an external ActionScript3 document? I'm working in Flash Builder 4, and I need to call a private function from an external AS3 document. I think I've imported it correctly....
import myapp.utils.WebcamFaceDetector;
import myapp.utils.FaceDetector;
But I want to call a function from "FaceDetector". Here's the part of the code in FaceDetector...
public class FaceDetector
{
private var detector :ObjectDetector;
private var options :ObjectDetectorOptions;
private var faceImage :Loader;
private var bmpTarget :Bitmap;
private var view :Sprite;
private var faceRectContainer :Sprite;
private var tf :TextField;
private function FaceDetector() {
initDetector();
}
//...
}
I want to call "private function FaceDetector()" to initiate at a certain point in another AS3 file. How do I properly declare it and get it to run?
The only way to access a private function it is to declare it as public or introduce an extra function and declare that as public.
The private attribute is meant to restrict access to that Class alone.
What you can do is create a protected function that subclasses your FaceDetector class and that gives you access but maybe not in the way that you want to use it.
On closer inspection you are using a private constructor (unless this is not your package) which prevents instantiation from other classes so I am not sure what you are really trying to accomplish.
If is was a normal private function (not a constructor) you could also register it to listen for events and and dispatch the event from where-ever you need it from.
The only proper way I know of to use private constructors other than utility classes are Singletons and that cannot even be done in ActionScript 3 (private constructors)
From your example code, the FaceDetector function is the contructor of the FaceDetector class. This means it is called when you construct a new instance of FaceDetector e.g.
var faceDetectorInstance:FaceDetector = new FaceDetector();
your constructor should be public not private. AS3 does not support private constructors.
you should make your initDetector method public, so you can call that directly e.g.
public function initDetector():void
{
//Do Stuff Here...
}
First, you cannot call a private class. The private keyword purpose is to stop external classes, including subclasses from calling the function.
Second, FaceDetector has the same name as the class. This means it is the constructor and is automatically called when you create a new instance of the class.
PS. Constructors in ActionScript 3.0 must be public

ActionScript Calling Private Functions By Changing Public Variables?

i've never tried to do this before, so my head a swimming a bit. i'd like to have a public boolean called enabled in myClass custom class. if it's called to be changed, how do i trigger a function from the change?
should i add an Event.CHANGE event listener to my variable? can i do that? or is there a more standard way?
We usually use properties for that.
Properties are just like public variables for the outside -- you can set instance.enabled = true; and so forth.. But you define properties as getters and/or setters functions for the class.
They are the perfect place for custom logic to be executed on value changes.
For example:
public class CustomClass {
private var _enabled:Boolean = false;
public function set enabled(value:Boolean):void {
trace('CustomClass.enabled is now', value);
this._enabled = value;
}
public function get enabled():Boolean {
trace('CustomClass.enabled was retrieved');
return this._enabled;
}
}
Note that they can't have the same name as your private variable and you don't need both of them defined. Actually, you don't even need a variable for a setter/getter. You could use them just like any function -- they just supply you with a different syntax.
For example:
var object:CustomClass = new CustomClass();
object.enabled = false;
if (object.enabled) {
...
}
They are great to expose a simple API, keeping you from rewriting outside code if the class' internals have to change.
AS3 Reference on getters and setters.