Turn RequestBroker::RetrieveThumbnail into a request derived from Download

Also start moving RenderThumbnail out of RequestBroker into its own Task. Add mutex to SaveRenderer to guard Render().
This commit is contained in:
Tamás Bálint Misius 2019-03-07 02:08:34 +01:00 committed by jacob1
parent 53f2018c7e
commit 3a76a3a514
11 changed files with 201 additions and 44 deletions

View File

@ -4,8 +4,6 @@
#include "ImageRequest.h" #include "ImageRequest.h"
#include "common/String.h" #include "common/String.h"
#include <memory>
namespace http namespace http
{ {
class AvatarRequest : public ImageRequest class AvatarRequest : public ImageRequest

View File

@ -940,6 +940,14 @@ void Client::Shutdown()
Client::~Client() Client::~Client()
{ {
if (versionCheckRequest)
{
versionCheckRequest->Cancel();
}
if (alternateVersionCheckRequest)
{
alternateVersionCheckRequest->Cancel();
}
} }

View File

@ -0,0 +1,54 @@
#include "ThumbnailRenderer.h"
#include <cmath>
#include "graphics/Graphics.h"
#include "simulation/SaveRenderer.h"
#include "client/GameSave.h"
ThumbnailRendererTask::ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale, bool decorations, bool fire) :
Save(new GameSave(*save)),
Width(width),
Height(height),
Decorations(decorations),
Fire(fire),
AutoRescale(autoRescale)
{
}
ThumbnailRendererTask::~ThumbnailRendererTask()
{
}
bool ThumbnailRendererTask::doWork()
{
thumbnail = std::unique_ptr<VideoBuffer>(SaveRenderer::Ref().Render(Save.get(), Decorations, Fire));
if (thumbnail)
{
if (AutoRescale)
{
int scaleX = (int)std::ceil((float)thumbnail->Width / Width);
int scaleY = (int)std::ceil((float)thumbnail->Height / Height);
int scale = scaleX > scaleY ? scaleX : scaleY;
int newWidth = thumbnail->Width / scale, newHeight = thumbnail->Height / scale;
thumbnail->Resize(newWidth, newHeight, true);
Width = newWidth;
Height = newHeight;
}
else
{
thumbnail->Resize(Width, Height, true);
}
return true;
}
else
{
return false;
}
}
std::unique_ptr<VideoBuffer> ThumbnailRendererTask::GetThumbnail()
{
return std::move(thumbnail);
}

View File

@ -0,0 +1,28 @@
#ifndef THUMBNAILRENDERER_H
#define THUMBNAILRENDERER_H
#include "tasks/Task.h"
#include <memory>
class GameSave;
class VideoBuffer;
class ThumbnailRendererTask : public Task
{
std::unique_ptr<GameSave> Save;
int Width, Height;
bool Decorations;
bool Fire;
bool AutoRescale;
std::unique_ptr<VideoBuffer> thumbnail;
public:
ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale = false, bool decorations = true, bool fire = true);
virtual ~ThumbnailRendererTask();
virtual bool doWork() override;
std::unique_ptr<VideoBuffer> GetThumbnail();
};
#endif // THUMBNAILRENDERER_H

View File

@ -0,0 +1,15 @@
#include "ThumbnailRequest.h"
#include "Config.h"
namespace http
{
ThumbnailRequest::ThumbnailRequest(int saveID, int saveDate, int width, int height) :
ImageRequest((
saveDate
? ByteString::Build("http://" STATICSERVER "/", saveID, "_", saveDate, "_small.pti")
: ByteString::Build("http://" STATICSERVER "/", saveID, "_small.pti")
), width, height)
{
}
}

View File

@ -0,0 +1,17 @@
#ifndef THUMBNAILREQUEST2_H
#define THUMBNAILREQUEST2_H
#include "ImageRequest.h"
#include "common/String.h"
namespace http
{
class ThumbnailRequest : public ImageRequest
{
public:
ThumbnailRequest(int saveID, int saveDate, int width, int height);
};
}
#endif // THUMBNAILREQUEST2_H

View File

@ -6,7 +6,6 @@
#include "Component.h" #include "Component.h"
#include "graphics/Graphics.h" #include "graphics/Graphics.h"
#include "gui/interface/Colour.h" #include "gui/interface/Colour.h"
#include "client/requestbroker/RequestListener.h"
#include <memory> #include <memory>

View File

@ -8,9 +8,11 @@
#include "SaveButton.h" #include "SaveButton.h"
#include "client/Client.h" #include "client/Client.h"
#include "client/SaveInfo.h" #include "client/SaveInfo.h"
#include "client/ThumbnailRequest.h"
#include "client/ThumbnailRenderer.h"
#include "graphics/Graphics.h" #include "graphics/Graphics.h"
#include "simulation/SaveRenderer.h" #include "simulation/SaveRenderer.h"
#include "client/requestbroker/RequestBroker.h" #include "client/GameSave.h"
namespace ui { namespace ui {
@ -18,11 +20,11 @@ SaveButton::SaveButton(Point position, Point size, SaveInfo * save):
Component(position, size), Component(position, size),
file(NULL), file(NULL),
save(save), save(save),
thumbnail(NULL), triedThumbnail(false),
waitingForThumb(false),
isMouseInsideAuthor(false), isMouseInsideAuthor(false),
isMouseInsideHistory(false), isMouseInsideHistory(false),
showVotes(false), showVotes(false),
thumbnailRequest(nullptr),
isButtonDown(false), isButtonDown(false),
isMouseInside(false), isMouseInside(false),
selected(false), selected(false),
@ -91,12 +93,12 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
Component(position, size), Component(position, size),
file(file), file(file),
save(NULL), save(NULL),
thumbnail(NULL),
wantsDraw(false), wantsDraw(false),
waitingForThumb(false), triedThumbnail(false),
isMouseInsideAuthor(false), isMouseInsideAuthor(false),
isMouseInsideHistory(false), isMouseInsideHistory(false),
showVotes(false), showVotes(false),
thumbnailRequest(nullptr),
isButtonDown(false), isButtonDown(false),
isMouseInside(false), isMouseInside(false),
selected(false), selected(false),
@ -117,30 +119,21 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
SaveButton::~SaveButton() SaveButton::~SaveButton()
{ {
RequestBroker::Ref().DetachRequestListener(this); if (thumbnailRequest)
{
thumbnailRequest->Cancel();
}
delete thumbnail;
delete actionCallback; delete actionCallback;
delete save; delete save;
delete file; delete file;
} }
void SaveButton::OnResponseReady(void * imagePtr, int identifier)
{
VideoBuffer * image = (VideoBuffer*)imagePtr;
if (image)
{
delete thumbnail;
thumbnail = image;
waitingForThumb = false;
if (file)
thumbSize = ui::Point(thumbnail->Width, thumbnail->Height);
}
}
void SaveButton::Tick(float dt) void SaveButton::Tick(float dt)
{ {
if(!thumbnail && !waitingForThumb) if (!thumbnail)
{
if (!triedThumbnail)
{ {
float scaleFactor = (Size.Y-25)/((float)YRES); float scaleFactor = (Size.Y-25)/((float)YRES);
ui::Point thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor); ui::Point thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor);
@ -148,19 +141,44 @@ void SaveButton::Tick(float dt)
{ {
if(save->GetGameSave()) if(save->GetGameSave())
{ {
waitingForThumb = true; thumbnailRenderer = std::unique_ptr<ThumbnailRendererTask>(new ThumbnailRendererTask(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y));
RequestBroker::Ref().RenderThumbnail(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, this); thumbnailRenderer->Start();
triedThumbnail = true;
} }
else if (save->GetID()) else if (save->GetID())
{ {
waitingForThumb = true; thumbnailRequest = new http::ThumbnailRequest(save->GetID(), save->GetVersion(), thumbBoxSize.X, thumbBoxSize.Y);
RequestBroker::Ref().RetrieveThumbnail(save->GetID(), save->GetVersion(), thumbBoxSize.X, thumbBoxSize.Y, this); thumbnailRequest->Start();
triedThumbnail = true;
} }
} }
else if (file && file->GetGameSave()) else if (file && file->GetGameSave())
{ {
waitingForThumb = true; thumbnailRenderer = std::unique_ptr<ThumbnailRendererTask>(new ThumbnailRendererTask(file->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, true, true, false));
RequestBroker::Ref().RenderThumbnail(file->GetGameSave(), true, false, thumbBoxSize.X, thumbBoxSize.Y, true, this); thumbnailRenderer->Start();
triedThumbnail = true;
}
}
if (thumbnailRequest && thumbnailRequest->CheckDone())
{
thumbnail = thumbnailRequest->Finish();
thumbnailRequest = nullptr;
}
if (thumbnailRenderer)
{
thumbnailRenderer->Poll();
if (thumbnailRenderer->GetDone())
{
thumbnail = thumbnailRenderer->GetThumbnail();
thumbnailRenderer.reset();
}
}
if (thumbnail && file)
{
thumbSize = ui::Point(thumbnail->Width, thumbnail->Height);
} }
} }
} }
@ -182,9 +200,9 @@ void SaveButton::Draw(const Point& screenPos)
{ {
//thumbBoxSize = ui::Point(thumbnail->Width, thumbnail->Height); //thumbBoxSize = ui::Point(thumbnail->Width, thumbnail->Height);
if (save && save->id) if (save && save->id)
g->draw_image(thumbnail, screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 255); g->draw_image(thumbnail.get(), screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 255);
else else
g->draw_image(thumbnail, screenPos.X+(Size.X-thumbSize.X)/2, screenPos.Y+(Size.Y-21-thumbSize.Y)/2, 255); g->draw_image(thumbnail.get(), screenPos.X+(Size.X-thumbSize.X)/2, screenPos.Y+(Size.Y-21-thumbSize.Y)/2, 255);
} }
else if (file && !file->GetGameSave()) else if (file && !file->GetGameSave())
g->drawtext(screenPos.X+(Size.X-Graphics::textwidth("Error loading save"))/2, screenPos.Y+(Size.Y-28)/2, "Error loading save", 180, 180, 180, 255); g->drawtext(screenPos.X+(Size.X-Graphics::textwidth("Error loading save"))/2, screenPos.Y+(Size.Y-28)/2, "Error loading save", 180, 180, 180, 255);

View File

@ -6,10 +6,16 @@
#include "Component.h" #include "Component.h"
#include "client/SaveFile.h" #include "client/SaveFile.h"
#include "client/SaveInfo.h" #include "client/SaveInfo.h"
#include "client/requestbroker/RequestListener.h"
#include "graphics/Graphics.h" #include "graphics/Graphics.h"
#include "gui/interface/Colour.h" #include "gui/interface/Colour.h"
#include <memory>
class ThumbnailRendererTask;
namespace http
{
class ThumbnailRequest;
}
namespace ui namespace ui
{ {
class SaveButton; class SaveButton;
@ -23,11 +29,11 @@ public:
virtual ~SaveButtonAction() {} virtual ~SaveButtonAction() {}
}; };
class SaveButton : public Component, public RequestListener class SaveButton : public Component
{ {
SaveFile * file; SaveFile * file;
SaveInfo * save; SaveInfo * save;
VideoBuffer * thumbnail; std::unique_ptr<VideoBuffer> thumbnail;
ui::Point thumbSize = ui::Point(0, 0); ui::Point thumbSize = ui::Point(0, 0);
String name; String name;
String votesString; String votesString;
@ -36,10 +42,12 @@ class SaveButton : public Component, public RequestListener
int voteBarHeightUp; int voteBarHeightUp;
int voteBarHeightDown; int voteBarHeightDown;
bool wantsDraw; bool wantsDraw;
bool waitingForThumb; bool triedThumbnail;
bool isMouseInsideAuthor; bool isMouseInsideAuthor;
bool isMouseInsideHistory; bool isMouseInsideHistory;
bool showVotes; bool showVotes;
std::unique_ptr<ThumbnailRendererTask> thumbnailRenderer;
http::ThumbnailRequest *thumbnailRequest;
public: public:
SaveButton(Point position, Point size, SaveInfo * save); SaveButton(Point position, Point size, SaveInfo * save);
SaveButton(Point position, Point size, SaveFile * file); SaveButton(Point position, Point size, SaveFile * file);
@ -59,8 +67,6 @@ public:
void Draw(const Point& screenPos) override; void Draw(const Point& screenPos) override;
void Tick(float dt) override; void Tick(float dt) override;
void OnResponseReady(void * imagePtr, int identifier) override;
void SetSelected(bool selected_) { selected = selected_; } void SetSelected(bool selected_) { selected = selected_; }
bool GetSelected() { return selected; } bool GetSelected() { return selected; }
void SetSelectable(bool selectable_) { selectable = selectable_; } void SetSelectable(bool selectable_) { selectable = selectable_; }

View File

@ -29,10 +29,14 @@ SaveRenderer::SaveRenderer(){
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
#endif #endif
pthread_mutex_init(&renderMutex, NULL);
} }
VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire) VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
{ {
pthread_mutex_lock(&renderMutex);
int width, height; int width, height;
VideoBuffer * tempThumb = NULL; VideoBuffer * tempThumb = NULL;
width = save->blockWidth; width = save->blockWidth;
@ -145,11 +149,15 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
if(doCollapse) if(doCollapse)
save->Collapse(); save->Collapse();
g->Release(); g->Release();
pthread_mutex_unlock(&renderMutex);
return tempThumb; return tempThumb;
} }
VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool decorations, bool fire) VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool decorations, bool fire)
{ {
pthread_mutex_lock(&renderMutex);
GameSave * tempSave; GameSave * tempSave;
try { try {
tempSave = new GameSave((char*)saveData, dataSize); tempSave = new GameSave((char*)saveData, dataSize);
@ -159,13 +167,17 @@ VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool
VideoBuffer * buffer = new VideoBuffer(64, 64); VideoBuffer * buffer = new VideoBuffer(64, 64);
buffer->BlendCharacter(32, 32, 'x', 255, 255, 255, 255); buffer->BlendCharacter(32, 32, 'x', 255, 255, 255, 255);
pthread_mutex_unlock(&renderMutex);
return buffer; return buffer;
} }
VideoBuffer * thumb = Render(tempSave, decorations, fire); VideoBuffer * thumb = Render(tempSave, decorations, fire);
delete tempSave; delete tempSave;
pthread_mutex_unlock(&renderMutex);
return thumb; return thumb;
} }
SaveRenderer::~SaveRenderer() { SaveRenderer::~SaveRenderer() {
pthread_mutex_destroy(&renderMutex);
} }

View File

@ -4,6 +4,7 @@
#include "graphics/OpenGLHeaders.h" #include "graphics/OpenGLHeaders.h"
#endif #endif
#include "common/Singleton.h" #include "common/Singleton.h"
#include "common/tpt-thread.h"
class GameSave; class GameSave;
class VideoBuffer; class VideoBuffer;
@ -15,6 +16,7 @@ class SaveRenderer: public Singleton<SaveRenderer> {
Graphics * g; Graphics * g;
Simulation * sim; Simulation * sim;
Renderer * ren; Renderer * ren;
pthread_mutex_t renderMutex;
public: public:
SaveRenderer(); SaveRenderer();
VideoBuffer * Render(GameSave * save, bool decorations = true, bool fire = true); VideoBuffer * Render(GameSave * save, bool decorations = true, bool fire = true);