diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/array.cpp | 65 | ||||
| -rw-r--r-- | core/array.h | 5 | ||||
| -rw-r--r-- | core/container_type_validate.h | 98 | ||||
| -rw-r--r-- | core/method_bind.h | 1 | ||||
| -rw-r--r-- | core/object.h | 1 | ||||
| -rw-r--r-- | core/script_language.h | 2 | ||||
| -rw-r--r-- | core/typed_array.cpp | 1 | ||||
| -rw-r--r-- | core/typed_array.h | 196 | 
8 files changed, 367 insertions, 2 deletions
| diff --git a/core/array.cpp b/core/array.cpp index d65bddae61..90dee44a58 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -30,8 +30,10 @@  #include "array.h" +#include "container_type_validate.h"  #include "core/hashfuncs.h"  #include "core/object.h" +#include "core/script_language.h"  #include "core/variant.h"  #include "core/vector.h" @@ -39,6 +41,8 @@ class ArrayPrivate {  public:  	SafeRefCount refcount;  	Vector<Variant> array; + +	ContainerTypeValidate typed;  };  void Array::_ref(const Array &p_from) const { @@ -108,12 +112,34 @@ uint32_t Array::hash() const {  	}  	return h;  } -void Array::operator=(const Array &p_array) { -	_ref(p_array); +void Array::_assign(const Array &p_array) { + +	if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) { +		//same type or untyped, just reference, shuold be fine +		_ref(p_array); +	} else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway +		_p->array = p_array._p->array; +	} else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid +		for (int i = 0; i < p_array._p->array.size(); i++) { +			if (!_p->typed.validate(p_array._p->array[i], "assign")) { +				return; +			} +		} +		_p->array = p_array._p->array; //then just copy, which is cheap anyway +	} else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible +		_ref(p_array); +	} else { +		ERR_FAIL_MSG("Assignment of arrays of incompatible types."); +	} +} + +void Array::operator=(const Array &p_array) { +	_assign(p_array);  }  void Array::push_back(const Variant &p_value) { +	ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back"));  	_p->array.push_back(p_value);  } @@ -124,11 +150,13 @@ Error Array::resize(int p_new_size) {  void Array::insert(int p_pos, const Variant &p_value) { +	ERR_FAIL_COND(!_p->typed.validate(p_value, "insert"));  	_p->array.insert(p_pos, p_value);  }  void Array::erase(const Variant &p_value) { +	ERR_FAIL_COND(!_p->typed.validate(p_value, "erase"));  	_p->array.erase(p_value);  } @@ -144,6 +172,7 @@ Variant Array::back() const {  int Array::find(const Variant &p_value, int p_from) const { +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1);  	return _p->array.find(p_value, p_from);  } @@ -151,6 +180,7 @@ int Array::rfind(const Variant &p_value, int p_from) const {  	if (_p->array.size() == 0)  		return -1; +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1);  	if (p_from < 0) {  		// Relative offset from the end @@ -173,11 +203,13 @@ int Array::rfind(const Variant &p_value, int p_from) const {  int Array::find_last(const Variant &p_value) const { +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1);  	return rfind(p_value);  }  int Array::count(const Variant &p_value) const { +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0);  	if (_p->array.size() == 0)  		return 0; @@ -193,6 +225,8 @@ int Array::count(const Variant &p_value) const {  }  bool Array::has(const Variant &p_value) const { +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "use 'has'"), false); +  	return _p->array.find(p_value, 0) != -1;  } @@ -203,6 +237,8 @@ void Array::remove(int p_pos) {  void Array::set(int p_idx, const Variant &p_value) { +	ERR_FAIL_COND(!_p->typed.validate(p_value, "set")); +  	operator[](p_idx) = p_value;  } @@ -216,6 +252,7 @@ Array Array::duplicate(bool p_deep) const {  	Array new_arr;  	int element_count = size();  	new_arr.resize(element_count); +	new_arr._p->typed = _p->typed;  	for (int i = 0; i < element_count; i++) {  		new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);  	} @@ -369,11 +406,13 @@ _FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value  int Array::bsearch(const Variant &p_value, bool p_before) { +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1);  	return bisect(_p->array, p_value, p_before, _ArrayVariantSort());  }  int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { +	ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);  	ERR_FAIL_NULL_V(p_obj, 0);  	_ArrayVariantSortCustom less; @@ -391,6 +430,7 @@ Array &Array::invert() {  void Array::push_front(const Variant &p_value) { +	ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front"));  	_p->array.insert(0, p_value);  } @@ -465,6 +505,27 @@ const void *Array::id() const {  	return _p->array.ptr();  } +Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { +	_p = memnew(ArrayPrivate); +	_p->refcount.init(); +	set_typed(p_type, p_class_name, p_script); +	_assign(p_from); +} + +void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { +	ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty."); +	ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user."); +	ERR_FAIL_COND_MSG(_p->typed.type != Variant::NIL, "Type can only be set once."); +	ERR_FAIL_COND_MSG(p_class_name != StringName() && p_type != Variant::OBJECT, "Class names can only be set for type OBJECT"); +	Ref<Script> script = p_script; +	ERR_FAIL_COND_MSG(script.is_valid() && p_class_name == StringName(), "Script class can only be set together with base class name"); + +	_p->typed.type = Variant::Type(p_type); +	_p->typed.class_name = p_class_name; +	_p->typed.script = script; +	_p->typed.where = "TypedArray"; +} +  Array::Array(const Array &p_from) {  	_p = nullptr; diff --git a/core/array.h b/core/array.h index 3b14bdb9fe..2840ce199c 100644 --- a/core/array.h +++ b/core/array.h @@ -47,6 +47,10 @@ class Array {  	int _clamp_index(int p_index) const;  	static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod); +protected: +	Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); +	void _assign(const Array &p_array); +  public:  	Variant &operator[](int p_idx);  	const Variant &operator[](int p_idx) const; @@ -101,6 +105,7 @@ public:  	const void *id() const; +	void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);  	Array(const Array &p_from);  	Array();  	~Array(); diff --git a/core/container_type_validate.h b/core/container_type_validate.h new file mode 100644 index 0000000000..3721668033 --- /dev/null +++ b/core/container_type_validate.h @@ -0,0 +1,98 @@ +#ifndef CONTAINER_TYPE_VALIDATE_H +#define CONTAINER_TYPE_VALIDATE_H + +#include "core/script_language.h" +#include "core/variant.h" + +struct ContainerTypeValidate { + +	Variant::Type type = Variant::NIL; +	StringName class_name; +	Ref<Script> script; +	const char *where = "conatiner"; + +	_FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const { +		if (type == p_type.type) { +			if (type != Variant::OBJECT) { +				return true; //nothing else to check +			} +		} else { +			return false; +		} + +		//both are object + +		if ((class_name != StringName()) != (p_type.class_name != StringName())) { +			return false; //both need to have class or none +		} + +		if (class_name != p_type.class_name) { +			if (!ClassDB::is_parent_class(p_type.class_name, class_name)) { +				return false; +			} +		} + +		if (script.is_null() != p_type.script.is_null()) { +			return false; +		} + +		if (script != p_type.script) { +			if (!p_type.script->inherits_script(script)) { +				return false; +			} +		} + +		return true; +	} + +	_FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") { + +		if (type == Variant::NIL) { +			return true; +		} + +		ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); +		if (type != p_variant.get_type()) { +			return false; +		} + +		if (type != Variant::OBJECT) { +			return true; +		} +#ifdef DEBUG_ENABLED +		ObjectID object_id = p_variant; +		if (object_id == ObjectID()) { +			return true; //fine its null; +		} +		Object *object = ObjectDB::get_instance(object_id); +		ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + "."); +#else +		Object *object = p_variant; +		if (object == nullptr) { +			return true; //fine +		} +#endif +		if (class_name == StringName()) { +			return true; //all good, no class type requested +		} + +		StringName obj_class = object->get_class_name(); +		if (obj_class != class_name) { +			ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, "Attempted to " + String(p_operation) + " an object of type '" + object->get_class() + "' into a " + where + ", which does not inherit from '" + String(class_name) + "'."); +		} + +		if (script.is_null()) { +			return true; //all good +		} + +		Ref<Script> other_script = object->get_script(); + +		//check base script.. +		ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); +		ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); + +		return true; +	} +}; + +#endif // CONTAINER_TYPE_VALIDATE_H diff --git a/core/method_bind.h b/core/method_bind.h index 588b472b62..d39f107ba6 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -39,6 +39,7 @@  #include "core/method_ptrcall.h"  #include "core/object.h"  #include "core/type_info.h" +#include "core/typedefs.h"  #include "core/variant.h"  #include <stdio.h> diff --git a/core/object.h b/core/object.h index 1eaab5034e..b40aef2a42 100644 --- a/core/object.h +++ b/core/object.h @@ -91,6 +91,7 @@ enum PropertyHint {  	PROPERTY_HINT_NODE_PATH_VALID_TYPES,  	PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog  	PROPERTY_HINT_INT_IS_OBJECTID, +	PROPERTY_HINT_ARRAY_TYPE,  	PROPERTY_HINT_MAX,  	// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit  }; diff --git a/core/script_language.h b/core/script_language.h index 2d86c5166d..5cc240efcb 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -135,6 +135,8 @@ public:  	virtual Ref<Script> get_base_script() const = 0; //for script inheritance +	virtual bool inherits_script(const Ref<Script> &p_script) const = 0; +  	virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so  	virtual ScriptInstance *instance_create(Object *p_this) = 0;  	virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) { return nullptr; } diff --git a/core/typed_array.cpp b/core/typed_array.cpp new file mode 100644 index 0000000000..55e45f0b3f --- /dev/null +++ b/core/typed_array.cpp @@ -0,0 +1 @@ +#include "typed_array.h" diff --git a/core/typed_array.h b/core/typed_array.h new file mode 100644 index 0000000000..c65d68b526 --- /dev/null +++ b/core/typed_array.h @@ -0,0 +1,196 @@ +#ifndef TYPED_ARRAY_H +#define TYPED_ARRAY_H + +#include "core/array.h" +#include "core/method_ptrcall.h" +#include "core/variant.h" + +template <class T> +class TypedArray : public Array { +public: +	template <class U> +	_FORCE_INLINE_ void operator=(const TypedArray<U> &p_array) { +		static_assert(__is_base_of(T, U)); +		_assign(p_array); +	} + +	_FORCE_INLINE_ void operator=(const Array &p_array) { +		_assign(p_array); +	} +	_FORCE_INLINE_ TypedArray(const Array &p_array) : +			Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) { +	} +	_FORCE_INLINE_ TypedArray() { +		set_typed(Variant::OBJECT, T::get_class_static(), Variant()); +	} +}; + +//specialization for the rest of variant types + +#define MAKE_TYPED_ARRAY(m_type, m_variant_type)                          \ +	template <>                                                           \ +	class TypedArray<m_type> : public Array {                             \ +	public:                                                               \ +		_FORCE_INLINE_ void operator=(const Array &p_array) {             \ +			_assign(p_array);                                             \ +		}                                                                 \ +		_FORCE_INLINE_ TypedArray(const Array &p_array) :                 \ +				Array(p_array, m_variant_type, StringName(), Variant()) { \ +		}                                                                 \ +		_FORCE_INLINE_ TypedArray() {                                     \ +			set_typed(m_variant_type, StringName(), Variant());           \ +		}                                                                 \ +	}; + +MAKE_TYPED_ARRAY(bool, Variant::BOOL) +MAKE_TYPED_ARRAY(uint8_t, Variant::INT) +MAKE_TYPED_ARRAY(int8_t, Variant::INT) +MAKE_TYPED_ARRAY(uint16_t, Variant::INT) +MAKE_TYPED_ARRAY(int16_t, Variant::INT) +MAKE_TYPED_ARRAY(uint32_t, Variant::INT) +MAKE_TYPED_ARRAY(int32_t, Variant::INT) +MAKE_TYPED_ARRAY(uint64_t, Variant::INT) +MAKE_TYPED_ARRAY(int64_t, Variant::INT) +MAKE_TYPED_ARRAY(float, Variant::FLOAT) +MAKE_TYPED_ARRAY(double, Variant::FLOAT) +MAKE_TYPED_ARRAY(String, Variant::STRING) +MAKE_TYPED_ARRAY(Vector2, Variant::VECTOR2) +MAKE_TYPED_ARRAY(Vector2i, Variant::VECTOR2I) +MAKE_TYPED_ARRAY(Rect2, Variant::RECT2) +MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I) +MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3) +MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I) +MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D) +MAKE_TYPED_ARRAY(Plane, Variant::PLANE) +MAKE_TYPED_ARRAY(Quat, Variant::QUAT) +MAKE_TYPED_ARRAY(AABB, Variant::AABB) +MAKE_TYPED_ARRAY(Basis, Variant::BASIS) +MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY(Color, Variant::COLOR) +MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME) +MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH) +MAKE_TYPED_ARRAY(RID, Variant::_RID) +MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE) +MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL) +MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY) +MAKE_TYPED_ARRAY(Array, Variant::ARRAY) +MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY) +MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY) +MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY) +MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY) +MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY) +MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY) +MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) +MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) +MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY) + +#ifdef PTRCALL_ENABLED + +template <class T> +struct PtrToArg<TypedArray<T>> { + +	_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + +		return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); +	} + +	_FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) { + +		*(Array *)p_ptr = p_val; +	} +}; + +template <class T> +struct PtrToArg<const TypedArray<T> &> { + +	_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + +		return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); +	} +}; + +#endif // PTRCALL_ENABLED + +#ifdef DEBUG_METHODS_ENABLED + +template <class T> +struct GetTypeInfo<TypedArray<T>> { +	static const Variant::Type VARIANT_TYPE = Variant::ARRAY; +	static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; +	static inline PropertyInfo get_class_info() { +		return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); +	} +}; + +template <class T> +struct GetTypeInfo<const TypedArray<T> &> { +	static const Variant::Type VARIANT_TYPE = Variant::ARRAY; +	static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; +	static inline PropertyInfo get_class_info() { +		return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); +	} +}; + +#define MAKE_TYPED_ARRAY_INFO(m_type, m_variant_type)                                                                        \ +	template <>                                                                                                              \ +	struct GetTypeInfo<TypedArray<m_type>> {                                                                                 \ +		static const Variant::Type VARIANT_TYPE = Variant::ARRAY;                                                            \ +		static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;                                        \ +		static inline PropertyInfo get_class_info() {                                                                        \ +			return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ +		}                                                                                                                    \ +	};                                                                                                                       \ +	template <>                                                                                                              \ +	struct GetTypeInfo<const TypedArray<m_type> &> {                                                                         \ +		static const Variant::Type VARIANT_TYPE = Variant::ARRAY;                                                            \ +		static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;                                        \ +		static inline PropertyInfo get_class_info() {                                                                        \ +			return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ +		}                                                                                                                    \ +	}; + +MAKE_TYPED_ARRAY_INFO(bool, Variant::BOOL) +MAKE_TYPED_ARRAY_INFO(uint8_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int8_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint16_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int16_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint32_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int32_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint64_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int64_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(float, Variant::FLOAT) +MAKE_TYPED_ARRAY_INFO(double, Variant::FLOAT) +MAKE_TYPED_ARRAY_INFO(String, Variant::STRING) +MAKE_TYPED_ARRAY_INFO(Vector2, Variant::VECTOR2) +MAKE_TYPED_ARRAY_INFO(Vector2i, Variant::VECTOR2I) +MAKE_TYPED_ARRAY_INFO(Rect2, Variant::RECT2) +MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I) +MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3) +MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I) +MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D) +MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE) +MAKE_TYPED_ARRAY_INFO(Quat, Variant::QUAT) +MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB) +MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS) +MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR) +MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME) +MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH) +MAKE_TYPED_ARRAY_INFO(RID, Variant::_RID) +MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE) +MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL) +MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY) +MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY) + +#endif + +#endif // TYPED_ARRAY_H |