[Bf-blender-cvs] [66389f89336] functions: inference list relations properly

Jacques Lucke noreply at git.blender.org
Mon Feb 18 18:19:26 CET 2019


Commit: 66389f8933671fd54bfbeaf42061d390bd6e1fc2
Author: Jacques Lucke
Date:   Mon Feb 18 18:18:47 2019 +0100
Branches: functions
https://developer.blender.org/rB66389f8933671fd54bfbeaf42061d390bd6e1fc2

inference list relations properly

===================================================================

M	source/blender/blenlib/BLI_lazy_init.hpp
M	source/blender/functions/c_wrapper.cpp
M	source/blender/functions/core/type_inferencing.cpp
M	source/blender/functions/core/type_inferencing.hpp
M	source/blender/functions/core/type_relations.cpp
M	source/blender/functions/core/type_relations.hpp

===================================================================

diff --git a/source/blender/blenlib/BLI_lazy_init.hpp b/source/blender/blenlib/BLI_lazy_init.hpp
index 66c5ba2a13c..654674fa1c1 100644
--- a/source/blender/blenlib/BLI_lazy_init.hpp
+++ b/source/blender/blenlib/BLI_lazy_init.hpp
@@ -1,8 +1,9 @@
 #define LAZY_INIT_NO_ARG(final_ret_type, builder_ret_type, func_name) \
-	builder_ret_type func_name##_impl(); \
-	final_ret_type func_name() \
+	static builder_ret_type func_name##_impl(void); \
+	final_ret_type func_name(void); \
+	final_ret_type func_name(void) \
 	{ \
 		static builder_ret_type value = func_name##_impl(); \
 		return value; \
 	} \
-	builder_ret_type func_name##_impl()
+	builder_ret_type func_name##_impl(void)
diff --git a/source/blender/functions/c_wrapper.cpp b/source/blender/functions/c_wrapper.cpp
index d3b921b1647..6f227a5d4aa 100644
--- a/source/blender/functions/c_wrapper.cpp
+++ b/source/blender/functions/c_wrapper.cpp
@@ -2,6 +2,7 @@
 #include "FN_functions.hpp"
 
 #include "function_nodes/function_nodes.hpp"
+#include "BLI_lazy_init.hpp"
 
 #include <iostream>
 
@@ -230,6 +231,28 @@ void FN_function_update_dependencies(
 	dependencies.update_depsgraph(deps_node);
 }
 
+class GetFloatListElement : public FN::TupleCallBody {
+	void call(const FN::Tuple &fn_in, FN::Tuple &fn_out) const override
+	{
+		auto list = fn_in.get<BLI::SmallVector<float>>(0);
+		int32_t index = fn_in.get<int32_t>(1);
+		fn_out.set<float>(0, list[index]);
+	}
+};
+
+LAZY_INIT_NO_ARG(FN::SharedFunction&, FN::SharedFunction, get__get_float_list_element)
+{
+	auto signature = FN::Signature({
+		FN::InputParameter("List", FN::Types::get_float_list_type()),
+		FN::InputParameter("Index", FN::Types::get_int32_type())
+	}, {
+		FN::OutputParameter("Value", FN::Types::get_float_type())
+	});
+	auto fn = FN::SharedFunction::New(signature);
+	fn->add_body(new GetFloatListElement());
+	return fn;
+}
+
 void FN_test_inferencer()
 {
 	FN::SharedType &float_ty = FN::Types::get_float_type();
@@ -237,8 +260,11 @@ void FN_test_inferencer()
 	FN::SharedType &fvec3_ty = FN::Types::get_fvec3_type();
 	FN::SharedType &float_list_ty = FN::Types::get_float_list_type();
 
+	FN::ListTypeRelations list_types(int32_ty);
+	list_types.insert(float_ty, float_list_ty, get__get_float_list_element());
+
 	{
-		FN::Inferencer inferencer;
+		FN::Inferencer inferencer(list_types);
 		inferencer.insert_final_type(0, float_ty);
 		inferencer.insert_final_type(1, int32_ty);
 		inferencer.insert_final_type(2, fvec3_ty);
@@ -254,7 +280,7 @@ void FN_test_inferencer()
 		BLI_assert(inferencer.get_final_type(4) == int32_ty);
 	}
 	{
-		FN::Inferencer inferencer;
+		FN::Inferencer inferencer(list_types);
 		inferencer.insert_final_type(0, float_ty);
 		inferencer.insert_final_type(1, int32_ty);
 		inferencer.insert_equality_relation({0, 2});
@@ -263,10 +289,12 @@ void FN_test_inferencer()
 		BLI_assert(!inferencer.inference());
 	}
 	{
-		FN::Inferencer inferencer;
+		FN::Inferencer inferencer(list_types);
 		inferencer.insert_final_type(0, float_ty);
 		inferencer.insert_list_relation({1}, {0});
 
 		BLI_assert(inferencer.inference());
+
+		BLI_assert(inferencer.get_final_type(1) == float_list_ty);
 	}
 }
\ No newline at end of file
diff --git a/source/blender/functions/core/type_inferencing.cpp b/source/blender/functions/core/type_inferencing.cpp
index a790f8eef13..11d0698d536 100644
--- a/source/blender/functions/core/type_inferencing.cpp
+++ b/source/blender/functions/core/type_inferencing.cpp
@@ -62,23 +62,90 @@ namespace FN {
 
 	bool Inferencer::inference()
 	{
-		while (!m_equality_relations.empty()) {
-			for (uint i = 0; i < m_equality_relations.size(); i++) {
-				EqualityRelation group = m_equality_relations[i];
+		while (!m_equality_relations.empty() || !m_list_relations.empty()) {
+			if (!this->evaluate_equality_relations()) {
+				return false;
+			}
+			if (!this->evaluate_list_relations()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	bool Inferencer::evaluate_equality_relations()
+	{
+		for (uint i = 0; i < m_equality_relations.size(); i++) {
+			EqualityRelation &relation = m_equality_relations[i];
+
+			for (uint64_t id : relation.ids) {
+				if (this->has_final_type(id)) {
+					if (!this->finalize_ids(relation.ids, this->get_final_type(id))) {
+						return false;
+					}
+					m_equality_relations.remove_and_reorder(i);
+					i--;
+					break;
+				}
+			}
+		}
+		return true;
+	}
+
+	bool Inferencer::evaluate_list_relations()
+	{
+		for (uint i = 0; i < m_list_relations.size(); i++) {
+			ListRelation &relation = m_list_relations[i];
+
+			bool done = false;
+
+			for (uint64_t list_id : relation.list_ids) {
+				if (this->has_final_type(list_id)) {
+					SharedType &list_type = this->get_final_type(list_id);
+					if (!m_list_types.is_list(list_type)) {
+						return false;
+					}
+					SharedType &base_type = m_list_types.get_base_of(list_type);
+					this->finalize_list_relation(relation, base_type, list_type);
+					done = true;
+					break;
+				}
+			}
 
-				for (uint64_t id : group.ids) {
-					if (this->has_final_type(id)) {
-						if (!this->finalize_ids(group.ids, this->get_final_type(id))) {
+			if (!done) {
+				for (uint64_t base_id : relation.base_ids) {
+					if (this->has_final_type(base_id)) {
+						SharedType &base_type = this->get_final_type(base_id);
+						if (!m_list_types.is_base(base_type)) {
 							return false;
 						}
-						m_equality_relations.remove_and_reorder(i);
-						i--;
+						SharedType &list_type = m_list_types.get_list_of(base_type);
+						this->finalize_list_relation(relation, base_type, list_type);
+						done = true;
 						break;
 					}
 				}
 			}
+
+			if (done) {
+				m_list_relations.remove_and_reorder(i);
+				i--;
+			}
 		}
+		return true;
+	}
 
+	bool Inferencer::finalize_list_relation(
+		ListRelation &relation,
+		SharedType &base_type,
+		SharedType &list_type)
+	{
+		if (!this->finalize_ids(relation.list_ids, list_type)) {
+			return false;
+		}
+		if (!this->finalize_ids(relation.base_ids, base_type)) {
+			return false;
+		}
 		return true;
 	}
 
diff --git a/source/blender/functions/core/type_inferencing.hpp b/source/blender/functions/core/type_inferencing.hpp
index 2ca3085e110..789ec58ee7c 100644
--- a/source/blender/functions/core/type_inferencing.hpp
+++ b/source/blender/functions/core/type_inferencing.hpp
@@ -1,4 +1,5 @@
 #include "core.hpp"
+#include "type_relations.hpp"
 
 namespace FN {
 
@@ -11,15 +12,26 @@ namespace FN {
 			SmallVector<uint64_t> list_ids, base_ids;
 		};
 
+
 		SmallMap<uint64_t, SharedType> m_final_types;
 		SmallVector<EqualityRelation> m_equality_relations;
 		SmallVector<ListRelation> m_list_relations;
 
+		ListTypeRelations &m_list_types;
+
 		bool finalize_id(uint64_t id, SharedType &type);
 		bool finalize_ids(SmallVector<uint64_t> ids, SharedType &type);
+		bool finalize_list_relation(
+			ListRelation &relation,
+			SharedType &base_type,
+			SharedType &list_type);
+
+		bool evaluate_equality_relations();
+		bool evaluate_list_relations();
 
 	public:
-		Inferencer() = default;
+		Inferencer(ListTypeRelations &list_types)
+			: m_list_types(list_types) {}
 
 		void insert_final_type(uint64_t id, SharedType &type);
 		void insert_equality_relation(SmallVector<uint64_t> ids);
diff --git a/source/blender/functions/core/type_relations.cpp b/source/blender/functions/core/type_relations.cpp
index 69257605121..308a77476d4 100644
--- a/source/blender/functions/core/type_relations.cpp
+++ b/source/blender/functions/core/type_relations.cpp
@@ -2,30 +2,70 @@
 
 namespace FN {
 
+	ListTypeRelations::ListTypeRelations(
+		SharedType &index_type)
+		: m_index_type(index_type) {}
+
 	void ListTypeRelations::insert(
 		SharedType &base_type,
 		SharedType &list_type,
-		SharedFunction &get_element,
-		SharedFunction &set_element)
+		SharedFunction &get_element)
 	{
-		BLI_assert(base_type == list_type);
+		BLI_assert(base_type != list_type);
 
 		BLI_assert(get_element->signature().has_interface(
 			{list_type, m_index_type},
 			{base_type}));
 
-		BLI_assert(set_element->signature().has_interface(
-			{list_type, m_index_type, base_type},
-			{list_type}));
-
 		Relation relation = {
 			base_type,
 			list_type,
 			get_element,
-			set_element
 		};
 
 		m_relations.append(relation);
 	}
 
+	bool ListTypeRelations::is_list(SharedType &type)
+	{
+		for (Relation &relation : m_relations) {
+			if (relation.list_type == type) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	bool ListTypeRelations::is_base(SharedType &type)
+	{
+		for (Relation &relation : m_relations) {
+			if (relation.base_type == type) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	SharedType &ListTypeRelations::get_list_of(SharedType &base_type)
+	{
+		for (Relation &relation : m_relations) {
+			if (relation.base_type == base_type) {
+				return relation.list_type;
+			}
+		}
+		BLI_assert(false);
+		return *(SharedType *)nullptr;
+	}
+
+	SharedType &ListTypeRelations::get_base_of(SharedType &list_type)
+	{
+		for (Relation &relation : m_relations) {
+			if (relation.list_type == list_type) {
+				return relation.base_type;
+			}
+		}
+		BLI_assert(false);
+		return *(SharedType *)nullptr;
+	}
+
 } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/core/type_relations.hpp b/source/blender/functions/core/type_relations.hpp
index 569510864f0..433966bb20d 100644
--- a/source/blender/functions/core/type_relations.hpp
+++ b/source/blender/functions/core/type_relations.hpp
@@ -11,7 +11,6 @@ namespace FN {
 			SharedType base_type;
 			SharedType list_type;
 			SharedFunction get_element;
-			SharedFunction set_element;
 		};
 
 		SharedType m_index_type;
@@ -23,8 +22,13 @@ namespace FN {
 		void insert(
 			SharedType &base_type,
 			SharedType &list_type,
-			SharedFunction &get_element,
-			SharedFunction &set_element);
+			SharedFunction &get_element);
+
+		bool is_list(SharedType &type);
+		bool is_base(SharedType &type);
+
+		SharedType &get_list_of(SharedType &base_type);
+		SharedType &get_base_of(SharedType &list_type);
 	};
 
 } /* namespace FN */
\ No newline at end of file



More information about the Bf-blender-cvs mailing list