How to access room extension variables from another class

Post here your questions about SFS2X. Here we discuss all server-side matters. For client API questions see the dedicated forums.

Moderators: Lapo, Bax

abuhusnagumi
Posts: 32
Joined: 21 Oct 2014, 07:59

How to access room extension variables from another class

Postby abuhusnagumi » 04 Nov 2014, 14:40

Please I need assistance. Firstly I am using SmartfoxServer2x 2.9.0. I have two extension zone and room extension and wanted to access a variable that is in room extension (GameRoomExtension) from this class (RoomVariablesUpdateHandler extends BaseServerEventHandler) which is triggered from zone extension. I did it this way
GameRoomExtension roomExt = (GameRoomExtension)room.getExtension();
roomExt.getVariableName();
but it didn't work. I am getting class cast exception. But when I use roomExt.getExtensionFileName() it returns same class. Please how can I access room extension variable through this class.
Thanks for your response.
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 04 Nov 2014, 16:48

Hi,
can you clarify this?

Code: Select all

GameRoomExtension roomExt = (GameRoomExtension)room.getExtension();
roomExt.getVariableName();


is getVariableName a method of the GameRoomExtension class?
If so you should be able to call it without problems.

If not I'd like to understand what error are you getting?
Lapo
--
gotoAndPlay()
...addicted to flash games
abuhusnagumi
Posts: 32
Joined: 21 Oct 2014, 07:59

Re: How to access room extension variables from another clas

Postby abuhusnagumi » 07 Nov 2014, 15:17

Code: Select all

public class ZoneExtension extends SFSExtension {
    @Override
    public void init() {
                  .....
                addEventHandler(SFSEventType.ROOM_VARIABLES_UPDATE, RoomVariablesUpdateHandler.class);
              .....
    }
}

public class GameRoomExtension extends SFSExtension{
   
   private int isCheck;
   
   @Override
    public void init() {
           ......
    }
    public boolean getisCheck()
    {
        return isCheck;
    }
}

public class RoomVariablesUpdateHandler extends BaseServerEventHandler {
    @Override
    public void handleServerEvent(ISFSEvent params) throws SFSException {
        Room room = (Room) params.getParameter(SFSEventParam.ROOM);
        GameRoomExtension gameExt = (GameRoomExtension) room.getExtension();
        gameExt.getisCheck(); // not working class cast exception
     }
}

Hope you get what I mean through the code. I don't know what is causing the class cast exception. Thanks for all your response.
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 07 Nov 2014, 15:32

It's a class loading problem.
The class GameRoomExtension loaded at Zone level is not the same as the one at Room level, because they live in separate class loaders, hence the problem.

More on this here:
http://docs2x.smartfoxserver.com/Advanc ... assLoading

I would recommend to use the interoperability method handleInternalMessage(...) to be able to send messages across different Extensions without class loader issues.

The idea is that you can invoke a method on another extension by passing a message like this:

Code: Select all

// At Zone Level
Room someRoom = getParentZone().getRoomByName("aGameRoom");

Integer score = (Integer) someRoom.getExtension().handleInternalMessage("getScore");


On the receiving end (the Room Extension) you will have something like this:


Code: Select all

@Override
public Object handleInternalMessage(String cmdName, Object params)
{
     if (cmdName.equals("getScore"))
          return this.getScore();

    else if (...)
 
   // etc...
}


cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 07 Nov 2014, 15:34

In alternative, if you want to avoid the class loading issue you can deploy everything under the __lib__/ folder as explained in the link to the docs I posted earlier.
This however will prevent you from reloading any Extension at runtime.
See the article for all the details.

hope it helps
Lapo

--

gotoAndPlay()

...addicted to flash games
abuhusnagumi
Posts: 32
Joined: 21 Oct 2014, 07:59

Re: How to access room extension variables from another clas

Postby abuhusnagumi » 10 Nov 2014, 09:23

Thanks a lots for your assistance, it works. I can now access the variable.
User avatar
Carl Lydon
Posts: 298
Joined: 12 Nov 2007, 16:15
Location: NYC
Contact:

Re: How to access room extension variables from another clas

Postby Carl Lydon » 26 Jan 2016, 00:05

So, there is no way to directly access a function within a room extension?
You have to use "handleInternalMessage" and there is no other way?

Code: Select all

GameRoomExtension gameExt = (GameRoomExtension) room.getExtension();


Doesn't work to communicate because we're not allowed to cast ISFSExtension to any other type....
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 26 Jan 2016, 08:48

Hi,
there are multiple ways to deal with this, but you first need to consider how class loading works in Java.
http://docs2x.smartfoxserver.com/Advanc ... assLoading

By default every Extension runs in a different class loader, allowing hot-reloading at runtime. If you give up this feature you can easily cross-call any method on any Extension but you will need to restart the server on every re-deploy.

If you keep the class loader segregation the best way to handle cross communication is via the handleInternalMessage(...) way.

The details are discussed in the article I've linked. If something is not clear let me know.

cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 26 Jan 2016, 08:48

Hi,
there are multiple ways to deal with this, but you first need to consider how class loading works in Java.
http://docs2x.smartfoxserver.com/Advanc ... assLoading

By default every Extension runs in a different class loader, allowing hot-reloading at runtime. If you give up this feature you can easily cross-call any method on any Extension but you will need to restart the server on every re-deploy.

If you keep the class loader segregation the best way to handle cross communication is via the handleInternalMessage(...) way.

The details are discussed in the article I've linked. If something is not clear let me know.

cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
Carl Lydon
Posts: 298
Joined: 12 Nov 2007, 16:15
Location: NYC
Contact:

Re: How to access room extension variables from another clas

Postby Carl Lydon » 06 Feb 2016, 03:19

I'm using handleInternalMessage to communicate between different game rooms.

It seems to work fine, but I'm wondering if there is a performance hit given that I have to send a String cmd to the recipient extension, then check the cmd to see what it matches. To keep the match condition check fast, I make the string just one letter, but then there is also the packing and unpacking of data into a single param object.

Do you think doing it this way will be much slower than calling a function directly? Not having to restart the server on every extension update is very convenient, but not if at the expense of the game being less scalable...

Also, is there any way to modify handleInternalMessage to accept an int instead of a string, as the cmd? If I did that, I could use enumerators and fave faster == checking.
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 06 Feb 2016, 19:02

Carl Lydon wrote:I'm using handleInternalMessage to communicate between different game rooms.

It seems to work fine, but I'm wondering if there is a performance hit given that I have to send a String cmd to the recipient extension, then check the cmd to see what it matches. To keep the match condition check fast, I make the string just one letter, but then there is also the packing and unpacking of data into a single param object.

There's no performance hit.

Do you think doing it this way will be much slower than calling a function directly? Not having to restart the server on every extension update is very convenient, but not if at the expense of the game being less scalable...

No problems there. None whatsoever. :)

Also, is there any way to modify handleInternalMessage to accept an int instead of a string, as the cmd? If I did that, I could use enumerators and fave faster == checking.

No, commands are always strings.
However String equality checks pose no performance issues, if that's what you have in mind.

Cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
Carl Lydon
Posts: 298
Joined: 12 Nov 2007, 16:15
Location: NYC
Contact:

Re: How to access room extension variables from another clas

Postby Carl Lydon » 07 Feb 2016, 22:59

Thanks Lapo!

My concerns were based on topics such as this:

http://stackoverflow.com/questions/1650 ... comparison

But I assume there might be something going on under the hood of SFS2X that would make String comparisons as fast as int comparisons in this case.
User avatar
Lapo
Site Admin
Posts: 21723
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: How to access room extension variables from another clas

Postby Lapo » 08 Feb 2016, 08:45

No, int comparison will always be faster, for the simple reason that numbers have fixed length (e.g. 32bit) while strings can be any length.
This however doesn't translate into performance or scalability issues, unless you're working with megabytes of text for some weird reason. This is because both operations are so fast that they will never have a chance to become a bottleneck.

On any decent server you can compare thousands of strings in less than 1ms. Heck, on my mac laptop I can compare 10K strings in 0.5ms!! :shock: So no, definitely not something you should worry about.

thanks
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
Carl Lydon
Posts: 298
Joined: 12 Nov 2007, 16:15
Location: NYC
Contact:

Re: How to access room extension variables from another clas

Postby Carl Lydon » 08 Feb 2016, 18:24

Great! Thanks. I'm enumerating my commands so they're only 1 or 2 characters long, so that should also help.
User avatar
Carl Lydon
Posts: 298
Joined: 12 Nov 2007, 16:15
Location: NYC
Contact:

Re: How to access room extension variables from another class

Postby Carl Lydon » 23 Oct 2016, 18:09

Question:

Although "handleInternalMessage" works fine, it adds quite a bit of extra work that can lead to errors if you miss step.

For example, if you call a function directly it's a pretty simple 1-step process, pretty much one line:

Code: Select all

roomExtnesion.doSomething(param1, param2);


Also, if you make a mistake with the parameters eclipse will tell you.

To use "handleInternalMessage", it's several steps:

Code: Select all

SFSObject params = new SFSObject();
params.putUtfString(Enums.PARAM1, param1);
params.putUtfString(Enums.PARAM2, param2);
roomExtnesion.handleInternalMessage(Enums.DO_SOMETHING, params);

and then:

public Object handleInternalMessage(String cmd, Object params){
      switch (cmd){
      case Enums.DO_SOMETHING:
                        param1  = params.getUtfString(Enums.PARAM1);
                        param2  = params.getUtfString(Enums.PARAM2);
         doSomething(param1, param2);
         break;
                  }
}


On top of that, there are certain data types that I have been unable to put into the SFSObject Object, such as user. The workaround was to pass the user id and get the user from that on the other end, which adds more lines.

So, after using this for some months now I'm considering if debugging might be a lot easier if I called the functions directly....

So, I think you said that it can work that way if you give up the ability to "hot swap" your extensions. I think that's a good tradeoff because these days I'm using the terminal instead of the admin tool anyway (because the admin tool keeps logging out on me), and it's just as easy to restart the server as it is to try to restart an extension...

So, I've been experimenting with trying to contact a dynamically created room extension directly and I can't seem to get it to work, and it's hard to find good examples because the "handleInternalMessage" solution always comes up in the forums.

This is what I have tried:

Code: Select all

LocationLobby ext = (LocationLobby)room.getExtension();
ext.internalInit(shortName, locationName);


And it seems to not work.

"LocationLobby" is the name of the room extension class, and "internalInit" is a public function. I'm calling the above lines right after creating the room.

Thanks,

Carl

Return to “SFS2X Questions”

Who is online

Users browsing this forum: No registered users and 26 guests