summaryrefslogtreecommitdiff
path: root/src/client
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
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')
-rw-r--r--src/client/Client.cpp2
-rw-r--r--src/client/requestbroker/ImageRequest.cpp147
-rw-r--r--src/client/requestbroker/ImageRequest.h14
-rw-r--r--src/client/requestbroker/RequestBroker.cpp (renamed from src/client/RequestBroker.cpp)188
-rw-r--r--src/client/requestbroker/RequestBroker.h (renamed from src/client/RequestBroker.h)117
-rw-r--r--src/client/requestbroker/RequestListener.h (renamed from src/client/RequestListener.h)0
-rw-r--r--src/client/requestbroker/ThumbRenderRequest.cpp56
-rw-r--r--src/client/requestbroker/ThumbRenderRequest.h16
8 files changed, 286 insertions, 254 deletions
diff --git a/src/client/Client.cpp b/src/client/Client.cpp
index 6267d91..ecb6466 100644
--- a/src/client/Client.cpp
+++ b/src/client/Client.cpp
@@ -42,7 +42,7 @@
#include "search/Thumbnail.h"
#include "preview/Comment.h"
#include "ClientListener.h"
-#include "RequestBroker.h"
+#include "requestbroker/RequestBroker.h"
#include "cajun/reader.h"
#include "cajun/writer.h"
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
diff --git a/src/client/requestbroker/ImageRequest.h b/src/client/requestbroker/ImageRequest.h
new file mode 100644
index 0000000..9a2cf34
--- /dev/null
+++ b/src/client/requestbroker/ImageRequest.h
@@ -0,0 +1,14 @@
+#include "RequestBroker.h"
+
+class ImageRequest: public RequestBroker::Request
+{
+public:
+ int Width, Height;
+ std::string URL;
+ int RequestTime;
+ void * HTTPContext;
+ ImageRequest(std::string url, int width, int height, ListenerHandle listener);
+ virtual RequestBroker::ProcessResponse Process(RequestBroker & rb);
+ virtual ~ImageRequest();
+ virtual void Cleanup();
+}; \ No newline at end of file
diff --git a/src/client/RequestBroker.cpp b/src/client/requestbroker/RequestBroker.cpp
index c3b7fdf..62e5fd7 100644
--- a/src/client/RequestBroker.cpp
+++ b/src/client/requestbroker/RequestBroker.cpp
@@ -1,14 +1,14 @@
#include <algorithm>
#include <iostream>
#include <typeinfo>
+#include <sstream>
#include <time.h>
#include "RequestBroker.h"
#include "RequestListener.h"
-#include "Client.h"
-#include "HTTP.h"
-#include "GameSave.h"
-#include "search/Thumbnail.h"
-#include "simulation/SaveRenderer.h"
+#include "ThumbRenderRequest.h"
+#include "ImageRequest.h"
+#include "client/Client.h"
+#include "client/GameSave.h"
//Asynchronous Thumbnail render & request processing
@@ -139,6 +139,8 @@ void RequestBroker::FlushThumbQueue()
{
if(CheckRequestListener(completeQueue.front()->Listener))
{
+ std::cout << typeid(*this).name() << " Calling listener: " << completeQueue.front()->Listener.second << std::endl;
+ std::cout.flush();
completeQueue.front()->Listener.second->OnResponseReady(completeQueue.front()->ResultObject);
}
else
@@ -190,15 +192,7 @@ void RequestBroker::thumbnailQueueProcessTH()
{
ProcessResponse resultStatus = OK;
Request * r = *req;
- switch(r->Type)
- {
- case Request::ThumbnailRender:
- resultStatus = processThumbnailRender(*(ThumbRenderRequest*)r);
- break;
- case Request::Image:
- resultStatus = processImage(*(ImageRequest*)r);
- break;
- }
+ resultStatus = r->Process(*this);
if(resultStatus == Duplicate || resultStatus == Failed || resultStatus == Finished)
{
req = activeRequests.erase(req);
@@ -233,147 +227,6 @@ void RequestBroker::thumbnailQueueProcessTH()
pthread_mutex_unlock(&runningMutex);
}
-RequestBroker::ProcessResponse RequestBroker::processThumbnailRender(ThumbRenderRequest & request)
-{
-#ifdef DEBUG
- std::cout << typeid(*this).name() << " Processing render request" << std::endl;
-#endif
- Thumbnail * thumbnail = SaveRenderer::Ref().Render(request.Save, request.Decorations, request.Fire);
- delete request.Save;
- request.Save = NULL;
-
- if(thumbnail)
- {
- thumbnail->Resize(request.Width, request.Height);
- request.ResultObject = (void*)thumbnail;
- requestComplete(&request);
- return Finished;
- }
- else
- {
- return Failed;
- }
- return Failed;
-}
-
-RequestBroker::ProcessResponse RequestBroker::processImage(ImageRequest & request)
-{
- VideoBuffer * image = NULL;
-
- //Have a look at the thumbnail cache
- for(std::deque<std::pair<std::string, VideoBuffer*> >::iterator iter = imageCache.begin(), end = imageCache.end(); iter != end; ++iter)
- {
- if((*iter).first == request.URL)
- {
- image = (*iter).second;
-#ifdef DEBUG
- std::cout << typeid(*this).name() << " " << request.URL << " found in cache" << std::endl;
-#endif
- }
- }
-
- if(!image)
- {
- if(request.HTTPContext)
- {
- if(http_async_req_status(request.HTTPContext))
- {
- pixel * imageData;
- char * data;
- int status, data_size, imgw, imgh;
- data = http_async_req_stop(request.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(imageCache.size() >= THUMB_CACHE_SIZE)
- {
- //Remove unnecessary from thumbnail cache
- delete imageCache.front().second;
- imageCache.pop_front();
- }
- imageCache.push_back(std::pair<std::string, VideoBuffer*>(request.URL, image));
- }
- else
- {
- #ifdef DEBUG
- std::cout << typeid(*this).name() << " Request for " << request.URL << " failed with status " << status << std::endl;
- #endif
- if(data)
- free(data);
-
- return Failed;
- }
- }
- }
- else
- {
- //Check for ongoing requests
- for(std::vector<Request*>::iterator iter = activeRequests.begin(), end = activeRequests.end(); iter != end; ++iter)
- {
- if((*iter)->Type != Request::Image)
- continue;
- ImageRequest * otherReq = (ImageRequest*)(*iter);
- if(otherReq->URL == request.URL && otherReq != &request)
- {
- #ifdef DEBUG
- std::cout << typeid(*this).name() << " Request for " << request.URL << " found, appending." << std::endl;
- #endif
- //Add the current listener to the item already being requested
- (*iter)->Children.push_back(&request);
- return Duplicate;
- }
- }
-
- //If it's not already being requested, request it
- #ifdef DEBUG
- std::cout << typeid(*this).name() << " Creating new request for " << request.URL << std::endl;
- #endif
- request.HTTPContext = http_async_req_start(NULL, (char *)request.URL.c_str(), NULL, 0, 0);
- request.RequestTime = time(NULL);
- }
- }
-
- if(image)
- {
-
- //Create a copy, to seperate from the cache
- VideoBuffer * myVB = new VideoBuffer(*image);
- myVB->Resize(request.Width, request.Height, true);
- request.ResultObject = (void*)myVB;
- requestComplete(&request);
- for(std::vector<Request*>::iterator childIter = request.Children.begin(), childEnd = request.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;
- requestComplete(*childIter);
- }
- }
- return Finished;
- }
-
- return OK;
-}
-
void RequestBroker::requestComplete(Request * completedRequest)
{
pthread_mutex_lock(&completeQueueMutex);
@@ -419,4 +272,29 @@ void RequestBroker::DetachRequestListener(RequestListener * tListener)
}
pthread_mutex_unlock(&listenersMutex);
+}
+
+RequestBroker::Request::Request(RequestType type, ListenerHandle listener)
+{
+ Type = type;
+ Listener = listener;
+ ResultObject = NULL;
+}
+RequestBroker::Request::~Request()
+{
+ std::vector<Request*>::iterator iter = Children.begin();
+ while(iter != Children.end())
+ {
+ delete (*iter);
+ iter++;
+ }
+}
+void RequestBroker::Request::Cleanup()
+{
+ std::vector<Request*>::iterator iter = Children.begin();
+ while(iter != Children.end())
+ {
+ (*iter)->Cleanup();
+ iter++;
+ }
} \ No newline at end of file
diff --git a/src/client/RequestBroker.h b/src/client/requestbroker/RequestBroker.h
index 9244e91..003ac37 100644
--- a/src/client/RequestBroker.h
+++ b/src/client/requestbroker/RequestBroker.h
@@ -3,6 +3,7 @@
#include <list>
#include <utility>
#include <deque>
+#include <string>
#include <pthread.h>
#undef GetUserName //God dammit microsoft!
@@ -14,103 +15,12 @@ class RequestListener;
typedef std::pair<int, RequestListener*> ListenerHandle;
class RequestBroker: public Singleton<RequestBroker>
{
+ friend class ImageRequest;
+ friend class ThumbRenderRequest;
+public:
+ class Request;
private:
- enum ProcessResponse { Finished, OK, Canceled, Failed, Duplicate };
-
- class Request
- {
- public:
- enum RequestType { ThumbnailRender, Image };
- RequestType Type;
- void * ResultObject;
- ListenerHandle Listener;
- std::vector<Request*> Children;
- Request(RequestType type, ListenerHandle listener)
- {
- Type = type;
- Listener = listener;
- ResultObject = NULL;
- }
- virtual ~Request()
- {
- std::vector<Request*>::iterator iter = Children.begin();
- while(iter != Children.end())
- {
- delete (*iter);
- iter++;
- }
- }
- virtual void Cleanup()
- {
- std::vector<Request*>::iterator iter = Children.begin();
- while(iter != Children.end())
- {
- (*iter)->Cleanup();
- iter++;
- }
- }
- };
-
- class ThumbRenderRequest: public Request
- {
- public:
- int Width, Height;
- bool Decorations;
- bool Fire;
- GameSave * Save;
- ThumbRenderRequest(GameSave * save, bool decorations, bool fire, int width, int height, ListenerHandle listener):
- Request(ThumbnailRender, listener)
- {
- Save = save;
- Width = width;
- Height = height;
- Decorations = decorations;
- Fire = fire;
- }
- virtual ~ThumbRenderRequest()
- {
- if(Save)
- delete Save;
- }
- virtual void Cleanup()
- {
- Request::Cleanup();
- if(ResultObject)
- {
- delete ((VideoBuffer*)ResultObject);
- ResultObject = NULL;
- }
- }
- };
-
- class ImageRequest: public Request
- {
- public:
- int Width, Height;
- std::string URL;
- int RequestTime;
- void * HTTPContext;
- ImageRequest(std::string url, int width, int height, ListenerHandle listener):
- Request(Image, listener)
- {
- URL = url;
- HTTPContext = NULL;
- Width = width;
- Height = height;
- }
- virtual ~ImageRequest() {}
- virtual void Cleanup()
- {
- Request::Cleanup();
- if(ResultObject)
- {
- delete ((VideoBuffer*)ResultObject);
- ResultObject = NULL;
- }
- }
- };
-
pthread_mutex_t listenersMutex;
pthread_mutex_t runningMutex;
pthread_mutex_t requestQueueMutex;
@@ -131,9 +41,6 @@ private:
void thumbnailQueueProcessTH();
void assureRunning();
- ProcessResponse processThumbnailRender(ThumbRenderRequest & request);
- ProcessResponse processImage(ImageRequest & request);
-
void requestComplete(Request * completedRequest);
public:
@@ -152,4 +59,18 @@ public:
bool CheckRequestListener(ListenerHandle handle);
ListenerHandle AttachRequestListener(RequestListener * tListener);
void DetachRequestListener(RequestListener * tListener);
+ enum ProcessResponse { Finished, OK, Canceled, Failed, Duplicate };
+ class Request
+ {
+ public:
+ enum RequestType { ThumbnailRender, Image };
+ RequestType Type;
+ void * ResultObject;
+ ListenerHandle Listener;
+ std::vector<Request*> Children;
+ Request(RequestType type, ListenerHandle listener);
+ virtual ProcessResponse Process(RequestBroker & rb) { return Failed; }
+ virtual ~Request();
+ virtual void Cleanup();
+ };
}; \ No newline at end of file
diff --git a/src/client/RequestListener.h b/src/client/requestbroker/RequestListener.h
index 1f53b2a..1f53b2a 100644
--- a/src/client/RequestListener.h
+++ b/src/client/requestbroker/RequestListener.h
diff --git a/src/client/requestbroker/ThumbRenderRequest.cpp b/src/client/requestbroker/ThumbRenderRequest.cpp
new file mode 100644
index 0000000..e239883
--- /dev/null
+++ b/src/client/requestbroker/ThumbRenderRequest.cpp
@@ -0,0 +1,56 @@
+#include <typeinfo>
+#include "ThumbRenderRequest.h"
+#include "client/GameSave.h"
+#include "graphics/Graphics.h"
+#include "search/Thumbnail.h"
+#include "simulation/SaveRenderer.h"
+
+ThumbRenderRequest::ThumbRenderRequest(GameSave * save, bool decorations, bool fire, int width, int height, ListenerHandle listener):
+ RequestBroker::Request(ThumbnailRender, listener)
+{
+ Save = save;
+ Width = width;
+ Height = height;
+ Decorations = decorations;
+ Fire = fire;
+}
+
+RequestBroker::ProcessResponse ThumbRenderRequest::Process(RequestBroker & rb)
+{
+#ifdef DEBUG
+ std::cout << typeid(*this).name() << " Processing render request" << std::endl;
+#endif
+ Thumbnail * thumbnail = SaveRenderer::Ref().Render(Save, Decorations, Fire);
+
+ delete Save;
+ Save = NULL;
+
+ if(thumbnail)
+ {
+ thumbnail->Resize(Width, Height);
+ ResultObject = (void*)thumbnail;
+ rb.requestComplete((Request*)this);
+ return RequestBroker::Finished;
+ }
+ else
+ {
+ return RequestBroker::Failed;
+ }
+ return RequestBroker::Failed;
+}
+
+ThumbRenderRequest::~ThumbRenderRequest()
+{
+ if(Save)
+ delete Save;
+}
+
+void ThumbRenderRequest::Cleanup()
+{
+ Request::Cleanup();
+ if(ResultObject)
+ {
+ delete ((VideoBuffer*)ResultObject);
+ ResultObject = NULL;
+ }
+} \ No newline at end of file
diff --git a/src/client/requestbroker/ThumbRenderRequest.h b/src/client/requestbroker/ThumbRenderRequest.h
new file mode 100644
index 0000000..97b3982
--- /dev/null
+++ b/src/client/requestbroker/ThumbRenderRequest.h
@@ -0,0 +1,16 @@
+#include "RequestBroker.h"
+
+class GameSave;
+class ThumbRenderRequest: public RequestBroker::Request
+{
+public:
+ int Width, Height;
+ bool Decorations;
+ bool Fire;
+ GameSave * Save;
+ ThumbRenderRequest(GameSave * save, bool decorations, bool fire, int width, int height, ListenerHandle listener);
+ virtual RequestBroker::ProcessResponse Process(RequestBroker & rb);
+ virtual ~ThumbRenderRequest();
+ virtual void Cleanup();
+};
+