[Bf-blender-cvs] [0c8c082f9d5] functions: improve shared lists

Jacques Lucke noreply at git.blender.org
Sat Mar 9 16:15:47 CET 2019


Commit: 0c8c082f9d5f5565508850d6494d28c233584fa4
Author: Jacques Lucke
Date:   Sat Mar 9 16:11:10 2019 +0100
Branches: functions
https://developer.blender.org/rB0c8c082f9d5f5565508850d6494d28c233584fa4

improve shared lists

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

M	source/blender/blenlib/BLI_shared.hpp
M	source/blender/functions/backends/tuple_call/tuple.hpp
M	source/blender/functions/c_wrapper.cpp
M	source/blender/functions/functions/lists.cpp
M	source/blender/functions/types/lists.hpp

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

diff --git a/source/blender/blenlib/BLI_shared.hpp b/source/blender/blenlib/BLI_shared.hpp
index 059fe77d7f3..2663bfb10dd 100644
--- a/source/blender/blenlib/BLI_shared.hpp
+++ b/source/blender/blenlib/BLI_shared.hpp
@@ -91,22 +91,35 @@ namespace BLI {
 
 		AutoRefCount &operator=(const AutoRefCount &other)
 		{
-			if (m_object == other.m_object) {
+			if (this == &other) {
+				return *this;
+			}
+			else if (m_object == other.m_object) {
+				return *this;
+			}
+			else {
+				this->decref();
+				m_object = other.m_object;
+				this->incref();
 				return *this;
 			}
-
-			this->decref();
-			m_object = other.m_object;
-			this->incref();
-			return *this;
 		}
 
 		AutoRefCount &operator=(AutoRefCount &&other)
 		{
-			this->decref();
-			m_object = other.m_object;
-			other.m_object = nullptr;
-			return *this;
+			if (this == &other) {
+				return *this;
+			}
+			else if (m_object == other.m_object) {
+				other.m_object = nullptr;
+				return *this;
+			}
+			else {
+				this->decref();
+				m_object = other.m_object;
+				other.m_object = nullptr;
+				return *this;
+			}
 		}
 
 		T *ptr() const
diff --git a/source/blender/functions/backends/tuple_call/tuple.hpp b/source/blender/functions/backends/tuple_call/tuple.hpp
index fbf01738d21..89a01270d10 100644
--- a/source/blender/functions/backends/tuple_call/tuple.hpp
+++ b/source/blender/functions/backends/tuple_call/tuple.hpp
@@ -116,6 +116,24 @@ namespace FN {
 			m_initialized[index] = true;
 		}
 
+		template<typename T>
+		inline void move_in(uint index, T &value)
+		{
+			BLI_assert(index < m_meta->element_amount());
+			BLI_assert(sizeof(T) == m_meta->element_size(index));
+
+			T *dst = (T *)this->element_ptr(index);
+
+			if (m_initialized[index]) {
+				std::copy_n(std::make_move_iterator(&value), 1, dst);
+			}
+			else {
+				std::uninitialized_copy_n(std::make_move_iterator(&value), 1, dst);
+			}
+
+			m_initialized[index] = true;
+		}
+
 		template<typename T>
 		inline void set(uint index, const T &value)
 		{
@@ -134,6 +152,21 @@ namespace FN {
 			return *(T *)this->element_ptr(index);
 		}
 
+		template<typename T>
+		inline T relocate_out(uint index) const
+		{
+			BLI_assert(index < m_meta->element_amount());
+			BLI_assert(sizeof(T) == m_meta->element_size(index));
+			BLI_assert(m_initialized[index]);
+
+			T &value = this->element_ref<T>(index);
+			T tmp = std::move(value);
+			value.~T();
+			m_initialized[index] = false;
+
+			return tmp;
+		}
+
 		template<typename T>
 		inline T get(uint index) const
 		{
@@ -242,6 +275,12 @@ namespace FN {
 			return (void *)((char *)m_data + m_meta->offsets()[index]);
 		}
 
+		template<typename T>
+		inline T &element_ref(uint index) const
+		{
+			return *(T *)this->element_ptr(index);
+		}
+
 		void *m_data;
 		bool *m_initialized;
 		bool m_owns_mem;
diff --git a/source/blender/functions/c_wrapper.cpp b/source/blender/functions/c_wrapper.cpp
index df5cee0def5..15a2a942f8f 100644
--- a/source/blender/functions/c_wrapper.cpp
+++ b/source/blender/functions/c_wrapper.cpp
@@ -29,16 +29,19 @@ static void playground()
 	Tuple fn_out(fn->signature().output_types());
 
 	auto list = SharedFloatList::New();
-	list->new_user();
-	fn_in.copy_in<SharedFloatList>(0, list);
+
+	BLI_assert(list->users() == 1);
+	fn_in.copy_in(0, list);
+	BLI_assert(list->users() == 2);
+
 	fn_in.set<float>(1, 42.0f);
 
-	std::cout << "Size before: " << list->size() << std::endl;
+	BLI_assert(list->users() == 2);
 	fn->body<TupleCallBody>()->call(fn_in, fn_out);
+	BLI_assert(list->users() == 1);
 
-	auto new_list = fn_out.copy_out<SharedFloatList>(0);
-	std::cout << "Size Old after: " << list->size() << std::endl;
-	std::cout << "Size New after: " << new_list->size() << std::endl;
+	auto new_list = fn_out.relocate_out<SharedFloatList>(0);
+	BLI_assert(new_list->users() == 1);
 }
 
 void FN_initialize()
diff --git a/source/blender/functions/functions/lists.cpp b/source/blender/functions/functions/lists.cpp
index 070b0b75528..590bfb50858 100644
--- a/source/blender/functions/functions/lists.cpp
+++ b/source/blender/functions/functions/lists.cpp
@@ -11,13 +11,13 @@ namespace FN { namespace Functions {
 	class AppendFloat : public TupleCallBody {
 		void call(Tuple &fn_in, Tuple &fn_out) const override
 		{
-			auto list = fn_in.copy_out<SharedFloatList>(0);
+			auto list = fn_in.relocate_out<SharedFloatList>(0);
 			float value = fn_in.get<float>(1);
 
-			auto mutable_list = list->get_mutable(false);
+			list = list->get_mutable();
+			list->append(value);
 
-			mutable_list->append(value);
-			fn_out.copy_in<SharedFloatList>(0, SharedFloatList::FromPointer(mutable_list));
+			fn_out.move_in(0, list);
 		}
 	};
 
diff --git a/source/blender/functions/types/lists.hpp b/source/blender/functions/types/lists.hpp
index 451bcf18733..dee4610ab01 100644
--- a/source/blender/functions/types/lists.hpp
+++ b/source/blender/functions/types/lists.hpp
@@ -4,6 +4,12 @@
 
 namespace FN { namespace Types {
 
+	template<typename T>
+	class List;
+
+	template<typename T>
+	using SharedList = AutoRefCount<List<T>>;
+
 	template<typename T>
 	class List : public BLI::SharedImmutable {
 	private:
@@ -47,18 +53,15 @@ namespace FN { namespace Types {
 			return m_data[index];
 		}
 
-		List *get_mutable(bool keep_other)
+		SharedList<T> get_mutable()
 		{
 			if (this->is_mutable()) {
-				return this;
+				return SharedList<T>::FromPointer(this);
 			}
 			else {
 				List *new_list = this->copy();
 				BLI_assert(new_list->is_mutable());
-				if (!keep_other) {
-					this->remove_user();
-				}
-				return new_list;
+				return SharedList<T>::FromPointer(new_list);
 			}
 		}
 
@@ -73,7 +76,4 @@ namespace FN { namespace Types {
 		}
 	};
 
-	template<typename T>
-	using SharedList = AutoRefCount<List<T>>;
-
 } } /* namespace FN::Types */
\ No newline at end of file



More information about the Bf-blender-cvs mailing list