mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-27 23:27:29 +01:00
feat(editor): the signalling, the hectometre posts and the terrain go to layers of their own: <scenery>_srk.scm, _hektometry.scm, _teren.scm, made by the first of them and included by the scenario file, the active layer left as it is; the station descriptions of the signalling there too
This commit is contained in:
@@ -2986,8 +2986,9 @@ bool editor_mode::save()
|
||||
}
|
||||
first_step_done(first_step::save);
|
||||
|
||||
// the heightmap terrain is kept in files of its own, the scenery only needs the directive which loads it
|
||||
// the heightmap terrain is kept in files of its own, the scenery only needs the directive which loads it, in a layer of its own
|
||||
std::vector<std::string> rootstatements;
|
||||
std::map<scene::layer_handle, std::vector<std::string>> statements;
|
||||
if (m_streamer.active())
|
||||
{
|
||||
std::string error;
|
||||
@@ -2997,7 +2998,13 @@ bool editor_mode::save()
|
||||
return false;
|
||||
}
|
||||
if (false == scene::Layers.terrain_directive())
|
||||
rootstatements.emplace_back("heightmap_terrain " + m_streamer.name() + " endheightmap_terrain");
|
||||
{
|
||||
auto const directive{"heightmap_terrain " + m_streamer.name() + " endheightmap_terrain"};
|
||||
if (auto const layer{output_layer("teren")}; layer != null_handle)
|
||||
statements[layer].push_back(directive);
|
||||
else
|
||||
rootstatements.push_back(directive);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_profile.changed)
|
||||
@@ -3016,14 +3023,14 @@ bool editor_mode::save()
|
||||
m_orthophoto_mark = map;
|
||||
scene::Layers.mark(scene::layer_handle{1}, "//$o", {map});
|
||||
}
|
||||
auto const terrainadded{false == rootstatements.empty()};
|
||||
auto const terrainadded{false == rootstatements.empty() || false == statements.empty()};
|
||||
auto const controls{turntable_controls(rootstatements)};
|
||||
auto const noses{nose_controls(rootstatements)};
|
||||
std::vector<std::string> trailing;
|
||||
auto const placed{m_vehicle.trainset_lines(trailing)};
|
||||
if (placed == 0)
|
||||
starter_trainset(trailing);
|
||||
auto const result = scene::Layers.save(rootstatements, trailing);
|
||||
auto const result = scene::Layers.save(rootstatements, trailing, statements);
|
||||
if (result.success && controls)
|
||||
m_turntable_included = true;
|
||||
if (result.success && noses)
|
||||
|
||||
@@ -1896,8 +1896,9 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void apply_switch_drive_choice(TTrack &Switch);
|
||||
void switch_drive_captured(TTrack const &Track);
|
||||
void switch_drives_committed(std::vector<TTrack *> const &Tracks);
|
||||
// places them in the active layer, as one step of the undo. returns: how many were placed
|
||||
std::size_t place_templates(std::vector<template_item> const &Items, std::string &Error) override;
|
||||
scene::layer_handle output_layer(std::string const &Part) override;
|
||||
// places them in the active layer or the given one, as one step of the undo. returns: how many were placed
|
||||
std::size_t place_templates(std::vector<template_item> const &Items, std::string &Error, scene::layer_handle Layer = scene::layer_handle{}) override;
|
||||
// moves them, as one step of the undo
|
||||
std::size_t move_templates(std::vector<std::pair<standing_template, template_item>> const &Moves) override;
|
||||
// takes them out, as one step of the undo
|
||||
|
||||
@@ -243,7 +243,41 @@ std::vector<editor_mode::standing_template> editor_mode::standing_templates(std:
|
||||
return result;
|
||||
}
|
||||
|
||||
std::size_t editor_mode::place_templates(std::vector<template_item> const &Items, std::string &Error)
|
||||
scene::layer_handle editor_mode::output_layer(std::string const &Part)
|
||||
{
|
||||
if (scene::Layers.empty())
|
||||
return null_handle;
|
||||
auto stem{scene::Layers.layer(scene::layer_handle{1}).name};
|
||||
if (auto const slash{stem.find_last_of("/\\")}; slash != std::string::npos)
|
||||
stem.erase(0, slash + 1);
|
||||
if (auto const dot{stem.rfind('.')}; dot != std::string::npos)
|
||||
stem.erase(dot);
|
||||
stem.erase(0, stem.find_first_not_of('$'));
|
||||
if (stem.empty())
|
||||
stem = "scenery";
|
||||
std::string reason;
|
||||
// a file of that name the scenery doesn't include, or one which can't take more, gives way to the next number
|
||||
for (int attempt = 1; attempt <= 9; ++attempt)
|
||||
{
|
||||
auto const name{ToLower(stem + "_" + Part + (attempt > 1 ? std::to_string(attempt) : std::string{}) + ".scm")};
|
||||
auto layer{null_handle};
|
||||
for (std::size_t index = 1; index <= scene::Layers.size() && layer == null_handle; ++index)
|
||||
if (auto const &existing{scene::Layers.layer(static_cast<scene::layer_handle>(index))}; false == existing.dead && false == existing.removed && existing.name == name)
|
||||
layer = scene::Layers.resolve(static_cast<scene::layer_handle>(index));
|
||||
if (layer == null_handle)
|
||||
layer = scene::Layers.create(name, scene::layer_handle{1}, reason, false);
|
||||
if (layer != null_handle && scene::Layers.accepts(layer, &reason))
|
||||
{
|
||||
scene::Layers.visible(layer, true);
|
||||
scene::Layers.locked(layer, false);
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
WriteLog("Editor: no layer for " + Part + ", the active one takes it: " + reason, logtype::generic);
|
||||
return null_handle;
|
||||
}
|
||||
|
||||
std::size_t editor_mode::place_templates(std::vector<template_item> const &Items, std::string &Error, scene::layer_handle const Layer)
|
||||
{
|
||||
if (Items.empty())
|
||||
return 0;
|
||||
@@ -252,7 +286,7 @@ std::size_t editor_mode::place_templates(std::vector<template_item> const &Items
|
||||
Error = STR_C("Templates can be placed only in a scenery opened for editing (-edit)");
|
||||
return 0;
|
||||
}
|
||||
auto const layer{scene::Layers.resolve(scene::Layers.active())};
|
||||
auto const layer{scene::Layers.resolve(Layer != null_handle ? Layer : scene::Layers.active())};
|
||||
if (std::string reason; false == scene::Layers.accepts(layer, &reason))
|
||||
{
|
||||
Error = STR_C("The active layer can't take them: ") + (reason.empty() ? std::string{STR_C("there's no active layer")} : reason);
|
||||
@@ -569,8 +603,11 @@ void hekto_tool::hekto_place()
|
||||
items.push_back(std::move(item));
|
||||
}
|
||||
std::string error;
|
||||
auto const placed{m_templates.place_templates(items, error)};
|
||||
auto const layer{items.empty() ? null_handle : m_templates.output_layer("hektometry")};
|
||||
auto const placed{m_templates.place_templates(items, error, layer)};
|
||||
tool.status = placed > 0 ? format(STR_P("%zu hectometre post placed, Ctrl+Z takes it back", "%zu hectometre posts placed, Ctrl+Z takes them back", static_cast<long long>(placed)), placed) : error;
|
||||
if (placed > 0 && layer != null_handle)
|
||||
tool.status += format(STR_C(" (layer \"%s\")"), scene::Layers.layer(layer).name.c_str());
|
||||
if (placed > 0)
|
||||
m_guide.first_step_done(editor_first_step::posts);
|
||||
WriteLog("Editor: " + tool.status, logtype::generic);
|
||||
|
||||
@@ -844,7 +844,7 @@ bool editor_mode::signal_place(signal_spot const &Spot, signal_template const &T
|
||||
if (Template.linked)
|
||||
item.values["#7"] = tool.linked[0] != '\0' ? std::string{tool.linked} : std::string{"none"};
|
||||
std::string error;
|
||||
if (place_templates({item}, error) == 0)
|
||||
if (place_templates({item}, error, output_layer("srk")) == 0)
|
||||
{
|
||||
tool.status = refused(STR_C("The signal couldn't be placed: ") + error);
|
||||
return false;
|
||||
@@ -1452,7 +1452,7 @@ std::size_t editor_mode::signal_batch(signal_changes const &Changes, std::vector
|
||||
std::vector<scene::instance_handle> instances;
|
||||
if (Error.empty() && false == items.empty())
|
||||
{
|
||||
if (place_templates(items, Error) == 0)
|
||||
if (place_templates(items, Error, output_layer("srk")) == 0)
|
||||
reads.clear();
|
||||
else
|
||||
{
|
||||
|
||||
@@ -879,7 +879,9 @@ srk_tool::record &srk_tool::record_of_open()
|
||||
auto *first{m_layout->switches.front()};
|
||||
entry.anchor = first->name();
|
||||
entry.track = first;
|
||||
entry.layer = alignment_store::layer_of(*first);
|
||||
entry.layer = m_templates.output_layer("srk");
|
||||
if (entry.layer == null_handle)
|
||||
entry.layer = alignment_store::layer_of(*first);
|
||||
m_records.push_back(std::move(entry));
|
||||
m_record = static_cast<int>(m_records.size()) - 1;
|
||||
m_anchor = first;
|
||||
|
||||
@@ -199,7 +199,10 @@ class editor_templates
|
||||
{
|
||||
public:
|
||||
virtual std::vector<standing_template> standing_templates(std::function<bool(std::string const &)> const &Accept) const = 0;
|
||||
virtual std::size_t place_templates(std::vector<template_item> const &Items, std::string &Error) = 0;
|
||||
// the layer a tool keeps what it makes in, "<scenery>_<Part>.scm", made when the scenery has none yet. returns: null_handle if there can't be one
|
||||
virtual scene::layer_handle output_layer(std::string const &Part) = 0;
|
||||
// in the active layer unless given another
|
||||
virtual std::size_t place_templates(std::vector<template_item> const &Items, std::string &Error, scene::layer_handle Layer = scene::layer_handle{}) = 0;
|
||||
virtual std::size_t move_templates(std::vector<std::pair<standing_template, template_item>> const &Moves) = 0;
|
||||
virtual std::size_t remove_templates(std::vector<scene::instance_handle> const &Instances) = 0;
|
||||
|
||||
|
||||
@@ -11469,3 +11469,6 @@ msgstr[2] "Odczyt przywrócony: %zu z %zu semaforów"
|
||||
|
||||
msgid ": the rest stand farther than 10 m from a track, by vehicles or their events are gone"
|
||||
msgstr ": pozostałe stoją dalej niż 10 m od toru, przy torze z pojazdami albo ich zdarzenia już nie istnieją"
|
||||
|
||||
msgid " (layer \"%s\")"
|
||||
msgstr " (warstwa \"%s\")"
|
||||
|
||||
@@ -558,7 +558,7 @@ void node_layers::stat(layer_handle const Layer)
|
||||
}
|
||||
|
||||
// creates empty layer, included from specified one. returns: handle to the new layer, or null_handle with the explanation in Reason
|
||||
layer_handle node_layers::create(std::string Name, layer_handle Parent, std::string &Reason)
|
||||
layer_handle node_layers::create(std::string Name, layer_handle Parent, std::string &Reason, bool const Activate)
|
||||
{
|
||||
Parent = resolve(Parent);
|
||||
if (false == valid(Parent) || layer(Parent).removed || layer(Parent).binary)
|
||||
@@ -639,7 +639,10 @@ layer_handle node_layers::create(std::string Name, layer_handle Parent, std::str
|
||||
created.context_begin = valid(anchor) ? layer(anchor).context_end : layer(Parent).context_insert();
|
||||
created.context_end = created.context_begin;
|
||||
|
||||
active(layerhandle);
|
||||
if (Activate)
|
||||
{
|
||||
active(layerhandle);
|
||||
}
|
||||
|
||||
return layerhandle;
|
||||
}
|
||||
|
||||
@@ -294,8 +294,8 @@ class node_layers
|
||||
void mark(layer_handle Layer, std::string const &Mark, std::vector<std::string> Lines);
|
||||
|
||||
// layer management. changes are applied to the scenery files by save()
|
||||
// creates empty layer, included from specified one. returns: handle to the new layer, or null_handle with the explanation in Reason
|
||||
layer_handle create(std::string Name, layer_handle Parent, std::string &Reason);
|
||||
// creates empty layer, included from specified one, made active unless told otherwise. returns: handle to the new layer, or null_handle with the explanation in Reason
|
||||
layer_handle create(std::string Name, layer_handle Parent, std::string &Reason, bool const Activate = true);
|
||||
bool can_remove(layer_handle Layer, std::string &Reason) const;
|
||||
// marks specified layer and the layers it includes as dropped from the scenery. their files are left on the disk
|
||||
bool remove(layer_handle Layer);
|
||||
@@ -348,8 +348,8 @@ class node_layers
|
||||
|
||||
// writes changes made in the editor to the scenery files: changed, created and deleted model instances and
|
||||
// memory cells, and layer changes. the files are left intact unless the whole operation can be performed.
|
||||
// Rootstatements: additional statements to place at the end of the scenario file
|
||||
save_result save(std::vector<std::string> const &Rootstatements = {}, std::vector<std::string> const &Trailingstatements = {});
|
||||
// Rootstatements: additional statements to place at the end of the scenario file; Statements: the same for other layers
|
||||
save_result save(std::vector<std::string> const &Rootstatements = {}, std::vector<std::string> const &Trailingstatements = {}, std::map<layer_handle, std::vector<std::string>> const &Statements = {});
|
||||
std::string check_sources() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -633,7 +633,7 @@ bool node_layers::compose(save_state &State, layer_handle const Layer, compositi
|
||||
}
|
||||
|
||||
// writes changes made in the editor to the scenery files
|
||||
save_result node_layers::save(std::vector<std::string> const &Rootstatements, std::vector<std::string> const &Trailingstatements)
|
||||
save_result node_layers::save(std::vector<std::string> const &Rootstatements, std::vector<std::string> const &Trailingstatements, std::map<layer_handle, std::vector<std::string>> const &Statements)
|
||||
{
|
||||
save_result result;
|
||||
if (m_layers.empty())
|
||||
@@ -1455,7 +1455,7 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements, st
|
||||
continue;
|
||||
}
|
||||
if (layer(candidate).created || state.patches.count(candidate) != 0 || appended.count(candidate) != 0 || created.count(candidate) != 0 || placed.count(candidate) != 0 ||
|
||||
markedtext.count(candidate) != 0 || (candidate == root && (false == Rootstatements.empty() || false == Trailingstatements.empty())))
|
||||
markedtext.count(candidate) != 0 || Statements.count(candidate) != 0 || (candidate == root && (false == Rootstatements.empty() || false == Trailingstatements.empty())))
|
||||
{
|
||||
outputs.emplace_back(candidate);
|
||||
}
|
||||
@@ -1568,6 +1568,14 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements, st
|
||||
added.text += statement + eol;
|
||||
}
|
||||
}
|
||||
if (auto const lookup{Statements.find(output)}; lookup != Statements.end())
|
||||
{
|
||||
for (auto const &statement : lookup->second)
|
||||
{
|
||||
ensure_newline(added.text, eol);
|
||||
added.text += statement + eol;
|
||||
}
|
||||
}
|
||||
if (output == root && false == Trailingstatements.empty())
|
||||
{
|
||||
composition trailing;
|
||||
|
||||
Reference in New Issue
Block a user