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

Author Topic: [SFML 2.0] Thread confusion!  (Read 7255 times)

0 Members and 1 Guest are viewing this topic.

Andreasit

  • Newbie
  • *
  • Posts: 5
    • View Profile
[SFML 2.0] Thread confusion!
« on: April 03, 2012, 10:17:12 pm »
Hi! i started to use sfml 2.0 today and i noticed that you no longer could Inheritance the thread class? i have an class that looks like this (very short version).

Code: [Select]

"Draw.h"-------------------------------------

class Draw: public sf::Thread{
private:
     virtual void run();
};

"main.cpp"-----------------------------------

Draw d;
d.launch();

-------------------------------------------------


Is it posible to still do it like this? do i need to have an instance of Thread in the class and then call it instead?

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Re: [SFML 2.0] Thread confusion!
« Reply #1 on: April 03, 2012, 10:37:18 pm »
Take a look at the documentation: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Thread.php

I think this is what you need:
class Draw
 {
 public :
     void run()
     {
         ...
     }
 };

 Draw d;
 sf::Thread thread(&Draw::run, &d);
 thread.launch();
« Last Edit: April 03, 2012, 10:38:58 pm by texus »
TGUI: C++ SFML GUI

Andreasit

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: [SFML 2.0] Thread confusion!
« Reply #2 on: April 04, 2012, 08:45:54 am »
I changed it to look like this:

Code: [Select]
class Draw
 {
 public:
     void draw(){d.launch();}
 private:
     sf::Thread d;
     void run()
     {
         ...
     }
 };

 Draw d;
 d.draw();

The thread takes the argument "sf::Thread t(&Draw::run,this)" in the constuctor. I have checked so that the thread starts, but i dont get anything on the screen. The class looks almost as it did before when i was using sfml 1.6 but now i wont work! Would you like to see the whole thing?

what do you need to do to draw on a thread? using sfml 1.6 you only needed to setActive(false) in the thread you werent using. Some new step in sfml 2.0?
« Last Edit: April 04, 2012, 08:59:03 am by Andreasit »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0] Thread confusion!
« Reply #3 on: April 04, 2012, 09:40:45 am »
Quote
Some new step in sfml 2.0?
Nop.

Please provide a complete and minimal source code that reproduces the problem, so that we can help you.
Laurent Gomila - SFML developer

Andreasit

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: [SFML 2.0] Thread confusion!
« Reply #4 on: April 04, 2012, 12:48:28 pm »
I tested some things and noticed that it worked if i did this:

Code: [Select]
---Thread 1---
window->setActive("true");
sf::Sprite sp;
sp.loadfromtexture(text);
window->setActive("false");

Do i really need to do this to draw an image?

Draw.h

Code: [Select]

#ifndef INCLUDED_DRAW
#define INCLUDED_DRAW

#include <vector>
#include <list>
#include <SFML\System\Thread.hpp>

namespace sf{
class Drawable;
class RenderWindow;
class Image;
class Clock;
template <typename T>
class Vector2;
typedef Vector2<int> Vector2i;
};

class Draw{
public:
typedef std::vector<std::list<sf::Drawable*>> VectorWithListWithDrawable;
typedef std::list<sf::Drawable*> ListWithDrawable;

enum WindowStyle{
Window=4,
Fullscreen=8,
Resize=2,
Titlebar=1,
None=0
};

Draw(sf::Vector2i Windowsize,unsigned int Bit,std::string NameOfWindow,int style=4);
Draw(int x,int y,unsigned int Bit,std::string NameOfWindow,int style=4);
~Draw();

//Draw options
void draw();
void addSprite(sf::Drawable*, int Layer);
void clearDrawBuffer();
void clearInsertBuffer();
sf::Image* getScreenDump();

//Settings
bool isOpen();
void threadWait();
void FPS();
void setWindowIcon(std::string IconPath);
sf::RenderWindow* getWindow();

private:
void Run();
void privatedraw();
void swapBuffer();

VectorWithListWithDrawable* ActualBuffer;
VectorWithListWithDrawable* BackBuffer;
sf::RenderWindow* ActualWindow;
sf::Image* WindowIcon;

sf::Clock* time;
int FPSCount;
bool screenShot;
sf::Image* screndump;
sf::Thread* drawThread;
};

#endif

Draw.cpp

Code: [Select]
#include "Draw.h"
#include <assert.h>
#include <iostream>
#include <SFML/Graphics.hpp>

Draw::Draw(sf::Vector2i Windowsize,unsigned int Bit,std::string NameOfWindows,int style){
ActualWindow = new sf::RenderWindow(sf::VideoMode(Windowsize.x, Windowsize.y, Bit), NameOfWindows,style);
ActualWindow->setActive(false);

ActualBuffer = new VectorWithListWithDrawable;
BackBuffer = new VectorWithListWithDrawable;
time=new sf::Clock();
WindowIcon=0;
FPSCount=0;
screenShot=false;
drawThread = new sf::Thread(&Draw::Run,this);
}

Draw::Draw(int x,int y,unsigned int Bit,std::string NameOfWindows,int style){
ActualWindow = new sf::RenderWindow(sf::VideoMode(x,y, Bit), NameOfWindows,style);
ActualWindow->setActive(false);

ActualBuffer = new VectorWithListWithDrawable;
BackBuffer = new VectorWithListWithDrawable;
time=new sf::Clock();
WindowIcon=0;
FPSCount=0;
screenShot=false;
drawThread = new sf::Thread(&Draw::Run,this);
}

Draw::~Draw(){
drawThread->wait();
ActualWindow->close();
delete ActualWindow;
delete WindowIcon;
delete time;
drawThread->terminate();
delete drawThread;
}

void Draw::privatedraw(){
ActualWindow->setActive(true);
ActualWindow->clear(sf::Color(0,0,0,255));
for(unsigned int i=0;i<(int)BackBuffer->size();i++){
for(ListWithDrawable::iterator it=BackBuffer->at(i).begin();it!=BackBuffer->at(i).end();it++){
ActualWindow->draw(*(*it));
}
}
ActualWindow->display();
clearDrawBuffer();
if(screenShot){
screndump=new sf::Image(ActualWindow->capture());
screenShot=false;
}
}
void Draw::clearDrawBuffer(){
for(int i = 0;i<(int)BackBuffer->size();i++){
for(ListWithDrawable::iterator it=BackBuffer->at(i).begin();it!=BackBuffer->at(i).end();it++){
delete (*it);
}
BackBuffer->at(i).clear();
}
}

void Draw::clearInsertBuffer(){
for(int i = 0;i<(int)ActualBuffer->size();i++){
for(ListWithDrawable::iterator it=ActualBuffer->at(i).begin();it!=ActualBuffer->at(i).end();it++){
delete (*it);
}
ActualBuffer->at(i).clear();
}
}

sf::Image* Draw::getScreenDump(){
this->screenShot=true;
drawThread->wait();
return screndump;
}

void Draw::addSprite(sf::Drawable* s, int Layer){
sf::Drawable* drawObj=0;
if(sf::Sprite* sp = dynamic_cast<sf::Sprite*>(s)){
drawObj = new sf::Sprite(*sp);
}
if(Layer>=(int)ActualBuffer->size()){
while(Layer>(int)ActualBuffer->size()-1){
ActualBuffer->push_back(Draw::ListWithDrawable());
}
}
if(Layer>=0){
ActualBuffer->at(Layer).push_back(drawObj);
}
else{
ActualBuffer->at(0).push_back(drawObj);
}
}

void Draw::threadWait(){
drawThread->wait();
}

bool Draw::isOpen(){
return ActualWindow->isOpen();
}

void Draw::FPS(){
FPSCount++;
if(time->getElapsedTime().asMilliseconds()>1){
std::cout<<"FPS: "<<FPSCount<<std::endl;
time->restart();
FPSCount=0;
}
}

sf::RenderWindow* Draw::getWindow(){
return ActualWindow;
}

void Draw::setWindowIcon(std::string IconPath){
if(WindowIcon!=0){
delete WindowIcon;
}
WindowIcon=new sf::Image();
WindowIcon->loadFromFile(IconPath);
ActualWindow->setIcon(32,32,WindowIcon->getPixelsPtr());
}

void Draw::Run(){
privatedraw();
}

void Draw::draw(){
drawThread->wait();
swapBuffer();
drawThread->launch();
}

void Draw::swapBuffer(){
VectorWithListWithDrawable* temp=BackBuffer;
BackBuffer=ActualBuffer;
ActualBuffer=temp;
}

main.cpp

Code: [Select]
#include "Draw.h"
#include "SFML\Graphics.hpp"
#include "ResourceManager.h"
#include <iostream>

int main(){
Draw* d=new Draw(1024,768,32,"Test");
sf::Event ev;

sf::Image im(/*RecourceManager::getImageHalfSize(*/RecourceManager::getImage("dragons7.jpg")/*)*/);

sf::Texture* text=new sf::Texture();
text->loadFromImage(im);
sf::Sprite* sp=new sf::Sprite();
sp->setTexture(*text);
while(d->isOpen()){
while(d->getWindow()->pollEvent(ev)){
if (ev.type == sf::Event::Closed)
d->getWindow()->close();
}
d->addSprite(sp,0);
d->draw();
}
d->threadWait();
delete sp;
delete d;
return 0;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0] Thread confusion!
« Reply #5 on: April 04, 2012, 01:16:24 pm »
Sorry, there's too much code.

Can't you summarize this with a complete and minimal code, so that we can focus on the problem?
Laurent Gomila - SFML developer

Andreasit

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: [SFML 2.0] Thread confusion!
« Reply #6 on: April 12, 2012, 02:42:27 am »
The problem im facing is that everytime i am loading an picture it loads on the wrong thread. If i then send it to the other thread that i am using to draw it wont draw anything.

So for it to work i need to call:
ActualWindow->setActive(true);
//Load image
ActualWindow->setActive(false);

But since i am drawing on the other thread it gives me the console message:
Failed to activate the window's context

I have some things i might try to fix it, but it aint the best fixes.
Any idées?


Andreasit

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: [SFML 2.0] Thread confusion!
« Reply #7 on: April 12, 2012, 08:44:03 pm »
I must be missing something REALLY big!

Thread 1:
Create window;
setActive(false);
creates text;
add to draw buffer;

Thread 2:
adds all drawables with window->draw;
window-display;

Blank screen! If i to the same thing but put the function outside the thread it works. Do the drawables has some rule to which thread it can be outputet on or something?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2.0] Thread confusion!
« Reply #8 on: April 12, 2012, 08:57:15 pm »
Please read this carefully: http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368

Otherwise we'll never be able to help you.
Laurent Gomila - SFML developer