Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Thread initialization issue  (Read 5132 times)

0 Members and 1 Guest are viewing this topic.

Charsmud

  • Newbie
  • *
  • Posts: 30
    • View Profile
Thread initialization issue
« on: June 21, 2014, 03:46:49 am »
I am having problems with creating a thread.  I have a method that I am trying to use with the thread that has one parameter, but I get this error:
1>------ Build started: Project: GameServer, Configuration: Release Win32 ------
1>  Heatbeat.cpp
1>C:\Users\Will\Documents\OpenGL\include\SFML/System/Thread.inl(48): error C2064: term does not evaluate to a function taking 1 arguments
1>          C:\Users\Will\Documents\OpenGL\include\SFML/System/Thread.inl(48) : while compiling class template member function 'void sf::priv::ThreadFunctorWithArg<F,A>::run(void)'
1>          with
1>          [
1>              F=void (__thiscall Heartbeat::* )(sf::IpAddress),
1>              A=sf::IpAddress
1>          ]
1>          C:\Users\Will\Documents\OpenGL\include\SFML/System/Thread.inl(79) : see reference to class template instantiation 'sf::priv::ThreadFunctorWithArg<F,A>' being compiled
1>          with
1>          [
1>              F=void (__thiscall Heartbeat::* )(sf::IpAddress),
1>              A=sf::IpAddress
1>          ]
1>          Heatbeat.cpp(26) : see reference to function template instantiation 'sf::Thread::Thread<void(__thiscall Heartbeat::* )(sf::IpAddress),sf::IpAddress>(F,A)' being compiled
1>          with
1>          [
1>              F=void (__thiscall Heartbeat::* )(sf::IpAddress),
1>              A=sf::IpAddress
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 

Here is the initialization method and target function:

void Heartbeat::prepareHeartbeat(ClientHandler clients)
{
        std::vector<sf::IpAddress> ips;


        for(int i = 0; i < clients.size(); i++)
        {
                PlayerSession player = clients.getPlayers().at(i);
                sf::IpAddress ip = player.getIp();
                ips.push_back(player.getIp());
                std::cout << player.getIp() << std::endl;
                sf::Thread thread(&Heartbeat::heartbeat, ip);

                thread.launch();

        }
}

void Heartbeat::heartbeat(sf::IpAddress ip)
{
        sf::Packet mPacket;
        sf::UdpSocket mSocket;
        mSocket.setBlocking(false);

        mPacket << ServerPacket::Heartbeat;
       

        sf::Packet returnPacket;
        sf::IpAddress returnIp;
        unsigned short returnPort;
        mSocket.send(mPacket, ip, 54000);
        if(mSocket.receive(returnPacket, returnIp, returnPort) != sf::Socket::Done)
        {
        }
        int x;
        if(returnPacket >> x)
        {
                if(x == ClientPacket::ReplyHeartbeat)
                {
                        std::cout << "Return heartbeat recieved by " << ip << ", sending another!" << std::endl;
                        heartbeat(ip);
                }
        }
}

Any ideas?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Thread initialization issue
« Reply #1 on: June 21, 2014, 10:40:47 am »
Heartbeat::heartbeat is a member function, therefore it takes one additional argument: this. And sf::Thread doesn't support more than one argument. You should rather use std::thread/std::bind if your compiler allows it.

And you should read the sf::Thread tutorial: your code is totally useless so far ;)
Laurent Gomila - SFML developer

Charsmud

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Thread initialization issue
« Reply #2 on: June 21, 2014, 06:00:57 pm »
I have attempted to move over to using std::bind; however I get the following error message:

1>------ Build started: Project: GameServer, Configuration: Release Win32 ------
1>  Heatbeat.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2825: '_Fty': must be a class or namespace when followed by '::'
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40) : see reference to class template instantiation 'std::tr1::_Result_type1<__formal,_Fty,_Arg0>' being compiled
1>          with
1>          [
1>              __formal=false,
1>              _Fty=void (__thiscall Heartbeat::* const )(sf::IpAddress),
1>              _Arg0=std::tr1::_Nil &
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(597) : see reference to class template instantiation 'std::tr1::_Result_of1<_Fty,_Farg0>' being compiled
1>          with
1>          [
1>              _Fty=void (__thiscall Heartbeat::* const )(sf::IpAddress),
1>              _Farg0=std::tr1::_Nil &
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xrefwrap(28) : see reference to class template instantiation 'std::tr1::_Result_of<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=void (__thiscall Heartbeat::* const (std::tr1::_Nil &))(sf::IpAddress)
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxbind1(273) : see reference to class template instantiation 'std::tr1::result_of<_Fty>' being compiled
1>          with
1>          [
1>              _Fty=void (__thiscall Heartbeat::* const (std::tr1::_Nil &))(sf::IpAddress)
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxbind0(10) : see reference to class template instantiation 'std::tr1::_Bind1<_Callable,_Arg0>::_Return<_Barg0,_Barg1,_Barg2,_Barg3,_Barg4,_Barg5,_Barg6,_Barg7,_Barg8,_Barg9>' being compiled
1>          with
1>          [
1>              _Callable=std::tr1::_Callable_pmd<void (__thiscall Heartbeat::* const )(sf::IpAddress),Heartbeat>,
1>              _Arg0=sf::IpAddress,
1>              _Barg0=std::tr1::_Nil &,
1>              _Barg1=std::tr1::_Nil &,
1>              _Barg2=std::tr1::_Nil &,
1>              _Barg3=std::tr1::_Nil &,
1>              _Barg4=std::tr1::_Nil &,
1>              _Barg5=std::tr1::_Nil &,
1>              _Barg6=std::tr1::_Nil &,
1>              _Barg7=std::tr1::_Nil &,
1>              _Barg8=std::tr1::_Nil &,
1>              _Barg9=std::tr1::_Nil &
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\functional(394) : see reference to class template instantiation 'std::tr1::_Bind_base<_Ret,_BindN>' being compiled
1>          with
1>          [
1>              _Ret=void (sf::IpAddress),
1>              _BindN=std::tr1::_Bind1<std::tr1::_Callable_pmd<void (__thiscall Heartbeat::* const )(sf::IpAddress),Heartbeat>,sf::IpAddress>
1>          ]
1>          Heatbeat.cpp(23) : see reference to class template instantiation 'std::tr1::_Bind<_Result_type,_Ret,_BindN>' being compiled
1>          with
1>          [
1>              _Result_type=std::tr1::_Notforced,
1>              _Ret=void (sf::IpAddress),
1>              _BindN=std::tr1::_Bind1<std::tr1::_Callable_pmd<void (__thiscall Heartbeat::* const )(sf::IpAddress),Heartbeat>,sf::IpAddress>
1>          ]
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2903: 'result' : symbol is neither a class template nor a function template
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2039: 'result' : is not a member of '`global namespace''
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2143: syntax error : missing ';' before '<'
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2039: 'type' : is not a member of '`global namespace''
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2238: unexpected token(s) preceding ';'
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2039: '_Type' : is not a member of 'std::tr1::_Result_type1<__formal,_Fty,_Arg0>'
1>          with
1>          [
1>              __formal=false,
1>              _Fty=void (__thiscall Heartbeat::* const )(sf::IpAddress),
1>              _Arg0=std::tr1::_Nil &
1>          ]
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2146: syntax error : missing ';' before identifier '_Type'
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2602: 'std::tr1::_Result_of1<_Fty,_Farg0>::_Type' is not a member of a base class of 'std::tr1::_Result_of1<_Fty,_Farg0>'
1>          with
1>          [
1>              _Fty=void (__thiscall Heartbeat::* const )(sf::IpAddress),
1>              _Farg0=std::tr1::_Nil &
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40) : see declaration of 'std::tr1::_Result_of1<_Fty,_Farg0>::_Type'
1>          with
1>          [
1>              _Fty=void (__thiscall Heartbeat::* const )(sf::IpAddress),
1>              _Farg0=std::tr1::_Nil &
1>          ]
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2868: 'std::tr1::_Result_of1<_Fty,_Farg0>::_Type' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Fty=void (__thiscall Heartbeat::* const )(sf::IpAddress),
1>              _Farg0=std::tr1::_Nil &
1>          ]
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxbind0(12): error C2091: function returns function
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxbind0(27): error C2091: function returns function
1>  ServerCore.cpp
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 

Here is the modified code (so now the thread isn't instantly terminated.  Overlooked that!):

Heartbeat::Heartbeat(ClientHandler clients)
{
        std::vector<sf::IpAddress> ips;


        for(int i = 0; i < clients.size(); i++)
        {
                PlayerSession player = clients.getPlayers().at(i);
                sf::IpAddress ip = player.getIp();
                ips.push_back(player.getIp());
                std::cout << player.getIp() << std::endl;
                sf::Thread thread(std::bind(&Heartbeat::heartbeat, ip));

                thread.launch();

        }
}

Everything else has stayed the same. 

EDIT:  Forgot to actually include the "this" in the bind call.  The thread should run fine now.  Thanks!
« Last Edit: June 21, 2014, 06:04:45 pm by Charsmud »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thread initialization issue
« Reply #3 on: June 21, 2014, 06:05:00 pm »
Please read a C++ documentation or tutorial about std::bind(), you're using it wrongly. In order to bind member functions, it needs a this pointer.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Charsmud

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Thread initialization issue
« Reply #4 on: June 21, 2014, 06:06:10 pm »
I realized this and fixed it a few minutes ago.  Thanks!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Thread initialization issue
« Reply #5 on: June 21, 2014, 07:48:15 pm »
Your code is still useless by the way. Nothing will run in parallel.
Laurent Gomila - SFML developer