diff --git a/application/editormode.h b/application/editormode.h index ccb9ea1d..9fd03efa 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -167,6 +167,12 @@ class editor_mode : public application_mode, private editor_track::observer, pri std::vector copies; // models an array added to the one it was made of bool joined{false}; // undone and redone together with the change before it std::shared_ptr terrain; // the heightmap terrain from before the change (Action::Terrain) + std::uint64_t serial{next_serial()}; // of each step made, for the revision of the history + static std::uint64_t next_serial() + { + static std::uint64_t counter{0}; + return ++counter; + } }; void push_snapshot(scene::basic_node *node, EditorSnapshot::Action Action = EditorSnapshot::Action::Move, std::string const &Serialized = std::string()); @@ -782,7 +788,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri TTrack *selected_track() const override; bool track_editing() const override; - std::size_t history_size() const override; + std::size_t history_revision() const override; glm::dvec3 camera_position() const override; track_hover const &hovered_track() const override; std::vector const &track_set() const override; diff --git a/application/editormodegauge.cpp b/application/editormodegauge.cpp index 4260033f..42ecf58c 100644 --- a/application/editormodegauge.cpp +++ b/application/editormodegauge.cpp @@ -604,10 +604,10 @@ void gauge_tool::update() m_gauge.published = false; } } - else if (track != m_gauge.track || m_history.history_size() != m_gauge.history || m_gauge.pending) + else if (track != m_gauge.track || m_history.history_revision() != m_gauge.history || m_gauge.pending) { m_gauge.track = track; - m_gauge.history = m_history.history_size(); + m_gauge.history = m_history.history_revision(); m_gauge.pending = false; scan_gauge(*track); m_gauge.published = false; @@ -645,7 +645,7 @@ void gauge_tool::scan_gauge_map() scan->space.emplace(scan->lines); m_gauge.map = {}; m_gauge.map.scanned = true; - m_gauge.map.history = m_history.history_size(); + m_gauge.map.history = m_history.history_revision(); auto const name{[](gauge::profile const *Profile) { return Profile != nullptr ? Profile->name : std::string{"-"}; }}; m_gauge.map.profile = name(chosen.railway) + ", " + name(chosen.road); m_gauge.current = -1; @@ -799,7 +799,7 @@ void gauge_tool::render_windows() m_gauge.current = -1; m_gauge.published = false; } - else if (m_gauge.map.history != m_history.history_size()) + else if (m_gauge.map.history != m_history.history_revision()) ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), STR_C("The scenery changed since the scan (%s)"), m_gauge.map.profile.c_str()); } render_gauge_hits(); diff --git a/application/editormodejoints.cpp b/application/editormodejoints.cpp index dff1cf4b..1d61aa66 100644 --- a/application/editormodejoints.cpp +++ b/application/editormodejoints.cpp @@ -164,7 +164,7 @@ void joints_tool::joints_start() continue; state.queue.push_back(track); } - state.history = m_history.history_size(); + state.history = m_history.history_revision(); state.places.clear(); state.runs.clear(); state.run_next = 0; @@ -568,7 +568,7 @@ void joints_tool::joints_fix(std::vector const &Indices) editor_track::commit(changed); for (auto *track : changed) track->mark_dirty(); - state.history = m_history.history_size(); + state.history = m_history.history_revision(); state.status = format(STR_C("%zu joints fixed, Ctrl+Z takes them back"), count); WriteLog("Editor: joints check - " + state.status, logtype::generic); } @@ -646,7 +646,7 @@ void joints_tool::render_options() ImGui::TextWrapped("%s", state.status.c_str()); if (state.issues.empty()) return; - if (state.history != m_history.history_size()) + if (state.history != m_history.history_revision()) ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", STR_C("The scenery changed since the check")); int filter{state.filter + 1}; ImGui::SetNextItemWidth(150.0f); diff --git a/application/editormodelineside.cpp b/application/editormodelineside.cpp index 58985fb0..20c5294e 100644 --- a/application/editormodelineside.cpp +++ b/application/editormodelineside.cpp @@ -404,10 +404,10 @@ void hekto_tool::hekto_read_kilometrage() void hekto_tool::hekto_update() { auto &tool{m_hekto}; - if (false == tool.dirty && tool.history == m_history.history_size()) + if (false == tool.dirty && tool.history == m_history.history_revision()) return; tool.dirty = false; - tool.history = m_history.history_size(); + tool.history = m_history.history_revision(); tool.posts.clear(); tool.found.clear(); tool.error.clear(); @@ -774,10 +774,10 @@ void fouling_tool::fouling_update() auto *selected{m_selection.selected_track()}; if (tool.scope == 0 && selected != tool.selected) tool.dirty = true; - if (false == tool.dirty && tool.history == m_history.history_size()) + if (false == tool.dirty && tool.history == m_history.history_revision()) return; tool.dirty = false; - tool.history = m_history.history_size(); + tool.history = m_history.history_revision(); tool.selected = selected; tool.points.clear(); tool.found.clear(); diff --git a/application/editormodeparallel.cpp b/application/editormodeparallel.cpp index 9253d51f..4a35bdd2 100644 --- a/application/editormodeparallel.cpp +++ b/application/editormodeparallel.cpp @@ -240,13 +240,13 @@ void parallel_tool::parallel_update() else if (track != nullptr && target != nullptr) tool.measured = std::abs(lateral_of(*track, *target)); - if (track == tool.built_for && tool.spacing == tool.built_spacing && tool.side == tool.built_side && tool.scope == tool.built_scope && m_history.history_size() == tool.built_history) + if (track == tool.built_for && tool.spacing == tool.built_spacing && tool.side == tool.built_side && tool.scope == tool.built_scope && m_history.history_revision() == tool.built_history) return; tool.built_for = track; tool.built_spacing = tool.spacing; tool.built_side = tool.side; tool.built_scope = tool.scope; - tool.built_history = m_history.history_size(); + tool.built_history = m_history.history_revision(); tool.pieces.clear(); tool.styles.clear(); tool.length = 0.0; diff --git a/application/editormodespeed.cpp b/application/editormodespeed.cpp index 8927886b..f3278dce 100644 --- a/application/editormodespeed.cpp +++ b/application/editormodespeed.cpp @@ -87,7 +87,7 @@ void speed_tool::speed_start() if (track != nullptr && rail(*track)) add(track); } - state.history = m_history.history_size(); + state.history = m_history.history_revision(); } void speed_tool::update() @@ -198,7 +198,7 @@ void speed_tool::speed_apply(std::vector const &Indices, bool const Branche } for (auto &verdict : state.results) verdict.set = speed_check::path_velocity(*verdict.track, verdict.path); - state.history = m_history.history_size(); + state.history = m_history.history_revision(); state.status = format(STR_C("Speed limits of %zu paths lowered to the safe ones, Ctrl+Z brings them back"), changes.size()) + skipped; WriteLog("Editor: speed check - " + state.status, logtype::generic); } @@ -262,7 +262,7 @@ void speed_tool::render_options() ImGui::TextWrapped("%s", state.status.c_str()); if (state.results.empty()) return; - if (state.history != m_history.history_size()) + if (state.history != m_history.history_revision()) ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), STR_C("The scenery changed since the check")); auto const *const within{STR_C("Within their limits too")}; auto const checkbox{ImGui::GetFrameHeight() + ImGui::GetStyle().ItemInnerSpacing.x + ImGui::CalcTextSize(within).x}; diff --git a/application/editormodesrk.cpp b/application/editormodesrk.cpp index f55c9e0a..d447dafc 100644 --- a/application/editormodesrk.cpp +++ b/application/editormodesrk.cpp @@ -318,7 +318,7 @@ void srk_tool::open(TTrack &Track) m_layout = std::move(found); m_hover = -1; m_view_state.exaggeration = 0.0f; - m_history_size = m_history.history_size(); + m_history_revision = m_history.history_revision(); // the record of the station, by any of its switches m_record = -1; for (int index = 0; index < static_cast(m_records.size()) && m_record < 0; ++index) @@ -336,7 +336,7 @@ void srk_tool::open(TTrack &Track) void srk_tool::refresh() { - m_history_size = m_history.history_size(); + m_history_revision = m_history.history_revision(); if (m_anchor == nullptr || m_anchor->m_editorremoved) { m_layout.reset(); @@ -405,7 +405,7 @@ void srk_tool::update() entry.anchor = name; m_changed = true; } - if ((m_layout.has_value() || m_anchor != nullptr) && m_history.history_size() != m_history_size) + if ((m_layout.has_value() || m_anchor != nullptr) && m_history.history_revision() != m_history_revision) refresh(); else if (m_layout.has_value() && false == m_signals_known) survey_signals(); @@ -445,7 +445,7 @@ void srk_tool::forget(scene::basic_node const *Node) // laid out again from its anchor at the next update m_layout.reset(); m_hover = -1; - m_history_size = 0; + m_history_revision = static_cast(-1); } } diff --git a/application/editormodesrk.h b/application/editormodesrk.h index 605676c3..d5c79e34 100644 --- a/application/editormodesrk.h +++ b/application/editormodesrk.h @@ -74,7 +74,7 @@ class srk_tool final : public editor_tool int m_record{-1}; // of the open station, -1 while it has none TTrack *m_anchor{nullptr}; // the switch the open station was found from bool m_reversed{false}; // the switches numbered from the right end of the schematic - std::size_t m_history_size{0}; + std::size_t m_history_revision{0}; TTrack const *m_picked{nullptr}; // the track selected when the station was looked for view m_view_state; int m_hover{-1}; // path of the layout under the mouse in the schematic diff --git a/application/editormodetrack.cpp b/application/editormodetrack.cpp index 1470d8e5..7deed462 100644 --- a/application/editormodetrack.cpp +++ b/application/editormodetrack.cpp @@ -59,9 +59,10 @@ bool editor_mode::track_editing() const return m_track_gizmo_using || m_dragging; } -std::size_t editor_mode::history_size() const +std::size_t editor_mode::history_revision() const { - return m_history.size(); + auto const top{m_history.empty() ? std::uint64_t{0} : m_history.back().serial}; + return static_cast(top * 1000003u) ^ (m_history.size() << 20) ^ g_redo.size(); } glm::dvec3 editor_mode::camera_position() const diff --git a/application/editortool.h b/application/editortool.h index 70f1c41e..267350ed 100644 --- a/application/editortool.h +++ b/application/editortool.h @@ -165,7 +165,8 @@ class editor_view class editor_history { public: - virtual std::size_t history_size() const = 0; + // changes with each step of the history taken, undone or redone, also once the oldest steps are dropped + virtual std::size_t history_revision() const = 0; virtual void push_track_snapshot(std::vector> States, std::vector Created = {}, std::vector Removed = {}) = 0; // the changes of the kilometrage made since the last step: one step of the history virtual void push_kilometrage_snapshot() = 0;