瀏覽代碼

[Core] Fix sharing of typed arrays from constructor

A Thousand Ships 1 年之前
父節點
當前提交
09460d33e6
共有 2 個文件被更改,包括 53 次插入6 次删除
  1. 16 6
      core/variant/typed_array.h
  2. 37 0
      tests/core/variant/test_array.h

+ 16 - 6
core/variant/typed_array.h

@@ -46,10 +46,15 @@ public:
 		_ref(p_array);
 	}
 	_FORCE_INLINE_ TypedArray(const Variant &p_variant) :
-			Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) {
+			TypedArray(Array(p_variant)) {
 	}
-	_FORCE_INLINE_ TypedArray(const Array &p_array) :
-			Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) {
+	_FORCE_INLINE_ TypedArray(const Array &p_array) {
+		set_typed(Variant::OBJECT, T::get_class_static(), Variant());
+		if (is_same_typed(p_array)) {
+			_ref(p_array);
+		} else {
+			assign(p_array);
+		}
 	}
 	_FORCE_INLINE_ TypedArray() {
 		set_typed(Variant::OBJECT, T::get_class_static(), Variant());
@@ -78,10 +83,15 @@ struct VariantInternalAccessor<const TypedArray<T> &> {
 			_ref(p_array);                                                                                       \
 		}                                                                                                        \
 		_FORCE_INLINE_ TypedArray(const Variant &p_variant) :                                                    \
-				Array(Array(p_variant), m_variant_type, StringName(), Variant()) {                               \
+				TypedArray(Array(p_variant)) {                                                                   \
 		}                                                                                                        \
-		_FORCE_INLINE_ TypedArray(const Array &p_array) :                                                        \
-				Array(p_array, m_variant_type, StringName(), Variant()) {                                        \
+		_FORCE_INLINE_ TypedArray(const Array &p_array) {                                                        \
+			set_typed(m_variant_type, StringName(), Variant());                                                  \
+			if (is_same_typed(p_array)) {                                                                        \
+				_ref(p_array);                                                                                   \
+			} else {                                                                                             \
+				assign(p_array);                                                                                 \
+			}                                                                                                    \
 		}                                                                                                        \
 		_FORCE_INLINE_ TypedArray() {                                                                            \
 			set_typed(m_variant_type, StringName(), Variant());                                                  \

+ 37 - 0
tests/core/variant/test_array.h

@@ -597,6 +597,43 @@ TEST_CASE("[Array] Iteration and modification") {
 	a4.clear();
 }
 
+TEST_CASE("[Array] Typed copying") {
+	TypedArray<int> a1;
+	a1.push_back(1);
+
+	TypedArray<double> a2;
+	a2.push_back(1.0);
+
+	Array a3 = a1;
+	TypedArray<int> a4 = a3;
+
+	Array a5 = a2;
+	TypedArray<int> a6 = a5;
+
+	a3[0] = 2;
+	a4[0] = 3;
+
+	// Same typed TypedArray should be shared.
+	CHECK_EQ(a1[0], Variant(3));
+	CHECK_EQ(a3[0], Variant(3));
+	CHECK_EQ(a4[0], Variant(3));
+
+	a5[0] = 2.0;
+	a6[0] = 3.0;
+
+	// Different typed TypedArray should not be shared.
+	CHECK_EQ(a2[0], Variant(2.0));
+	CHECK_EQ(a5[0], Variant(2.0));
+	CHECK_EQ(a6[0], Variant(3.0));
+
+	a1.clear();
+	a2.clear();
+	a3.clear();
+	a4.clear();
+	a5.clear();
+	a6.clear();
+}
+
 } // namespace TestArray
 
 #endif // TEST_ARRAY_H