summaryrefslogtreecommitdiff
path: root/gui/src/threadedChainImageLoader.cpp
diff options
context:
space:
mode:
authorTim Redfern <tim@getdrop.com>2017-09-13 13:36:26 +0100
committerTim Redfern <tim@getdrop.com>2017-09-13 13:36:26 +0100
commitb4972d6ba659cec3759fd87d6f0489a040e0fbf6 (patch)
tree8646589d0db594c69eb5c6d6d86f6d05d8e3043f /gui/src/threadedChainImageLoader.cpp
parent304c8f22dfb4e068685b2a1e1023129a7cd12eb4 (diff)
chainImageSet and threadedChainImageLoader
Diffstat (limited to 'gui/src/threadedChainImageLoader.cpp')
-rw-r--r--gui/src/threadedChainImageLoader.cpp99
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();
+ }
+}
+