diff options
| author | Tim Redfern <tim@getdrop.com> | 2017-09-13 13:36:26 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@getdrop.com> | 2017-09-13 13:36:26 +0100 |
| commit | b4972d6ba659cec3759fd87d6f0489a040e0fbf6 (patch) | |
| tree | 8646589d0db594c69eb5c6d6d86f6d05d8e3043f /gui/src/threadedChainImageLoader.cpp | |
| parent | 304c8f22dfb4e068685b2a1e1023129a7cd12eb4 (diff) | |
chainImageSet and threadedChainImageLoader
Diffstat (limited to 'gui/src/threadedChainImageLoader.cpp')
| -rw-r--r-- | gui/src/threadedChainImageLoader.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/gui/src/threadedChainImageLoader.cpp b/gui/src/threadedChainImageLoader.cpp new file mode 100644 index 0000000..ba3dd26 --- /dev/null +++ b/gui/src/threadedChainImageLoader.cpp @@ -0,0 +1,99 @@ +#include "threadedChainImageLoader.h" +#include <sstream> + +threadedChainImageLoader::threadedChainImageLoader(){ + nextID = 0; + ofAddListener(ofEvents().update, this, &threadedChainImageLoader::update); + ofAddListener(ofURLResponseEvent(),this,&threadedChainImageLoader::urlResponse); + + startThread(); + lastUpdate = 0; +} + +threadedChainImageLoader::~threadedChainImageLoader(){ + images_to_load_from_disk.close(); + images_to_update.close(); + waitForThread(true); + ofRemoveListener(ofEvents().update, this, &threadedChainImageLoader::update); + ofRemoveListener(ofURLResponseEvent(),this,&threadedChainImageLoader::urlResponse); +} + +// Load an image from disk. +//-------------------------------------------------------------- +void threadedChainImageLoader::loadFromDisk(chainImage& image, string filename) { + nextID++; + chainImageLoaderEntry entry(image); + entry.filename = filename; + entry.image->setUseTexture(false); + entry.name = filename; + + images_to_load_from_disk.send(entry); +} + + +// Load an url asynchronously from an url. +//-------------------------------------------------------------- +void threadedChainImageLoader::loadFromURL(chainImage& image, string url) { + nextID++; + chainImageLoaderEntry entry(image); + entry.url = url; + entry.image->setUseTexture(false); + entry.name = "image" + ofToString(nextID); + images_async_loading[entry.name] = entry; + ofLoadURLAsync(entry.url, entry.name); +} + + +// Reads from the queue and loads new images. +//-------------------------------------------------------------- +void threadedChainImageLoader::threadedFunction() { + setThreadName("threadedChainImageLoader " + ofToString(thread.get_id())); + chainImageLoaderEntry entry; + while( images_to_load_from_disk.receive(entry) ) { + if(entry.image->load(entry.filename) ) { + images_to_update.send(entry); + }else{ + ofLogError("threadedChainImageLoader") << "couldn't load file: \"" << entry.filename << "\""; + } + } + ofLogVerbose("threadedChainImageLoader") << "finishing thread on closed queue"; +} + + +// When we receive an url response this method is called; +// The loaded image is removed from the async_queue and added to the +// update queue. The update queue is used to update the texture. +//-------------------------------------------------------------- +void threadedChainImageLoader::urlResponse(ofHttpResponse & response) { + // this happens in the update thread so no need to lock to access + // images_async_loading + entry_iterator it = images_async_loading.find(response.request.name); + if(response.status == 200) { + if(it != images_async_loading.end()) { + it->second.image->load(response.data); + images_to_update.send(it->second); + } + }else{ + // log error. + ofLogError("threadedChainImageLoader") << "couldn't load url, response status: " << response.status; + ofRemoveURLRequest(response.request.getID()); + } + + // remove the entry from the queue + if(it != images_async_loading.end()) { + images_async_loading.erase(it); + } +} + + +// Check the update queue and update the texture +//-------------------------------------------------------------- +void threadedChainImageLoader::update(ofEventArgs & a){ + // Load 1 image per update so we don't block the gl thread for too long + chainImageLoaderEntry entry; + if (images_to_update.tryReceive(entry)) { + entry.image->setUseTexture(true); + entry.image->update(); + } +} + |
