getUserList() flushing issue AS3

You think you've found a bug? Please report it here.

Moderators: Lapo, Bax

Post Reply
loren.bednar
Posts: 2
Joined: 29 Aug 2007, 20:33

getUserList() flushing issue AS3

Post by loren.bednar »

I'm noticing that for some reason, the array containing users is not flushing when users leave rooms. When I debug out the array which is returned from getUserList(), it contains several commas and at the end are the current users in the room.

Basically, if you have 1 user in the room, I would expect to reference that user as such:

roomInstance.getUserList()[0]

Currently, after I've reset the server and entered/left the room twice, after tracing out the array returned, my user's location in the array is 3 and I need to reference it like this:

roomInstance.getUserList()[2]

I have programmed a workaround which corrects this, but I am wondering if there was something I missed during setup that would enable or disable flushing the user list when a user leaves. It's iterating through the user list, but instead of rebuilding it with fresh data, it's just replacing the existing data with blank data and pushing the next user to the bottom of the array.

I apologize if I wrote that in circles, let me know if I need to clarify my problem more.

Thanks!

-Loren
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

Basically, if you have 1 user in the room, I would expect to reference that user as such:

roomInstance.getUserList()[0]
Nope, users are indexed by their userId, they are not ordered.
In other words if I am user Lapo and my userId == 120, you can grab my user object by referencing it with:

Code: Select all

userLapo = userList[120]
It's not recommended to use a for (var i=0; i < userList.length ... ) in this case but rather to use an iterative form like for (var user in userList)
Lapo
--
gotoAndPlay()
...addicted to flash games
loren.bednar
Posts: 2
Joined: 29 Aug 2007, 20:33

Post by loren.bednar »

ah great, thanks :) goodbye for loop!

thanks again,

Loren
jalava
Posts: 40
Joined: 03 Sep 2007, 12:23

Post by jalava »

But then, it is a bug!

getUserList() should return an object and not array.

It is true that flash array allows misusing it by defining what ever indices and indices do not need to be consecutive.

However, if you have array that has two items at indexes 2 and 8, the length() of array goes to 9.

You really should revise AS3 api and change the return value into Object or Dictionary.
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

I don't think it's a bug: arrays and objects are pretty ambiguous in Actionscript and Dictionaries don't seem to be solving the problem at all. ( A real dictionary should also provide utility methods such as size(), contains() etc... )

In this code:

Code: Select all

var x:Array = []
x["country"] = "Sweden"
trace(x.country)
we can call the "x" variable an associative array, an object, a dictionary, a map... whatever... ;)

The important thing to say here is that we pass a data structure (which I would refer to as an associative array) that contains non contiguous numeric keys. So you should use an iterator to cycle through it.

I will anyway take a note of this issue in our bug tracker to see if there's a way to remove the ambiguity without affecting the current codebase and performance

Thanks
Lapo
--
gotoAndPlay()
...addicted to flash games
ryratt
Posts: 29
Joined: 10 Jun 2008, 00:33

Post by ryratt »

Lapo wrote:I don't think it's a bug: arrays and objects are pretty ambiguous in Actionscript and Dictionaries don't seem to be solving the problem at all. ( A real dictionary should also provide utility methods such as size(), contains() etc... )
I think what's happening is you are using an array like an object and it only works because just about everything is a subclass of Object in actionscript (at least in 3). This caused an issue in our code with getUserVariables. We ended up editing the User class on the client code and added a new method called getUserVarsObj that returns an object that we can loop through. The built in getUserVariables just returned an empty array because nothing was indexed by number. I suppose I could have cast it as an Object or something, but in my opinion it shouldn't be an array, so I also changed the property and had the built in getUserVariables cast the object as an array instead so the package classes that need it can use it normally.

I agree this is a bug, I think if your docs say something returns an array, people are expecting an array returned with int indexes and so forth, otherwise the plain old Object class is perfect. You could even cast them to your own dynamic classes if you needed some additional functionality.
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

Actually this discussion was centered on the user list array...
I think what's happening is you are using an array like an object and it only works because just about everything is a subclass of Object in actionscript (at least in 3).
Nope, the problem is that we use an associative array, which is the equivalent of a Map in java/c# or a dictionary in python etc...
We are not using a List made of contiguous elements.
That's why we recommend to iterate over it instead of using the index-based for loop
This caused an issue in our code with getUserVariables.
Can you give us all the details about the problem? (maybe in another thread so we don't mix different things)
Lapo
--
gotoAndPlay()
...addicted to flash games
ryratt
Posts: 29
Joined: 10 Jun 2008, 00:33

Post by ryratt »

Lapo wrote:Actually this discussion was centered on the user list array...

Nope, the problem is that we use an associative array, which is the equivalent of a Map in java/c# or a dictionary in python etc...
We are not using a List made of contiguous elements.
That's why we recommend to iterate over it instead of using the index-based for loop
Yeah, I see that you did that, what I mean is this: I don't believe Actionscript supports associative arrays the way Php and Python does or that maybe just that arrays weren't intended to be used that way.

Since Array extends Object, you're basically using an Object when you make an associative array like you are doing. They are both dynamic classes so you can add whatever you like to them. They made Array to be dynamic so you can add to it the integer keys at any time.

The following code shows what I mean:

Code: Select all

var myArr:Array = new Array();
myArr["item1"] = "test1";
trace(myArr, myArr.length); // traces " 0"
myArr.shift();
trace(myArr, myArr.length); // traces " 0"
myArr[0] = "test3";
trace(myArr, myArr.length); // traces "test3 1"

trace("\n");
var myObj:Object = new Object();
myObj.item1 = "test1";
myObj[0] = "test2";
for(var prop:String in myObj) {
	trace("myObj." + prop + ":", myObj[prop]);
}

trace("\n");
var myArrAsObj:Object = myArr as Object;
for(var prop2:String in myArrAsObj) { 
        // shifted element remains in this loop
	trace("myArrAsObj."+prop2+":", myArrAsObj[prop2]);
}

As you can see, the last 2 for loops do the exact same thing. You can also note that on the first plain array I made, built-in Array methods and properties don't work on the things added with a String key (this is evident by "shift()" not taking away the first element we added, and length returning 0). So you are basically using an Object object. You might as well cast it as such so that it doesn't confuse people, in my opinion.

edit: again, you could also make your own Dynamic class called "UserList" or something too if you don't like the way Object or Array work.
Also, I am using AS3 I don't remember if the results would be the same in older versions or not.
Post Reply