diff --git a/src/core/all_cases/internal/all_cases.cc b/src/core/all_cases/internal/all_cases.cc index 83f01bc..e7c8b0e 100644 --- a/src/core/all_cases/internal/all_cases.cc +++ b/src/core/all_cases/internal/all_cases.cc @@ -1,7 +1,3 @@ -#include - -#include "utils/utility.h" -#include "ranges/ranges.h" #include "all_cases/all_cases.h" using klotski::range_reverse; @@ -10,9 +6,11 @@ using klotski::cases::AllCases; using klotski::cases::BasicRanges; using klotski::cases::ALL_CASES_NUM; +typedef std::array Heads; + /// Generate all possible klotski heads. -static consteval std::array heads() { - std::array heads {}; +static consteval Heads get_heads() { + Heads heads {}; for (int i = 0, head = 0; head < 15; ++head) { if (head % 4 != 3) { heads[i++] = head; @@ -60,7 +58,6 @@ static void build_cases(const std::vector &ranges, if (offset > 14) { continue; } - // !! <- broken // ( xx xx xx ) xx xx xx ... [range] // +1 00 00 00 ... (delta) @@ -83,7 +80,6 @@ void AllCases::build() { if (available_) { return; // reduce consumption of mutex } - std::lock_guard guard {building_}; if (available_) { return; // data is already available @@ -94,7 +90,7 @@ void AllCases::build() { for (auto &x : reversed) { x = range_reverse(x); } - for (const auto head : heads()) { + for (const auto head : get_heads()) { build_cases(ranges, reversed, get_cases()[head], head); } available_ = true; @@ -105,7 +101,6 @@ void AllCases::build_async(Executor &&executor, Notifier &&callback) { callback(); return; // reduce consumption of mutex } - building_.lock(); if (available_) { building_.unlock(); @@ -113,21 +108,22 @@ void AllCases::build_async(Executor &&executor, Notifier &&callback) { return; // data is already available } - const auto counter = std::make_shared>(0); - const auto all_done = std::make_shared(std::move(callback)); - const auto reversed = std::make_shared>(BasicRanges::instance().fetch()); + auto &ranges = BasicRanges::instance().fetch(); + auto reversed = std::make_shared>(ranges); for (auto &x : *reversed) { x = range_reverse(x); } - for (const auto head : heads()) { - executor([=, this] { + Worker worker {executor}; + for (const auto head : get_heads()) { + worker.post([head, reversed] { build_cases(BasicRanges::instance().fetch(), *reversed, get_cases()[head], head); - if (counter->fetch_add(1) == heads().size() - 1) { // all tasks done - available_ = true; - building_.unlock(); // release building mutex - all_done->operator()(); // trigger callback - } }); } + + worker.then([this, callback = std::move(callback)] { + available_ = true; + building_.unlock(); + callback(); + }); }