Fix internally generated nodes causing crashes in VoxelGraphEditor

This commit is contained in:
Marc Gilleron 2022-08-13 18:22:07 +01:00
parent 1c0298af1d
commit 5c47188773
3 changed files with 42 additions and 18 deletions

View File

@ -729,8 +729,18 @@ void VoxelGraphEditor::update_range_analysis_previews() {
// Note, some nodes can appear twice in this map due to internal expansion.
Span<const uint32_t> execution_map = VoxelGeneratorGraph::get_last_execution_map_debug_from_current_thread();
for (unsigned int i = 0; i < execution_map.size(); ++i) {
const String node_view_path = node_to_gui_name(execution_map[i]);
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_node(node_view_path));
const uint32_t node_id = execution_map[i];
// Some returned nodes might not be in the user-facing graph because they get generated during compilation
if (!_graph->has_node(node_id)) {
ZN_PRINT_VERBOSE(
format("Ignoring node {} from range analysis results, not present in user graph", node_id));
continue;
}
const String node_view_path = node_to_gui_name(node_id);
Node *node = _graph_edit->get_node(node_view_path);
ZN_ASSERT_CONTINUE(node != nullptr);
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(node);
ZN_ASSERT_CONTINUE(node_view != nullptr);
node_view->set_modulate(Color(1, 1, 1));
}
}
@ -946,6 +956,11 @@ void VoxelGraphEditor::_on_profile_button_pressed() {
}
for (const NodeRatio &nr : node_ratios) {
// Some nodes generated during compilation aren't present in the user-facing graph
if (!_graph->has_node(nr.node_id)) {
ZN_PRINT_VERBOSE(format("Ignoring node {} from profiling results, not present in user graph", nr.node_id));
continue;
}
const String ui_node_name = node_to_gui_name(nr.node_id);
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_node(ui_node_name));
ERR_CONTINUE(node_view == nullptr);

View File

@ -60,11 +60,12 @@ public:
// If no local optimization is done, this can remain the same for any position lists.
// If local optimization is used, it may be recomputed before each query.
struct ExecutionMap {
// TODO Typo?
// TODO Rename typo?
std::vector<uint16_t> operation_adresses;
// Stores node IDs referring to the user-facing graph.
// Each index corresponds to operation indices.
// The same node can appear twice, because sometimes a user-facing node compiles as multiple nodes.
// It can also include some nodes not explicitely present in the user graph (like auto-inputs).
std::vector<uint32_t> debug_nodes;
// From which index in the adress list operations will start depending on Y
unsigned int xzy_start_index = 0;

View File

@ -58,23 +58,31 @@ inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
dst.insert(dst.end(), src.begin(), src.end());
}
/*
// Removes all items satisfying the given predicate.
// This can reduce the size of the container. Items are moved to preserve order.
// template <typename T, typename F>
// inline void remove_if(std::vector<T> &vec, F predicate) {
// unsigned int j = 0;
// for (unsigned int i = 0; i < vec.size(); ++i) {
// if (predicate(vec[i])) {
// continue;
// } else {
// if (i != j) {
// vec[j] = vec[i];
// }
// ++j;
// }
// }
// vec.resize(j);
// }
// More direct option than `vec.erase(std::remove_if(vec.begin(), vec.end(), predicate))`.
template <typename T, typename F>
inline void remove_if(std::vector<T> &vec, F predicate) {
unsigned int i = 0;
unsigned int j = 0;
for (; i < vec.size(); ++i) {
if (predicate(vec[i])) {
++i;
break;
}
}
for (; i < vec.size(); ++i) {
if (predicate(i)) {
continue;
} else {
vec[j] = vec[i];
++j;
}
}
vec.resize(j);
}
*/
template <typename T>
size_t find_duplicate(Span<const T> items) {