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

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to