14#include <MazeBuilder/maze_factory.h>
30 static std::string create_single(
const configurator &config)
32 auto grid_creator = [](
const configurator &config) -> std::unique_ptr<grid_interface>
34 return std::make_unique<grid>(config.rows(), config.columns(), config.levels());
37 auto maze_creator = [grid_creator](
const configurator &config) -> std::unique_ptr<maze_interface>
39 static constexpr auto GRID_CREATION_ID{
"g1"};
43 if (!gf.is_registered(GRID_CREATION_ID))
46 if (!gf.register_creator(GRID_CREATION_ID, grid_creator))
53 if (
auto igrid = gf.create(GRID_CREATION_ID, std::cref(config)); igrid.has_value())
55 static randomizer rng{};
57 rng.seed(config.seed());
62 auto &&igridimpl = igrid.value();
64 if (
auto success = algo_runner.value()->run(igridimpl.get(), std::ref(rng)))
66 static stringify _stringifier;
68 _stringifier.run(igridimpl.get(), std::ref(rng));
70 return std::make_unique<maze_str>(igridimpl->operations().get_str());
82 static constexpr auto MAZE_CREATION_ID{
"m1"};
86 if (!mf.is_registered(MAZE_CREATION_ID))
88 if(!mf.register_creator(MAZE_CREATION_ID, maze_creator))
94 if (
auto maze_optional = mf.create(MAZE_CREATION_ID, std::cref(config)); maze_optional.has_value())
96 s = maze_optional.value()->maze();
99 return !s.empty(); });
105 template <
typename... Configs>
106 static std::vector<std::string> create_async(
const Configs &...configs)
108 static_assert(
sizeof...(configs) > 1,
"Need multiple configs for concurrent execution");
110 const unsigned int hardware_threads = std::thread::hardware_concurrency();
111 const size_t num_configs =
sizeof...(configs);
113 std::vector<std::string> results;
114 results.reserve(num_configs);
116 if (hardware_threads > 1 && num_configs >= 2)
119 std::vector<std::future<std::string>> futures;
120 futures.reserve(num_configs);
123 auto launch_async = [](
const configurator &config)
125 return std::async(std::launch::async, [config]()
126 {
return create_single(config); });
129 (futures.push_back(launch_async(configs)), ...);
132 for (
auto &future : futures)
134 results.push_back(future.get());
140 (results.push_back(create_single(configs)), ...);
148 template <
typename Config>
149 static inline std::string create(
const Config &config)
152 using DecayedConfig = std::decay_t<Config>;
155 std::is_same_v<DecayedConfig, configurator> ||
156 std::is_same_v<DecayedConfig, std::reference_wrapper<configurator>> ||
157 std::is_same_v<DecayedConfig, std::reference_wrapper<const configurator>>,
158 "Parameter must be a configurator or reference to configurator");
161 if constexpr (std::is_same_v<DecayedConfig, std::reference_wrapper<configurator>> ||
162 std::is_same_v<DecayedConfig, std::reference_wrapper<const configurator>>)
165 return detail::create_single(config.get());
170 return detail::create_single(config);
175 template <
typename... Configs>
176 static inline std::vector<std::string> create(
const Configs &...configs)
178 static_assert(
sizeof...(configs) > 1,
"Use single parameter version for one configurator");
182 ((std::is_same_v<std::decay_t<Configs>, configurator> ||
183 std::is_same_v<std::decay_t<Configs>, std::reference_wrapper<configurator>> ||
184 std::is_same_v<std::decay_t<Configs>, std::reference_wrapper<const configurator>>) &&
186 "All parameters must be configurator objects or references to configurators");
189 auto unwrap_config = [](
const auto &cfg) ->
const configurator &
191 using ConfigType = std::decay_t<
decltype(cfg)>;
192 if constexpr (std::is_same_v<ConfigType, std::reference_wrapper<configurator>> ||
193 std::is_same_v<ConfigType, std::reference_wrapper<const configurator>>)
204 return detail::create_async(unwrap_config(configs)...);
static std::optional< std::unique_ptr< algo_interface > > make_algo_from_config(const configurator &config)
Determine the maze generation algorithm from the configuration.
Definition configurator.h:243
static Duration duration(F &&f, Args &&...args)
Definition progress.h:34
Namespace for the maze builder.
Definition algo_interface.h:6