17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-09 10:12:24 +01:00

refactor(editor): the speed check is a tool of its own

The second tool out of editor_mode. Tools get two more hooks, the overlay
drawn over the view and the options in the tool window, and the editor
gives them the track it focuses on, the node it makes current, the norms
of the route design and the snapshot of the tracks for the undo.

The check gets a self-test command, speedcheck <scope>, which runs it
through and logs the paths found too fast for their geometry.
This commit is contained in:
maj00r
2026-10-21 09:10:27 +02:00
parent 3c9c90b468
commit 0c2880f48f
7 changed files with 130 additions and 52 deletions

View File

@@ -8,8 +8,7 @@ http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "application/editormode.h"
#include "application/editoruilayer.h"
#include "application/editormodespeed.h"
#include "application/editorprojection.h"
#include "application/editormodeshared.h"
#include "editor/editorFormat.hpp"
@@ -44,7 +43,7 @@ std::string speed_text(double const Speed)
} // namespace
void editor_mode::speed_start()
void speed_tool::speed_start()
{
auto &state{m_speed};
state.queue.clear();
@@ -52,14 +51,14 @@ void editor_mode::speed_start()
state.results.clear();
state.selected = -1;
state.status.clear();
state.options.norms = m_route.design.norms;
state.options.norms = m_services.route_norms();
auto const add = [&](TTrack *Track) {
for (int i = 0; i < static_cast<int>(Track->m_paths.size()); ++i)
state.queue.emplace_back(Track, i);
};
if (state.scope == 0)
{
auto *track{selected_track()};
auto *track{m_services.selected_track()};
if (track == nullptr || false == rail(*track))
{
state.status = STR_C("Select a track first");
@@ -88,10 +87,10 @@ void editor_mode::speed_start()
if (track != nullptr && rail(*track))
add(track);
}
state.history = m_history.size();
state.history = m_services.history_size();
}
void editor_mode::speed_step()
void speed_tool::update()
{
auto &state{m_speed};
if (state.next >= state.queue.size())
@@ -122,7 +121,7 @@ void editor_mode::speed_step()
WriteLog("Editor: speed check - " + state.status, logtype::generic);
}
std::vector<int> editor_mode::speed_listed() const
std::vector<int> speed_tool::speed_listed() const
{
std::vector<int> listed;
for (int i = 0; i < static_cast<int>(m_speed.results.size()); ++i)
@@ -136,7 +135,7 @@ std::vector<int> editor_mode::speed_listed() const
return listed;
}
void editor_mode::speed_focus(int const Index)
void speed_tool::speed_focus(int const Index)
{
auto &state{m_speed};
if (Index < 0 || Index >= static_cast<int>(state.results.size()))
@@ -146,12 +145,11 @@ void editor_mode::speed_focus(int const Index)
auto const &paths{simulation::Paths.sequence()};
if (std::find(paths.begin(), paths.end(), verdict.track) == paths.end() || verdict.track->m_editorremoved)
return;
m_node = verdict.track;
ui()->set_node(m_node);
focus_track(*verdict.track, verdict.path, verdict.position);
m_services.set_current_node(verdict.track);
m_services.focus_track(*verdict.track, verdict.path, verdict.position);
}
void editor_mode::speed_apply(std::vector<int> const &Indices, bool const Branches)
void speed_tool::speed_apply(std::vector<int> const &Indices, bool const Branches)
{
auto &state{m_speed};
struct change
@@ -191,7 +189,7 @@ void editor_mode::speed_apply(std::vector<int> const &Indices, bool const Branch
state.status = STR_C("Nothing changed") + skipped;
return;
}
push_track_snapshot(std::move(states));
m_services.push_track_snapshot(std::move(states));
for (auto const &entry : changes)
{
auto const velocity{entry.track->eType == tt_Switch ? speed_check::switch_velocity(entry.limits[0], entry.limits[1]) : entry.limits[0]};
@@ -200,12 +198,12 @@ void editor_mode::speed_apply(std::vector<int> const &Indices, bool const Branch
}
for (auto &verdict : state.results)
verdict.set = speed_check::path_velocity(*verdict.track, verdict.path);
state.history = m_history.size();
state.history = m_services.history_size();
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);
}
void editor_mode::render_speed_body()
void speed_tool::render_options()
{
auto &state{m_speed};
ImGui::PushTextWrapPos(0.0f);
@@ -264,7 +262,7 @@ void editor_mode::render_speed_body()
ImGui::TextWrapped("%s", state.status.c_str());
if (state.results.empty())
return;
if (state.history != m_history.size())
if (state.history != m_services.history_size())
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};
@@ -357,7 +355,7 @@ void editor_mode::render_speed_body()
}
}
void editor_mode::draw_speed_overlay() const
void speed_tool::draw_overlay() const
{
auto const &state{m_speed};
if (false == state.open || state.results.empty())
@@ -380,3 +378,30 @@ void editor_mode::draw_speed_overlay() const
drawlist->AddText(ImVec2(screen.x + 14.0f, screen.y - 7.0f), colour, text.c_str());
}
}
void speed_tool::check_line()
{
m_speed.scope = 0;
speed_start();
}
editor_selftest_result speed_tool::selftest(std::string const &Command, std::istringstream &Words)
{
if (Command == "speedcheck")
{
int scope{0};
Words >> scope;
m_speed.scope = scope;
speed_start();
while (m_speed.next < m_speed.queue.size())
update();
WriteLog("SELFTEST speedcheck: " + m_speed.status);
for (auto const index : speed_listed())
{
auto const &verdict{m_speed.results[index]};
WriteLog(format("SELFTEST speedcheck %s path %d: set %.0f safe %.0f", verdict.track->name().c_str(), verdict.path, verdict.set, verdict.safe));
}
return editor_selftest_result::handled;
}
return editor_selftest_result::unhandled;
}