From 680a36549adaed0c3ce7e8906fadbdf190b0b3b0 Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Sun, 29 Jan 2012 14:44:36 +0000 Subject: [PATCH] Background retrieval of save info and save list. --- src/PowderToy.cpp | 4 ++ src/dialogues/ErrorMessage.cpp | 50 +++++++++++++++++++++ src/dialogues/ErrorMessage.h | 20 +++++++++ src/interface/Label.cpp | 13 +++--- src/interface/Label.h | 9 +++- src/preview/PreviewController.cpp | 6 ++- src/preview/PreviewController.h | 1 + src/preview/PreviewModel.cpp | 74 +++++++++++++++++++++++++++++-- src/preview/PreviewModel.h | 18 ++++++++ src/preview/PreviewView.cpp | 5 +++ src/preview/PreviewView.h | 1 + src/search/SearchController.cpp | 1 + src/search/SearchModel.cpp | 64 ++++++++++++++++++++------ src/search/SearchModel.h | 11 +++++ src/search/SearchView.cpp | 23 ++++++++-- 15 files changed, 271 insertions(+), 29 deletions(-) create mode 100644 src/dialogues/ErrorMessage.cpp create mode 100644 src/dialogues/ErrorMessage.h diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index 406e33479..9174ed0a5 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -18,6 +18,8 @@ #include "game/GameController.h" #include "game/GameView.h" +#include "dialogues/ErrorMessage.h" + #include "client/HTTP.h" using namespace std; @@ -73,6 +75,8 @@ int main(int argc, char * argv[]) GameController * gameController = new GameController(); engine->ShowWindow(gameController->GetView()); + new ErrorMessage("Error", "This is a test error message"); + SDL_Event event; while(engine->Running()) { diff --git a/src/dialogues/ErrorMessage.cpp b/src/dialogues/ErrorMessage.cpp new file mode 100644 index 000000000..bce0c3377 --- /dev/null +++ b/src/dialogues/ErrorMessage.cpp @@ -0,0 +1,50 @@ +/* + * ErrorMessage.cpp + * + * Created on: Jan 29, 2012 + * Author: Simon + */ + +#include "ErrorMessage.h" +#include "interface/Button.h" +#include "interface/Label.h" + +ErrorMessage::ErrorMessage(std::string title, std::string message): + ui::Window(ui::Point(-1, -1), ui::Point(200, 75)) +{ + ui::Label * titleLabel = new ui::Label(ui::Point(2, 1), ui::Point(Size.X-4, 16), title); + titleLabel->SetTextColour(ui::Colour(200, 100, 50)); + titleLabel->SetAlignment(AlignLeft, AlignBottom); + AddComponent(titleLabel); + + ui::Label * messageLabel = new ui::Label(ui::Point(4, 18), ui::Point(Size.X-8, 60), message); + messageLabel->SetAlignment(AlignLeft, AlignTop); + AddComponent(messageLabel); + + class DismissAction: public ui::ButtonAction + { + void ActionCallback(ui::Button * sender) + { + ui::Engine::Ref().CloseWindow(); + } + }; + + ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "Dismiss"); + okayButton->SetAlignment(AlignRight, AlignBottom); + okayButton->SetBorderColour(ui::Colour(200, 200, 200)); + okayButton->SetActionCallback(new DismissAction()); + AddComponent(okayButton); + ui::Engine::Ref().ShowWindow(this); +} + +void ErrorMessage::OnDraw() +{ + Graphics * g = ui::Engine::Ref().g; + + g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4); + g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); +} + +ErrorMessage::~ErrorMessage() { +} + diff --git a/src/dialogues/ErrorMessage.h b/src/dialogues/ErrorMessage.h new file mode 100644 index 000000000..f8575bde7 --- /dev/null +++ b/src/dialogues/ErrorMessage.h @@ -0,0 +1,20 @@ +/* + * ErrorMessage.h + * + * Created on: Jan 29, 2012 + * Author: Simon + */ + +#ifndef ERRORMESSAGE_H_ +#define ERRORMESSAGE_H_ + +#include "interface/Window.h" + +class ErrorMessage: public ui::Window { +public: + ErrorMessage(std::string title, std::string message); + virtual void OnDraw(); + virtual ~ErrorMessage(); +}; + +#endif /* ERRORMESSAGE_H_ */ diff --git a/src/interface/Label.cpp b/src/interface/Label.cpp index 6fc47e201..e5f99a246 100644 --- a/src/interface/Label.cpp +++ b/src/interface/Label.cpp @@ -6,7 +6,7 @@ using namespace ui; -Label::Label(Window* parent_state, std::string labelText): +/*Label::Label(Window* parent_state, std::string labelText): Component(parent_state), text(labelText), textPosition(ui::Point(0, 0)), @@ -14,19 +14,20 @@ Label::Label(Window* parent_state, std::string labelText): textHAlign(AlignCentre) { TextPosition(); -} +}*/ Label::Label(Point position, Point size, std::string labelText): Component(position, size), text(labelText), textPosition(ui::Point(0, 0)), textVAlign(AlignMiddle), - textHAlign(AlignCentre) + textHAlign(AlignCentre), + textColour(255, 255, 255) { TextPosition(); } -Label::Label(std::string labelText): +/*Label::Label(std::string labelText): Component(), text(labelText), textPosition(ui::Point(0, 0)), @@ -34,7 +35,7 @@ Label::Label(std::string labelText): textHAlign(AlignCentre) { TextPosition(); -} +}*/ Label::~Label() { @@ -80,6 +81,6 @@ void Label::SetText(std::string text) void Label::Draw(const Point& screenPos) { Graphics * g = Engine::Ref().g; - g->drawtext(screenPos.X+textPosition.X, screenPos.Y+textPosition.Y, text, 255, 255, 255, 255); + g->drawtext(screenPos.X+textPosition.X, screenPos.Y+textPosition.Y, text, textColour.Red, textColour.Green, textColour.Blue, 255); } diff --git a/src/interface/Label.h b/src/interface/Label.h index 9b5a454cb..b92514067 100644 --- a/src/interface/Label.h +++ b/src/interface/Label.h @@ -5,6 +5,7 @@ #include "Component.h" #include "Misc.h" +#include "Colour.h" namespace ui { @@ -14,10 +15,12 @@ namespace ui ui::Point textPosition; HorizontalAlignment textHAlign; VerticalAlignment textVAlign; + + Colour textColour; public: - Label(Window* parent_state, std::string labelText); + //Label(Window* parent_state, std::string labelText); Label(Point position, Point size, std::string labelText); - Label(std::string labelText); + //Label(std::string labelText); virtual ~Label(); void TextPosition(); @@ -26,6 +29,8 @@ namespace ui VerticalAlignment GetVAlignment() { return textVAlign; } void SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign) { textHAlign = hAlign; textVAlign = vAlign; TextPosition(); } + void SetTextColour(Colour textColour) { this->textColour = textColour; } + virtual void Draw(const Point& screenPos); }; diff --git a/src/preview/PreviewController.cpp b/src/preview/PreviewController.cpp index db3cdee05..ac68e0738 100644 --- a/src/preview/PreviewController.cpp +++ b/src/preview/PreviewController.cpp @@ -13,7 +13,6 @@ PreviewController::PreviewController(int saveID, ControllerCallback * callback): HasExited(false) { - // TODO Auto-generated constructor stub previewModel = new PreviewModel(); previewView = new PreviewView(); previewModel->AddObserver(previewView); @@ -24,6 +23,11 @@ PreviewController::PreviewController(int saveID, ControllerCallback * callback): this->callback = callback; } +void PreviewController::Update() +{ + previewModel->Update(); +} + Save * PreviewController::GetSave() { return previewModel->GetSave(); diff --git a/src/preview/PreviewController.h b/src/preview/PreviewController.h index 452d6868c..e9b0fb5ad 100644 --- a/src/preview/PreviewController.h +++ b/src/preview/PreviewController.h @@ -27,6 +27,7 @@ public: bool GetDoOpen(); Save * GetSave(); PreviewView * GetView() { return previewView; } + void Update(); virtual ~PreviewController(); }; diff --git a/src/preview/PreviewModel.cpp b/src/preview/PreviewModel.cpp index 07396cb89..658a76743 100644 --- a/src/preview/PreviewModel.cpp +++ b/src/preview/PreviewModel.cpp @@ -11,18 +11,63 @@ PreviewModel::PreviewModel(): save(NULL), savePreview(NULL), - doOpen(false) + doOpen(false), + updateSavePreviewWorking(false), + updateSavePreviewFinished(false), + updateSaveInfoWorking(false), + updateSaveInfoFinished(false) { // TODO Auto-generated constructor stub } +void * PreviewModel::updateSaveInfoTHelper(void * obj) +{ + return ((PreviewModel*)obj)->updateSaveInfoT(); +} + +void * PreviewModel::updateSavePreviewTHelper(void * obj) +{ + return ((PreviewModel*)obj)->updateSavePreviewT(); +} + +void * PreviewModel::updateSaveInfoT() +{ + Save * tempSave = Client::Ref().GetSave(tSaveID, tSaveDate); + updateSaveInfoFinished = true; + return tempSave; +} + +void * PreviewModel::updateSavePreviewT() +{ + Thumbnail * tempThumb = Client::Ref().GetPreview(tSaveID, tSaveDate); + updateSavePreviewFinished = true; + return tempThumb; +} + void PreviewModel::UpdateSave(int saveID, int saveDate) { - save = Client::Ref().GetSave(saveID, saveDate); - notifySaveChanged(); - savePreview = Client::Ref().GetPreview(saveID, saveDate); + this->tSaveID = saveID; + this->tSaveDate = saveDate; + + save = NULL; + savePreview = NULL; notifyPreviewChanged(); + notifySaveChanged(); + + if(!updateSavePreviewWorking) + { + updateSavePreviewWorking = true; + updateSavePreviewFinished = false; + pthread_create(&updateSavePreviewThread, 0, &PreviewModel::updateSavePreviewTHelper, this); + } + + if(!updateSaveInfoWorking) + { + updateSaveInfoWorking = true; + updateSaveInfoFinished = false; + pthread_create(&updateSaveInfoThread, 0, &PreviewModel::updateSaveInfoTHelper, this); + } } void PreviewModel::SetDoOpen(bool doOpen) @@ -67,6 +112,27 @@ void PreviewModel::AddObserver(PreviewView * observer) { observer->NotifySaveChanged(this); } +void PreviewModel::Update() +{ + if(updateSavePreviewWorking) + { + if(updateSavePreviewFinished) + { + pthread_join(updateSavePreviewThread, (void**)(&savePreview)); + notifyPreviewChanged(); + } + } + + if(updateSaveInfoWorking) + { + if(updateSaveInfoFinished) + { + pthread_join(updateSaveInfoThread, (void**)(&save)); + notifySaveChanged(); + } + } +} + PreviewModel::~PreviewModel() { if(save) delete save; diff --git a/src/preview/PreviewModel.h b/src/preview/PreviewModel.h index 23ac2d7d8..e0e596696 100644 --- a/src/preview/PreviewModel.h +++ b/src/preview/PreviewModel.h @@ -9,6 +9,7 @@ #define PREVIEWMODEL_H_ #include +#include #include "PreviewView.h" #include "search/Save.h" #include "search/Thumbnail.h" @@ -23,6 +24,22 @@ class PreviewModel { Thumbnail * savePreview; void notifyPreviewChanged(); void notifySaveChanged(); + + //Background retrieval + int tSaveID; + int tSaveDate; + + bool updateSavePreviewWorking; + volatile bool updateSavePreviewFinished; + pthread_t updateSavePreviewThread; + static void * updateSavePreviewTHelper(void * obj); + void * updateSavePreviewT(); + + bool updateSaveInfoWorking; + volatile bool updateSaveInfoFinished; + pthread_t updateSaveInfoThread; + static void * updateSaveInfoTHelper(void * obj); + void * updateSaveInfoT(); public: PreviewModel(); Thumbnail * GetPreview(); @@ -31,6 +48,7 @@ public: void UpdateSave(int saveID, int saveDate); bool GetDoOpen(); void SetDoOpen(bool doOpen); + void Update(); virtual ~PreviewModel(); }; diff --git a/src/preview/PreviewView.cpp b/src/preview/PreviewView.cpp index 4ab54b2a3..de5869219 100644 --- a/src/preview/PreviewView.cpp +++ b/src/preview/PreviewView.cpp @@ -57,6 +57,11 @@ void PreviewView::OnDraw() g->draw_line(Position.X+XRES/2, Position.Y, Position.X+XRES/2, Position.Y+Size.Y, 255, 255, 255, XRES+BARSIZE); } +void PreviewView::OnTick(float dt) +{ + c->Update(); +} + void PreviewView::OnMouseDown(int x, int y, unsigned button) { if(!(x > Position.X && y > Position.Y && y < Position.Y+Size.Y && x < Position.X+Size.X)) //Clicked outside window diff --git a/src/preview/PreviewView.h b/src/preview/PreviewView.h index e788210e7..a526ef76a 100644 --- a/src/preview/PreviewView.h +++ b/src/preview/PreviewView.h @@ -28,6 +28,7 @@ public: void NotifyPreviewChanged(PreviewModel * sender); void NotifySaveChanged(PreviewModel * sender); virtual void OnDraw(); + virtual void OnTick(float dt); virtual void OnMouseDown(int x, int y, unsigned button); virtual ~PreviewView(); }; diff --git a/src/search/SearchController.cpp b/src/search/SearchController.cpp index 2102a7dea..6aff9622c 100644 --- a/src/search/SearchController.cpp +++ b/src/search/SearchController.cpp @@ -43,6 +43,7 @@ Save * SearchController::GetLoadedSave() void SearchController::Update() { + searchModel->Update(); if(activePreview && activePreview->HasExited) { delete activePreview; diff --git a/src/search/SearchModel.cpp b/src/search/SearchModel.cpp index d7406206f..e40c4b0db 100644 --- a/src/search/SearchModel.cpp +++ b/src/search/SearchModel.cpp @@ -6,29 +6,43 @@ SearchModel::SearchModel(): currentSort("votes"), showOwn(false), - loadedSave(NULL) + loadedSave(NULL), + updateSaveListWorking(false), + updateSaveListFinished(false), + saveListLoaded(false) { } +void * SearchModel::updateSaveListTHelper(void * obj) +{ + return ((SearchModel *)obj)->updateSaveListT(); +} + +void * SearchModel::updateSaveListT() +{ + vector * tempSaveList = Client::Ref().SearchSaves((currentPage-1)*20, 20, lastQuery, currentSort, resultCount); + updateSaveListFinished = true; + return tempSaveList; +} + void SearchModel::UpdateSaveList(int pageNumber, std::string query) { lastQuery = query; lastError = ""; + saveListLoaded = false; saveList.clear(); - currentPage = 1; - resultCount = 0; - notifySaveListChanged(); - notifyPageChanged(); - vector * tempSaveList = Client::Ref().SearchSaves((pageNumber-1)*20, 20, query, currentSort, resultCount); - saveList = *tempSaveList; - delete tempSaveList; - if(!saveList.size()) - { - lastError = Client::Ref().GetLastError(); - } + //resultCount = 0; currentPage = pageNumber; - notifyPageChanged(); notifySaveListChanged(); + notifyPageChanged(); + + //Threading + if(!updateSaveListWorking) + { + updateSaveListFinished = false; + updateSaveListWorking = true; + pthread_create(&updateSaveListThread, 0, &SearchModel::updateSaveListTHelper, this); + } } void SearchModel::SetLoadedSave(Save * save) @@ -45,6 +59,30 @@ vector SearchModel::GetSaveList() return saveList; } +void SearchModel::Update() +{ + if(updateSaveListWorking) + { + if(updateSaveListFinished) + { + updateSaveListWorking = false; + lastError = ""; + saveListLoaded = true; + vector * tempSaveList; + pthread_join(updateSaveListThread, (void**)(&tempSaveList)); + saveList = *tempSaveList; + delete tempSaveList; + if(!saveList.size()) + { + lastError = Client::Ref().GetLastError(); + } + //currentPage = pageNumber; + notifyPageChanged(); + notifySaveListChanged(); + } + } +} + void SearchModel::AddObserver(SearchView * observer) { observers.push_back(observer); diff --git a/src/search/SearchModel.h b/src/search/SearchModel.h index e99e4ca99..d52529d0c 100644 --- a/src/search/SearchModel.h +++ b/src/search/SearchModel.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "Save.h" #include "SearchView.h" @@ -26,6 +27,14 @@ private: void notifyPageChanged(); void notifySortChanged(); void notifyShowOwnChanged(); + + //Variables and methods for backgroun save request + bool saveListLoaded; + bool updateSaveListWorking; + volatile bool updateSaveListFinished; + pthread_t updateSaveListThread; + static void * updateSaveListTHelper(void * obj); + void * updateSaveListT(); public: SearchModel(); virtual ~SearchModel(); @@ -42,6 +51,8 @@ public: bool GetShowOwn() { return showOwn; } void SetLoadedSave(Save * save); Save * GetLoadedSave(); + bool GetSavesLoaded() { return saveListLoaded; } + void Update(); }; #endif // SEARCHMODEL_H diff --git a/src/search/SearchView.cpp b/src/search/SearchView.cpp index b1d976586..b9c8bcb0e 100644 --- a/src/search/SearchView.cpp +++ b/src/search/SearchView.cpp @@ -152,6 +152,16 @@ void SearchView::NotifySaveListChanged(SearchModel * sender) delete saveButtons[i]; } saveButtons.clear(); + if(!sender->GetSavesLoaded()) + { + nextButton->Enabled = false; + previousButton->Enabled = false; + } + else + { + nextButton->Enabled = true; + previousButton->Enabled = true; + } if(!saves.size()) { if(!errorLabel) @@ -159,10 +169,17 @@ void SearchView::NotifySaveListChanged(SearchModel * sender) errorLabel = new ui::Label(ui::Point(((XRES+BARSIZE)/2)-100, ((YRES+MENUSIZE)/2)-6), ui::Point(200, 12), "Error"); AddComponent(errorLabel); } - if(sender->GetLastError().length()) - errorLabel->SetText("\bo" + sender->GetLastError()); + if(!sender->GetSavesLoaded()) + { + errorLabel->SetText("Loading..."); + } else - errorLabel->SetText("\boNo saves found"); + { + if(sender->GetLastError().length()) + errorLabel->SetText("\bo" + sender->GetLastError()); + else + errorLabel->SetText("\boNo saves found"); + } } else {