Wednesday, September 5, 2012

Switch to Flex and Flash Develop

So today I tried to make a document class and compile it... It couldn't be found. I've done this many times... So I checked common errors. I even tried editing and saving the "automatically generated" document class just in case there was some slight mistake in my typing. But then my "automatically generated" document class was not found either. Then I decided to compile some old projects that used document classes... They didn't compile. I checked the files classPath settings. As I compile off a USB stick so that changes often. That was all fine and dandy... Did some research and I found some people have actually solved the problem by re-installing flash. I am not sure if I have some type of horrible coding practice or what is going on. But the most common hang ups I come across are errors in package structure that I can't find. And I've been doing actionScript on a daily basis for about 2 years now.

Messenger and Interpreter Pattern AS3

Making a messenger design pattern in as3 should not be too hard:
Seeing that this is possible:

function doStuff():void
{
 trace("doStuff called");
}

var obj:Object = new Object();
obj["x"] = 100;
trace(obj.x);

obj["f"] = doStuff;
obj.f();
obj["f"]();

var fString:String = "f";
obj[fString]();

//output:
//100
//doStuff called
//doStuff called
//doStuff called

Speed Test: Dot Operator and Empty Functions

For a component based class, if a component does NOT need updating,
should it call an empty update function, or should it have a variable
called "needsUpdate" that determines if an update method is called?

Class Test:

Component based object:
package com.JM.RESEARCH_CLASSES.functionOrFlag{
 
 import com.JM.RESEARCH_CLASSES.functionOrFlag.ModuleWithEmptyUpdateLocalFunction;
 import flash.utils.getTimer;
 
 public class TEST_FuncOrFlag {
  
  private var module1:ModuleWithEmptyUpdateLocalFunction;
  private var module2:ModuleWithEmptyUpdateLocalFunction;
  private var module3:ModuleWithEmptyUpdateLocalFunction;
  private var module4:ModuleWithEmptyUpdateLocalFunction;
  
  private var hasModule1:Boolean = true;
  private var hasModule2:Boolean = true;
  private var hasModule3:Boolean = true;
  private var hasModule4:Boolean = true;
  
  private var module3_updateLocal:Function;
  
  private var variableAccessTest:Boolean;
  
  
  private var module1NeedsUpdate:Boolean = false;
  
  
  private var loopTimes:int = 654321;
  private var ii:int;
  private var t1:int;
  private var t2:int;
  private var tt:int;

  public function TEST_FuncOrFlag() {
   module1 = new ModuleWithEmptyUpdateLocalFunction();
   module2 = new ModuleWithEmptyUpdateLocalFunction();
   module3 = new ModuleWithEmptyUpdateLocalFunction();
   module4 = new ModuleWithEmptyUpdateLocalFunction();
   
   module3_updateLocal = module3.updateLocal;
  }
  
  public function test():void
  {
   t1 = getTimer();
   for(ii=0; ii < loopTimes; ii++){
    if(hasModule1 && module1NeedsUpdate)
    {
     module1.updateLocal();
    }
   }
   t2 = getTimer();
   tt = t2-t1;
   trace("skipping function call time: " + tt);
   
   
   t1 = getTimer();
   for(ii=0; ii < loopTimes; ii++){
    if(hasModule2)
    {
     module2.updateLocal();
    }
   }
   t2 = getTimer();
   tt = t2-t1;
   trace("empty function call time: " + tt);
   
   
   t1 = getTimer();
   for(ii=0; ii < loopTimes; ii++){
    if(hasModule3)
    {
     module3_updateLocal(); //call bound function.
    }
   }
   t2 = getTimer();
   tt = t2-t1;
   trace("empty function call, bound function:" + tt);
   
   t1 = getTimer();
   for(ii=0; ii < loopTimes; ii++){
    if(hasModule4)
    {
     variableAccessTest = module4.testPublicVar;
    }
   }
   t2 = getTimer();
   tt = t2-t1;
   trace("public variable access:" + tt);
   
     t2 = getTimer();
   tt = t2-t1;
   trace("empty function call, bound function:" + tt);
   
   t1 = getTimer();
   for(ii=0; ii < loopTimes; ii++){
    if(true)
    {
     internalFunc();
    }
   }
   t2 = getTimer();
   tt = t2-t1;
   trace("internal function call:" + tt);
   
  }
  
  private function internalFunc():void{}; //empty function.

 }//class
}//package
//Module with empty update:
package  com.JM.RESEARCH_CLASSES.functionOrFlag{
 
 public class ModuleWithEmptyUpdateLocalFunction {
  
  public var testPublicVar:Boolean = true;

  public function ModuleWithEmptyUpdateLocalFunction() {
   // constructor code
  }
  
  public function updateLocal():void
  {
   //do nothing. This function needs not to be updated.
   //we are doing this to keep uniform architecture.
  }
 }
}

//Testing setup:
import com.JM.RESEARCH_CLASSES.functionOrFlag.TEST_FuncOrFlag;
var test:TEST_FuncOrFlag = new TEST_FuncOrFlag();
test.test();
Results:
skipping function call time:
20, 19, 20, 21

empty function call time:
126, 128, 137, 131


Explanation of results:
Making function call to empty function is slower
than checking a boolean that is PART of a class.

So we have:
Two Boolean checks(FASTER) 
vs
Using the DOT operator to access ANOTHER object.
AND calling a function.

UPDATE:
Trying out a bound function call to empty function.
The theory: It would be nice for the main "gameObject"
to have a single vector that stores all the objects
who's updateLocal() function need to be called.

If the module does NOT exist, or does not need to be updated,
it simply would not have it's update method included in the vector.

Results:
empty function call, bound function: 159, 155, 145, 144
A bit slower than calling an empty function.
Not surprising, as I already knew calling bound functions was a bit slow.

Earlier I had tried to do something like:
private var math_sqrt:Function = Math.sqrt;
And found that:
math_sqrt() is slower than Math.sqrt();


Judging by results:
I would say that for a particle system, it definitely makes sense
to use an MVC or Bridge pattern.
If you have 1000 particles, having ONE class that updates all the particles
positions is going to be ONE function call rather than 1000 slow function
calls to each self-updating particle.

Now... I need to do one more test.
To see if it is the function call, or simply the use of the dot-operator.

For example: When using an MVC model in a particle system,
you have to prepped all of your logic with a reference to the the
current object you are working on:

If working with self updating particles you can write:
vel_x += acc_x;

If working with an MVC model where there is an updater class for the particle
system:
currentParticle.vel_x += currentParticle.acc_x;

Question:
How slow is the dot operator accessing a VARIABLE compared to the
dot operator calling an EMPTY FUNCTION?

Need to do a quick test on this.

public variable access: 19, 20, 21, 21
Result: Pretty much as fast as accessing local variables.

FINAL WORDS:
I read this article that mentions that OOP is made to increase programmer efficiency, NOT code execution efficiency:

http://www.as3dp.com/2011/04/beginners-oop-design-patterns-in-actionscript-3-0-post-2-code-organizer/

This is a good point...  So....  Even though a bound function call is the SLOWEST...

I really think the design of having a que of modules in a vector that are all updated in a loop is quite elegant...

I think I am going to program my gameObject class this way.

I am being a bit ambitious thinking that my
game object class needs to be so efficient that
I could use instances of "gameObject" as particles in a particle system.

FINAL RESULTS: (I swear I am done now)
skipping function call time        : 20,  19,  20,  21
empty function call time           : 126, 128, 137, 131
empty function call, bound function: 159, 155, 145, 144
public variable access             : 19,  20,  21,  21
internal function call             :109 , 124, 125, 109

Monday, September 3, 2012

Iteratively traverse a node tree diagram

Put this diagram here for my own reference. This is how I go about iteratively traversing an entire tree. Where each node has ONE parent but multiple children. Taking a break on making a linked particle-type to create a component-based enemy that has a movement, display, collisionDetection, and collisionResolution modules.... Its a real pain to do... But I figure if I do it right the first time I will be able to re-use this enemy class multiple times by fitting it with different modules. I'll make an enemy factory class that utilizes this enemy shell class. The enemy factory class will have a default implementation for constructing enemies for fast prototyping, but it will be customizable. The enemy factory will NOT be a singleton. My mind is a bit fried. The end.

Speed Test: Binding Math Functions to variables

I was surprised! Binding a Math library call to a function to avoid lookup using the dot operator did not result in a performance increase. In fact, just the opposite!
//result:
//Math_sqrt is about twice as SLOW as Math.sqrt
//I am suprised.

var Math_sqrt:Function = Math.sqrt;
var loopTimes:int = 54321;
var t1:int;
var t2:int;
var tt:int;
var ii:int;

t1 = getTimer();
for(ii=0; ii < loopTimes; ii++){
 Math_sqrt(ii);
}
t2 = getTimer();
tt = t2 - t1;
trace("Math_sqrt time==" + tt);


t1 = getTimer();
for(ii=0; ii < loopTimes; ii++){
 Math.sqrt(ii);
}
t2 = getTimer();
tt = t2 - t1;
trace("Math.sqrt time==" + tt);

Sunday, September 2, 2012

Turret Class Demo

Font embedding resources I found helpful:
ONE
TWO
THREE
However, I just ended up making a text object with all the characters
I needed to use and put it off screen on my .fla file to implicitly
embed the characters I needed.

Hackish, but the quickest and most reliable way to embed I know.

Lastly: Need to figure out why my filter effect takes about 10 seconds
to kick in when I embed my demo on the web. Yet when I test it on my
computer it runs immediately. There must be some minute difference in how
actionScript's virtual machine processes bitmap alphas on my computer vs
on the web.