summaryrefslogtreecommitdiffhomepage
path: root/main/editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/editor.cpp')
-rw-r--r--main/editor.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/main/editor.cpp b/main/editor.cpp
index 7759b596..58b1e14a 100644
--- a/main/editor.cpp
+++ b/main/editor.cpp
@@ -2,7 +2,9 @@
#include "serialize/json-helper.hpp"
#include "serialize/tile-atlas.hpp"
#include "src/loader.hpp"
+#include "random.hpp"
#include "compat/assert.hpp"
+#include "compat/unreachable.hpp"
#include <filesystem>
#include <vector>
@@ -23,6 +25,7 @@ void tile_type::load_atlases()
Containers::StringView name = atlas->name();
if (auto x = name.findLast('.'); x)
name = name.prefix(x.data());
+ std::get<1>(_permutation).reserve((std::size_t)atlas->num_tiles().product());
_atlases[name] = std::move(atlas);
}
}
@@ -43,6 +46,81 @@ std::shared_ptr<tile_atlas> tile_type::atlas(Containers::StringView str)
ABORT("no such atlas: %s", str.cbegin());
}
+void tile_type::clear_selection()
+{
+ _selected_tile = {};
+ _permutation = {};
+ _selection_mode = sel_none;
+}
+
+void tile_type::select_tile(const std::shared_ptr<tile_atlas>& atlas, std::uint8_t variant)
+{
+ ASSERT(atlas);
+ clear_selection();
+ _selection_mode = sel_tile;
+ _selected_tile = { atlas, variant };
+}
+
+void tile_type::select_tile_permutation(const std::shared_ptr<tile_atlas>& atlas)
+{
+ ASSERT(atlas);
+ clear_selection();
+ _selection_mode = sel_perm;
+ _permutation = { atlas, {} };
+}
+
+bool tile_type::is_tile_selected(const std::shared_ptr<tile_atlas>& atlas, std::uint8_t variant)
+{
+ ASSERT(atlas);
+ return _selection_mode == sel_tile && _selected_tile == std::make_tuple(atlas, variant);
+}
+
+bool tile_type::is_permutation_selected(const std::shared_ptr<tile_atlas>& atlas)
+{
+ ASSERT(atlas);
+ return _selection_mode == sel_perm && std::get<0>(_permutation) == atlas;
+}
+
+template<std::random_access_iterator T>
+void fisher_yates(T begin, T end)
+{
+ const auto N = std::distance(begin, end);
+ for (auto i = N-1; i >= 1; i--)
+ {
+ const auto j = random(i+1);
+ using std::swap;
+ swap(begin[i], begin[j]);
+ }
+}
+
+std::tuple<std::shared_ptr<tile_atlas>, std::uint8_t> tile_type::get_selected_perm()
+{
+ auto& [atlas, vec] = _permutation;
+ const std::size_t N = atlas->num_tiles().product();
+ if (N == 0)
+ return {};
+ if (vec.empty())
+ {
+ for (std::uint8_t i = 0; i < N; i++)
+ vec.push_back(i);
+ fisher_yates(vec.begin(), vec.end());
+ }
+ const auto idx = vec.back();
+ vec.pop_back();
+ return {atlas, idx};
+}
+
+std::optional<std::tuple<std::shared_ptr<tile_atlas>, std::uint8_t>> tile_type::get_selected()
+{
+ switch (_selection_mode)
+ {
+ case sel_none: return std::nullopt;
+ case sel_tile: return _selected_tile;
+ case sel_perm: return get_selected_perm();
+ default: unreachable();
+ }
+}
+
editor_state::editor_state()
{
}