Well attempting to do so either results in a bunch of “Failed to activate the window's context” followed by a “XIO: fatal IO error 11 (Resource temporarily unavailable) on X server: 0”, or an immediate “XInitThreads has not been called”. Considering that other people were having the same problem (and calling XInitThread isn’t cross-platform), I thought it was just impossible.
Here is a basic example that produces either of those errors (I’m guessing depending on wether draw() or waitEvent() gets called first):
#include <thread>
#include <memory>
#include <SFML/Graphics.hpp>
sf::Sprite sprite;
bool quit = false;
void draw(sf::RenderWindow *window) {
while (!quit) {
window->draw(sprite);
window->display();
}
}
int main() {
sf::Texture texture;
texture.loadFromFile("poivron.png");
sprite = sf::Sprite(texture);
sf::RenderWindow window(sf::VideoMode(640, 360), "test");
window.setFramerateLimit(300);
std::thread rendering(draw, &window);
sf::Event event;
while (true) {
if (window.waitEvent(event)) {
if (event.type == sf::Event::Closed)
break;
}
else
break;
}
quit = true;
rendering.join();
}
Am I doing something wrong? I guess I should have made a post in the help forum first, sorry about that.
Edit, to clarify my point:Synchronising the threads to prevent concurrent access like this:
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
#include <memory>
#include <SFML/Graphics.hpp>
std::mutex m;
sf::Sprite sprite;
bool quit = false;
void draw(sf::RenderWindow *window) {
unsigned i = 0;
while(!quit) {
sprite.setPosition((i % 10) * 30, (i / 10) * 30);
i++;
if (i > 100) {
i = 0;
}
m.lock();
std::cout << "Rendering." << std::endl;
window->clear();
window->draw(sprite);
window->display();
m.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main() {
sf::Texture texture;
texture.loadFromFile("poivron.png");
sprite = sf::Sprite(texture);
sf::RenderWindow window(sf::VideoMode(640, 360), "test");
window.setFramerateLimit(300);
std::thread rendering(draw, &window);
window.setActive(false);
sf::Event event;
while (true) {
m.lock();
std::cout << "Waiting for an event…" << std::endl;
bool ok = window.waitEvent(event);
std::cout << "Event received." << std::endl;
m.unlock();
if (ok) {
if (event.type == sf::Event::Closed)
break;
}
else
break;
}
quit = true;
rendering.join();
}
effectively gets rid of the errors and crashes, but then the rendering is halted while waiting for an event (see attachment).