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

Author Topic: Can GetEvent or sf::Input be called from another thread?  (Read 11711 times)

0 Members and 1 Guest are viewing this topic.

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Can GetEvent or sf::Input be called from another thread?
« Reply #15 on: December 31, 2010, 06:09:47 am »
That workaround is not needed in SFML.. You can simply inherit from sf::Thread and in SFML2 it can take an object and associated member function to run. So it more or less does it for you :)
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

mercurio7891

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Can GetEvent or sf::Input be called from another thread?
« Reply #16 on: December 31, 2010, 12:21:05 pm »
for me my system is design base on a thread pool. So a subsystem is technically not bounded to any thread but spreaded in the pool. However as the sf::Input and GetEvent can't be separated from the main thread, I just forced them together :)

The main advantage of using a thread pool is so that we are not locked to 1 subsystem per thread, and we can scale the number of threads as and when the computer has more cores available.

Wafthrudnir

  • Newbie
  • *
  • Posts: 26
    • View Profile
Can GetEvent or sf::Input be called from another thread?
« Reply #17 on: December 31, 2010, 05:08:33 pm »
@Groogy:

Thanks, I didn't know that  :)
Black Metal + Coding = Win!

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Can GetEvent or sf::Input be called from another thread?
« Reply #18 on: December 31, 2010, 06:48:39 pm »
Aaah, I think I'm starting to understand how threads work.
I did some experiments but still the results weren't very good hehe.
I tried doing this (following my example):

Code: [Select]
//App is a sf::RenderWindow object

class main_roll : public sf::Thread
{
public:
       sf::Sprite char1;
       //Override threaded function inherited from sf::Thread:
       virtual void Run()
       {
                while(App.IsOpened())
                {
                       App.Clear();
                       App.Draw(char1);
                       App.Display();
                }
       }
       void MainInputs()
       {
                  while(App.IsOpened())
                      //Get Inputs and Move char1
       }
       void MainRoll()
       {
              Launch();
              MainInputs();
       }

};


But the results were bizarre. Distorted Graphics, white screens flashing...
I'm guessing it's because the main thread and the thread that runs the drawable objects are not synchronized. How could I do this? Mutex's?

Thanks for all the help so far and happy new year community  :D

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Can GetEvent or sf::Input be called from another thread?
« Reply #19 on: January 01, 2011, 07:43:23 pm »
All I can do is referring you to my previous wall of text. I described there how to synchronize, if you use nutex,  critical section or atomic operations is up to your implementation.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Wafthrudnir

  • Newbie
  • *
  • Posts: 26
    • View Profile
Can GetEvent or sf::Input be called from another thread?
« Reply #20 on: January 01, 2011, 09:47:00 pm »
Yes, use Mutexes.

I think this could help...
Code: [Select]

//App is a sf::RenderWindow object

class main_roll : public sf::Thread
{
public:
       sf::Sprite char1;
       //Override threaded function inherited from sf::Thread:
       virtual void Run()
       {
                while(App.IsOpened())
                {
                       //MUTEX LOCK <--------------------------
                       App.Clear();
                       App.Draw(char1);
                       App.Display();
                       //MUTEX UNLOCK <--------------------------
                }
       }
       void MainInputs()
       {
                  while(App.IsOpened())
                  {
                      //MUTEX LOCK <--------------------------
                      //Get Inputs and Move char1
                      //MUTEX UNLOCK <--------------------------
                  }
       }
       void MainRoll()
       {
              Launch();
              MainInputs();
       }

};


Maybe this could give you some FPS Issue?!
Black Metal + Coding = Win!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Can GetEvent or sf::Input be called from another thread?
« Reply #21 on: January 01, 2011, 11:17:54 pm »
Nice example of what not to do with threads ;)

Threads must be used to make things run in parallel. If you end up synchronizing everything, you loose all the benefits -- and you have a code that is even worse than the single-threaded version.

Use threads when you know what you do, not just because "it's cool" ;)
Laurent Gomila - SFML developer

Wafthrudnir

  • Newbie
  • *
  • Posts: 26
    • View Profile
Can GetEvent or sf::Input be called from another thread?
« Reply #22 on: January 02, 2011, 01:22:51 am »
I was wondering why to use threads anyway in a game (except for a loading/statusbar, that's displayed on top of an animated map etc.) :?

The mutexes in the code example above may work, but yes, threading in this one does not really make sense.

@Contadotempo

Imaging this:

Everything gets drawn to screen, to do this, the app needs to know the x-coordinates of each object.
But if you want to access them, you need to block them, so no other thread can change it's values while reading them (could cause serious bullsh**).
And while your app is drawing, no input can be processed, if it changes the objects coordinates.
SO...
after your App has drawn everything, it frees the mutex...you push the left-key...but...oh no...the app already has locked the mutex again, you have not been fast enough...so no update on movement...

If there is no lock, things get messed up...Variables get read and written to by different threads at the same time...the screen refreshes while reading a value that has just been change at the same time...instead of getting a X-Position of 6 you get a 32523 or something else, because the writing was not finished.
Black Metal + Coding = Win!

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Can GetEvent or sf::Input be called from another thread?
« Reply #23 on: January 02, 2011, 02:01:27 pm »
Waft is correct but there are ways to go around this need of locking the data and I've already described one way using synchronization and data duplication(one for each thread).

Also there is a way to make it completely asynchronous without any need for locking data(In my implementation I actually use mutexes around 1 queue but when I get time I'll remove it) which gives you 100% exploitation of parallel programming. How this is possible is based on data duplication. How you duplicate the data depends on the model. For my model the data is duplicated on the run and I can't go into detail as I'm writing from my phone. For you guys, just to get started, have the data duplicated at the end of the frame.

If you still don't see the need of data duplication. It's very simple, we never want threads that work on the same memory. What we basically wants are processes which still interfaces with each others easily. If you don't know what a process is then simple explained, a thread with private memory. This is easily made by duplication of the data. An easiest way to do that is by stopping all the threads except for the main, copy the data from main to the various threads.

Writing on the phone is hard and takes a long time to do XD
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Can GetEvent or sf::Input be called from another thread?
« Reply #24 on: February 04, 2011, 12:54:52 pm »
I'm sorry for replying a month later, but exam season in university left me with no time and I only got a chance to come here now. I really can't go out without saying thanks after I find the solution so here I am. :)

I ended up following Groogy's implementation  and using sf::Thread and its working nice and smooth now. Thanks guys for all the help.

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Can GetEvent or sf::Input be called from another thread?
« Reply #25 on: February 04, 2011, 01:49:51 pm »
I'm glad you got it to work :)

Get things running parallel is pretty hard for newbies to do right. Also since you can see that CPU's are not getting better, they are just getting an increased core size, being able to utilize that is pretty important for the future.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio