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 "common/String.h"
#include <memory>
namespace http
{
class AvatarRequest : public ImageRequest

View File

@ -940,6 +940,14 @@ void Client::Shutdown()
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 "graphics/Graphics.h"
#include "gui/interface/Colour.h"
#include "client/requestbroker/RequestListener.h"
#include <memory>

View File

@ -8,9 +8,11 @@
#include "SaveButton.h"
#include "client/Client.h"
#include "client/SaveInfo.h"
#include "client/ThumbnailRequest.h"
#include "client/ThumbnailRenderer.h"
#include "graphics/Graphics.h"
#include "simulation/SaveRenderer.h"
#include "client/requestbroker/RequestBroker.h"
#include "client/GameSave.h"
namespace ui {
@ -18,11 +20,11 @@ SaveButton::SaveButton(Point position, Point size, SaveInfo * save):
Component(position, size),
file(NULL),
save(save),
thumbnail(NULL),
waitingForThumb(false),
triedThumbnail(false),
isMouseInsideAuthor(false),
isMouseInsideHistory(false),
showVotes(false),
thumbnailRequest(nullptr),
isButtonDown(false),
isMouseInside(false),
selected(false),
@ -91,12 +93,12 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
Component(position, size),
file(file),
save(NULL),
thumbnail(NULL),
wantsDraw(false),
waitingForThumb(false),
triedThumbnail(false),
isMouseInsideAuthor(false),
isMouseInsideHistory(false),
showVotes(false),
thumbnailRequest(nullptr),
isButtonDown(false),
isMouseInside(false),
selected(false),
@ -117,50 +119,66 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
SaveButton::~SaveButton()
{
RequestBroker::Ref().DetachRequestListener(this);
if (thumbnailRequest)
{
thumbnailRequest->Cancel();
}
delete thumbnail;
delete actionCallback;
delete save;
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)
{
if(!thumbnail && !waitingForThumb)
if (!thumbnail)
{
float scaleFactor = (Size.Y-25)/((float)YRES);
ui::Point thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor);
if(save)
if (!triedThumbnail)
{
if(save->GetGameSave())
float scaleFactor = (Size.Y-25)/((float)YRES);
ui::Point thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor);
if (save)
{
waitingForThumb = true;
RequestBroker::Ref().RenderThumbnail(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, this);
if(save->GetGameSave())
{
thumbnailRenderer = std::unique_ptr<ThumbnailRendererTask>(new ThumbnailRendererTask(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y));
thumbnailRenderer->Start();
triedThumbnail = true;
}
else if (save->GetID())
{
thumbnailRequest = new http::ThumbnailRequest(save->GetID(), save->GetVersion(), thumbBoxSize.X, thumbBoxSize.Y);
thumbnailRequest->Start();
triedThumbnail = true;
}
}
else if(save->GetID())
else if (file && file->GetGameSave())
{
waitingForThumb = true;
RequestBroker::Ref().RetrieveThumbnail(save->GetID(), save->GetVersion(), thumbBoxSize.X, thumbBoxSize.Y, this);
thumbnailRenderer = std::unique_ptr<ThumbnailRendererTask>(new ThumbnailRendererTask(file->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, true, true, false));
thumbnailRenderer->Start();
triedThumbnail = true;
}
}
else if(file && file->GetGameSave())
if (thumbnailRequest && thumbnailRequest->CheckDone())
{
waitingForThumb = true;
RequestBroker::Ref().RenderThumbnail(file->GetGameSave(), true, false, thumbBoxSize.X, thumbBoxSize.Y, true, this);
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);
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
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())
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 "client/SaveFile.h"
#include "client/SaveInfo.h"
#include "client/requestbroker/RequestListener.h"
#include "graphics/Graphics.h"
#include "gui/interface/Colour.h"
#include <memory>
class ThumbnailRendererTask;
namespace http
{
class ThumbnailRequest;
}
namespace ui
{
class SaveButton;
@ -23,11 +29,11 @@ public:
virtual ~SaveButtonAction() {}
};
class SaveButton : public Component, public RequestListener
class SaveButton : public Component
{
SaveFile * file;
SaveInfo * save;
VideoBuffer * thumbnail;
std::unique_ptr<VideoBuffer> thumbnail;
ui::Point thumbSize = ui::Point(0, 0);
String name;
String votesString;
@ -36,10 +42,12 @@ class SaveButton : public Component, public RequestListener
int voteBarHeightUp;
int voteBarHeightDown;
bool wantsDraw;
bool waitingForThumb;
bool triedThumbnail;
bool isMouseInsideAuthor;
bool isMouseInsideHistory;
bool showVotes;
std::unique_ptr<ThumbnailRendererTask> thumbnailRenderer;
http::ThumbnailRequest *thumbnailRequest;
public:
SaveButton(Point position, Point size, SaveInfo * save);
SaveButton(Point position, Point size, SaveFile * file);
@ -59,8 +67,6 @@ public:
void Draw(const Point& screenPos) override;
void Tick(float dt) override;
void OnResponseReady(void * imagePtr, int identifier) override;
void SetSelected(bool selected_) { selected = selected_; }
bool GetSelected() { return selected; }
void SetSelectable(bool selectable_) { selectable = selectable_; }

View File

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

View File

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