diff options
author | Jacques Lucke <jacques@blender.org> | 2020-02-25 16:34:29 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-02-25 16:34:29 +0300 |
commit | bf9c6aad9e9514cb06ea2433bbba31920886e800 (patch) | |
tree | c7df8c2d635c26833a0cd5fa21ad270e716c5b27 | |
parent | deb14fcfdab7c41d5ec6384067305871b4a0895e (diff) |
first node with a variable number of sockets
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 9 | ||||
-rw-r--r-- | source/blender/simulations/nodes/my_test_node.cc | 131 |
2 files changed, 120 insertions, 20 deletions
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index acd8519795d..c8c527b4f0f 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1040,6 +1040,15 @@ typedef struct MyTestNodeStorage { int x; } MyTestNodeStorage; +typedef struct VariadicNodeSocketIdentifier { + struct VariadicNodeSocketIdentifier *next, *prev; + char identifier[8]; +} VariadicNodeSocketIdentifier; + +typedef struct FloatAddNodeStorage { + ListBase inputs_info; /* VariadicNodeSocketIdentifier */ +} FloatAddNodeStorage; + /* script node mode */ #define NODE_SCRIPT_INTERNAL 0 #define NODE_SCRIPT_EXTERNAL 1 diff --git a/source/blender/simulations/nodes/my_test_node.cc b/source/blender/simulations/nodes/my_test_node.cc index 9c131a80896..044a6712f28 100644 --- a/source/blender/simulations/nodes/my_test_node.cc +++ b/source/blender/simulations/nodes/my_test_node.cc @@ -14,6 +14,8 @@ #include "BLI_string.h" #include "BLI_array_cxx.h" #include "BLI_map.h" +#include "BLI_listbase_wrapper.h" +#include "BLI_string_utils.h" #include "PIL_time.h" @@ -27,6 +29,7 @@ using BLI::Array; using BLI::ArrayRef; +using BLI::IntrusiveListBaseWrapper; using BLI::LinearAllocator; using BLI::Map; using BLI::rgba_f; @@ -324,7 +327,7 @@ class SocketDefinition { struct PointerRNA *ptr, struct PointerRNA *node_ptr, const char *text)>; - using InitStorageFn = std::function<void *()>; + using NewStorageFn = std::function<void *()>; using CopyStorageFn = std::function<void *(const void *)>; using FreeStorageFn = std::function<void(void *)>; template<typename T> using TypedInitStorageFn = std::function<void(T *)>; @@ -334,7 +337,7 @@ class SocketDefinition { DrawInNodeFn m_draw_in_node_fn; rgba_f m_color = {0.0f, 0.0f, 0.0f, 1.0f}; std::string m_storage_struct_name; - InitStorageFn m_init_storage_fn; + NewStorageFn m_new_storage_fn; CopyStorageFn m_copy_storage_fn; FreeStorageFn m_free_storage_fn; @@ -354,7 +357,7 @@ class SocketDefinition { m_stype.draw_color = SocketDefinition::get_draw_color; m_stype.free_self = [](bNodeSocketType *UNUSED(stype)) {}; - m_init_storage_fn = []() { return nullptr; }; + m_new_storage_fn = []() { return nullptr; }; m_copy_storage_fn = [](const void *storage) { BLI_assert(storage == nullptr); UNUSED_VARS_NDEBUG(storage); @@ -378,12 +381,12 @@ class SocketDefinition { } void add_dna_storage(StringRef struct_name, - InitStorageFn init_storage_fn, + NewStorageFn init_storage_fn, CopyStorageFn copy_storage_fn, FreeStorageFn free_storage_fn) { m_storage_struct_name = struct_name; - m_init_storage_fn = init_storage_fn; + m_new_storage_fn = init_storage_fn; m_copy_storage_fn = copy_storage_fn; m_free_storage_fn = free_storage_fn; } @@ -446,7 +449,7 @@ class SocketDefinition { static void init_socket(bNodeTree *UNUSED(ntree), bNode *UNUSED(node), bNodeSocket *socket) { const SocketDefinition *def = get_from_socket(socket); - socket->default_value = def->m_init_storage_fn(); + socket->default_value = def->m_new_storage_fn(); } static void copy_socket(bNodeTree *UNUSED(dst_ntree), @@ -490,11 +493,14 @@ class SocketDefinition { class NodeDefinition { public: using DeclareNodeFn = std::function<void(NodeBuilder &node_builder)>; - using InitStorageFn = std::function<void *()>; - using CopyStorageFn = std::function<void *(void *)>; + using NewStorageFn = std::function<void *()>; + using CopyStorageFn = std::function<void *(const void *)>; using FreeStorageFn = std::function<void(void *)>; using DrawInNodeFn = std::function<void(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr)>; + template<typename T> using TypedNewStorageFn = std::function<T *()>; + template<typename T> using TypedCopyStorageFn = std::function<T *(const T *)>; + template<typename T> using TypedFreeStorageFn = std::function<void(T *)>; template<typename T> using TypedInitStorageFn = std::function<void(T *)>; using CopyBehaviorFn = std::function<void(bNode *dst_node, const bNode *src_node)>; using LabelFn = std::function<void(bNodeTree *ntree, bNode *node, char *r_label, int maxlen)>; @@ -502,7 +508,7 @@ class NodeDefinition { private: bNodeType m_ntype; DeclareNodeFn m_declare_node_fn; - InitStorageFn m_init_storage_fn; + NewStorageFn m_new_storage_fn; CopyStorageFn m_copy_storage_fn; FreeStorageFn m_free_storage_fn; CopyBehaviorFn m_copy_node_fn; @@ -530,8 +536,8 @@ class NodeDefinition { ntype->userdata = (void *)this; m_declare_node_fn = [](NodeBuilder &UNUSED(builder)) {}; - m_init_storage_fn = []() { return nullptr; }; - m_copy_storage_fn = [](void *storage) { + m_new_storage_fn = []() { return nullptr; }; + m_copy_storage_fn = [](const void *storage) { BLI_assert(storage == nullptr); UNUSED_VARS_NDEBUG(storage); return nullptr; @@ -570,17 +576,37 @@ class NodeDefinition { } void add_dna_storage(StringRef struct_name, - InitStorageFn init_storage_fn, + NewStorageFn new_storage_fn, CopyStorageFn copy_storage_fn, FreeStorageFn free_storage_fn) { struct_name.copy(m_ntype.storagename); - m_init_storage_fn = init_storage_fn; + m_new_storage_fn = new_storage_fn; m_copy_storage_fn = copy_storage_fn; m_free_storage_fn = free_storage_fn; } template<typename T> + void add_dna_storage(StringRef struct_name, + TypedNewStorageFn<T> new_storage_fn, + TypedCopyStorageFn<T> copy_storage_fn, + TypedFreeStorageFn<T> free_storage_fn) + { + this->add_dna_storage( + struct_name, + [new_storage_fn]() { return (void *)new_storage_fn(); }, + [copy_storage_fn](const void *storage_) { + const T *storage = (const T *)storage_; + T *new_storage = copy_storage_fn(storage); + return (void *)new_storage; + }, + [free_storage_fn](const void *storage_) { + T *storage = (T *)storage_; + free_storage_fn(storage); + }); + } + + template<typename T> void add_dna_storage(StringRef struct_name, TypedInitStorageFn<T> init_storage_fn) { this->add_dna_storage( @@ -590,7 +616,7 @@ class NodeDefinition { init_storage_fn((T *)buffer); return buffer; }, - [](void *buffer) { + [](const void *buffer) { void *new_buffer = MEM_callocN(sizeof(T), __func__); memcpy(new_buffer, buffer, sizeof(T)); return new_buffer; @@ -648,7 +674,7 @@ class NodeDefinition { LinearAllocator<> allocator; NodeDecl node_decl{*ntree, *node}; NodeBuilder node_builder{allocator, node_decl}; - node->storage = def->m_init_storage_fn(); + node->storage = def->m_new_storage_fn(); def->m_declare_node_fn(node_builder); node_decl.build(); } @@ -707,6 +733,13 @@ template<typename T> static T *get_socket_storage(bNodeSocket *socket) return (T *)socket->default_value; } +static void update_tree(bContext *C) +{ + bNodeTree *ntree = CTX_wm_space_node(C)->edittree; + ntree->update = NTREE_UPDATE; + ntreeUpdateTree(CTX_data_main(C), ntree); +} + void register_node_type_my_test_node() { { @@ -738,11 +771,7 @@ void register_node_type_my_test_node() uiItemL(layout, "Hello World", 0); UI_but_func_set( but, - [](bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)) { - bNodeTree *ntree = CTX_wm_space_node(C)->edittree; - ntree->update = NTREE_UPDATE; - ntreeUpdateTree(CTX_data_main(C), ntree); - }, + [](bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)) { update_tree(C); }, nullptr, nullptr); }); @@ -763,6 +792,68 @@ void register_node_type_my_test_node() }); ntype.register_type(); } + { + static NodeDefinition ntype("FloatAddNode", "Float Add Node", ""); + ntype.add_dna_storage<FloatAddNodeStorage>( + "FloatAddNodeStorage", + []() { return (FloatAddNodeStorage *)MEM_callocN(sizeof(FloatAddNodeStorage), __func__); }, + [](const FloatAddNodeStorage *storage) { + FloatAddNodeStorage *new_storage = (FloatAddNodeStorage *)MEM_callocN( + sizeof(FloatAddNodeStorage), __func__); + LISTBASE_FOREACH (VariadicNodeSocketIdentifier *, value, &storage->inputs_info) { + void *new_value = MEM_dupallocN(value); + BLI_addtail(&new_storage->inputs_info, new_value); + } + return new_storage; + }, + [](FloatAddNodeStorage *storage) { + BLI_freelistN(&storage->inputs_info); + MEM_freeN(storage); + }); + ntype.add_declaration([](NodeBuilder &node_builder) { + FloatAddNodeStorage *storage = node_builder.node_storage<FloatAddNodeStorage>(); + LISTBASE_FOREACH (VariadicNodeSocketIdentifier *, value, &storage->inputs_info) { + node_builder.float_input(value->identifier, "Value"); + } + node_builder.float_output("result", "Result"); + }); + ntype.add_draw_fn([](uiLayout *layout, struct bContext *UNUSED(C), struct PointerRNA *ptr) { + bNode *node = (bNode *)ptr->data; + uiBut *but = uiDefBut(uiLayoutGetBlock(layout), + UI_BTYPE_BUT, + 0, + "Add Input", + 0, + 0, + 100, + 40, + nullptr, + 0, + 0, + 0, + 0, + "Add new input"); + UI_but_func_set( + but, + [](bContext *C, void *arg1, void *UNUSED(arg2)) { + bNode *node = (bNode *)arg1; + FloatAddNodeStorage *storage = get_node_storage<FloatAddNodeStorage>(node); + VariadicNodeSocketIdentifier *value = (VariadicNodeSocketIdentifier *)MEM_callocN( + sizeof(VariadicNodeSocketIdentifier), __func__); + BLI_uniquename(&storage->inputs_info, + value, + "ID", + '.', + offsetof(VariadicNodeSocketIdentifier, identifier), + sizeof(value->identifier)); + BLI_addtail(&storage->inputs_info, value); + update_tree(C); + }, + node, + nullptr); + }); + ntype.register_type(); + } } void init_socket_data_types() |