Fix graph not recompiling after changing a subresource
This commit is contained in:
parent
ba8d9aad52
commit
62c807fa71
@ -68,7 +68,7 @@ public:
|
||||
void find_terminal_nodes(std::vector<uint32_t> &node_ids) const;
|
||||
|
||||
template <typename F>
|
||||
inline void for_each_node(F f) const {
|
||||
inline void for_each_node_const(F f) const {
|
||||
for (auto it = _nodes.begin(); it != _nodes.end(); ++it) {
|
||||
const Node *node = it->second;
|
||||
ERR_CONTINUE(node == nullptr);
|
||||
@ -76,6 +76,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline void for_each_node(F f) {
|
||||
for (auto it = _nodes.begin(); it != _nodes.end(); ++it) {
|
||||
Node *node = it->second;
|
||||
ERR_CONTINUE(node == nullptr);
|
||||
f(*node);
|
||||
}
|
||||
}
|
||||
|
||||
void copy_from(const ProgramGraph &other, bool copy_subresources);
|
||||
void get_connections(std::vector<ProgramGraph::Connection> &connections) const;
|
||||
//void get_connections_from_and_to(std::vector<ProgramGraph::Connection> &connections, uint32_t node_id) const;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "voxel_generator_graph.h"
|
||||
#include "../../util/macros.h"
|
||||
#include "../../util/profiling.h"
|
||||
#include "../../util/profiling_clock.h"
|
||||
#include "voxel_graph_node_db.h"
|
||||
@ -17,6 +18,14 @@ VoxelGeneratorGraph::~VoxelGeneratorGraph() {
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::clear() {
|
||||
_graph.for_each_node([this](ProgramGraph::Node &node) {
|
||||
for (size_t i = 0; i < node.params.size(); ++i) {
|
||||
Ref<Resource> resource = node.params[i];
|
||||
if (resource.is_valid()) {
|
||||
unregister_subresource(**resource);
|
||||
}
|
||||
}
|
||||
});
|
||||
_graph.clear();
|
||||
{
|
||||
RWLockWrite wlock(_runtime_lock);
|
||||
@ -54,7 +63,14 @@ uint32_t VoxelGeneratorGraph::create_node(NodeTypeID type_id, Vector2 position,
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::remove_node(uint32_t node_id) {
|
||||
ERR_FAIL_COND(_graph.try_get_node(node_id) == nullptr);
|
||||
ProgramGraph::Node *node = _graph.try_get_node(node_id);
|
||||
ERR_FAIL_COND(node == nullptr);
|
||||
for (size_t i = 0; i < node->params.size(); ++i) {
|
||||
Ref<Resource> resource = node->params[i];
|
||||
if (resource.is_valid()) {
|
||||
unregister_subresource(**resource);
|
||||
}
|
||||
}
|
||||
_graph.remove_node(node_id);
|
||||
emit_changed();
|
||||
}
|
||||
@ -141,7 +157,18 @@ void VoxelGeneratorGraph::set_node_param(uint32_t node_id, uint32_t param_index,
|
||||
ERR_FAIL_INDEX(param_index, node->params.size());
|
||||
|
||||
if (node->params[param_index] != value) {
|
||||
Ref<Resource> prev_resource = node->params[param_index];
|
||||
if (prev_resource.is_valid()) {
|
||||
unregister_subresource(**prev_resource);
|
||||
}
|
||||
|
||||
node->params[param_index] = value;
|
||||
|
||||
Ref<Resource> resource = value;
|
||||
if (resource.is_valid()) {
|
||||
register_subresource(**resource);
|
||||
}
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
}
|
||||
@ -569,6 +596,8 @@ VoxelGenerator::Result VoxelGeneratorGraph::generate_block(VoxelBlockRequest &in
|
||||
}
|
||||
|
||||
VoxelGraphRuntime::CompilationResult VoxelGeneratorGraph::compile() {
|
||||
const int64_t time_before = OS::get_singleton()->get_ticks_usec();
|
||||
|
||||
std::shared_ptr<Runtime> r = std::make_shared<Runtime>();
|
||||
VoxelGraphRuntime &runtime = r->runtime;
|
||||
|
||||
@ -694,6 +723,9 @@ VoxelGraphRuntime::CompilationResult VoxelGeneratorGraph::compile() {
|
||||
RWLockWrite wlock(_runtime_lock);
|
||||
_runtime = r;
|
||||
|
||||
const int64_t time_spent = OS::get_singleton()->get_ticks_usec() - time_before;
|
||||
PRINT_VERBOSE(String("Voxel graph compiled in {0} us").format(varray(time_spent)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1199,15 +1231,35 @@ static bool load_graph_from_variant_data(ProgramGraph &graph, Dictionary data) {
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::load_graph_from_variant_data(Dictionary data) {
|
||||
clear();
|
||||
|
||||
if (::load_graph_from_variant_data(_graph, data)) {
|
||||
_graph.for_each_node([this](ProgramGraph::Node &node) {
|
||||
for (size_t i = 0; i < node.params.size(); ++i) {
|
||||
Ref<Resource> resource = node.params[i];
|
||||
if (resource.is_valid()) {
|
||||
register_subresource(**resource);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// It's possible to auto-compile on load because `graph_data` is the only property set by the loader,
|
||||
// which is enough to have all information we need
|
||||
compile();
|
||||
|
||||
} else {
|
||||
_graph.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::register_subresource(Resource &resource) {
|
||||
resource.connect(CoreStringNames::get_singleton()->changed, this, "_on_subresource_changed");
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::unregister_subresource(Resource &resource) {
|
||||
resource.disconnect(CoreStringNames::get_singleton()->changed, this, "_on_subresource_changed");
|
||||
}
|
||||
|
||||
// Debug land
|
||||
|
||||
float VoxelGeneratorGraph::debug_measure_microseconds_per_voxel(bool singular) {
|
||||
@ -1400,9 +1452,9 @@ Dictionary VoxelGeneratorGraph::_b_compile() {
|
||||
return d;
|
||||
}
|
||||
|
||||
// void VoxelGeneratorGraph::_on_subresource_changed() {
|
||||
// emit_changed();
|
||||
// }
|
||||
void VoxelGeneratorGraph::_on_subresource_changed() {
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("clear"), &VoxelGeneratorGraph::clear);
|
||||
@ -1476,7 +1528,7 @@ void VoxelGeneratorGraph::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_set_graph_data", "data"), &VoxelGeneratorGraph::load_graph_from_variant_data);
|
||||
ClassDB::bind_method(D_METHOD("_get_graph_data"), &VoxelGeneratorGraph::get_graph_as_variant_data);
|
||||
|
||||
// ClassDB::bind_method(D_METHOD("_on_subresource_changed"), &VoxelGeneratorGraph::_on_subresource_changed);
|
||||
ClassDB::bind_method(D_METHOD("_on_subresource_changed"), &VoxelGeneratorGraph::_on_subresource_changed);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "graph_data", PROPERTY_HINT_NONE, "",
|
||||
PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL),
|
||||
|
@ -159,6 +159,9 @@ public:
|
||||
private:
|
||||
Dictionary get_graph_as_variant_data() const;
|
||||
void load_graph_from_variant_data(Dictionary data);
|
||||
void register_subresource(Resource &resource);
|
||||
void unregister_subresource(Resource &resource);
|
||||
void _on_subresource_changed();
|
||||
|
||||
int _b_get_node_type_count() const;
|
||||
Dictionary _b_get_node_type_info(int type_id) const;
|
||||
@ -171,9 +174,6 @@ private:
|
||||
Vector2 _b_debug_analyze_range(Vector3 min_pos, Vector3 max_pos) const;
|
||||
Dictionary _b_compile();
|
||||
|
||||
void _on_subresource_changed();
|
||||
void connect_to_subresource_changes();
|
||||
|
||||
struct WeightOutput {
|
||||
unsigned int layer_index;
|
||||
unsigned int output_buffer_index;
|
||||
|
@ -83,7 +83,7 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
|
||||
std::unordered_map<uint32_t, uint32_t> node_id_to_dependency_graph;
|
||||
|
||||
// Not using the generic `get_terminal_nodes` function because our terminal nodes do have outputs
|
||||
graph.for_each_node([&terminal_nodes](const ProgramGraph::Node &node) {
|
||||
graph.for_each_node_const([&terminal_nodes](const ProgramGraph::Node &node) {
|
||||
const VoxelGraphNodeDB::NodeType &type = VoxelGraphNodeDB::get_singleton()->get_type(node.type_id);
|
||||
if (type.category == VoxelGraphNodeDB::CATEGORY_OUTPUT) {
|
||||
terminal_nodes.push_back(node.id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user