mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-05 06:24:27 +01:00
feat(editor): edit parameters of a placed include
This commit is contained in:
@@ -210,8 +210,8 @@ void node_layers::visible(layer_handle Layer, bool const Visible)
|
||||
}
|
||||
if (Visible)
|
||||
{
|
||||
// nodes of a removed include stay out of sight
|
||||
if (Node->m_layerhidden && (false == tracked(Node->m_instance) || false == instance(Node->m_instance).removed))
|
||||
// nodes of a removed include stay out of sight, and so do the ones the editor replaced with its own
|
||||
if (Node->m_layerhidden && (false == tracked(Node->m_instance) || (false == instance(Node->m_instance).removed && false == stale(Node))))
|
||||
{
|
||||
Node->visible(true);
|
||||
Node->m_layerhidden = false;
|
||||
@@ -613,7 +613,7 @@ bool node_layers::can_merge(layer_handle Source, layer_handle Target, std::strin
|
||||
{
|
||||
// directives of includes placed in the editor are prepared for the end of their layer file
|
||||
auto const unsaved{std::any_of(std::begin(m_instances), std::end(m_instances), [&](include_instance const &Instance) {
|
||||
return false == Instance.dead && false == Instance.removed && false == Instance.directive.empty() && resolve(Instance.layer) == Source;
|
||||
return false == Instance.dead && false == Instance.removed && false == Instance.span.valid() && resolve(Instance.layer) == Source;
|
||||
})};
|
||||
if (unsaved)
|
||||
{
|
||||
@@ -695,6 +695,7 @@ void node_layers::instance_begin(std::string const &File, source_span const &Spa
|
||||
included.layer = handle();
|
||||
included.file = &(*m_templates.emplace(File).first);
|
||||
included.span = Span;
|
||||
included.context = m_context;
|
||||
m_instance = static_cast<instance_handle>(m_instances.size());
|
||||
}
|
||||
|
||||
@@ -741,7 +742,7 @@ void node_layers::removed(instance_handle Instance, bool Removed)
|
||||
auto const includelayer{resolve(m_instances[Instance - 1].layer)};
|
||||
auto const layervisible{false == valid(includelayer) || layer(includelayer).visible};
|
||||
auto const update_node = [=, this](basic_node *Node, layer_item const Item) {
|
||||
if (Node == nullptr || Node->m_instance != Instance)
|
||||
if (Node == nullptr || Node->m_instance != Instance || (Item == layer_item::model && stale(Node)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -791,6 +792,67 @@ instance_handle node_layers::place(layer_handle Layer, std::string const &File,
|
||||
return static_cast<instance_handle>(m_instances.size());
|
||||
}
|
||||
|
||||
// text of the directive of specified include, as changed in the editor or as it stands in the scenery file
|
||||
std::string node_layers::directive(instance_handle const Instance) const
|
||||
{
|
||||
if (false == tracked(Instance))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto const &included{instance(Instance)};
|
||||
if (false == included.directive.empty() || false == included.span.valid() || false == valid(included.layer))
|
||||
{
|
||||
return included.directive;
|
||||
}
|
||||
std::string text(static_cast<std::size_t>(included.span.end - included.span.begin), '\0');
|
||||
std::ifstream input{path(included.layer), std::ios_base::binary};
|
||||
if (false == input.is_open() || false == input.seekg(included.span.begin).good() || false == input.read(text.data(), static_cast<std::streamsize>(text.size())).good())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
// replaces the directive of specified include, the scenery file receives it on save
|
||||
bool node_layers::modify(instance_handle const Instance, std::string const &Directive)
|
||||
{
|
||||
if (false == tracked(Instance) || m_instances[Instance - 1].dead || Directive.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_instances[Instance - 1].directive = Directive;
|
||||
return true;
|
||||
}
|
||||
|
||||
// takes the models specified include was loaded with out of the scene, once the editor shows its own in their place
|
||||
void node_layers::rebuilt(instance_handle const Instance)
|
||||
{
|
||||
if (false == tracked(Instance) || m_instances[Instance - 1].rebuilt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto const removed{m_instances[Instance - 1].removed};
|
||||
for (auto *model : simulation::Instances.sequence())
|
||||
{
|
||||
if (model == nullptr || model->m_instance != Instance || model->m_preview)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// NOTE: the models themselves are left alone, events of the scenery can refer to them
|
||||
simulation::Region->erase(model);
|
||||
if (false == removed)
|
||||
{
|
||||
count(model->layer(), layer_item::model, -1);
|
||||
}
|
||||
if (model->visible())
|
||||
{
|
||||
model->visible(false);
|
||||
model->m_layerhidden = true;
|
||||
}
|
||||
}
|
||||
m_instances[Instance - 1].rebuilt = true;
|
||||
}
|
||||
|
||||
} // namespace scene
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -100,10 +100,11 @@ struct include_instance
|
||||
layer_handle layer{null_handle}; // layer of the file holding the directive
|
||||
std::string const *file{nullptr}; // name of the included template
|
||||
source_span span; // location of the whole directive in the file; invalid for directive which wasn't saved yet
|
||||
std::string directive; // text of the directive, for include placed in the editor and not saved yet
|
||||
layer_context context; // placement the directive of include placed in the editor was prepared for
|
||||
std::string directive; // text of the directive, for include placed or changed in the editor and not saved yet
|
||||
layer_context context; // placement in effect at the directive
|
||||
bool removed{false}; // the include is to be dropped from the scenery
|
||||
bool dead{false}; // removal of the include was saved
|
||||
bool rebuilt{false}; // models the include was loaded with gave way to the ones made by the editor
|
||||
};
|
||||
|
||||
// marks nodes defined by a template which was included in a way the editor doesn't keep track of
|
||||
@@ -277,6 +278,18 @@ class node_layers
|
||||
// registers include directive made in the editor, to be written to the file of specified layer on save.
|
||||
// the directive has to be prepared for the placement in effect at the end of that file. returns: handle to the include
|
||||
instance_handle place(layer_handle Layer, std::string const &File, std::string const &Directive);
|
||||
// text of the directive of specified include, as changed in the editor or as it stands in the scenery file.
|
||||
// returns: empty text if the directive can't be read
|
||||
std::string directive(instance_handle Instance) const;
|
||||
// replaces the directive of specified include, the scenery file receives it on save. NOTE: the nodes aren't touched
|
||||
bool modify(instance_handle Instance, std::string const &Directive);
|
||||
// takes the models specified include was loaded with out of the scene, once the editor shows its own in their place
|
||||
void rebuilt(instance_handle Instance);
|
||||
// true if specified node was replaced by the editor with a node showing the current state of its include
|
||||
bool stale(basic_node const *Node) const
|
||||
{
|
||||
return tracked(Node->m_instance) && instance(Node->m_instance).rebuilt && false == Node->m_preview;
|
||||
}
|
||||
// true if specified layer is included, directly or not, by the other one
|
||||
bool is_descendant(layer_handle Layer, layer_handle const Ancestor) const;
|
||||
|
||||
|
||||
@@ -275,6 +275,7 @@ struct node_layers::file_patch
|
||||
std::size_t length{0}; // size of that definition
|
||||
basic_node const *node{nullptr}; // node defined by the replacement
|
||||
layer_handle site{null_handle}; // layer included by the directive in the replacement
|
||||
instance_handle instance{0}; // include of a template made by the directive in the replacement
|
||||
layer_handle inlined{null_handle}; // layer whose content replaces the range
|
||||
};
|
||||
std::vector<edit> edits;
|
||||
@@ -460,6 +461,10 @@ bool node_layers::compose(save_state &State, layer_handle const Layer, compositi
|
||||
{
|
||||
Output.sites.push_back({edit.site, span});
|
||||
}
|
||||
if (edit.instance != 0)
|
||||
{
|
||||
Output.instances.push_back({edit.instance, span});
|
||||
}
|
||||
Output.text.append(edit.text, edit.lead - lead, std::string::npos);
|
||||
}
|
||||
cursor = end;
|
||||
@@ -692,6 +697,17 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
edit.end = included.span.end;
|
||||
state.patches[included.layer].edits.emplace_back(std::move(edit));
|
||||
}
|
||||
else if (false == included.directive.empty())
|
||||
{
|
||||
// changed in the editor, the new directive takes the place of the one in the file
|
||||
file_patch::edit edit;
|
||||
edit.begin = included.span.begin;
|
||||
edit.end = included.span.end;
|
||||
edit.length = included.directive.size();
|
||||
edit.text = included.directive;
|
||||
edit.instance = static_cast<instance_handle>(idx + 1);
|
||||
state.patches[included.layer].edits.emplace_back(std::move(edit));
|
||||
}
|
||||
}
|
||||
else if (false == included.removed && false == included.directive.empty())
|
||||
{
|
||||
@@ -840,7 +856,7 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
for (std::size_t idx = 0; idx < m_instances.size(); ++idx)
|
||||
{
|
||||
auto const &included{m_instances[idx]};
|
||||
if (false == included.dead && false == included.removed && included.span.valid() && state.content.count(included.layer) != 0)
|
||||
if (false == included.dead && false == included.removed && included.directive.empty() && included.span.valid() && state.content.count(included.layer) != 0)
|
||||
{
|
||||
state.instances[included.layer].emplace_back(static_cast<instance_handle>(idx + 1));
|
||||
}
|
||||
|
||||
@@ -385,6 +385,7 @@ public:
|
||||
std::string m_name;
|
||||
bool m_dirty { false };
|
||||
bool m_layerhidden { false }; // the node was visible until the editor hid its scenery layer, or the include which defines it
|
||||
bool m_preview { false }; // the node was made by the editor to show an include it placed or changed, and is replaced when the include changes
|
||||
scene::layer_handle m_layer { null_handle }; // scenery layer this node belongs to, if any
|
||||
// include of an *.inc template which defines the node; 0 if the node is defined directly by a scenery layer file.
|
||||
// such nodes can't be rewritten one by one on scenery save. set only for scenery opened for editing
|
||||
|
||||
Reference in New Issue
Block a user