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

Author Topic: Threading in a class  (Read 4516 times)

0 Members and 1 Guest are viewing this topic.

WraithDrof

  • Newbie
  • *
  • Posts: 3
    • View Profile
Threading in a class
« on: June 12, 2013, 10:53:20 am »
I apologise if this seems rushed or I missed an easy google search, I tried but I'm running out of time quickly so this is sort of my last resort. It should be a fairly simple question though.

I started SFML pretty much today and all I want is a class which handles all the rendering in my program, and a thread which handles rendering alone. I can get the code defined here for getting a thread to work in a class, but when I apply that to my own program I get the error:

"error C2064: term does not evaluate to a function taking 1 arguments xx\include\SFML\System\Thread.inl   48   1"


I have a feeling this is also because I am unfamiliar with the initiliazation lines in class constructors. My code is as follows (its pretty much stock standard from the tutorials, just been arranged differently)

#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <vector>

class SpriteManager
{
        public:
                SpriteManager(void) : window(sf::VideoMode(gameWidth, gameHeight, 32), "Feldspar"), m_thread(&SpriteManager::renderingThread, &SpriteManager::window)
                {
                        window.setVerticalSyncEnabled(true);

                        // Deactivate OpenGL context so it can be used in the other thread
                        window.setActive(false);

                        // Set up a box for the player to romp around in
                        sf::Texture texture;
                        if (!texture.loadFromFile("resources/textures/emberGolem.png", sf::IntRect(0, 0, 60, 60)))      // IntRect = A simple rectangle. Takes coordinates for top left corner in the image and then size of rectangle.
                        {
                                // error...
                        }

                        sf::Sprite sprite;
                        sprite.setTexture(texture);
                        sprite.setPosition(sf::Vector2f(100, 100));
                        sprite.move(sf::Vector2f(100, 0));

                        vSprites.push_back(&sprite);

                        while (window.isOpen())
                        {
                                // Handle events
                                sf::Event event;
                                while (window.pollEvent(event))
                                {
                                        // Window closed or escape key pressed: exit
                                        if ((event.type == sf::Event::Closed) ||
                                           ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
                                        {
                                                window.close();
                                                break;
                                        }

                                        // Key listeners
                                        if (event.type == sf::Event::KeyPressed)
                                        {
                               
                                                // Movement keys
                                                if(event.key.code == sf::Keyboard::A)
                                                        sprite.move(sf::Vector2f(-moveSpeed, 0));
                                                else if(event.key.code == sf::Keyboard::S)
                                                        sprite.move(sf::Vector2f(0, moveSpeed));
                                                else if(event.key.code == sf::Keyboard::D)
                                                        sprite.move(sf::Vector2f(moveSpeed, 0));
                                                else if(event.key.code == sf::Keyboard::W)
                                                        sprite.move(sf::Vector2f(0, -moveSpeed));
                                        }
                                }

                                //
                                // Main loop goes here
                                //

                        }
                }

                ~SpriteManager(void);

                void addSprite(sf::Sprite* pSprite);

        private:
                void renderingThread(sf::RenderWindow* window)
                {
                        int i = 0;      // Generic iterator variable which is recycled a few times. Best to reuse memory where we can.

                        while (window->isOpen())
                        {
                                // Clear the window
                                window->clear(sf::Color::Black);

                                // Run through the vector to draw all objects on the screen
                                for(i = 0; i < vSprites.size(); i++)
                                {
                                        window->draw(*vSprites[i]);
                                }

                                // End of the current frame
                                window->display();
                        }
                }

                static const int gameWidth = 800;
                static const int gameHeight = 600;

                static const int moveSpeed = 10;        // This should be in whichever file the player/creature is in
               
                std::vector<sf::Sprite*> vSprites;
                sf::RenderWindow window;
                sf::Thread m_thread;
};

 

Help would be much appreciated!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Threading in a class
« Reply #1 on: June 12, 2013, 11:16:09 am »
Look at the tutorial's examples for member functions:

class MyClass
{
public:

    void func()
    {
    }
};

MyClass object;
sf::Thread thread(&MyClass::func, &object);

class ClassWithThread
{
public:

    ClassWithThread()
    : m_thread(&ClassWithThread::f, this)
    {
    }

private:

    void f()
    {
        ...
    }

    sf::Thread m_thread;
};

Can't you spot the difference with your code? ;)
Laurent Gomila - SFML developer

WraithDrof

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Threading in a class
« Reply #2 on: June 13, 2013, 06:36:42 am »
Thanks! I knew I was being stupid about something -.-
Although I guess my real problem was that I was still trying to get renderingThread to contain an argument, but it isn't really required since I could just use window elsewhere in the class.

Out of curiosity, how would I make it so the function assigned to the thread took an argument?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Threading in a class
« Reply #3 on: June 13, 2013, 08:45:56 am »
SFML provides only a few overloads, it doesn't have one for a member function with argument. But, as the tutorial shows, you can use lambdas or std/boost::bind, depending on what your environment supports.
Laurent Gomila - SFML developer

WraithDrof

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Threading in a class
« Reply #4 on: June 15, 2013, 08:41:40 am »
Shouldn't be an issue. Thank you very much for your help!