From 75fc333e84a94665e8a0c5609d8b11ec198698fb Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sun, 25 Dec 2022 17:17:07 +0100 Subject: fix some file closing + index dementia --- oop2eindopdr/CacheManager.cpp | 16 ++++++++-------- oop2eindopdr/CacheManager.h | 18 +++++++++++++++--- oop2eindopdr/Pokedex.cpp | 3 ++- oop2eindopdr/PokemonCard.cpp | 2 ++ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/oop2eindopdr/CacheManager.cpp b/oop2eindopdr/CacheManager.cpp index 6062b70..c335de3 100644 --- a/oop2eindopdr/CacheManager.cpp +++ b/oop2eindopdr/CacheManager.cpp @@ -41,31 +41,32 @@ void CacheManager::update_cache() { date.close(); } -void CacheManager::retry(std::string label, std::function action, std::function retry_if) { +void CacheManager::retry(std::string label, bool check_pre, std::function action, std::function retry_if) { for (unsigned int i = 0; i < max_tries; i++) { + if (check_pre && retry_if() == false) return; action(); - if (retry_if() == false) return; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (!check_pre && retry_if() == false) return; } std::cout << "retry " << label << " failed after " << max_tries << " tries" << std::endl; } -std::fstream* CacheManager::cache_get(std::string filename) { return cache_get(filename.c_str()); } std::fstream* CacheManager::cache_get(const char* filename) { std::filesystem::path fixed_path = prefix_cache_path(filename); // fix duplicate slashes and add prefix - retry("mkdir", [&] { + retry_if("mkdir", [&] { std::filesystem::create_directories(fixed_path.parent_path()); // make sure folder exists }, [&] { return !std::filesystem::exists(fixed_path.parent_path()); }); - retry("touch file", [&] { + retry_if("touch file", [&] { std::fstream(fixed_path, std::ios::trunc | std::ios::out).close(); // touch file }, [&] { return !std::filesystem::exists(fixed_path); }); std::fstream* file = nullptr; - retry("get file handle", [&] { + retry_while("get file handle", [&] { delete file; file = new std::fstream(fixed_path.c_str(), std::ios::out | std::ios::in); // open file }, [&] { @@ -76,12 +77,11 @@ std::fstream* CacheManager::cache_get(const char* filename) { return file; } -bool CacheManager::cache_exists(std::string filename) { return cache_exists(filename.c_str()); } bool CacheManager::cache_exists(const char* filename) { return std::filesystem::exists(prefix_cache_path(filename)); } - std::string CacheManager::prefix_cache_path(const char* filename) { return this->cache_path + "/" + std::string(filename); } + diff --git a/oop2eindopdr/CacheManager.h b/oop2eindopdr/CacheManager.h index 1e0a565..9bd47e3 100644 --- a/oop2eindopdr/CacheManager.h +++ b/oop2eindopdr/CacheManager.h @@ -15,7 +15,19 @@ private: const unsigned int max_tries = 100; - virtual void retry(std::string label, std::function action, std::function retry_if); + /** + * @brief retry `action` as long as `retry_if` returns false, until `max_tries` + * + * @param label this label gets printed if retry_count exceeds max_tries + * @param check_pre `true` = check `retry_if` before `action`, `false` = check `retry_if` after `action` + * @param action this gets executed as long as `retry_if` returns false + * @param retry_if this returns whether `action` is successful (boolean) + */ + virtual void retry(std::string label, bool check_pre, std::function action, std::function retry_if); + /** @brief alias for `retry` with `check_pre` = false (check after action) */ + virtual void retry_while(std::string label, std::function action, std::function retry_if) { retry(label, false, action, retry_if); }; + /** @brief alias for `retry` with `check_pre` = true (check before action) */ + virtual void retry_if(std::string label, std::function action, std::function retry_if) { retry(label, true, action, retry_if); }; public: /** @brief initialize CacheManager class at `cache_path` */ CacheManager(const char* cache_path); @@ -35,10 +47,10 @@ public: /** @brief get fstream for file in cache or create file */ virtual std::fstream* cache_get(const char* filename); - virtual std::fstream* cache_get(std::string filename); + virtual std::fstream* cache_get(std::string filename) { return cache_get(filename.c_str()); }; /** @brief check if file exists in cache */ virtual bool cache_exists(const char* filename); - virtual bool cache_exists(std::string filename); + virtual bool cache_exists(std::string filename) { return cache_exists(filename.c_str()); }; /** @brief add cache path before filename */ virtual std::string prefix_cache_path(const char* filename); diff --git a/oop2eindopdr/Pokedex.cpp b/oop2eindopdr/Pokedex.cpp index 8a9defe..c55469a 100644 --- a/oop2eindopdr/Pokedex.cpp +++ b/oop2eindopdr/Pokedex.cpp @@ -44,6 +44,7 @@ void Pokedex::load_collection_local() { while (std::getline(cache_collection, id)) { this->cards.push_back(new PokemonCard::from_cache(this, id)); } + cache_collection.close(); } void Pokedex::verify_collection() { @@ -79,7 +80,7 @@ std::vector Pokedex::search_cards_by_id_local(std::string query) { std::vector Pokedex::search_cards_by_id_remote(std::string query) { std::cout << "couldn't find card in cache, trying api..." << std::endl; - std::vector api_cards = api->get_cards_by_query((std::string("name:\"") + query + "\" OR id:\"" + query + "\"").c_str()); + std::vector api_cards = api->get_cards_by_query((std::string("name:\"") + query + "\" OR id:*" + query + "*").c_str()); std::vector out; for (PokemonCard* api_card : api_cards) { diff --git a/oop2eindopdr/PokemonCard.cpp b/oop2eindopdr/PokemonCard.cpp index eb6a6e5..9715fc3 100644 --- a/oop2eindopdr/PokemonCard.cpp +++ b/oop2eindopdr/PokemonCard.cpp @@ -100,6 +100,8 @@ void PokemonCard::raw_load_cache(const char* cache_path) { nlohmann::json raw_json = nlohmann::json::parse(info_json_content.str()); this->raw_load_json(raw_json); + + info_json_file.close(); } std::string PokemonCard::short_identifier() { -- cgit v1.2.3