From 2b1145fb0aec3feb9cbab2df9be57ab43fc7f975 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sat, 24 Dec 2022 22:03:59 +0100 Subject: WIP download manager --- oop2eindopdr/DownloadManager.cpp | 39 +++++++++++++++++++++++++++++++++++++++ oop2eindopdr/DownloadManager.h | 32 ++++++++++++++++++++++++++++++++ oop2eindopdr/Pokedex.cpp | 2 ++ oop2eindopdr/Pokedex.h | 2 ++ oop2eindopdr/PokemonCard.cpp | 17 +++++++++++++---- oop2eindopdr/PokemonCard.h | 6 ++++++ oop2eindopdr/makefile | 1 + 7 files changed, 95 insertions(+), 4 deletions(-) diff --git a/oop2eindopdr/DownloadManager.cpp b/oop2eindopdr/DownloadManager.cpp index e69de29..ff24613 100644 --- a/oop2eindopdr/DownloadManager.cpp +++ b/oop2eindopdr/DownloadManager.cpp @@ -0,0 +1,39 @@ +#include +#include + +#include "DownloadManager.h" + +DownloadManager::DownloadManager() { } + +DownloadManager::~DownloadManager() { + for (std::thread* download : download_queue) { + download->join(); + delete download; + download = nullptr; + } +} + +std::fstream* DownloadManager::open_file(std::string filename) { + while (this->file_queue.size() > this->max_files); + std::fstream* out = new std::fstream(filename); + this->file_queue.push_back(out); + return out; +} + +void DownloadManager::close_file(std::fstream* file_ptr) { + file_ptr->close(); + delete file_ptr; + this->file_queue.erase(std::remove(this->file_queue.begin(), this->file_queue.end(), file_ptr)); +} + +std::thread* DownloadManager::wget(std::string url, std::string filename) { + std::thread* download = new std::thread([url, filename, this] { + cpr::Response res = cpr::Get(cpr::Url{url}); + std::fstream* file = this->open_file(filename); + *file << res.text; + this->close_file(file); + }); + download_queue.push_back(download); + return download; +} + diff --git a/oop2eindopdr/DownloadManager.h b/oop2eindopdr/DownloadManager.h index 45dcbb0..c98ae67 100644 --- a/oop2eindopdr/DownloadManager.h +++ b/oop2eindopdr/DownloadManager.h @@ -1,3 +1,35 @@ #pragma once +#include +#include +#include +class DownloadManager { +private: + const unsigned max_files = 50; + + std::vector download_queue = {}; + std::vector file_queue = {}; + + /** + * @brief open file in DownloadManager (THREAD-ONLY) + * + * this function opens a file, but blocks until a slot is available, so + * should only be used in threads + */ + std::fstream* open_file(std::string filename); + /** + * @brief close file in DownloadManager (THREAD-ONLY) + * + * this function closes a file and removes it's pointer from the file_queue + * vector + */ + void close_file(std::fstream* file_ptr); + +public: + DownloadManager(); + virtual ~DownloadManager(); + + /** @brief downlaod `url` to `file` and close `file` when done */ + virtual std::thread* wget(std::string url, std::string filename); +}; diff --git a/oop2eindopdr/Pokedex.cpp b/oop2eindopdr/Pokedex.cpp index 9418a41..b60b125 100644 --- a/oop2eindopdr/Pokedex.cpp +++ b/oop2eindopdr/Pokedex.cpp @@ -3,6 +3,7 @@ #include #include "CacheManager.h" +#include "DownloadManager.h" #include "Pokedex.h" #include "PokemonTCGAPIClient.h" #include "PokemonCard.h" @@ -10,6 +11,7 @@ Pokedex::Pokedex() { this->cache = new CacheManager("./cache"); this->api = new PokemonTCGAPIClient(); + this->download_manager = new DownloadManager(); if (this->cache->cache_exists("index")) this->load_collection_local(); diff --git a/oop2eindopdr/Pokedex.h b/oop2eindopdr/Pokedex.h index 28d0d31..41cbf7c 100644 --- a/oop2eindopdr/Pokedex.h +++ b/oop2eindopdr/Pokedex.h @@ -7,6 +7,7 @@ class PokemonCard; class PokemonTCGAPIClient; +class DownloadManager; /** @brief user pokedex class, handles caching and api access silently */ class Pokedex { @@ -24,6 +25,7 @@ private: /** @brief cache connection */ CacheManager* cache = nullptr; PokemonTCGAPIClient* api = nullptr; + DownloadManager* download_manager = nullptr; friend class PokemonCard; diff --git a/oop2eindopdr/PokemonCard.cpp b/oop2eindopdr/PokemonCard.cpp index 51e7f59..c7e4ea3 100644 --- a/oop2eindopdr/PokemonCard.cpp +++ b/oop2eindopdr/PokemonCard.cpp @@ -6,6 +6,7 @@ #include "Pokedex.h" #include "PokemonCard.h" #include "PokemonTCGAPIClient.h" +#include "DownloadManager.h" using std::endl; @@ -58,13 +59,18 @@ void PokemonCard::verify_files() { !this->pokedex->cache->cache_exists(prefix_cache_path("card_hires.png"))) { download_files(); } - - this->pokedex->cache->cache_get(prefix_cache_path("complete"))->close(); } void PokemonCard::download_files() { - this->pokedex->cache->cache_get(prefix_cache_path("card.png"))->close(); - this->pokedex->cache->cache_get(prefix_cache_path("card_hires.png"))->close(); + std::thread* card_normal_dl = this->pokedex->download_manager->wget(this->url_card_normal, prefix_cache_path("card.png")); + std::thread* card_hires_dl = this->pokedex->download_manager->wget(this->url_card_hires, prefix_cache_path("card_hires.png")); + + this->image_download_thread = new std::thread([card_hires_dl, card_normal_dl, this] { + card_normal_dl->join(); + card_hires_dl->join(); + + this->pokedex->cache->cache_get(prefix_cache_path("complete"))->close(); + }); } void PokemonCard::raw_load_json(nlohmann::json raw_data) { @@ -75,6 +81,9 @@ void PokemonCard::raw_load_json(nlohmann::json raw_data) { for (nlohmann::json raw_attack : raw_data["attacks"]) this->attacks.push_back(raw_attack["name"]); + this->url_card_normal = raw_data["images"]["small"].get(); + this->url_card_hires = raw_data["images"]["large"].get(); + // json needs to be written here so complete api response is preserved this->raw_data = raw_data; } diff --git a/oop2eindopdr/PokemonCard.h b/oop2eindopdr/PokemonCard.h index 691110a..33a9d97 100644 --- a/oop2eindopdr/PokemonCard.h +++ b/oop2eindopdr/PokemonCard.h @@ -3,6 +3,7 @@ #include #include #include +#include class Pokedex; @@ -19,6 +20,11 @@ private: /** @brief add cache path before filename */ virtual std::string prefix_cache_path(const char* filename); + std::thread* image_download_thread = nullptr; + + std::string url_card_normal = ""; + std::string url_card_hires = ""; + public: PokemonCard(Pokedex* pokedex = nullptr); virtual ~PokemonCard(); diff --git a/oop2eindopdr/makefile b/oop2eindopdr/makefile index 533121d..dac4a06 100644 --- a/oop2eindopdr/makefile +++ b/oop2eindopdr/makefile @@ -4,6 +4,7 @@ RM = rm -f TARGET = main OUTPUT_ZIP = Eindopdracht_2180996.zip +CFLAGS += -g CFLAGS += -std=c++17 LFLAGS += -lstdc++ -lcpr -lzip -- cgit v1.2.3