mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 05:09:20 +02:00
feat(editor): include database, placing .inc templates from the node bank
This commit is contained in:
@@ -294,9 +294,15 @@ struct node_layers::composition
|
||||
layer_handle layer;
|
||||
source_span span;
|
||||
};
|
||||
struct instance_place
|
||||
{
|
||||
instance_handle instance;
|
||||
source_span span;
|
||||
};
|
||||
std::string text;
|
||||
std::vector<node_place> nodes;
|
||||
std::vector<site_place> sites;
|
||||
std::vector<instance_place> instances;
|
||||
|
||||
// adds another piece of text at the end
|
||||
void append(composition const &Other)
|
||||
@@ -315,6 +321,12 @@ struct node_layers::composition
|
||||
place.span.end += offset;
|
||||
sites.emplace_back(place);
|
||||
}
|
||||
for (auto place : Other.instances)
|
||||
{
|
||||
place.span.begin += offset;
|
||||
place.span.end += offset;
|
||||
instances.emplace_back(place);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -324,6 +336,7 @@ struct node_layers::save_state
|
||||
std::map<layer_handle, file_patch> patches;
|
||||
std::map<layer_handle, std::vector<basic_node const *>> nodes; // unchanged nodes defined in each file
|
||||
std::map<layer_handle, std::vector<layer_handle>> includes; // unchanged include directives in each file, by included layer
|
||||
std::map<layer_handle, std::vector<instance_handle>> instances; // unchanged includes of templates in each file
|
||||
std::string eol{"\r\n"};
|
||||
std::string error;
|
||||
};
|
||||
@@ -477,6 +490,13 @@ bool node_layers::compose(save_state &State, layer_handle const Layer, compositi
|
||||
Output.sites.push_back({included, shift(layer(included).sites.front().span)});
|
||||
}
|
||||
}
|
||||
if (auto const lookup{State.instances.find(Layer)}; lookup != State.instances.end())
|
||||
{
|
||||
for (auto const included : lookup->second)
|
||||
{
|
||||
Output.instances.push_back({included, shift(instance(included).span)});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -608,7 +628,7 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
state.patches[source.layer].edits.emplace_back(std::move(edit));
|
||||
rewritten.emplace(Node);
|
||||
}
|
||||
else if (Model != nullptr && false == Node->m_template)
|
||||
else if (Model != nullptr && false == Node->from_template())
|
||||
{
|
||||
// created in the editor. the definition is placed at the end of the layer file, with the placement in effect there
|
||||
std::string text;
|
||||
@@ -654,6 +674,41 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
state.patches[erased.first].edits.emplace_back(std::move(edit));
|
||||
}
|
||||
|
||||
// includes of templates
|
||||
std::map<layer_handle, std::vector<instance_handle>> placed; // directives made in the editor, by target layer
|
||||
for (std::size_t idx = 0; idx < m_instances.size(); ++idx)
|
||||
{
|
||||
auto const &included{m_instances[idx]};
|
||||
if (included.dead)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (included.span.valid())
|
||||
{
|
||||
if (included.removed)
|
||||
{
|
||||
file_patch::edit edit;
|
||||
edit.begin = included.span.begin;
|
||||
edit.end = included.span.end;
|
||||
state.patches[included.layer].edits.emplace_back(std::move(edit));
|
||||
}
|
||||
}
|
||||
else if (false == included.removed && false == included.directive.empty())
|
||||
{
|
||||
auto const target{resolve(included.layer)};
|
||||
if (false == is_output(target))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (false == included.context.matches(layer(target).context_end))
|
||||
{
|
||||
// shouldn't happen, merge of layers is refused when it'd lead to this
|
||||
return fail("include \"" + *included.file + "\" was placed for different origin, rotation or scale than its layer ends with");
|
||||
}
|
||||
placed[target].emplace_back(static_cast<instance_handle>(idx + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// layer changes
|
||||
std::map<layer_handle, std::vector<layer_handle>> appended; // merged layers placed at the end of their target
|
||||
std::set<layer_handle> absorbed; // merged layers which cease to exist as files
|
||||
@@ -748,7 +803,7 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (layer(candidate).created || state.patches.count(candidate) != 0 || appended.count(candidate) != 0 || created.count(candidate) != 0 ||
|
||||
if (layer(candidate).created || state.patches.count(candidate) != 0 || appended.count(candidate) != 0 || created.count(candidate) != 0 || placed.count(candidate) != 0 ||
|
||||
(candidate == root && false == Rootstatements.empty()))
|
||||
{
|
||||
outputs.emplace_back(candidate);
|
||||
@@ -782,6 +837,14 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
}
|
||||
state.includes[included.sites.front().parent].emplace_back(candidate);
|
||||
}
|
||||
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)
|
||||
{
|
||||
state.instances[included.layer].emplace_back(static_cast<instance_handle>(idx + 1));
|
||||
}
|
||||
}
|
||||
|
||||
std::map<layer_handle, composition> texts;
|
||||
for (auto const output : outputs)
|
||||
@@ -822,6 +885,17 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
text.text += definition.second + eol;
|
||||
}
|
||||
}
|
||||
if (auto const lookup{placed.find(output)}; lookup != placed.end())
|
||||
{
|
||||
for (auto const included : lookup->second)
|
||||
{
|
||||
auto const &directive{instance(included).directive};
|
||||
ensure_newline(text.text, eol);
|
||||
auto const offset{static_cast<std::streamoff>(text.text.size())};
|
||||
text.instances.push_back({included, {offset, offset + static_cast<std::streamoff>(directive.size())}});
|
||||
text.text += directive + eol;
|
||||
}
|
||||
}
|
||||
if (output == root)
|
||||
{
|
||||
for (auto const &statement : Rootstatements)
|
||||
@@ -927,6 +1001,13 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
source.scale = (model != nullptr ? model->Scale() : glm::vec3{1.f});
|
||||
}
|
||||
}
|
||||
for (auto const &place : texts[output].instances)
|
||||
{
|
||||
auto &included{m_instances[place.instance - 1]};
|
||||
included.layer = output;
|
||||
included.span = place.span;
|
||||
included.directive.clear();
|
||||
}
|
||||
for (auto const &place : texts[output].sites)
|
||||
{
|
||||
auto &included{layer(place.layer)};
|
||||
@@ -961,6 +1042,11 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
|
||||
{
|
||||
stat(output);
|
||||
}
|
||||
for (auto &included : m_instances)
|
||||
{
|
||||
// removed includes are gone from the files now
|
||||
included.dead = included.dead || included.removed;
|
||||
}
|
||||
m_erased.clear();
|
||||
if (removedterrain)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user