-
Notifications
You must be signed in to change notification settings - Fork 0
CURA-13049 Add a Reusable ChainableEnvironment and optimize the EnvironmentMap #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| version: "1.0.0" | ||
| version: "1.1.0" |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,11 +5,12 @@ namespace CuraFormulaeEngine::env | |||||||||||
|
|
||||||||||||
| std::optional<eval::Value> EnvironmentMap::get(const std::string& key) const noexcept | ||||||||||||
| { | ||||||||||||
| if (!has(key)) | ||||||||||||
| auto iterator = environment_.find(key); | ||||||||||||
| if (iterator == environment_.end()) | ||||||||||||
| { | ||||||||||||
| return std::nullopt; | ||||||||||||
| } | ||||||||||||
| return environment_.at(key); | ||||||||||||
| return iterator->second; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| bool EnvironmentMap::has(const std::string& key) const noexcept | ||||||||||||
|
|
@@ -32,44 +33,67 @@ void EnvironmentMap::set(const std::string& key, const eval::Value& value) noexc | |||||||||||
| environment_.insert_or_assign(key, value); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| void EnvironmentMap::add(const std::unordered_map<std::string, eval::Value>& values) | ||||||||||||
| { | ||||||||||||
| environment_.insert(values.begin(), values.end()); | ||||||||||||
|
wawanbreton marked this conversation as resolved.
|
||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| EnvironmentMap EnvironmentMap::clone() const noexcept | ||||||||||||
| { | ||||||||||||
| return EnvironmentMap{environment_}; | ||||||||||||
| return EnvironmentMap{ environment_ }; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| std::optional<eval::Value> LocalEnvironment::get(const std::string& key) const noexcept | ||||||||||||
| std::optional<eval::Value> LocalEnvironment::getImpl(const std::string& key) const noexcept | ||||||||||||
| { | ||||||||||||
| if (local_environment_.has(key)) | ||||||||||||
| { | ||||||||||||
| return local_environment_.get(key); | ||||||||||||
| } | ||||||||||||
| if (shadow_environment_ && shadow_environment_->has(key)) | ||||||||||||
| return local_environment_.get(key); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| bool LocalEnvironment::hasImpl(const std::string& key) const noexcept | ||||||||||||
| { | ||||||||||||
| return local_environment_.has(key); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| std::unordered_map<std::string, eval::Value> LocalEnvironment::getAllImpl() const noexcept | ||||||||||||
| { | ||||||||||||
| return local_environment_.getAll(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| void LocalEnvironment::set(const std::string& key, const eval::Value& value) | ||||||||||||
| { | ||||||||||||
| local_environment_.set(key, value); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| void LocalEnvironment::add(const std::unordered_map<std::string, eval::Value>& values) | ||||||||||||
| { | ||||||||||||
| local_environment_.add(values); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| std::optional<eval::Value> ChainableEnvironment::get(const std::string& key) const noexcept | ||||||||||||
| { | ||||||||||||
| std::optional<eval::Value> value = getImpl(key); | ||||||||||||
| if (! value.has_value() && shadow_environment_) | ||||||||||||
| { | ||||||||||||
| return shadow_environment_->get(key); | ||||||||||||
| value = shadow_environment_->get(key); | ||||||||||||
| } | ||||||||||||
| return std::nullopt; | ||||||||||||
| return value; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| bool LocalEnvironment::has(const std::string& key) const noexcept | ||||||||||||
| bool ChainableEnvironment::has(const std::string& key) const noexcept | ||||||||||||
| { | ||||||||||||
| return local_environment_.has(key) || (shadow_environment_ && shadow_environment_->has(key)); | ||||||||||||
| return hasImpl(key) || (shadow_environment_ && shadow_environment_->has(key)); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| std::unordered_map<std::string, eval::Value> LocalEnvironment::getAll() const noexcept | ||||||||||||
| std::unordered_map<std::string, eval::Value> ChainableEnvironment::getAll() const noexcept | ||||||||||||
| { | ||||||||||||
| std::unordered_map<std::string, eval::Value> all; | ||||||||||||
| if (shadow_environment_) { | ||||||||||||
| if (shadow_environment_) | ||||||||||||
| { | ||||||||||||
| all = shadow_environment_->getAll(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| auto scoped = local_environment_.getAll(); | ||||||||||||
| auto scoped = getAllImpl(); | ||||||||||||
| all.insert(scoped.begin(), scoped.end()); | ||||||||||||
|
||||||||||||
| all.insert(scoped.begin(), scoped.end()); | |
| for (const auto& [key, value] : scoped) | |
| { | |
| all.insert_or_assign(key, value); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree with the suggestion here, why not use insert_or_assign to assure scoped will override the shadow env? I do realize that this was the code before, just wondering if this was ever the right logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the overriding ordering was never a real question, since the keys in each chained environment are in practice mutually exclusive. We could make it an actual topic if required, but I don't really see a need yet. That would also imply writing documentation to make it explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree that keys are always mutually exclusive, I can see a ton of use cases where global stack is shadowing an extruder stack for instance and both stacks have a ton of duplicate keys. For me the naming ShadowEnvoronment makes it very much expected that the variables from this env will be overwritten.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree that the same setting can be in both the extruder settings and the global settings, however this is handled internally in CuraEngine by having the Settings objects chained together. So in the end, when asking for a value in the extruders settings adapter, it will call the global Setting objects if the extruder Setting has no such key. However the adapter containing the global Setting is not linked to the adapter containing the extruders Settings
I added a diagram in the engine documentation to get an overview of the adapters chain:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then the current logic is still non-expected right and thus error-prone? I can imagine situations in either curaengine or curator where we would rely on this behavior. I believe we're currently not relying on this behavior but it would be a pain to debug.
And if we don't want the for-loop we can also adjust the ordering of both insertion-blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes indeed, the current logic is inconsistent and could lead to bugs in the future. I will do the changes to improve it.
Uh oh!
There was an error while loading. Please reload this page.