Repository navigation
fix(ModelIO): repair corrupted model files and harden model load/save #1369
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
Changes from all commits
2917c88
44942f1
35f1e56
2a02b90
ddf5172
547b4be
b2f35b5
9579a3f
9e565ce
288aecf
7f4e620
e4eb903
4fff975
c749cd2
7b8b0bf
9ff215e
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 |
|---|---|---|
|
|
@@ -23,7 +23,9 @@ | |
|
|
||
| #pragma once | ||
|
|
||
| #include <geode/basic/logger.hpp> | ||
| #include <geode/basic/range.hpp> | ||
| #include <geode/basic/uuid.hpp> | ||
|
|
||
| #include <geode/model/common.hpp> | ||
| #include <geode/model/mixin/core/component_type.hpp> | ||
|
|
@@ -64,6 +66,27 @@ namespace geode | |
| } | ||
| }; | ||
|
|
||
| template < typename Mixin, typename Model > | ||
| [[nodiscard]] bool has_mixin_component( | ||
| const Model& model, const uuid& component_id ) | ||
| { | ||
| return model.Mixin::has_component( component_id ); | ||
| } | ||
|
|
||
| template < typename > | ||
| struct ComponentsExistenceChecker; | ||
|
|
||
| template < typename... Components > | ||
| struct ComponentsExistenceChecker< std::tuple< Components... > > | ||
| { | ||
| template < typename Model > | ||
| bool apply( const Model& model, const uuid& component_id ) const | ||
| { | ||
| return ( | ||
| has_mixin_component< Components >( model, component_id ) | ||
| || ... ); | ||
| } | ||
| }; | ||
| } // namespace internal | ||
|
|
||
| namespace detail | ||
|
|
@@ -74,6 +97,9 @@ namespace geode | |
| typename Model::Builder builder{ model }; | ||
| const internal::ComponentsTypesChecker< typename Model::Components > | ||
| checker; | ||
| const internal::ComponentsExistenceChecker< | ||
| typename Model::Components > | ||
| existence_checker; | ||
| std::vector< uuid > components_to_remove; | ||
| for( const auto vertex : | ||
| Range{ model.nb_components_with_relations() } ) | ||
|
|
@@ -84,6 +110,13 @@ namespace geode | |
| { | ||
| components_to_remove.push_back( component_id.id ); | ||
| } | ||
| else if( !existence_checker.apply( model, component_id.id ) ) | ||
| { | ||
| Logger::warning( "[filter_unsupported_components] " | ||
| "Removing relations of missing ", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same rationale: the relations pointing to missing components are removed during load, so the model is repaired and usable; a warning reports it instead of failing the whole load. |
||
| component_id.string() ); | ||
| components_to_remove.push_back( component_id.id ); | ||
| } | ||
| } | ||
| for( const auto& component : components_to_remove ) | ||
| { | ||
|
|
||
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 wonder if it should be a simple warning, or an exception raising?
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.
Kept as a warning on purpose: this runs on load, and our policy for corrupted files is to repair what can be repaired and warn, rather than reject the whole model. Here the invalid component is dropped, so the loaded model stays consistent.