AS3 Profiling - Why do Object and Function counts increase when setting text - actionscript-3

Firstly can some one please explain what is meant by Object and Function in a profiling environment.
Secondly, why does the Object and Function count increase when I repeatedly set the text property of a textfield:
override public function setLanguage(id:String):void
{
if (id == "en")
{
ui.title.text = _data.text.title.en;
ui.title.direction = Direction.LTR;
}
else if (id == "ae")
{
ui.title.text = _data.text.title.en;
ui.title.direction = Direction.RTL;
}
}

From Laurent:
Internally, TextField::text is most likely a getter/setter (since it needs to set a flag to update the text field display, also possibly update the HTML content, etc.) so when you set it you are effectively calling a function.
This means that TextField.text is implemented as a property getter and setter, so if you had to code it, you would see something like
private var _text:String="";
public function get text():String {
return _text;
}
public function set text(value:String):void {
_text=value;
}
Your Object count increases every time you reference (looking for a better word, don't kill me about this :P) an object (I trust you know what objects are), and your Function count increases every time you invoke a function.
So when you do something like
myTextField.text="Hello World";
you are referencing object myTextField and invoking its function set text(String);, causing your counts to increase by 1 each.

Internally, TextField::text is most likely a getter/setter (since it needs to set a flag to update the text field display, also possibly update the HTML content, etc.) so when you set it you are effectively calling a function.
What is it you don't understand about the difference between a Function and an Object? Could you be more specific?

Related

How to have protected set functions?

I'm working in ActionScript 3, but I'm guessing this is a universal concept.
I've recently stumbled upon the world of get and set functions, and I immediately tried to apply it to my code, since before I'd need to run an explicit set function so that two parameters would keep up to date with each other.
However, I only ever actually SET the variable in a subclass to where the variable is defined - so I'd like it to be protected. Unfortunately, the code seems to only work when the set function is public, and I have no clue. All the examples I could find online never used a set function except outside of the class it was defined in.
This isn't so much something that's going to be difficult to work around (I would just use an explicit set function) as something I want to understand to become a better programmer, and maybe help someone else who is in my position.
Here's my code which might make my point a bit clearer:
private var _iColumn:int;
private var _iRow:int;
public function get iColumn():int { return _iColumn; }
public function get iRow():int { return _iRow; }
protected function set iColumn(setValue:int):void {
_iColumn = setValue;
resetClickArea();
}
protected function set iRow(setValue:int):void {
_iRow = setValue;
resetClickArea();
}
public function TileElement(column:int, row:int)
{
iColumn = column; // Complains that property is read-only
iRow = row; // Complains that property is read-only
}
Both getter and setter need to have the same namespace (public, protected or private) so if the getter needs to be public your only option is to make the setter public as well or replace the setter by a protected function like setIRow or something.
Making both getter and setter protected would make valid code but of course you won't be able to access the the property from outside.
Most languages don't even have this nice feature of get and set keywords. You would be better off creating your own getter and setter functions getRow(); and setRow(r);. One other bonus is that you don't get too attached to this AS3 feature, and it would be easier to work within other languages like C++.

AS3: Returning value from another function after event happened

Basically I want to check if a user exists in a database using AMF (and that works great!). But then I want to return the boolean value to another function (in another class) that originally called the "checkUserExistance" function. But, since the database connection isn't immidiate, this function will always return a false value (even if "result" is true). So I would like to have the return-line inside the "onUserChecked"-function but that of course gives me an error. I thought I could create an eventListener, but then, the "return userExists"-line would also have to be inside another function, which doesnät work(?)... What can I do?
public function checkUserExistance(username:String) {
var responderBOOLEAN:Responder = new Responder(onUserChecked, onFault)
var userExists:Boolean = false;
connection.connect(gateway);
connection.call("User.checkUser", responderBOOLEAN, username);
connection.close();
function onUserChecked(result:Boolean):void {
userExists = result;
}
return userExists;
}
I'm sorry but you are trying to force an Asynchronous call to a Synchronous one and this is WRONG.
See here
You should learn how to handle events in the correct way.
What can i suggest you that helped me a lot is this
The only true answer here is to save userExists as a member variable, and dispatch event when the server returns you a response. The client side of the things should be similar to:
// add listener, ServerEvent is a custom event (see below)
server.addEventListener(ServerEvent.CHECK_RESPONSE, onCheckResponse);
server.checkUserExistance('username'); // start the query
function onCheckResponse(e:ServerEvent):void {
if (e.userExists) {
}
}
// inside server class
function onUserChecked(result:Boolean):void {
userExists = true;
dispatchEvent(new ServerEvent(ServerEvent.CHECK_RESPONSE, userExists));
}
/* ServerEvent is a custom class that extens Event
Such classes are used so you can pass special properties in them
via constructor (pass data, store it into member variable)
and through getter for that variable.
If you don't like it, simply add/dispatch Event.COMPLETE
and use public property to get userExists from server
*/

ActionScript 3: Assigning a named function to a variable of type Function

I'm working with a game loop and am attempting to handle user input by assigning various methods to a variable of type Function depending on the games state.
I'm assigning a defined function called InputState1 to my Function variable inputFunction:
var inputFunction:Function = InputState1;
where InputState1 is:
public function InputState1():void
{
// input logic
}
and call inputFunction in the game loop's update method:
override protected function update(timeDelta:Number):void
{
trace(inputFunction);
inputFunction();
}
When I trace the inputFunction, it returns an empty function.
Is it possible to assign a named function to a function variable and if so, how would I go about doing this properly?
Solution: I was invoking my function variables call method instead of just calling the function. It works now.
What I have understood from your argument is that you want a game state to be identified and act according to it, well you always can define a String holding the game state value which updates as game state changes, and make a function returning that string,(or directly comapre that string wth defined states)
var gameState:String="initial";
override protected function update(timeDelta:Number,gameState:String):void
{
gameState="newstate"; //depending upon your condition requirement
}
if(gameState="requredState"){
//do required stuff
}
The issue was that I was invoking my function variable's call method instead of just calling the function. It works now and I've edited the code in my question to the correct version.

Value Will Set properly, but Get receives Null

So, I have successfully grabbed a value out of an XML document and set it into a separate class called "AddCommas." The trace functions have shown me that it sets properly.
For more details, my objective is to take the language indicator ("fr" for french or "en" for english), set it inside the appropriate class and into a variable I will use. Now, I am using this variable to be used in an if statement; which will help me format a number properly (commas, decimals, spaces) per the clients request.
However, my problem is when I try to get the value to use it. It always comes back as Null. I have placed traces all over my program trying to pinpoint when this happens, but I cannot find it. Here's the code...
The pull from the XML file and into the set (this works fine, but I am adding it for your benefit in case I missed something)
public var commaHold = new AddCommas();
localLanguage = xmlObj.localLanguage;
trace("localLanguage + " + localLanguage);
commaHold.setLanguage(localLanguage); // Set Language
//More code follows...
This is the set function istelf...
public function setLanguage(localLanguage:String){
langHold = localLanguage;
trace("Set Language = " + langHold); //This always shows a successful set
}
Now am I wrong in thinking that in AS3, once langHold in my AddCommas class has been set I should be able to use it without calling a get within the function I am using the If Statement in, right? Such as this?
var language = langHold;
if (language == "en"){
trace("Language is = " + language); // More code follows afterwards and as of now, this shows NULL
Now, I have attempted plenty of Get functions to add the language variable in the call itself to this function and it's always the same. Am I missing some fundamentals here?
Thank you very much for your time.
If you expect a string comparison you need to use quotes, unless en is a String variable since langHold is a String, like:
if (language == "en"){
Consider modifying the set function to use the as3 keyword like:
private var _language:String;
public function set language(value:String):void {
_language = value;
//do other stuff here if necessary, put a breakpoint on the line above
}
public function get language():String{
return _language;
//put a breakpoint on the line above
}
You should be able to see when any instance of your class has the property changed. The only other issue I can think of is it is not the same instance of the class and therefore doesn't share the property value you set earlier. In the debugger you can check the "hashCode" or "address" it shows for this to see if it changes when it hits the breakpoints.
Here's a sample Singleton structure in AS3 (this all goes in one file):
package com.shaunhusain.singletonExample
{
public class SingletonExample
{
private static var instance:SingletonExample;
public static function getIntance():SingletonExample
{
if( instance == null ) instance = new SingletonExample( new SingletonEnforcer() );
return instance;
}
/**
*
* #param se Blocks creation of new managers instead use static method getInstance
*/
public function SingletonExample(se:SingletonEnforcer)
{
}
}
}
internal class SingletonEnforcer {public function SingletonEnforcer(){}}
using this single shared instance from any other class would look something like this:
private var singletonInstance:SingletonExample = SingletonExample.getInstance();
ShaunHusain's theory of using a Singleton was the perfect solution I needed. However, his code gave me a bizarre 1061 error and my format and code appeared to be error free. Regardless, I looked up another way to use a Singleton as follows that worked perfectly for me. Honestly, Shaun's code should work for anyone and I have no idea why it wasn't. I am perfectly willing to admit that it was probably a typo on my end that I just did not see.
I ended up embedding the Set and Get within the Singletons class and used it as an intermediary to hold the information I needed. It worked perfectly.
package chart {
import chart.*;
//
public class StaticInstance {
private static var instance:StaticInstance;
private static var allowInstantiation:Boolean;
private var language:String;
public static function getInstance():StaticInstance {
if (instance == null) {
allowInstantiation = true;
instance = new StaticInstance();
allowInstantiation = false;
}
return instance;
}
public function StaticInstance():void {
if (!allowInstantiation) {
throw new Error("Error: Instantiation failed: Use StaticInsance.getInstance() instead of new.");
}
}
public function setLanguage(_language:String):void{
language = _language;
trace("language set = " + language);
}
public function getLanguage():String{
return language;
}
}
}
This code allowed me to hold the data and call upon it again from two different classes. It's a very hack job instead of just being able to pass on the variable from function to function, but in my case we didn't create this file, we are modifying it and attempting to do things beyond the original scope of the project.
Thanks again for your help Shaun! I hope this helps other people!

Make Flex TextInput show no prompt on empty String

I am using a s:TextInput in Flex 4.5. It shows it's prompt text if the underlying text value is null or empty String. Does anybody know if I can make either don't show the prompt on empty String or even show a different prompt?
I already found a way by extending the TextInput class and overriding some of the methods but I am still hoping anyone here knows an easier way ;-)
Ok, so based on the comments, here it is:
You store the current prompt value in a private variable, like so:
private var _inputPrompt:String = "";
Then you create a getter, so the value is accessible from outside of this class:
public function get inputPrompt():String
{
return _inputPrompt;
}
Now you can bind inputPrompt anywhere you need it, however, the problem is the getter won't be recalled once the private value changes. You can fix this very easily: Create an update method, for example like so:
public function updateInputPrompt(value:String):void
{
_inputPrompt = value;
}
Ok, nothing fancy so far. I'm guessing this is the point where you are right now. In order to "force" the getter to be recalled, you have to bind it to an event, like so:
[Bindable(event="inputPromptUpdated")]
public function get inputPrompt():String
{
return _inputPrompt;
}
Finally, you can simply dispatch this event when the value is update (i.e. in the updateInputPrompt method):
public function updateInputPrompt(value:String):void
{
_inputPrompt = value;
dispatchEvent("inputPromptUpdated"); // For binding
}
This way, the getter will be recalled every time you dispatch that event.
Hope this helps. Have a great day, and a great weekend!