[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