1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#pragma once
#include <queue>
#include <list>
#include <utility>
#include <deque>
#include <pthread.h>
#undef GetUserName //God dammit microsoft!
#include "Singleton.h"
class GameSave;
class VideoBuffer;
class RequestListener;
typedef std::pair<int, RequestListener*> ListenerHandle;
class RequestBroker: public Singleton<RequestBroker>
{
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;
pthread_mutex_t completeQueueMutex;
pthread_t thumbnailQueueThread;
bool thumbnailQueueRunning;
std::vector<ListenerHandle> validListeners;
std::deque<std::pair<std::string, VideoBuffer*> > imageCache;
std::queue<Request*> completeQueue;
std::vector<Request*> requestQueue;
std::vector<Request*> activeRequests;
static void * thumbnailQueueProcessHelper(void * ref);
void thumbnailQueueProcessTH();
void assureRunning();
ProcessResponse processThumbnailRender(ThumbRenderRequest & request);
ProcessResponse processImage(ImageRequest & request);
void requestComplete(Request * completedRequest);
public:
RequestBroker();
virtual ~RequestBroker();
void Shutdown();
void FlushThumbQueue();
void RetrieveImage(std::string imageUrl, int width, int height, RequestListener * tListener);
void RenderThumbnail(GameSave * gameSave, bool decorations, bool fire, int width, int height, RequestListener * tListener);
void RenderThumbnail(GameSave * gameSave, int width, int height, RequestListener * tListener);
void RetrieveThumbnail(int saveID, int saveDate, int width, int height, RequestListener * tListener);
void RetrieveThumbnail(int saveID, int width, int height, RequestListener * tListener);
void RetrieveAvatar(std::string username, int width, int height, RequestListener * tListener);
bool CheckRequestListener(ListenerHandle handle);
ListenerHandle AttachRequestListener(RequestListener * tListener);
void DetachRequestListener(RequestListener * tListener);
};
|