1
Graphics / Re: sf::Texture::~Texture() Crashes App On Exit
« on: November 17, 2016, 12:00:18 am »
Some code to help with how to use callbacks in a thread-safe manner:
typedef std::function<void(const std::string &data, bool success)> DownloadCallback;
struct DownloadItem {
std::string data;
DownloadCallback callback;
bool success;
};
class Downloader {
public:
void downloadItem(const std::string &itemUrl, const DownloadCallback &itemCallback) {
_mutex.lock();
// save itemUrl and itemCallback
_mutex.unlock();
// items get processed in background thread
}
void update() {
DownloadItem item;
bool gotItem = false;
_mutex.lock();
if (!_completedList.empty()) {
item = _completedList[0];
gotItem = true;
_completedList.erase(_completedList.begin());
}
_mutex.unlock();
if (gotItem) {
item.callback(item.data, item.success);
}
}
private:
// could use a queue instead of vector
std::vector<DownloadItem> _completedList;
std::mutex _mutex;
};
// UI thread
MyApp::run() {
downloader.downloadItem("http://mysite.com/image.png", [&](const std::string &data, bool success) {
if (success) {
texture.loadFromMemory(data.c_str(), data.size());
} else {
sf::err() << "Failed to download image.\n";
}
});
while (window.isOpen()) {
// poll the downloader for completions
downloader.update();
// draw stuff
}
}
struct DownloadItem {
std::string data;
DownloadCallback callback;
bool success;
};
class Downloader {
public:
void downloadItem(const std::string &itemUrl, const DownloadCallback &itemCallback) {
_mutex.lock();
// save itemUrl and itemCallback
_mutex.unlock();
// items get processed in background thread
}
void update() {
DownloadItem item;
bool gotItem = false;
_mutex.lock();
if (!_completedList.empty()) {
item = _completedList[0];
gotItem = true;
_completedList.erase(_completedList.begin());
}
_mutex.unlock();
if (gotItem) {
item.callback(item.data, item.success);
}
}
private:
// could use a queue instead of vector
std::vector<DownloadItem> _completedList;
std::mutex _mutex;
};
// UI thread
MyApp::run() {
downloader.downloadItem("http://mysite.com/image.png", [&](const std::string &data, bool success) {
if (success) {
texture.loadFromMemory(data.c_str(), data.size());
} else {
sf::err() << "Failed to download image.\n";
}
});
while (window.isOpen()) {
// poll the downloader for completions
downloader.update();
// draw stuff
}
}