Archive for May, 2010

Links: Design Patterns

May 27, 2010
  1. Structural Patterns – Facade Patternhides the complexities of system from the client and provides a simpler interface, see there as well
    (list of patterns as in book “Design Patterns, Elements of Reusable Object Oriented Software” by E.Gamma, R.Helm, R.Johnson, J.Vlissides):

    1. Creational Patterns:
      1. Factory Pattern
      2. Abstract Factory Pattern
      3. Singleton Pattern
      4. Builder Pattern
      5. Prototype Pattern
    2. Structural Patterns:
      1. Adapter Pattern
      2. Bridge Pattern
      3. Composite Pattern
      4. Decorator Pattern
      5. Facade Pattern
      6. Flyweight Pattern
      7. Proxy Pattern
    3. Behavioral Patterns:
      1. Chain of Responsibility Pattern
      2. Command Pattern
      3. Interpreter Pattern
      4. Iterator Pattern
      5. Mediator Pattern
      6. Momento Pattern
      7. Observer Pattern
      8. State Pattern
      9. Strategy Pattern
      10. Template Pattern
      11. Visitor Pattern
  2. Entry-Point Function Definition: Microsoft DLL
  3. QueryInterface retrieves pointers to the supported interfaces on an object

Design Patterns: Singleton

May 21, 2010

1). Implementation from Scott Morgan: (ExternalInterfaceBuffer source code)

package …
public class ExternalInterfaceBuffer{

private static var instance:ExternalInterfaceBuffer = new ExternalInterfaceBuffer();
public function ExternalInterfaceBuffer() {
if( instance ) throw new Error( “Singleton and can only be accessed through Singleton.getInstance()” );
}

public static function getInstance():ExternalInterfaceBuffer {
return instance;
}

2). from Darron Schall: Actionscript 3 Singleton Redux

package …

private static const _instance:Model = new Model( SingletonLock )
public function Model( lock:Class )
{
// Verify that the lock is the correct class reference.
if ( lock != SingletonLock ){
throw new Error( “Invalid Singleton access.  Use Model.instance.” );
}
}

class SingletonLock{} // end class

3). Grant Skinner: AS3 Singleton

4). What if you would like to pass some arguments in constructor?

External Interface

May 21, 2010

ExternalInterfaceBuffer source code by Scott Morgan

package com.yahoo.webapis.maps.utils {

public class ExternalInterfaceBuffer {

import flash.external.ExternalInterface;
import flash.utils.setInterval;
import flash.utils.clearInterval;

private static var instance:ExternalInterfaceBuffer = new ExternalInterfaceBuffer();
private var methodQueue:Array = new Array();
private var methodCallInterval:Number;

public function ExternalInterfaceBuffer() {
if( instance ) throw new Error( “Singleton and can only be accessed through Singleton.getInstance()” );
}

public static function getInstance():ExternalInterfaceBuffer {
return instance;
}

public function addCall(obj:Object):void {
methodQueue.push(obj);
if (isNaN(methodCallInterval) || methodCallInterval == 0) {
methodCallInterval = setInterval(methodChurn, 50);
}
}

private function methodChurn():void {
if (methodQueue[0].method != undefined && methodQueue[0].method != null) {
ExternalInterface.call(methodQueue[0].method, methodQueue[0].data);
}
methodQueue.shift();
if (methodQueue.length == 0) {
clearInterval(methodCallInterval);
methodCallInterval = undefined;
}
}


Links: Definitions

May 17, 2010
  1. Hash tables (hush function), “to quickly locate a data record (for example, a dictionary definition) given its “search key
    Associative arrays, dynamic sets.
  2. Namespaces: tutorial from Grant Skinner
  3. Matrices in AS3: tutorial from Senocular
  4. Matrix: analog of  “MovieClip.localToGlobal(point)” on Matrix level:

import flash.geom.Matrix;
/**
 * "Global" matrix of nested MovieClip
 * @author Sergei Nikiforovski, 2010
 * note: as2 !
 */
public function getMc_nestedMatrix( mc:MovieClip ):Matrix
 {
 var m0:Matrix = mc.transform.matrix;

 var mc2:MovieClip;
 var m:Matrix = new Matrix();

 for (var s in mc) {
 if ( typeof( mc[s] ) == "movieclip" ) {
 mc2 = mc[s];
 m = getMc_nestedMatrix( mc2 );
 break;
 }
 }

 m.concat( m0 );
 return m;
 }

Links: AS3 code to use

May 17, 2010
  1. Bulk loader – getting started:
    var loader : BulkLoader = new BulkLoader(“main-site”);
    loader.add(“background.jpg”, {id:”bg”});
    loader.add(“/unreliable-web-service.xml”, {maxTries:6});
    loader.addEventListener(BulkLoader.COMPLETE, onAllLoad):
    loader.start();
    Developer guide.
  2. Debugging
    a). as3 hidden treasure in the mm.cfg fiel. Revealing and documenting many Flash secrets,
    – Windows, C:\Documents and Settings\username\mm.cfg
    b). Socket output server: SOS-max
  3. Tween, animations:
    a). Greensock: TweenLite, TweenMax, TweenNan
    b). Caurina tweener
  4. Component’s framework:
    a). AsWing, code download
    b). Minimal comps (BIT-101Peters Keith)  –  Google code
  5. External Interface:
    a). Buffer Source Code,
    b). Adobe example

Links: Flex, AS – PHP

May 17, 2010

1. Back end links:

  • Flex – building remote endpoint by Kevin Scroeder (browse for Zend posts there !), using Zend Framework. Provide data access layer;  ability to use components;  Zend studio, Zend_tool; MVC design pattern. Auto-created Folder’s structure: apps.configs, apps.controllers, apps.models, apps.views, apps/Bootstrap.php, docs, library, public, test; Two classes which extends zend’s Zend_Db_Table_Abstract, Zend_Db_Table_Row_Abstract. Service.php functions: getAll..(), get..ByID(), create..(); gateway.php; bootstrap.php
  • Flex and ZendFramework

Local Connection : Grant Skinner

May 10, 2010

as3 (SWFBridge3.as)  vs  as2 (SWFBridge2.as)  code:

Class variables (both):
baseID:String
myID:String;
extID:String;
lc:LocalConnection;   //used just one lc – that’s nice!
_connected:Boolean=false; //very useful, will dispath
host:Boolean=true; //will auto determine who is host (host the one, came first)
clientObj:Object; //will “redirect” or apply calls to this object (executes methods on the object)

Class:est=
SWFBridgeAS3( p_id:String,p_clientObj:Object)  <-> SWFBridgeAS2(p_id:String,p_clientObj:Object)
as3: SWFBridgeAS3 extends EventDispatcher
as2 (in constructor): EventDispatcher.initialize(this);

Class constructor:
both: lc = new LocalConnection();

as3: lc.client = this;
as2 (redirection to class function,  compare to lc.client = this  in as3 ):
var _this:Object = this;
lc.com_gskinner_utils_SWFBridge_init = function() {
_this.com_gskinner_utils_SWFBridge_init();
}
lc.com_gskinner_utils_SWFBridge_receive = function() {
_this.com_gskinner_utils_SWFBridge_receive.apply(_this,arguments);
}

as2:  host = lc.connect(baseID+”_host”);
as3:
try {
lc.connect(baseID+”_host”);
} catch(e:ArgumentError) {
host = false;
}

both  ( gust will call init() function on host and host will “ping” back, variables this._connected will be send try and connect event fired – brilliant!):
if (!host) {
lc.connect(myID);
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}

init :
public function com_gskinner_utils_SWFBridge_init():Void {
trace(“SWFBridge (AS2) connected as “+(host?”host”:”client”));
if (host) {
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
_connected = true;
dispatchEvent({type:”connect”});
}
difference in as3: dispatchEvent(new Event(Event.CONNECT));

Exchanging messages:

1. send():
as3:
public function send(p_method:String,…p_args:Array):void {
if (!_connected) { throw new ArgumentError(“Send failed because the object is not connected.”); }
p_args.unshift(p_method);
p_args.unshift(“com_gskinner_utils_SWFBridge_receive”);
p_args.unshift(extID);
lc.send.apply(lc,p_args);
}
as2:
public function send():Void {
if (!_connected) { return; }
var args:Array = arguments.slice(0);
args.unshift(“com_gskinner_utils_SWFBridge_receive”);
args.unshift(extID);
lc.send.apply(lc,args);
}
note (arguments sent internally): connectionName, nameOfMethodtoCall_onBridgeClass, nameOfMethodtoCall_onClientObjectClass, argumentsOfFinalMethod

2. receive:
as3:
public function com_gskinner_utils_SWFBridge_receive(p_method:String,…p_args:Array):void {
try {
clientObj[p_method].apply(clientObj,p_args);
} catch (e:*) {
trace(“SWFBridge ERROR:  “+e);
}
}
as2:
public function com_gskinner_utils_SWFBridge_receive():Void {
var args:Array = arguments.slice(0);
var method:String = String(args.shift());
clientObj[method].apply(clientObj,args);
}

Other class methods:
public function close():void
public function get id():String
public function get connected():Boolean

Usage:
Could be used for communication as3-as2, as3-as3, as2-as2; browser-projector (check Security Domain guidelines in “LocalConnection” help)

Link: http://www.gskinner.com/blog/archives/2007/07/swfbridge_easie.html

Usage Example:
import com.gskinner.utils.SWFBridgeAS3;

var sb1:SWFBridgeAS3 = new SWFBridgeAS3(“test”,this);

sb1.addEventListener(Event.CONNECT,onConnect);
function onConnect(p_evt:Event) {
out(p_evt);
}

function click1(p_evt:Event) {
out(“click”)
sb1.send(“sbTest”,”sent from”,loaderInfo.url.substr(loaderInfo.url.lastIndexOf(“/”)));
}

Appendix 1, SWFBridgeAS3.as:
/**
* SWFBridgeAS3 by Grant Skinner. March 11, 2007
* Visit http://www.gskinner.com/blog for documentation, updates and more free code.
*
* You may distribute this class freely, provided it is not modified in any way (including
* removing this header or changing the package path).
*
* Please contact info@gskinner.com prior to distributing modified versions of this class.
*/

package com.gskinner.utils {
import flash.net.LocalConnection;
import flash.events.EventDispatcher;
import flash.events.Event;

public class SWFBridgeAS3 extends EventDispatcher {
private var baseID:String;
private var myID:String;
private var extID:String;
private var lc:LocalConnection;
private var _connected:Boolean=false;
private var host:Boolean=true;
private var clientObj:Object;

public function SWFBridgeAS3(p_id:String,p_clientObj:Object) {
baseID = p_id.split(“:”).join(“”);
lc = new LocalConnection();
lc.client = this;
clientObj = p_clientObj;

try {
lc.connect(baseID+”_host”);
} catch(e:ArgumentError) {
host = false;
}

myID = baseID+((host)?”_host”:”_guest”);
extID = baseID+((host)?”_guest”:”_host”);
if (!host) {
lc.connect(myID);
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
}

public function send(p_method:String,…p_args:Array):void {
if (!_connected) { throw new ArgumentError(“Send failed because the object is not connected.”); }
p_args.unshift(p_method);
p_args.unshift(“com_gskinner_utils_SWFBridge_receive”);
p_args.unshift(extID);
lc.send.apply(lc,p_args);
}

public function close():void {
try { lc.close(); } catch (e:*) {}
lc = null;
clientObj = null;
if (!_connected) { throw new ArgumentError(“Close failed because the object is not connected.”); }
_connected = false;
}

public function get id():String {
return baseID;
}

public function get connected():Boolean {
return _connected;
}

public function com_gskinner_utils_SWFBridge_receive(p_method:String,…p_args:Array):void {
try {
clientObj[p_method].apply(clientObj,p_args);
} catch (e:*) {
trace(“SWFBridge ERROR:  “+e);
}
}

public function com_gskinner_utils_SWFBridge_init():void {
trace(“SWFBridge (AS3) connected: “+(host?”host”:”client”));
if (host) {
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
_connected = true;
dispatchEvent(new Event(Event.CONNECT));
}
}
}

Appendix 2, SWFBridgeAS2.as:
/**
* SWFBridgeAS2 by Grant Skinner. March 11, 2007
* Visit http://www.gskinner.com/blog for documentation, updates and more free code.
*
* You may distribute this class freely, provided it is not modified in any way (including
* removing this header or changing the package path).
*
* Please contact info@gskinner.com prior to distributing modified versions of this class.
*/

import mx.events.EventDispatcher;

class com.gskinner.utils.SWFBridgeAS2 {
private var baseID:String;
private var myID:String;
private var extID:String;
private var lc:LocalConnection;
private var host:Boolean;
private var clientObj:Object;
private var _connected:Boolean=false;

private var dispatchEvent:Function;
public var addEventListener:Function;
public var removeEventListener:Function;

public function SWFBridgeAS2(p_id:String,p_clientObj:Object) {
EventDispatcher.initialize(this);

baseID = p_id.split(“:”).join(“”);

lc = new LocalConnection();
var _this:Object = this;
lc.com_gskinner_utils_SWFBridge_init = function() {
_this.com_gskinner_utils_SWFBridge_init();
}
lc.com_gskinner_utils_SWFBridge_receive = function() {
_this.com_gskinner_utils_SWFBridge_receive.apply(_this,arguments);
}

clientObj = p_clientObj;

host = lc.connect(baseID+”_host”);

myID = baseID+((host)?”_host”:”_guest”);
extID = baseID+((host)?”_guest”:”_host”);

if (!host) {
lc.connect(myID);
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
}

public function close():Void {
lc.close();
delete(clientObj);
delete(lc);
_connected = false;
}

public function send():Void {
if (!_connected) { return; }
var args:Array = arguments.slice(0);
args.unshift(“com_gskinner_utils_SWFBridge_receive”);
args.unshift(extID);
lc.send.apply(lc,args);
}

public function get id():String {
return baseID;
}

public function get connected():Boolean {
return _connected;
}

public function com_gskinner_utils_SWFBridge_receive():Void {
var args:Array = arguments.slice(0);
var method:String = String(args.shift());
clientObj[method].apply(clientObj,args);
}

public function com_gskinner_utils_SWFBridge_init():Void {
trace(“SWFBridge (AS2) connected as “+(host?”host”:”client”));
if (host) {
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
_connected = true;
dispatchEvent({type:”connect”});
}
}

Appendix 3, SWFBridgeSimpletTest.fla:
import com.gskinner.utils.SWFBridgeAS2;

var sb1 = new SWFBridgeAS2(“test”,this);
var sb2 = new SWFBridgeAS2(“test”,this);

sb2.addEventListener(“connect”,this);

function connect(p_evt) {
trace(“connected”);
}

btn1.onRelease = function() {
_root.click1();
}

function click1() {
trace(“click1”);
sb1.send(“sbTest”,”fun”,”stuff”);
}

btn2.onRelease = function() {
_root.click2();
}

function click2() {
trace(“click2”);
sb2.send(“sbTest”,”sad”,”poo”);
}

function sbTest(p_param1,p_param2) {
trace(“sbTest: “+p_param1+” : “+p_param2);
}

Appendix 4, SWFBridgeTestAS3.as:
import com.gskinner.utils.SWFBridgeAS3;

var loader = new Loader()
loader.load(new URLRequest(“SWFBridgeTestAS2.swf”));
addChild(loader);

var sb1:SWFBridgeAS3 = new SWFBridgeAS3(“test”,this);

sb1.addEventListener(Event.CONNECT,onConnect);
function onConnect(p_evt:Event) {
out(p_evt);
}

btn1.addEventListener(“click”,click1)

function click1(p_evt:Event) {
out(“click”)
sb1.send(“sbTest”,”sent from”,loaderInfo.url.substr(loaderInfo.url.lastIndexOf(“/”)));
}

function sbTest(p_param1,p_param2){
out(“sbTest: “+p_param1+” : “+p_param2);
}

function out(p_txt:*) {
trace(p_txt);
outFld.appendText(“\n”+String(p_txt));
}

Appendix 5, SWFBridgeTestAS2.as:
import com.gskinner.utils.SWFBridgeAS2;

var sb1 = new SWFBridgeAS2(“test”,this);
sb1.addEventListener(“connect”,this);

function connect(p_evt) {
out(“connected”);
}

btn1.onRelease = function() {
_root.click1();
}

function click1() {
out(“click1”);
sb1.send(“sbTest”,”sent from”,_url.substr(_url.lastIndexOf(“/”)));
}

function sbTest(p_param1,p_param2) {
out(“sbTest: “+p_param1+” : “+p_param2);
}

function out(p_txt) {
trace(p_txt)
outFld.text += “\n”+p_txt;
}

/**
* SWFBridgeAS2 by Grant Skinner. March 11, 2007
* Visit http://www.gskinner.com/blog for documentation, updates and more free code.
*
* You may distribute this class freely, provided it is not modified in any way (including
* removing this header or changing the package path).
*
* Please contact info@gskinner.com prior to distributing modified versions of this class.
*/import mx.events.EventDispatcher;

class com.gskinner.utils.SWFBridgeAS2 {
private var baseID:String;
private var myID:String;
private var extID:String;
private var lc:LocalConnection;
private var host:Boolean;
private var clientObj:Object;
private var _connected:Boolean=false;

private var dispatchEvent:Function;
public var addEventListener:Function;
public var removeEventListener:Function;

public function SWFBridgeAS2(p_id:String,p_clientObj:Object) {
EventDispatcher.initialize(this);

baseID = p_id.split(“:”).join(“”);

lc = new LocalConnection();
var _this:Object = this;
lc.com_gskinner_utils_SWFBridge_init = function() {
_this.com_gskinner_utils_SWFBridge_init();
}
lc.com_gskinner_utils_SWFBridge_receive = function() {
_this.com_gskinner_utils_SWFBridge_receive.apply(_this,arguments);
}

clientObj = p_clientObj;

host = lc.connect(baseID+”_host”);

myID = baseID+((host)?”_host”:”_guest”);
extID = baseID+((host)?”_guest”:”_host”);

if (!host) {
lc.connect(myID);
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
}

public function close():Void {
lc.close();
delete(clientObj);
delete(lc);
_connected = false;
}

public function send():Void {
if (!_connected) { return; }
var args:Array = arguments.slice(0);
args.unshift(“com_gskinner_utils_SWFBridge_receive”);
args.unshift(extID);
lc.send.apply(lc,args);
}

public function get id():String {
return baseID;
}

public function get connected():Boolean {
return _connected;
}

public function com_gskinner_utils_SWFBridge_receive():Void {
var args:Array = arguments.slice(0);
var method:String = String(args.shift());
clientObj[method].apply(clientObj,args);
}

public function com_gskinner_utils_SWFBridge_init():Void {
trace(“SWFBridge (AS2) connected as “+(host?”host”:”client”));
if (host) {
lc.send(extID,”com_gskinner_utils_SWFBridge_init”);
}
_connected = true;
dispatchEvent({type:”connect”});
}
}