Demystified for the benefit of my own understanding of course. Maybe if I take it step-by-step it will make some sense. I’ve been reading “Learning Flash Media Server 3” and I find I’m reading the same part over and over. I figure if I write it in my own words it’ll start to sink in.
Consider the following code:
ballSO = SharedObject.getRemote("ballSO", myNC.uri, false);
ballSO.connect(myNC);
ballSO.addEventListener(SyncEvent.SYNC, updateBallPos);
So, here we have ballSO created on the Flash Media Server, and we’ve added an EventListener to is, so that every time the SharedObject on the Flash Media Server changes, we can catch a SYNC event and do some stuff in our application. As is says in the book: “Whenever a client changes a shared object’s data property, the action invokes a sync event”.
Another way of say this is: whenever a client uses setProperty() to register a state change on a SharedObject, the following happens:
· The SharedObject’s data property changes in some way
· The SharedObject calls setDirty(), which informs the FMS that the value of a property in the SharedObject has changed
But back to our event listener.
The thing that makes SyncEvent stand out among other EventListeners is its changeList property:
- The changeList is an array of objects.
- Each object in the changeList array “contains properties that describe the changed members of a remote shared object”.
- The properties of each changeList array object are:
The code property is of special interest; It allows us to figure out what’s happening on the server. When we initially create our SharedObject, all the properties are initialized to empty strings.
Here are the values that code can have (with my shorthand explanation):
- clear – either you just connected successfully, or all properties of the object have been deleted
- success – the client (you) have changed the SO
- reject – the client (you) did not successfully change the SO
- change – another client (not you) has changed the SO
- delete – the object you’re trying to change not longer exists
Here’s a basic implementation of our SyncEvent handler function:
private function updateBallPos(se:SyncEvent):void {
for(var i:int = 0; i < se.changeList.length; i++) {
if (se.changeList[i].code == "change") {
switch (se.changeList[i].name) {
case "xPos":
this.x = ballSO.data.xPos;
break;
case "yPos":
this.y = ballSO.data.yPos;
break;
}
}
}
}
OK – we loop through our SyncEvent (“se”) looking for an object in the changeList whose code is “change”. Then we’re using a switch construct to look for the value of that object’s “name” attribute that matches something that we want to change or keep in sync.
So – and here’s the part that has me wrapped around the axle – we update our local client based on the a value of the SharedObject’s data object.
OK so – if we consider ballSO.data as (what we would call in Perl) an associative array (or hash), then we can get to dynamically created data using something like the technique in the switch cases in this code snippet:
var currentDataIndex:String;
// note: the string myName is defined in the class constructor
for(var i:int = 0; i < se.changeList.length; i++) {
if (se.changeList[i].code == "change") {
switch (se.changeList[i].name) {
case myName + "xPos":
currentDataIndex = myName + "xPos";
this.x = ballSO.data[currentDataIndex];
break;
case myName + "yPos":
currentDataIndex = myName + "yPos";
this.y = ballSO.data[currentDataIndex];
break;
}
}
Of course, defensive programming would have us write cases for all the conditions:
if(se.changeList[i].code == "success") { ... }
if(se.changeList[i].code == "reject") { ... }