mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 05:09:20 +02:00
feat(editor): undo and redo take back the kept alignments and switches together with the paths: each step of the history keeps the //$h and //$r records from before it; a deleted switch or slip forgets its record in the same step, so undoing the deletion brings it back; edits of the switch number, rail and km and forgetting a kept design stay outside the history; self-test commands deleting paths
This commit is contained in:
@@ -33,6 +33,8 @@ std::string const kMark{"//$h"};
|
||||
double const kStep{1.0};
|
||||
|
||||
std::vector<record> g_records;
|
||||
std::vector<record> g_base; // as they were before the changes not yet in the undo history
|
||||
bool g_changed{false};
|
||||
bool g_loaded{false};
|
||||
|
||||
// format of the lines, coordinates in the space of the file:
|
||||
@@ -257,6 +259,8 @@ stored_element describe(alignment::element const &Element)
|
||||
void reset()
|
||||
{
|
||||
g_records.clear();
|
||||
g_base.clear();
|
||||
g_changed = false;
|
||||
g_loaded = false;
|
||||
}
|
||||
|
||||
@@ -363,6 +367,8 @@ void load()
|
||||
}
|
||||
}
|
||||
}
|
||||
g_base = g_records;
|
||||
g_changed = false;
|
||||
if (false == g_records.empty())
|
||||
WriteLog("Editor: " + std::to_string(g_records.size()) + " horizontal alignment(s) read from the scenery", logtype::generic);
|
||||
}
|
||||
@@ -585,6 +591,7 @@ int store(alignment::design const &Design, alignment::result const &Result, doub
|
||||
g_records.push_back(std::move(entry));
|
||||
index = static_cast<int>(g_records.size()) - 1;
|
||||
}
|
||||
g_changed = true;
|
||||
mark(g_records[index].layer);
|
||||
return index;
|
||||
}
|
||||
@@ -596,6 +603,7 @@ void forget(int const Index)
|
||||
return;
|
||||
auto const layer{g_records[Index].layer};
|
||||
g_records.erase(g_records.begin() + Index);
|
||||
g_changed = true;
|
||||
mark(layer);
|
||||
}
|
||||
|
||||
@@ -607,4 +615,32 @@ std::optional<double> chainage_at(glm::dvec3 const &Point)
|
||||
return g_records[found->record].origin + found->chainage;
|
||||
}
|
||||
|
||||
std::optional<std::vector<record>> take_changes()
|
||||
{
|
||||
if (false == g_changed)
|
||||
return std::nullopt;
|
||||
auto before{std::move(g_base)};
|
||||
g_base = g_records;
|
||||
g_changed = false;
|
||||
return before;
|
||||
}
|
||||
|
||||
void settle()
|
||||
{
|
||||
g_base = g_records;
|
||||
g_changed = false;
|
||||
}
|
||||
|
||||
void restore(std::vector<record> Records)
|
||||
{
|
||||
std::set<scene::layer_handle> layers;
|
||||
for (auto const *list : {&g_records, &Records})
|
||||
for (auto const &entry : *list)
|
||||
layers.insert(entry.layer);
|
||||
g_records = std::move(Records);
|
||||
for (auto const layer : layers)
|
||||
mark(layer);
|
||||
settle();
|
||||
}
|
||||
|
||||
} // namespace alignment_store
|
||||
|
||||
@@ -87,5 +87,11 @@ int store(alignment::design const &Design, alignment::result const &Result, doub
|
||||
void forget(int const Index);
|
||||
// km of the point on the stored alignments, if it lies on one
|
||||
std::optional<double> chainage_at(glm::dvec3 const &Point);
|
||||
// the records as they were before the changes made since the last call, if there were any; the current ones become the base
|
||||
std::optional<std::vector<record>> take_changes();
|
||||
// the current records become the base, the changes made so far aren't a part of the undo history
|
||||
void settle();
|
||||
// puts the records back as they were, for undo and redo
|
||||
void restore(std::vector<record> Records);
|
||||
|
||||
} // namespace alignment_store
|
||||
|
||||
@@ -33,6 +33,8 @@ std::string const kMark{"//$r"};
|
||||
double const kTolerance{0.02};
|
||||
|
||||
std::vector<record> g_records;
|
||||
std::vector<record> g_base; // as they were before the changes not yet in the undo history
|
||||
bool g_changed{false};
|
||||
bool g_loaded{false};
|
||||
|
||||
// format of the lines, coordinates in the space of the file:
|
||||
@@ -100,6 +102,8 @@ void mark(scene::layer_handle const Layer)
|
||||
void reset()
|
||||
{
|
||||
g_records.clear();
|
||||
g_base.clear();
|
||||
g_changed = false;
|
||||
g_loaded = false;
|
||||
}
|
||||
|
||||
@@ -143,6 +147,8 @@ void load()
|
||||
g_records.push_back(std::move(entry));
|
||||
}
|
||||
}
|
||||
g_base = g_records;
|
||||
g_changed = false;
|
||||
if (false == g_records.empty())
|
||||
WriteLog("Editor: " + std::to_string(g_records.size()) + " switch record(s) read from the scenery", logtype::generic);
|
||||
}
|
||||
@@ -189,11 +195,13 @@ void put(record Entry, scene::layer_handle const Layer)
|
||||
if (Entry.number == "-")
|
||||
Entry.number = existing->number;
|
||||
*existing = std::move(Entry);
|
||||
g_changed = true;
|
||||
mark(existing->layer);
|
||||
return;
|
||||
}
|
||||
Entry.layer = Layer;
|
||||
g_records.push_back(std::move(Entry));
|
||||
g_changed = true;
|
||||
mark(g_records.back().layer);
|
||||
}
|
||||
|
||||
@@ -204,7 +212,9 @@ void forget(std::string const &Name)
|
||||
for (auto const &entry : g_records)
|
||||
if (entry.name == Name)
|
||||
layers.insert(entry.layer);
|
||||
auto const count{g_records.size()};
|
||||
g_records.erase(std::remove_if(g_records.begin(), g_records.end(), [&](record const &Entry) { return Entry.name == Name; }), g_records.end());
|
||||
g_changed = g_changed || g_records.size() != count;
|
||||
for (auto const layer : layers)
|
||||
mark(layer);
|
||||
}
|
||||
@@ -234,6 +244,7 @@ void tidy()
|
||||
g_records.erase(std::remove_if(g_records.begin(), g_records.end(), gone), g_records.end());
|
||||
for (auto const layer : layers)
|
||||
mark(layer);
|
||||
g_changed = g_changed || false == layers.empty();
|
||||
}
|
||||
|
||||
std::string label(record const &Record)
|
||||
@@ -254,4 +265,32 @@ std::string label(record const &Record)
|
||||
return text;
|
||||
}
|
||||
|
||||
std::optional<std::vector<record>> take_changes()
|
||||
{
|
||||
if (false == g_changed)
|
||||
return std::nullopt;
|
||||
auto before{std::move(g_base)};
|
||||
g_base = g_records;
|
||||
g_changed = false;
|
||||
return before;
|
||||
}
|
||||
|
||||
void settle()
|
||||
{
|
||||
g_base = g_records;
|
||||
g_changed = false;
|
||||
}
|
||||
|
||||
void restore(std::vector<record> Records)
|
||||
{
|
||||
std::set<scene::layer_handle> layers;
|
||||
for (auto const *list : {&g_records, &Records})
|
||||
for (auto const &entry : *list)
|
||||
layers.insert(entry.layer);
|
||||
g_records = std::move(Records);
|
||||
for (auto const layer : layers)
|
||||
mark(layer);
|
||||
settle();
|
||||
}
|
||||
|
||||
} // namespace switch_store
|
||||
|
||||
@@ -57,5 +57,11 @@ void forget(std::string const &Name);
|
||||
void tidy();
|
||||
// "Rz 60E1-500-1:12 L", as the type is written on the lists of the switches
|
||||
std::string label(record const &Record);
|
||||
// the records as they were before the changes made since the last call, if there were any; the current ones become the base
|
||||
std::optional<std::vector<record>> take_changes();
|
||||
// the current records become the base, the changes made so far aren't a part of the undo history
|
||||
void settle();
|
||||
// puts the records back as they were, for undo and redo
|
||||
void restore(std::vector<record> Records);
|
||||
|
||||
} // namespace switch_store
|
||||
|
||||
Reference in New Issue
Block a user