summaryrefslogtreecommitdiff
path: root/src/client/requestbroker/ImageRequest.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2013-03-14 11:30:24 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2013-03-14 11:30:24 (GMT)
commit9479b7f3300658156c467980c28d3436a728bc0c (patch)
tree631a10f9fe9628d1250109f6b9c643d008591d39 /src/client/requestbroker/ImageRequest.cpp
parent7a055a9d90ea3464bbdc314df423e2aa768ce2be (diff)
downloadpowder-9479b7f3300658156c467980c28d3436a728bc0c.zip
powder-9479b7f3300658156c467980c28d3436a728bc0c.tar.gz
Move requestbroker into new folder, make request process function a method of Request
Diffstat (limited to 'src/client/requestbroker/ImageRequest.cpp')
-rw-r--r--src/client/requestbroker/ImageRequest.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/client/requestbroker/ImageRequest.cpp b/src/client/requestbroker/ImageRequest.cpp
new file mode 100644
index 0000000..6e4f66c
--- /dev/null
+++ b/src/client/requestbroker/ImageRequest.cpp
@@ -0,0 +1,147 @@
+#include <iostream>
+#include <typeinfo>
+#include "ImageRequest.h"
+#include "graphics/Graphics.h"
+#include "client/HTTP.h"
+
+ImageRequest::ImageRequest(std::string url, int width, int height, ListenerHandle listener):
+ Request(Image, listener)
+{
+ URL = url;
+ HTTPContext = NULL;
+ Width = width;
+ Height = height;
+}
+
+ImageRequest::~ImageRequest()
+{
+
+}
+
+RequestBroker::ProcessResponse ImageRequest::Process(RequestBroker & rb)
+{
+ VideoBuffer * image = NULL;
+
+ //Have a look at the thumbnail cache
+ for(std::deque<std::pair<std::string, VideoBuffer*> >::iterator iter = rb.imageCache.begin(), end = rb.imageCache.end(); iter != end; ++iter)
+ {
+ if((*iter).first == URL)
+ {
+ image = (*iter).second;
+#ifdef DEBUG
+ std::cout << typeid(*this).name() << " " << URL << " found in cache" << std::endl;
+#endif
+ }
+ }
+
+ if(!image)
+ {
+ if(HTTPContext)
+ {
+ if(http_async_req_status(HTTPContext))
+ {
+ pixel * imageData;
+ char * data;
+ int status, data_size, imgw, imgh;
+ data = http_async_req_stop(HTTPContext, &status, &data_size);
+
+ if (status == 200 && data)
+ {
+ imageData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh);
+ free(data);
+
+ if(imageData)
+ {
+ //Success!
+ image = new VideoBuffer(imageData, imgw, imgh);
+ free(imageData);
+ }
+ else
+ {
+ //Error thumbnail
+ image = new VideoBuffer(32, 32);
+ image->SetCharacter(14, 14, 'x', 255, 255, 255, 255);
+ }
+
+ if(rb.imageCache.size() >= THUMB_CACHE_SIZE)
+ {
+ //Remove unnecessary from thumbnail cache
+ delete rb.imageCache.front().second;
+ rb.imageCache.pop_front();
+ }
+ rb.imageCache.push_back(std::pair<std::string, VideoBuffer*>(URL, image));
+ }
+ else
+ {
+ #ifdef DEBUG
+ std::cout << typeid(*this).name() << " Request for " << URL << " failed with status " << status << std::endl;
+ #endif
+ if(data)
+ free(data);
+
+ return RequestBroker::Failed;
+ }
+ }
+ }
+ else
+ {
+ //Check for ongoing requests
+ for(std::vector<Request*>::iterator iter = rb.activeRequests.begin(), end = rb.activeRequests.end(); iter != end; ++iter)
+ {
+ if((*iter)->Type != Request::Image)
+ continue;
+ ImageRequest * otherReq = (ImageRequest*)(*iter);
+ if(otherReq->URL == URL && otherReq != this)
+ {
+ #ifdef DEBUG
+ std::cout << typeid(*this).name() << " Request for " << URL << " found, appending." << std::endl;
+ #endif
+ //Add the current listener to the item already being requested
+ (*iter)->Children.push_back(this);
+ return RequestBroker::Duplicate;
+ }
+ }
+
+ //If it's not already being requested, request it
+ #ifdef DEBUG
+ std::cout << typeid(*this).name() << " Creating new request for " << URL << std::endl;
+ #endif
+ HTTPContext = http_async_req_start(NULL, (char *)URL.c_str(), NULL, 0, 0);
+ RequestTime = time(NULL);
+ }
+ }
+
+ if(image)
+ {
+
+ //Create a copy, to seperate from the cache
+ VideoBuffer * myVB = new VideoBuffer(*image);
+ myVB->Resize(Width, Height, true);
+ ResultObject = (void*)myVB;
+ rb.requestComplete(this);
+ for(std::vector<Request*>::iterator childIter = Children.begin(), childEnd = Children.end(); childIter != childEnd; ++childIter)
+ {
+ if((*childIter)->Type == Request::Image)
+ {
+ ImageRequest * childReq = (ImageRequest*)*childIter;
+ VideoBuffer * tempImage = new VideoBuffer(*image);
+ tempImage->Resize(childReq->Width, childReq->Height, true);
+ childReq->ResultObject = (void*)tempImage;
+ rb.requestComplete(*childIter);
+ }
+ }
+ return RequestBroker::Finished;
+ }
+
+ return RequestBroker::OK;
+}
+
+void ImageRequest::Cleanup()
+{
+ Request::Cleanup();
+ if(ResultObject)
+ {
+ delete ((VideoBuffer*)ResultObject);
+ ResultObject = NULL;
+ }
+} \ No newline at end of file