mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-26 20:34:54 +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:
@@ -1466,13 +1466,13 @@ bool editor_mode::update()
|
||||
draw_track_spread();
|
||||
draw_build_overlay();
|
||||
draw_track_intent();
|
||||
speed_step();
|
||||
m_speed.update();
|
||||
joints_step();
|
||||
draw_track_hints();
|
||||
draw_empty_scenery_hint();
|
||||
draw_profile_overlay();
|
||||
draw_infra_overlay();
|
||||
draw_speed_overlay();
|
||||
m_speed.draw_overlay();
|
||||
draw_joints_overlay();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "input/editorkeyboardinput.h"
|
||||
#include "vehicle/Camera.h"
|
||||
#include "application/editormodegauge.h"
|
||||
#include "application/editormodespeed.h"
|
||||
#include "application/editortool.h"
|
||||
#include "scene/sceneeditor.h"
|
||||
#include "scene/scenenode.h"
|
||||
@@ -745,7 +746,9 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void render_track_gizmo();
|
||||
void commit_track_drag(bool const Force);
|
||||
void cancel_track_tools();
|
||||
void push_track_snapshot(std::vector<std::pair<TTrack *, editor_track::state>> States, std::vector<TTrack *> Created = {}, std::vector<TTrack *> Removed = {});
|
||||
void push_track_snapshot(std::vector<std::pair<TTrack *, editor_track::state>> States, std::vector<TTrack *> Created = {}, std::vector<TTrack *> Removed = {}) override;
|
||||
void set_current_node(scene::basic_node *Node) override;
|
||||
alignment::limits const &route_norms() const override;
|
||||
// false, with the reason, when one of the paths can't be changed, its file not taking the changes back
|
||||
static bool tracks_editable(std::vector<TTrack *> const &Tracks, std::string &Reason);
|
||||
void trim_history();
|
||||
@@ -857,8 +860,6 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
std::string m_track_events_missing;
|
||||
void render_path_events(TTrack &Track);
|
||||
std::string m_track_mode_notice;
|
||||
gauge_tool m_gauge{*this};
|
||||
std::vector<editor_tool *> m_tools{&m_gauge};
|
||||
struct route_design
|
||||
{
|
||||
TTrack *from{nullptr};
|
||||
@@ -1619,7 +1620,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void track_context_release();
|
||||
void render_track_context();
|
||||
void split_track_at(TTrack &Track, glm::dvec3 const &Point);
|
||||
void focus_track(TTrack &Track, int const Path, glm::dvec3 const &Point);
|
||||
void focus_track(TTrack &Track, int const Path, glm::dvec3 const &Point) override;
|
||||
// the camera flies over Duration seconds to the place Distance back from the target along Look, looking along it
|
||||
void fly_to(glm::dvec3 const &Target, glm::dvec3 const &Look, double const Distance, double const Duration = 0.6) override;
|
||||
// paths found by their names
|
||||
@@ -2458,30 +2459,9 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void infra_attach(EditorSnapshot &Snapshot);
|
||||
void render_infra_body();
|
||||
|
||||
// speed limits of the paths checked against what their geometry allows
|
||||
struct speed_state
|
||||
{
|
||||
bool open{false};
|
||||
int scope{0}; // 0: the line through the selected path, 1: the whole scenery
|
||||
speed_check::options options;
|
||||
std::vector<std::pair<TTrack *, int>> queue;
|
||||
std::size_t next{0};
|
||||
std::vector<speed_check::verdict> results;
|
||||
bool show_all{false};
|
||||
int limits{0}; // 0: all the paths, 1: only those with a speed limit set, 2: only those without
|
||||
int selected{-1};
|
||||
std::size_t history{0}; // size of the undo history at the check
|
||||
std::string status;
|
||||
};
|
||||
speed_state m_speed;
|
||||
void render_speed_body();
|
||||
void speed_start();
|
||||
void speed_step();
|
||||
void speed_focus(int const Index);
|
||||
// with Branches the limits of the switch branches count too, otherwise they're only warnings
|
||||
void speed_apply(std::vector<int> const &Indices, bool const Branches);
|
||||
std::vector<int> speed_listed() const;
|
||||
void draw_speed_overlay() const;
|
||||
gauge_tool m_gauge{*this};
|
||||
speed_tool m_speed{*this};
|
||||
std::vector<editor_tool *> m_tools{&m_gauge, &m_speed};
|
||||
|
||||
// joints of the paths: ends which almost meet, steps, kinks, jumps of the cant and of the grade
|
||||
struct joints_state
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
53
application/editormodespeed.h
Normal file
53
application/editormodespeed.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "application/editortool.h"
|
||||
#include "editor/editorSpeed.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class speed_tool final : public editor_tool
|
||||
{
|
||||
public:
|
||||
explicit speed_tool(editor_services &Services) : m_services{Services} {}
|
||||
void update() override;
|
||||
void draw_overlay() const override;
|
||||
void render_options() override;
|
||||
editor_selftest_result selftest(std::string const &Command, std::istringstream &Words) override;
|
||||
void set_open(bool const Open) { m_speed.open = Open; }
|
||||
void check_line();
|
||||
|
||||
private:
|
||||
editor_services &m_services;
|
||||
// speed limits of the paths checked against what their geometry allows
|
||||
struct speed_state
|
||||
{
|
||||
bool open{false};
|
||||
int scope{0}; // 0: the line through the selected path, 1: the whole scenery
|
||||
speed_check::options options;
|
||||
std::vector<std::pair<TTrack *, int>> queue;
|
||||
std::size_t next{0};
|
||||
std::vector<speed_check::verdict> results;
|
||||
bool show_all{false};
|
||||
int limits{0}; // 0: all the paths, 1: only those with a speed limit set, 2: only those without
|
||||
int selected{-1};
|
||||
std::size_t history{0}; // size of the undo history at the check
|
||||
std::string status;
|
||||
};
|
||||
speed_state m_speed;
|
||||
void speed_start();
|
||||
void speed_focus(int const Index);
|
||||
// with Branches the limits of the switch branches count too, otherwise they're only warnings
|
||||
void speed_apply(std::vector<int> const &Indices, bool const Branches);
|
||||
std::vector<int> speed_listed() const;
|
||||
};
|
||||
@@ -67,6 +67,17 @@ glm::dvec3 editor_mode::camera_position() const
|
||||
return Camera.Pos;
|
||||
}
|
||||
|
||||
void editor_mode::set_current_node(scene::basic_node *Node)
|
||||
{
|
||||
m_node = Node;
|
||||
ui()->set_node(m_node);
|
||||
}
|
||||
|
||||
alignment::limits const &editor_mode::route_norms() const
|
||||
{
|
||||
return m_route.design.norms;
|
||||
}
|
||||
|
||||
void editor_mode::select_track(scene::basic_node *Node)
|
||||
{
|
||||
auto *track = dynamic_cast<TTrack *>(Node);
|
||||
@@ -514,7 +525,7 @@ void editor_mode::render_track_inspector()
|
||||
{
|
||||
auto const &io{ImGui::GetIO()};
|
||||
m_profile.open = m_track_window_open && m_track_tab == track_tab::profile;
|
||||
m_speed.open = m_track_window_open && m_track_tab == track_tab::speed;
|
||||
m_speed.set_open(m_track_window_open && m_track_tab == track_tab::speed);
|
||||
m_infra.open = m_track_window_open && m_track_tab == track_tab::infra;
|
||||
m_joints.open = m_track_window_open && m_track_tab == track_tab::joints;
|
||||
if (false == m_track_window_open || m_track_tab != track_tab::lineside)
|
||||
@@ -547,7 +558,7 @@ void editor_mode::render_track_inspector()
|
||||
{
|
||||
switch (m_track_tab)
|
||||
{
|
||||
case track_tab::speed: render_speed_body(); break;
|
||||
case track_tab::speed: m_speed.render_options(); break;
|
||||
case track_tab::joints: render_joints_body(); break;
|
||||
default: render_infra_body(); break;
|
||||
}
|
||||
|
||||
@@ -814,9 +814,8 @@ void editor_mode::render_track_context()
|
||||
}
|
||||
if (ImGui::MenuItem(STR_C("Speed check of the line"), "V"))
|
||||
{
|
||||
m_speed.scope = 0;
|
||||
show_track_tab(track_tab::speed);
|
||||
speed_start();
|
||||
m_speed.check_line();
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(track_selected(track) ? STR_C("Take out of the selection") : STR_C("Add to the selection"), STR_C("Shift+LMB")))
|
||||
|
||||
@@ -12,9 +12,13 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include <cstddef>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "editor/editorTrack.hpp"
|
||||
|
||||
class TTrack;
|
||||
namespace scene
|
||||
{
|
||||
@@ -36,6 +40,10 @@ class editor_services
|
||||
virtual std::size_t history_size() const = 0;
|
||||
virtual glm::dvec3 camera_position() const = 0;
|
||||
virtual void fly_to(glm::dvec3 const &Target, glm::dvec3 const &Look, double const Distance, double const Duration = 0.6) = 0;
|
||||
virtual void focus_track(TTrack &Track, int const Path, glm::dvec3 const &Point) = 0;
|
||||
virtual void set_current_node(scene::basic_node *Node) = 0;
|
||||
virtual alignment::limits const &route_norms() const = 0;
|
||||
virtual void push_track_snapshot(std::vector<std::pair<TTrack *, editor_track::state>> States, std::vector<TTrack *> Created = {}, std::vector<TTrack *> Removed = {}) = 0;
|
||||
|
||||
protected:
|
||||
~editor_services() = default;
|
||||
@@ -46,6 +54,8 @@ class editor_tool
|
||||
public:
|
||||
virtual ~editor_tool() = default;
|
||||
virtual void update() {}
|
||||
virtual void draw_overlay() const {}
|
||||
virtual void render_options() {}
|
||||
virtual void render_windows() {}
|
||||
virtual void forget(scene::basic_node const *Node) {}
|
||||
virtual editor_selftest_result selftest(std::string const &Command, std::istringstream &Words) { return editor_selftest_result::unhandled; }
|
||||
|
||||
Reference in New Issue
Block a user