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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - P@u1

Pages: 1 [2] 3 4 ... 6
16
Network / Two physical packets per sf::Packet?
« on: October 23, 2011, 01:44:34 pm »
I did some tests:

Code: [Select]
int main(int argc, char** argv)
{
sf::TcpListener listener;
sf::Socket::Status status = listener.Listen(3456);
alwaysAssert(status == sf::Socket::Done);
sf::Thread thread([&]()
{
sf::TcpSocket socket;
sf::Socket::Status status = listener.Accept(socket);
alwaysAssert(status == sf::Socket::Done);
std::size_t receivedLen;
char buffer[10000];
while(true)
{
socket.Receive(buffer, sizeof(buffer), receivedLen);
}
});
thread.Launch();

sf::TcpSocket socket;
status = socket.Connect("127.0.0.1", 3456);
alwaysAssert(status == sf::Socket::Done);

sf::Packet toSend;
toSend << "hello";
const char * const msg = "1234hello";
unsigned int len = strlen(msg);

for(int i = 0; i < 20; ++i)
{
sf::Clock clock;
for(int i = 0; i < 100000; ++i)
{
status = socket.Send(toSend);
alwaysAssert(status == sf::Socket::Done);
}
unsigned int elapsed = clock.GetElapsedTime();
cout << "Duration with packet: " << elapsed << " ms" << endl;

//give the network time to stabilize
sf::Sleep(10000);

clock.Reset();

for(int i = 0; i < 100000; ++i)
{
status = socket.Send(msg, len);
alwaysAssert(status == sf::Socket::Done);
}
elapsed = clock.GetElapsedTime();
cout << "Duration without packet: " << elapsed << " ms" << endl;

//give the network time to stabilize
sf::Sleep(10000);
}

thread.Terminate();

return 0;
}


I forwarded the output to a textfile and started it in release mode.
The output is this:
Quote
Duration with packet: 17732 ms
Duration without packet: 8257 ms
Duration with packet: 17495 ms
Duration without packet: 9239 ms
Duration with packet: 17827 ms
Duration without packet: 8324 ms
Duration with packet: 16481 ms
Duration without packet: 8103 ms
Duration with packet: 16720 ms
Duration without packet: 8155 ms
Duration with packet: 16290 ms
Duration without packet: 8158 ms
Duration with packet: 16321 ms
Duration without packet: 8132 ms
Duration with packet: 16337 ms
Duration without packet: 8162 ms
Duration with packet: 16294 ms
Duration without packet: 8168 ms
Duration with packet: 16403 ms
Duration without packet: 8187 ms
Duration with packet: 16337 ms
Duration without packet: 8132 ms
Duration with packet: 16388 ms
Duration without packet: 8074 ms
Duration with packet: 16714 ms
Duration without packet: 8167 ms
Duration with packet: 16321 ms
Duration without packet: 8533 ms
Duration with packet: 16336 ms
Duration without packet: 8184 ms
Duration with packet: 16331 ms
Duration without packet: 8140 ms
Duration with packet: 16310 ms
Duration without packet: 8157 ms
Duration with packet: 16260 ms
Duration without packet: 8357 ms
Duration with packet: 16418 ms
Duration without packet: 8129 ms
Duration with packet: 16191 ms
Duration without packet: 8080 ms


This shows that when testing locally with very small messages, using sf::Packet takes about twice the time then sending without sf::Packet.
I'm quite sure that it's because of 2 packets being sent instead of one.

Does this convince you, or do I need to do more? ^^

Here is also a possible solution:
When sending a packet you first make sure that the vector is large enough to store 4 additional bytes (for the size).
Then you use std::memmov to move the data 4 bytes to the right.
Then you write the size at the first 4 bytes.
Then you use the Send overload which takes raw bytes.
Then you use memmove again to revert the change.

I have 2 more questions:
- Why are you always using resize when something is written to a packet? If the standard-library implementation allocates exactly the size you request and no more then you need to reallocate for every write. Maybe it would be better to allocate more than is needed.
- When having an non-blocking socket and doing a sent, must the buffer which is sent then be unchanged until the operation is completed?
For example if I do:
Code: [Select]
char buffer[1024];
socket.Send(buffer, sizeof(buffer));
buffer[1023] = 'a';

Can the change to the buffer then affect what actually is sent?
With boost::asio this can happen, but it also tells you when the operation is completed.

17
Network / Need help with simple UDP game
« on: October 22, 2011, 11:54:53 pm »
With enet all sends and receives are asynchronously.

You can also specify what reliability guarantees you need (for example reliable sequenced which is like tcp or no guaranees at all which is like udp).
There are also things like unreliable sequenced, just take a look at the docs.

I recommend to use sf::Packet to serialize data and then get a pointer to the internal array and send the array using enet.

I'm not using enet at the moment, as I want to do something with tcp. So I use sfml atm, but I consider switchting to boost::asio again.

Sfml networking is extremely easy to use which is a good thing, but imo the asynchronous operations are not handled in a very good way, because as far as i know you need to do a lot of polling (calling receive and test if the status is != NotReady) on every socket manually. On the other side boost::asio is a lot more complex.

Maybe you can talk about for what you are going to use the networking, then it would be easier to recommend the appropriate library.

18
Network / Two physical packets per sf::Packet?
« on: October 22, 2011, 11:46:59 pm »
What kind of prove do you need?

If you are only talking about having perfomance problems with tcp at all, this would be no problem.

19
Network / Two physical packets per sf::Packet?
« on: October 22, 2011, 04:10:01 pm »
I don't agree that a dynamic memory allocation is worse than using an additoinal packet.

Bandwith is VERY rare while cpu and ram are VERY fast.
I would sacrifice a lot of cycles to gain additional bandwith :-)
Maybe you could reuse one or more buffers (maybe hold them in a pool)?

20
Network / Need help with simple UDP game
« on: October 22, 2011, 03:58:41 pm »
I just read the tutorials from boost.
I will see if I can find the source code I used and if so, I will post it.

I always used the async_xx functions like async_send_to and async_receive_from.

But short after I started with boost i switched to enet because I recognized that implementing a reliable protocol on top of udp is not an too easy task.

Edit: I found the files with asio. I can upload them if you want, but it is not high-quality code :D

Here are some samples:
Code: [Select]

//some class instances you might need
boost::asio::io_service ioService_;
boost::asio::ip::udp::socket socket_;
boost::asio::ip::udp::endpoint remoteEndpointStorage_;
boost::array<char, 3000> readBuffer_;

//that is used to receive
socket_.async_receive_from(buffer(readBuffer_), remoteEndpointStorage_, 0, boost::bind(&AbstractNetworkObject::onReadFinished,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
//that is used to send
socket_.async_send_to(boost::asio::buffer(packet.GetData(),
packet.GetDataSize()), i->first,
boost::bind(&AbstractNetworkObject::onSendFinished, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));


//that is used to update the status:
while(ioService_.poll() > 0);

21
Network / Two physical packets per sf::Packet?
« on: October 22, 2011, 03:56:01 pm »
Hi everyone,

I just read some of the network source code and recognized a possible problem.

TcpSocket::Send(Packet& packet) looks like this:
Code: [Select]

TcpSocket::Send(Packet& packet)
//...
// First send the packet size
    Uint32 packetSize = htonl(static_cast<unsigned long>(size));
    Status status = Send(reinterpret_cast<const char*>(&packetSize), sizeof(packetSize));

//...
// Send the packet data
    if (packetSize > 0)
    {
        return Send(data, size);
    }
//...


And you also disable nagle-algorithm, so that if I understand it right every call to send directly sends a physical packet over the network.
You are calling send 2 times in a row with very low time between the calls.
If that really yields 2 phyiscal packets (and it should do as nagle algorithm is off) with tcp/ip-header then this is quite a big overhead, don't you think so?

22
Window / Application freezes when moving the window
« on: October 12, 2011, 06:57:49 pm »
Very strange...
I just did a recompile and now it's working.

23
Window / Application freezes when moving the window
« on: October 12, 2011, 06:13:05 pm »
My class worked fine on my desktop-pc, and now I tried it on my laptop.
There it crashes here:
Code: [Select]
bool ThreadedEventLoopRenderWindow::PollEvent(sf::Event &event)
{
sf::Lock lock(queueMutex_); //<----------here
if(pendingEvents_.empty())
{
return false;
}
event = pendingEvents_.front();
pendingEvents_.pop();
return true;
}

:-(

The error message is:
Quote
First-chance exception at 0x772426fc in LockstepMario.exe: 0xC0000008: An invalid handle was specified.


Do you have any ideas why this happens and why it happens on my laptop but not on my desktop pc?

24
Window / Application freezes when moving the window
« on: October 12, 2011, 09:57:44 am »
Do you have any ideas on how to solve this?
Maybe you could add an timeout to WaitEvent. Then I can set a flag (with proper synchronization ofc) and check the flag in the eventThread everytime it returns from waitevent.
Then in the other thread I set this flag and wait for the thread to terminate.

Edit: Just got another idea: I could make the thread terminate itself when an Closed event is received (after pushing the event to the queue).

25
Window / Application freezes when moving the window
« on: October 11, 2011, 05:37:46 pm »
Thx 4 your help.
I now tried to implement a transparent version which inherits from sf::RenderWindow (it's not perfect as some methods are not virtual, but I didn't want to forward each method call...).
Maybe this is also interesting for SFML because other people might have the same problem.
Another non perfect thing is that I need to use Terminate to make the thread exit, as I don't have any other method to exit the WaitEvent loop.

Here is the code (I ommited things like includes and include guards):
Code: [Select]
//never cast up to sf::Renderwindow (some non-virtual functions are hidden)!
class ThreadedEventLoopRenderWindow : public sf::RenderWindow
{
public:
ThreadedEventLoopRenderWindow(){}
~ThreadedEventLoopRenderWindow();
void Create(sf::VideoMode mode, const std::string& title, unsigned long style = sf::Style::Default, const sf::ContextSettings& settings = sf::ContextSettings());
void Close();
bool PollEvent(sf::Event &event);
private:
std::unique_ptr<sf::Thread> eventThread_;
sf::Mutex queueMutex_;
std::queue<sf::Event> pendingEvents_;
};

//.cpp file
ThreadedEventLoopRenderWindow::~ThreadedEventLoopRenderWindow()
{
if(eventThread_)
{
sf::Lock lock(queueMutex_);
eventThread_->Terminate();
}
}

void ThreadedEventLoopRenderWindow::Create(sf::VideoMode mode, const std::string& title, unsigned long style /*= sf::Style::Default*/, const sf::ContextSettings& settings /*= sf::ContextSettings()*/)
{
sf::Mutex createMutex;
eventThread_.reset(new sf::Thread([&]()
{
{
sf::Lock createLock(createMutex);
sf::RenderWindow::Create(mode, title, style, settings);
SetActive(false);
}
sf::Event evt;
while(true)
{
bool ok = WaitEvent(evt);
if(ok)
{
sf::Lock lock(queueMutex_);
pendingEvents_.push(evt);
}
else
{
cerr << "error occurred while waiting for event" << endl;
}
}
}));
eventThread_->Launch();
sf::Sleep(100); //hack to make sure that the window is created (sfml does not have a wait condition afaik)
sf::Lock createLock2(createMutex);
}

bool ThreadedEventLoopRenderWindow::PollEvent(sf::Event &event)
{
sf::Lock lock(queueMutex_);
if(pendingEvents_.empty())
{
return false;
}
event = pendingEvents_.front();
pendingEvents_.pop();
return true;
}

void ThreadedEventLoopRenderWindow::Close()
{
if(eventThread_)
{
sf::Lock lock(queueMutex_);
eventThread_->Terminate();
}
sf::RenderWindow::Close();
}

26
Window / Application freezes when moving the window
« on: October 11, 2011, 02:28:37 pm »
I just used the forum search, but only found 1 other thread for this topic, which did not have good solutions.
Can you please give me some links or some suggestions here?

What is a good way to deal with it?
I thought about using a thread which processes the event loop and pushes important events to a threasafe queue and do all other things in another thread.
But I'm not sure, if it will work out to manipulate a window from different threads.

27
Window / Application freezes when moving the window
« on: October 11, 2011, 11:37:32 am »
Hi,

I recognized that while I'm moving a window the game logic pauses.
It's most probably because the program is captured in the event loop.
Is there a fix for this other than using more than 1 thread?

28
General / Possible Bug in RenderWindow Destructor (SFML 2.0)
« on: October 09, 2011, 08:03:19 pm »
ok, good to know.
Didn't know that sfml uses globals.

29
General / Possible Bug in RenderWindow Destructor (SFML 2.0)
« on: October 09, 2011, 12:36:38 pm »
Hi,

I just started a new project and this time I used the singleton pattern for my game class.
I first implemented it so that in the static deinitializers the Game object is destroyed which invokes the RenderWindow destructor.
This yields a crash:
Quote
Unhandled exception at 0x77bb1c1d in LockstepMario.exe: 0xC0000005: Access violation reading location 0xfeeefef6.
    ntdll.dll!77bb1c1d()    
    [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]   
>   LockstepMario.exe!sf::priv::MutexImpl::Lock()  Line 52 + 0xc bytes   C++
    LockstepMario.exe!sf::Mutex::Lock()  Line 62   C++
    LockstepMario.exe!sf::Lock::Lock(sf::Mutex & mutex)  Line 39   C++
    LockstepMario.exe!sf::GlResource::~GlResource()  Line 72 + 0xd bytes   C++
    LockstepMario.exe!sf::Renderer::~Renderer()  + 0x16 bytes   C++
    LockstepMario.exe!sf::RenderTarget::~RenderTarget()  Line 53 + 0xb bytes   C++
    LockstepMario.exe!sf::RenderWindow::~RenderWindow()  Line 60 + 0xe bytes   C++
    LockstepMario.exe!Game::~Game()  Line 14 + 0x8 bytes   C++
    LockstepMario.exe!Game::`scalar deleting destructor'()  + 0x2b bytes   C++
    LockstepMario.exe!std::default_delete<Game>::operator()(Game * _Ptr)  Line 2068 + 0x2b bytes   C++
    LockstepMario.exe!std::unique_ptr<Game,std::default_delete<Game> >::_Delete()  Line 2345   C++
    LockstepMario.exe!std::unique_ptr<Game,std::default_delete<Game> >::~unique_ptr<Game,std::default_delete<Game> >()  Line 2302   C++
    LockstepMario.exe!`dynamic atexit destructor for 'Game::instance_''()  + 0x28 bytes   C++
    LockstepMario.exe!doexit(int code, int quick, int retcaller)  Line 567   C
    LockstepMario.exe!exit(int code)  Line 393 + 0xd bytes   C
    LockstepMario.exe!__tmainCRTStartup()  Line 284   C
    LockstepMario.exe!mainCRTStartup()  Line 189   C
    kernel32.dll!760d3677()    
    ntdll.dll!77b89f02()    
    ntdll.dll!77b89ed5()    
(I'm using visual studio 2010).
I did some investigation and figured out that MutexImpl::myMutex has the address 0xfeefee which means that it is uninitialized.   

But when I put a call to release the singleton in atexit, it works.

Here is some code:
Code: [Select]
int main(int argc, char** argv)
{
Game::Instance().Run();
return 0;
}

//new file here
class Game
{
public:
Game();
~Game();
void Run();

static Game& Instance()
{
if(!instance_)
{
instance_.reset(new Game());
//atexit(Destroy); when I add this lines, everything works!
}
return *instance_;
}
private:
void Init();
void MainLoop();
void HandleEvents();
void Update();
void Draw();
sf::RenderWindow window_;

static void Destroy(){instance_.release();}
static std::unique_ptr<Game> instance_;
};


The other methods don't do anything interesting, but I can post them if you want.

Note: I'm using SFML 2.0, but not the latest build atm.

30
DotNet / Is it important to Dispose SFML objects?
« on: September 22, 2011, 12:52:59 pm »
I now added Dispose calls and it doesen't crash anymore.
But why did it crash when I didn't call Dispose()?
Is this some bug in the destructor code?

Pages: 1 [2] 3 4 ... 6
anything