mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-29 01:07:28 +01:00
Catenary as plain node entries in scenery files
This commit is contained in:
@@ -3004,15 +3004,30 @@ bool editor_mode::save()
|
||||
std::transform(b.begin(), b.end(), b.begin(), [](unsigned char const C) { return static_cast<char>(std::tolower(C)); });
|
||||
return a == b;
|
||||
};
|
||||
// the catenary straight in the scenery files: the node entries of the changed ones go into the files of their layers anew
|
||||
scene::node_blocks catenaryblocks;
|
||||
catenaryblocks.kinds = {"suspension", "chain", "gantry", "anchor"};
|
||||
std::vector<std::string> catenaryinline;
|
||||
for (auto const &file : catenary_scene_files())
|
||||
{
|
||||
// a catenary file of the name of a scenery file would take its place, and the scenery its directive
|
||||
for (std::size_t layer = 1; layer <= scene::Layers.size(); ++layer)
|
||||
if (false == catenary_scene_file_inline(file) || false == catenary_scene_file_changed(file))
|
||||
continue;
|
||||
scene::layer_handle target{null_handle};
|
||||
for (std::size_t layer = 1; layer <= scene::Layers.size() && target == null_handle; ++layer)
|
||||
if (scene::Layers.listed(static_cast<scene::layer_handle>(layer)) && same_file(scene::Layers.layer(static_cast<scene::layer_handle>(layer)).name, file))
|
||||
{
|
||||
ui()->set_status(format(STR_C("The catenary couldn't be saved: its file \"%s\" is a file of the scenery; give the catenary another file"), file.c_str()), true);
|
||||
return false;
|
||||
}
|
||||
target = static_cast<scene::layer_handle>(layer);
|
||||
std::string reason;
|
||||
if (target == null_handle)
|
||||
reason = STR("it isn't in a scenery file the editor can rewrite (an include template)");
|
||||
else
|
||||
scene::Layers.accepts(target, &reason);
|
||||
if (target == null_handle || false == scene::Layers.accepts(target))
|
||||
{
|
||||
ui()->set_status(format(STR_C("The catenary in \"%s\" couldn't be saved: %s"), file.c_str(), reason.c_str()), true);
|
||||
return false;
|
||||
}
|
||||
catenaryblocks.lines[target] = catenary_scene_entries(file);
|
||||
catenaryinline.push_back(file);
|
||||
}
|
||||
if (catenary_scene_changed())
|
||||
{
|
||||
@@ -3055,7 +3070,10 @@ bool editor_mode::save()
|
||||
trailing.insert(trailing.end(), trainset.lines.begin(), trainset.lines.end());
|
||||
if (placed == 0)
|
||||
starter_trainset(trailing);
|
||||
auto const result = scene::Layers.save(rootstatements, trailing, layerstatements);
|
||||
auto const result = scene::Layers.save(rootstatements, trailing, layerstatements, &catenaryblocks);
|
||||
if (result.success)
|
||||
for (auto const &file : catenaryinline)
|
||||
catenary_scene_file_saved(file);
|
||||
if (result.success && controls)
|
||||
m_turntable_included = true;
|
||||
if (result.success && noses)
|
||||
|
||||
@@ -695,29 +695,34 @@ void catenary_editor::catenary_file_follow()
|
||||
auto const active{scene::Layers.active()};
|
||||
if (false == scene::Layers.valid(active))
|
||||
return; // the scenery wasn't opened for editing: no layers
|
||||
// the catenary file of the active layer (the one it includes), or a new one named after it next to it; not while a chain
|
||||
// goes on (a chain is in one file) nor when the user gave the file
|
||||
// the new poles go into the file of the active layer, as its node entries; not while a chain goes on (a chain is in one
|
||||
// file) nor when the user gave the file
|
||||
if (false == tool.file_own && tool.last < 0 && tool.selected < 0)
|
||||
{
|
||||
std::string wanted;
|
||||
for (auto const &file : catenary_scene_files())
|
||||
if (catenary_scene_file_layer(file) == active)
|
||||
{
|
||||
wanted = file;
|
||||
break;
|
||||
}
|
||||
if (wanted.empty())
|
||||
{
|
||||
std::filesystem::path const name{scene::Layers.layer(active).name};
|
||||
wanted = (name.parent_path() / (name.stem().string() + "_siec.scm")).generic_string();
|
||||
}
|
||||
std::snprintf(tool.file, sizeof(tool.file), "%s", wanted.c_str());
|
||||
}
|
||||
// a file the scenery doesn't include yet gets its directive in the file of the active layer
|
||||
if (tool.file[0] != '\0')
|
||||
std::snprintf(tool.file, sizeof(tool.file), "%s", scene::Layers.layer(active).name.c_str());
|
||||
if (tool.file[0] == '\0')
|
||||
return;
|
||||
// the file of a layer takes the entries straight; another one is a catenary file of its own (catenary <file> endcatenary),
|
||||
// whose directive goes into the file of the active layer
|
||||
if (catenary_layer_of(tool.file) != 0)
|
||||
catenary_scene_file_inline(tool.file, true);
|
||||
else if (false == catenary_scene_file_inline(tool.file))
|
||||
catenary_scene_file_layer(tool.file, active);
|
||||
}
|
||||
|
||||
std::size_t catenary_editor::catenary_layer_of(std::string const &File)
|
||||
{
|
||||
auto const same = [](std::string const &A, std::string const &B) {
|
||||
auto a{std::filesystem::path(A).lexically_normal().generic_string()}, b{std::filesystem::path(B).lexically_normal().generic_string()};
|
||||
std::transform(a.begin(), a.end(), a.begin(), [](unsigned char const C) { return static_cast<char>(std::tolower(C)); });
|
||||
std::transform(b.begin(), b.end(), b.begin(), [](unsigned char const C) { return static_cast<char>(std::tolower(C)); });
|
||||
return a == b;
|
||||
};
|
||||
for (std::size_t layer = 1; layer <= scene::Layers.size(); ++layer)
|
||||
if (scene::Layers.listed(static_cast<scene::layer_handle>(layer)) && same(scene::Layers.layer(static_cast<scene::layer_handle>(layer)).name, File))
|
||||
return layer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool catenary_editor::typed_span() const
|
||||
{
|
||||
auto const &tool{m_catenary};
|
||||
@@ -4278,7 +4283,7 @@ void catenary_editor::render_catenary_cantilever_ui()
|
||||
if (ImGui::InputText(STR_C("Catenary file"), tool.file, sizeof(tool.file)))
|
||||
tool.file_own = true;
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("File in the scenery directory the new poles go to; a new one is added to the scenery with the directive catenary <file> endcatenary when it's saved, in the file of the active layer. By default the catenary file of the active layer, or a new one named after it"));
|
||||
ImGui::SetTooltip("%s", STR_C("Where the new poles go: by default the file of the active layer, as its node entries (node ... suspension / chain / gantry / anchor), saved with the scenery. Another file name makes a catenary file of its own, included with catenary <file> endcatenary from the file of the active layer"));
|
||||
if (tool.file_own)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
@@ -4288,15 +4293,20 @@ void catenary_editor::render_catenary_cantilever_ui()
|
||||
ImGui::SetTooltip("%s", STR_C("The catenary file follows the active layer again"));
|
||||
}
|
||||
{
|
||||
// where it ends up: the file, and the layer whose file includes it
|
||||
auto const layer{static_cast<scene::layer_handle>(catenary_scene_file_layer(tool.file))};
|
||||
auto const files{catenary_scene_files()};
|
||||
auto const known{std::find(files.begin(), files.end(), std::string{tool.file}) != files.end()};
|
||||
auto const fresh{catenary_scene_new_files()};
|
||||
auto const created{known && std::find(fresh.begin(), fresh.end(), std::string{tool.file}) != fresh.end()};
|
||||
auto const layername{scene::Layers.valid(layer) ? scene::Layers.layer(layer).name : std::string{}};
|
||||
if (false == layername.empty())
|
||||
ImGui::TextDisabled("%s", format(known && false == created ? STR_C("included by %s") : STR_C("new: the save writes it and its directive into %s"), layername.c_str()).c_str());
|
||||
// where it ends up: straight in the file of a layer, or a catenary file of its own and the layer whose file includes it
|
||||
if (catenary_scene_file_inline(tool.file))
|
||||
ImGui::TextDisabled("%s", STR_C("node entries in this scenery file (layer), saved with the scenery"));
|
||||
else
|
||||
{
|
||||
auto const layer{static_cast<scene::layer_handle>(catenary_scene_file_layer(tool.file))};
|
||||
auto const files{catenary_scene_files()};
|
||||
auto const known{std::find(files.begin(), files.end(), std::string{tool.file}) != files.end()};
|
||||
auto const fresh{catenary_scene_new_files()};
|
||||
auto const created{known && std::find(fresh.begin(), fresh.end(), std::string{tool.file}) != fresh.end()};
|
||||
auto const layername{scene::Layers.valid(layer) ? scene::Layers.layer(layer).name : std::string{}};
|
||||
if (false == layername.empty())
|
||||
ImGui::TextDisabled("%s", format(known && false == created ? STR_C("catenary file included by %s") : STR_C("catenary file of its own: the save writes it and its directive into %s"), layername.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
render_catenary_chain_state();
|
||||
}
|
||||
|
||||
@@ -170,6 +170,8 @@ struct catenary_editor
|
||||
void catenary_scan();
|
||||
// the catenary file of the new poles follows the active layer of the scenery
|
||||
void catenary_file_follow();
|
||||
// the scenery layer of this file name; 0 none
|
||||
static std::size_t catenary_layer_of(std::string const &File);
|
||||
// Placing: the spot of a new pole, which takes the zigzag proposed after the last pole and the step of the span
|
||||
bool catenary_spot_at(TTrack &Track, int const Path, glm::dvec3 const &Point, glm::dvec3 const &Cursor, int const Side, catenary_spot &Spot, bool const Placing = false) const;
|
||||
// the zigzag (Iet-107): the largest staggers allowed for the speed of the line, and those the next poles get
|
||||
|
||||
Reference in New Issue
Block a user