Problem to joining room

varis
edited November 2013 in Native
Hi! I have an app made with windows c++ and I have a problem when I try to join a room, but it´s weird. When I open the app for first time, I can connect without problems, I join a room and can create it. But then, if I back to MenuScene and go again to join and create the room, the app stop and can´t connect to it.

I was debugging and I couldn´t found any mistake. Here is my code, hope you guys could help to resolve this.

[code2=cpp]const ExitGames::Common::JString MODE = L"mode";
const ExitGames::Common::JString NAME = L"name";
const ExitGames::Common::JString UNKNOW = L"unknow";
int tamanoo = 3;

void NetworkLogic::opCreateRoom(void)
{
ExitGames::Common::JString tmp;

ExitGames::Common::Hashtable *room = new ExitGames::Common::Hashtable;
room->put<ExitGames::Common::JString, int>(MODE,tamanoo);

ExitGames::Common::Hashtable *player = new ExitGames::Common::Hashtable;
player->put<ExitGames::Common::JString, ExitGames::Common::JString>(NAME,UNKNOW);

ExitGames::Common::JVector<ExitGames::Common::JString> *lobby = new ExitGames::Common::JVector<ExitGames::Common::JString>;
lobby->addElement(ExitGames::Common::JString(L"mode"));

mLoadBalancingClient.opCreateRoom(tmp=(int)GETTIMEMS(),true,true,2,*room,*lobby);
mStateAccessor.setState(STATE_JOINING);
}

void NetworkLogic::opJoinRandomRoom(void)
{
ExitGames::Common::Hashtable *room = new ExitGames::Common::Hashtable;
ExitGames::Common::ValueObject<int>(tamanoo));
room->put<ExitGames::Common::JString,int>(MODE,tamanoo);

mLoadBalancingClient.opJoinRandomRoom(*room,2);
}[/code2]

The app crash exactly in mLoadBalancingClient.opJoinRandomRoom(*room,2), but I really don´t know why :S

Thanks in advance!

Comments

  • Hi varis.

    Which version of the client SDK are you using? v3.2.2.1?

    In the code that you have provided you are allocating dynamic storage with new that never gets deallocated with delete. Maybe that's related to your problem? If you are also doing that at other places, then maybe the memory that you allocate , but never deallocate, sums up and you simply run out of memory?
  • PS: I won't allocate them dynamically at all. Its better to just allocate on the stack whenever possible and allocate dynamically only when you have to.
  • Hi again and thanks for asnwering.

    I use SDK v3.2.2.0. I forgot delete the pointers, but even doing that, I have the same problem. So I change the code like this but have the same problem, app get freeze and doesn´t say any error code.

    [code2=cpp]const ExitGames::Common::JString MODE = L"mode";
    const ExitGames::Common::JString NAME = L"name";
    const ExitGames::Common::JString UNKNOW = L"unknow";
    int tamanoo = 3;

    void NetworkLogic::opCreateRoom(void)
    {
    ExitGames::Common::JString tmp;

    ExitGames::Common::Hashtable room;
    room->put<ExitGames::Common::JString, int>(MODE,tamanoo);

    ExitGames::Common::JVector<ExitGames::Common::JString> lobby;
    lobby.addElement(ExitGames::Common::JString(L"mode"));

    mLoadBalancingClient.opCreateRoom(tmp=(int)GETTIMEMS(),true,true,2,room,lobby);
    mStateAccessor.setState(STATE_JOINING);
    }

    void NetworkLogic::opJoinRandomRoom(void)
    {
    ExitGames::Common::Hashtable room;
    room.put<ExitGames::Common::JString,int>(MODE,tamanoo);

    mLoadBalancingClient.opJoinRandomRoom(room,2);
    }[/code2]

    It´s true that I have another pointer in the code, but I always do a delete after using them, so I don´t know why I can´t join and create another room after going to MenuScene... I don´t if it is the version of SDK because with the last version I didn´t have any problems to connect or disconnect. Any help would be great. Thanks agains.
  • I increased the memory of my marmalade app, but still has the same problem. Any ideas please?
  • More info. I debug again and I get this error in Allocate.h

    ExitGames::Common::Hashtable*
    ExitGames::Common::MemoryManagement::allocateArray<ExitGames::Common::Hashtable>(unsigned int)

    I don´t know how to resolve this :S
  • Hi varis.

    I have tested you provided code with demo_loadBalancing and version 3.2.2.0 of the codebase, but not only does that code look correct, I also could not reproduce your issue with it: it just works fine for me: Even after 10 times creating and leaving a room it still works like a charm. So to me it looks like your issue isn't related to that part of the code, but may be caused by something else.

    About your last code:
    What error? You have just provided a code line, but no error message.

    Maybe its a good idea to comment out everything that you do inside a room, just create and leave it, but do not send any ingame data - that way you could see, if its really just creating and leaving a room, which already causes trouble or if it has something to do with what you are doing ingame.
    You could also try to reproduce your issues with the demo. If you can't reproduce it with it, then it has to have something to do with what your game makes different than the demo and you should be able to find the cause by tracking it down in those differences. If it is reproducible with the demo, then you could provide us your modified demo as a reproduction case and we could have a look without the need for you to provide access to your game code.
  • 6zVQXS0.pnghttp://i.imgur.com/6zVQXS0.png

    Hi again. I think I found the error but I don´t know how to resolve it. The error say "could not read variable object value after assignement" in the lane of joininRandomRoom. I let this code for joininRandomRoom:

    [code2=cpp]ExitGames::Common::Hashtable room;
    mLoadBalancingClient.opJoinRandomRoom(room,2);[/code2]

    I remove room.put function to see if it was the error with variables but nothing changed. I don´t know what variable object value can´t be read.
  • Hi again.

    Sorry, but I am afraid that this isn't enough info for me to find the cause of the problem.

    Would you mind sending us a reproduction case, so that we can track the problem down?
  • Hi, I send you the code of my NetworkLogic. I hope you can see the mistake anywhere and fix it. I don´t know if you need another kind of reproduction, I only have the error that I gave to you in the image, that object variable value could not be read but I don´t why.

    Thanks for all.
  • Hi varis.

    When I have said reproduction case, I meant a self-contained project, with which I can reproduce the bug: The NetworkLogic.cpp that you have sent to me, has dozens of dependencies to other files that you have not shared and a lot off that stuff is unrelated to Photon.
    You could take the demo_loadBalancing project from within our SDK as a base and modify it in a way that you can reproduce your issue with it, then supply me with your modified version of the demo. That way I can actually compile and debug the code and you can be sure that it indeed has something to do with how your code uses Photon.

    Nonetheless I can already give you some feedback on the code that you have shared:
    1.
    It's a very good idea to always give English names to all your identifiers: every coder will have to have some English skills anyways as the keywords and most of the resources in the web are in English. Using a different language like in your case Spanish, means that whenever you share your code with someone, who doesn't speak that language, you will make it unnecessary harder for him to read your code.

    2.
    [code2=cpp]void NetworkLogic::sendTiempo(void)
    {
    ExitGames::Common::Hashtable palabras;
    palabras.put<int,int>(0,secc);
    palabras.put<int, int>(1,minn);
    mLoadBalancingClient.opRaiseEvent(false, palabras, 100);
    palabras.~Hashtable();
    }[/code2]
    You should not explicitly call destructors on local variables: the instances will automatically get destructed, when you leave the scope of the function. Calling the destructor yourself means, that it gets called 2 times instead of one time, which leads into undefined behavior -> That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you.
    So that code from above should instead look like this:
    [code2=cpp]void NetworkLogic::sendTiempo(void)
    {
    ExitGames::Common::Hashtable palabras;
    palabras.put<int,int>(0,secc);
    palabras.put<int, int>(1,minn);
    mLoadBalancingClient.opRaiseEvent(false, palabras, 100);
    }[/code2]
    The same is true for sendEventPalabras().

    3.
    You are currently using the same eventcode for all your events. The eventCode is supposed to be used to differentiate between the different types of events on the receiving side. It looks like you are currently differentiating through checking the count of keys in the received event hashtable. That looks like a dirty hack to me that is likely to let things break as soon as 2 different event types happen to have the same amount of keys or if one type does not always have the same amount of keys.

    4.
    [code2=cpp]char* NetworkLogic::convertirJString(ExitGames::Common::JString cadena){
    int i;
    char buffer[SIZE_BUFFER+1];
    for(i=0; i<cadena.length(); i++){
    buffer=cadena.charAt(i);
    }
    buffer='\0';
    return buffer;
    }[/code2]
    I guess that code and all those sister-functions are intended to convert from JString to char*. In that case it's definitely quite limited, as it does not account for non-ascii characters. Why don't you just use our builtin string conversion API?
    Instead of
    [code2=cpp]convertirJString(myString);[/code2]
    just call
    [code2=cpp]myString.UTF8Representation().cstr();[/code2]

    5.
    [code2=cpp]int NetworkLogic::convertirAInt(ExitGames::Common::JString cadena){
    int i, vuelta;
    char buffer[20];
    for(i=0; i<cadena.length(); i++){
    buffer=cadena.charAt(i);
    }
    buffer='\0';
    vuelta=atoi(buffer);
    return vuelta;
    }[/code2]
    Are you really sending ints around as strings, just to convert them back on the receiving side? Why not just directly sending ints?

    6.
    [code2=cpp]EGLOG(ExitGames::Common::DebugLevel::INFO, L"", &mLoadBalancingClient);[/code2]
    What is that supposed to be/do? Passing more optional arguments to a printf-like function, than you are specifying in the format string, won't do anything else than just provoke undefined behavior.

    7.
    [code2=cpp]strcpy(name2, convertirJString(eventContent.getValue((25+tamanoo*tamanoo))->toString()));[/code2]
    About this and all the other similar lines in your customEventAction() implementation:
    toString() is supposed as a debugging interface. You could for example call myHashtable.toString() to get a string representation of a hashtable, that you can print to a log file to see if the hashtable looks like expected. You should NEVER use it to read out a string value from an Object. You are actually stringifying the whole Object-instance here, but what you actually want to do is reading out the string value from the Object instance, that you have previously stored in it.
    So the correct code would be:
    [code2=cpp]ExitGames::Common::ValueObject<ExitGames::Common::JString>(eventContent.getValue(25+tamanoo*tamanoo)).getDataCopy();[/code2]
    Therefor in combination with paragraph 4 the whole line should rather look like this:
    [code2=cpp]strcpy(name2, ExitGames::Common::ValueObject<ExitGames::Common::JString>(eventContent.getValue(25+tamanoo*tamanoo)).getDataCopy().UTF8Representation().cstr());[/code2]
  • Thank you very much! The problem was the destructo on Hashtable as you said. But I followed all your steps to have a better and clearly code.

    And from now, I will write my code in English too :). Thanks again!
  • You are welcome. I am glad that we have now found the cause of the problem. :-)