[Bf-blender-cvs] [0a0c8c4aa03] nodes_playground: allow passing node itself into the execution function
Jacques Lucke
noreply at git.blender.org
Sun Jan 6 17:25:49 CET 2019
Commit: 0a0c8c4aa03185da2c13cfce8654f08d34e59314
Author: Jacques Lucke
Date: Sun Jan 6 11:37:54 2019 +0100
Branches: nodes_playground
https://developer.blender.org/rB0a0c8c4aa03185da2c13cfce8654f08d34e59314
allow passing node itself into the execution function
===================================================================
M source/blender/modifiers/intern/node_compiler.hpp
M source/blender/modifiers/intern/node_compiler_testing.cpp
===================================================================
diff --git a/source/blender/modifiers/intern/node_compiler.hpp b/source/blender/modifiers/intern/node_compiler.hpp
index 823ede7904a..7ffc501fdc3 100644
--- a/source/blender/modifiers/intern/node_compiler.hpp
+++ b/source/blender/modifiers/intern/node_compiler.hpp
@@ -158,19 +158,30 @@ llvm::CallInst *callPointer(
void *pointer, llvm::FunctionType *type, llvm::ArrayRef<llvm::Value *> arguments);
class ExecuteFunctionNode : public Node {
- virtual void *getExecuteFunction() = 0;
+protected:
+ void *execute_function = nullptr;
+ bool use_this = false;
+public:
void buildLLVMIR(
std::vector<llvm::Value *> &inputs, llvm::IRBuilder<> *builder,
std::vector<llvm::Value *> &r_outputs, llvm::IRBuilder<> **r_builder)
{
+ assert(this->execute_function);
+
llvm::LLVMContext &context = builder->getContext();
+ std::vector<llvm::Value *> arguments;
+ if (this->use_this) {
+ llvm::Value *this_pointer = builder->CreateIntToPtr(builder->getInt64((size_t)this), llvm::Type::getVoidTy(context)->getPointerTo());
+ arguments.push_back(this_pointer);
+ }
+ arguments.insert(arguments.end(), inputs.begin(), inputs.end());
+
std::vector<llvm::Type *> arg_types;
for (auto socket : this->inputs()) {
arg_types.push_back(socket.type->getLLVMType(context));
}
- std::vector<llvm::Value *> arguments = inputs;
std::vector<llvm::Value *> output_pointers;
for (auto socket : this->outputs()) {
llvm::Type *type = socket.type->getLLVMType(context);
@@ -182,7 +193,7 @@ class ExecuteFunctionNode : public Node {
llvm::FunctionType *ftype = llvm::FunctionType::get(
llvm::Type::getVoidTy(context), arg_types, false);
- callPointer(*builder, this->getExecuteFunction(), ftype, arguments);
+ callPointer(*builder, this->execute_function, ftype, arguments);
for (auto output_pointer : output_pointers) {
llvm::Value *result = builder->CreateLoad(output_pointer);
diff --git a/source/blender/modifiers/intern/node_compiler_testing.cpp b/source/blender/modifiers/intern/node_compiler_testing.cpp
index 9eaf9227346..7f0ebebc936 100644
--- a/source/blender/modifiers/intern/node_compiler_testing.cpp
+++ b/source/blender/modifiers/intern/node_compiler_testing.cpp
@@ -22,7 +22,84 @@ public:
}
};
+struct MyTypeStruct {
+ int a, b, c;
+};
+
+class MyType : public NC::Type {
+public:
+ MyType() {}
+
+ llvm::Type *createLLVMType(llvm::LLVMContext &context)
+ {
+ return llvm::Type::getVoidTy(context)->getPointerTo();
+ }
+};
+
auto *type_int32 = new IntegerType(32);
+auto *type_custom = new MyType();
+
+
+
+class MyTypeInputNode;
+static void my_type_input(MyTypeInputNode *node, void **r_value);
+
+class MyTypeInputNode : public NC::ExecuteFunctionNode {
+private:
+ MyTypeStruct data;
+public:
+ MyTypeInputNode(int a, int b, int c)
+ {
+ this->data.a = a;
+ this->data.b = b;
+ this->data.c = c;
+ this->m_outputs.add("Value", type_custom);
+ this->execute_function = (void *)my_type_input;
+ this->use_this = true;
+ }
+
+ friend void my_type_input(MyTypeInputNode *node, void **r_value)
+ {
+ *r_value = new MyTypeStruct(node->data);
+ }
+};
+
+class MyTypePrintNode;
+static void my_type_print(MyTypeStruct *a, MyTypeStruct *b, int *r_value)
+{
+ std::cout << "A: " << a->a << " " << a->b << " " << a->c << std::endl;
+ std::cout << "B: " << b->a << " " << b->b << " " << b->c << std::endl;
+ *r_value = 123;
+}
+
+class MyTypePrintNode : public NC::ExecuteFunctionNode {
+public:
+ MyTypePrintNode()
+ {
+ this->m_inputs.add("A", type_custom);
+ this->m_inputs.add("B", type_custom);
+ this->m_outputs.add("Output", type_int32);
+ this->execute_function = (void *)my_type_print;
+ }
+};
+
+class ModifyMyTypeNode;
+static void modify_my_type(MyTypeStruct *data, MyTypeStruct **r_data)
+{
+ data->a = 500;
+ *r_data = data;
+}
+
+class ModifyMyTypeNode : public NC::ExecuteFunctionNode {
+public:
+ ModifyMyTypeNode()
+ {
+ this->m_inputs.add("In", type_custom);
+ this->m_outputs.add("Out", type_custom);
+ this->execute_function = (void *)modify_my_type;
+ }
+};
+
class IntInputNode : public NC::SingleBuilderNode {
private:
@@ -84,23 +161,26 @@ public:
}
};
-static void print_number(int number, int *r_number)
-{
- std::cout << "The number is: " << number << std::endl;
- *r_number = number + 42;
-}
+class PrintIntegerNode;
+static void print_number(PrintIntegerNode *node, int number, int *r_number);
class PrintIntegerNode : public NC::ExecuteFunctionNode {
+private:
+ std::string prefix;
public:
PrintIntegerNode()
{
this->m_inputs.add("In", type_int32);
this->m_outputs.add("Out", type_int32);
+ this->execute_function = (void *)print_number;
+ this->use_this = true;
+ this->prefix = "Hello Number ";
}
- void *getExecuteFunction()
+ friend void print_number(PrintIntegerNode *node, int number, int *r_number)
{
- return (void *)print_number;
+ std::cout << node->prefix << number << std::endl;
+ *r_number = number + 42;
}
};
@@ -111,42 +191,23 @@ extern "C" {
void run_tests()
{
- int test_value = 1000;
-
- auto in1 = new IntInputNode(1);
- auto in2 = new IntRefInputNode(&test_value);
- auto in3 = new IntInputNode(10);
-
- auto add1 = new AddIntegersNode();
- auto add2 = new AddIntegersNode();
- auto add3 = new AddIntegersNode();
-
- auto print1 = new PrintIntegerNode();
+ auto in1 = new MyTypeInputNode(10, 20, 30);
+ auto mod1 = new ModifyMyTypeNode();
+ auto print1 = new MyTypePrintNode();
NC::DataFlowGraph graph;
graph.nodes.push_back(in1);
- graph.nodes.push_back(in2);
- graph.nodes.push_back(in3);
- graph.nodes.push_back(add1);
- graph.nodes.push_back(add2);
- graph.nodes.push_back(add3);
graph.nodes.push_back(print1);
+ graph.links.links.push_back(NC::Link(in1->Output(0), print1->Input(0)));
+ graph.links.links.push_back(NC::Link(in1->Output(0), mod1->Input(0)));
+ graph.links.links.push_back(NC::Link(mod1->Output(0), print1->Input(1)));
- graph.links.links.push_back(NC::Link(in1->Output(0), add1->Input(0)));
- graph.links.links.push_back(NC::Link(in2->Output(0), add1->Input(1)));
- graph.links.links.push_back(NC::Link(in2->Output(0), add2->Input(0)));
- graph.links.links.push_back(NC::Link(in3->Output(0), add2->Input(1)));
- graph.links.links.push_back(NC::Link(add1->Output(0), add3->Input(0)));
- graph.links.links.push_back(NC::Link(add2->Output(0), add3->Input(1)));
- graph.links.links.push_back(NC::Link(add3->Output(0), print1->Input(0)));
-
-
- NC::SocketArraySet inputs = { in1->Output(0), in2->Output(0) };
+ NC::SocketArraySet inputs = { };
NC::SocketArraySet outputs = { print1->Output(0) };
NC::DataFlowCallable *callable = graph.generateCallable("Hello", inputs, outputs);
callable->printCode();
- int result = ((int (*)(int, int))callable->getFunctionPointer())(10, 25);
+ int result = ((int (*)())callable->getFunctionPointer())();
std::cout << result << std::endl;
// NC::SocketSet inputs = { add1->Input(0), add1->Input(1), add2->Input(1) };
More information about the Bf-blender-cvs
mailing list