You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-03 16:55:53 +00:00
Merge pull request #86079 from dsnopek/required-args
Add `RequiredParam<T>` and `RequiredResult<T>` to mark `Object *` arguments and return values as required
This commit is contained in:
@@ -167,7 +167,7 @@ void ResourceLoader::_bind_methods() {
|
|||||||
|
|
||||||
////// ResourceSaver //////
|
////// ResourceSaver //////
|
||||||
|
|
||||||
Error ResourceSaver::save(const Ref<Resource> &p_resource, const String &p_path, BitField<SaverFlags> p_flags) {
|
Error ResourceSaver::save(RequiredParam<Resource> p_resource, const String &p_path, BitField<SaverFlags> p_flags) {
|
||||||
return ::ResourceSaver::save(p_resource, p_path, p_flags);
|
return ::ResourceSaver::save(p_resource, p_path, p_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public:
|
|||||||
|
|
||||||
static ResourceSaver *get_singleton() { return singleton; }
|
static ResourceSaver *get_singleton() { return singleton; }
|
||||||
|
|
||||||
Error save(const Ref<Resource> &p_resource, const String &p_path, BitField<SaverFlags> p_flags);
|
Error save(RequiredParam<Resource> p_resource, const String &p_path, BitField<SaverFlags> p_flags);
|
||||||
Error set_uid(const String &p_path, ResourceUID::ID p_uid);
|
Error set_uid(const String &p_path, ResourceUID::ID p_uid);
|
||||||
Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource);
|
Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource);
|
||||||
void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
|
void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ static String get_property_info_type_name(const PropertyInfo &p_info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String get_type_meta_name(const GodotTypeInfo::Metadata metadata) {
|
static String get_type_meta_name(const GodotTypeInfo::Metadata metadata) {
|
||||||
static const char *argmeta[13] = { "none", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "double", "char16", "char32" };
|
static const char *argmeta[14] = { "none", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "double", "char16", "char32", "required" };
|
||||||
return argmeta[metadata];
|
return argmeta[metadata];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1942,6 +1942,10 @@
|
|||||||
{
|
{
|
||||||
"name": "GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR32",
|
"name": "GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR32",
|
||||||
"value": 12
|
"value": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GDEXTENSION_METHOD_ARGUMENT_METADATA_OBJECT_IS_REQUIRED",
|
||||||
|
"value": 13
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ void ResourceFormatSaver::_bind_methods() {
|
|||||||
GDVIRTUAL_BIND(_recognize_path, "resource", "path");
|
GDVIRTUAL_BIND(_recognize_path, "resource", "path");
|
||||||
}
|
}
|
||||||
|
|
||||||
Error ResourceSaver::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) {
|
Error ResourceSaver::save(RequiredParam<Resource> rp_resource, const String &p_path, uint32_t p_flags) {
|
||||||
ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, vformat("Can't save empty resource to path '%s'.", p_path));
|
EXTRACT_PARAM_OR_FAIL_V_MSG(p_resource, rp_resource, ERR_INVALID_PARAMETER, vformat("Can't save empty resource to path '%s'.", p_path));
|
||||||
String path = p_path;
|
String path = p_path;
|
||||||
if (path.is_empty()) {
|
if (path.is_empty()) {
|
||||||
path = p_resource->get_path();
|
path = p_resource->get_path();
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public:
|
|||||||
FLAG_REPLACE_SUBRESOURCE_PATHS = 64,
|
FLAG_REPLACE_SUBRESOURCE_PATHS = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Error save(const Ref<Resource> &p_resource, const String &p_path = "", uint32_t p_flags = (uint32_t)FLAG_NONE);
|
static Error save(RequiredParam<Resource> p_resource, const String &p_path = "", uint32_t p_flags = (uint32_t)FLAG_NONE);
|
||||||
static void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions);
|
static void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions);
|
||||||
static void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front = false);
|
static void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front = false);
|
||||||
static void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
|
static void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "core/templates/hash_set.h"
|
#include "core/templates/hash_set.h"
|
||||||
#include "core/templates/list.h"
|
#include "core/templates/list.h"
|
||||||
#include "core/templates/safe_refcount.h"
|
#include "core/templates/safe_refcount.h"
|
||||||
|
#include "core/variant/required_ptr.h"
|
||||||
#include "core/variant/variant.h"
|
#include "core/variant/variant.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "core/templates/simple_type.h"
|
#include "core/templates/simple_type.h"
|
||||||
#include "core/typedefs.h"
|
#include "core/typedefs.h"
|
||||||
#include "core/variant/method_ptrcall.h"
|
#include "core/variant/method_ptrcall.h"
|
||||||
|
#include "core/variant/required_ptr.h"
|
||||||
#include "core/variant/type_info.h"
|
#include "core/variant/type_info.h"
|
||||||
#include "core/variant/variant.h"
|
#include "core/variant/variant.h"
|
||||||
#include "core/variant/variant_internal.h"
|
#include "core/variant/variant_internal.h"
|
||||||
|
|||||||
@@ -269,6 +269,42 @@ struct PtrToArg<const T *> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is for RequiredParam.
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct PtrToArg<RequiredParam<T>> {
|
||||||
|
typedef typename RequiredParam<T>::ptr_type EncodeT;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ static RequiredParam<T> convert(const void *p_ptr) {
|
||||||
|
if (p_ptr == nullptr) {
|
||||||
|
return RequiredParam<T>::_err_return_dont_use();
|
||||||
|
}
|
||||||
|
return RequiredParam<T>(*reinterpret_cast<T *const *>(p_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ static void encode(const RequiredParam<T> &p_var, void *p_ptr) {
|
||||||
|
*((typename RequiredParam<T>::ptr_type *)p_ptr) = p_var._internal_ptr_dont_use();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is for RequiredResult.
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct PtrToArg<RequiredResult<T>> {
|
||||||
|
typedef typename RequiredResult<T>::ptr_type EncodeT;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ static RequiredResult<T> convert(const void *p_ptr) {
|
||||||
|
if (p_ptr == nullptr) {
|
||||||
|
return RequiredResult<T>::_err_return_dont_use();
|
||||||
|
}
|
||||||
|
return RequiredResult<T>(*reinterpret_cast<T *const *>(p_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ static void encode(const RequiredResult<T> &p_var, void *p_ptr) {
|
||||||
|
*((typename RequiredResult<T>::ptr_type *)p_ptr) = p_var._internal_ptr_dont_use();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// This is for ObjectID.
|
// This is for ObjectID.
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|||||||
246
core/variant/required_ptr.h
Normal file
246
core/variant/required_ptr.h
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* required_ptr.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/variant/variant.h"
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RequiredResult {
|
||||||
|
static_assert(!is_fully_defined_v<T> || std::is_base_of_v<Object, T>, "T must be an Object subtype");
|
||||||
|
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using ptr_type = std::conditional_t<std::is_base_of_v<RefCounted, T>, Ref<T>, T *>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ptr_type _value = ptr_type();
|
||||||
|
|
||||||
|
_FORCE_INLINE_ RequiredResult() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RequiredResult(const RequiredResult &p_other) = default;
|
||||||
|
RequiredResult(RequiredResult &&p_other) = default;
|
||||||
|
RequiredResult &operator=(const RequiredResult &p_other) = default;
|
||||||
|
RequiredResult &operator=(RequiredResult &&p_other) = default;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ RequiredResult(std::nullptr_t) :
|
||||||
|
RequiredResult() {}
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(std::nullptr_t) { _value = nullptr; }
|
||||||
|
|
||||||
|
// These functions should not be called directly, they are only for internal use.
|
||||||
|
_FORCE_INLINE_ ptr_type _internal_ptr_dont_use() const { return _value; }
|
||||||
|
_FORCE_INLINE_ static RequiredResult<T> _err_return_dont_use() { return RequiredResult<T>(); }
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult(const RequiredResult<T_Other> &p_other) :
|
||||||
|
_value(p_other._value) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(const RequiredResult<T_Other> &p_other) {
|
||||||
|
_value = p_other._value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult(T_Other *p_ptr) :
|
||||||
|
_value(p_ptr) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(T_Other *p_ptr) {
|
||||||
|
_value = p_ptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult(const Ref<T_Other> &p_ref) :
|
||||||
|
_value(p_ref) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(const Ref<T_Other> &p_ref) {
|
||||||
|
_value = p_ref;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult(Ref<T_Other> &&p_ref) :
|
||||||
|
_value(std::move(p_ref)) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(Ref<T_Other> &&p_ref) {
|
||||||
|
_value = std::move(p_ref);
|
||||||
|
return &this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult(const Variant &p_variant) :
|
||||||
|
_value(static_cast<T *>(p_variant.get_validated_object())) {}
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(const Variant &p_variant) {
|
||||||
|
_value = static_cast<T *>(p_variant.get_validated_object());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult(const Variant &p_variant) :
|
||||||
|
_value(static_cast<T *>(p_variant.operator Object *())) {}
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredResult &operator=(const Variant &p_variant) {
|
||||||
|
_value = static_cast<T *>(p_variant.operator Object *());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ element_type *ptr() const {
|
||||||
|
return *_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ element_type *ptr() const {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ operator ptr_type() {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ operator Variant() const {
|
||||||
|
return Variant(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ element_type *operator*() const {
|
||||||
|
return ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ element_type *operator->() const {
|
||||||
|
return ptr();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RequiredParam {
|
||||||
|
static_assert(!is_fully_defined_v<T> || std::is_base_of_v<Object, T>, "T must be an Object subtype");
|
||||||
|
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using ptr_type = std::conditional_t<std::is_base_of_v<RefCounted, T>, Ref<T>, T *>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ptr_type _value = ptr_type();
|
||||||
|
|
||||||
|
_FORCE_INLINE_ RequiredParam() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// These functions should not be called directly, they are only for internal use.
|
||||||
|
_FORCE_INLINE_ ptr_type _internal_ptr_dont_use() const { return _value; }
|
||||||
|
_FORCE_INLINE_ bool _is_null_dont_use() const {
|
||||||
|
if constexpr (std::is_base_of_v<RefCounted, T>) {
|
||||||
|
return _value.is_null();
|
||||||
|
} else {
|
||||||
|
return _value == nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_FORCE_INLINE_ static RequiredParam<T> _err_return_dont_use() { return RequiredParam<T>(); }
|
||||||
|
|
||||||
|
// Prevent erroneously assigning null values by explicitly removing nullptr constructor/assignment.
|
||||||
|
RequiredParam(std::nullptr_t) = delete;
|
||||||
|
RequiredParam &operator=(std::nullptr_t) = delete;
|
||||||
|
|
||||||
|
RequiredParam(const RequiredParam &p_other) = default;
|
||||||
|
RequiredParam(RequiredParam &&p_other) = default;
|
||||||
|
RequiredParam &operator=(const RequiredParam &p_other) = default;
|
||||||
|
RequiredParam &operator=(RequiredParam &&p_other) = default;
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam(const RequiredParam<T_Other> &p_other) :
|
||||||
|
_value(p_other._internal_ptr_dont_use()) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam &operator=(const RequiredParam<T_Other> &p_other) {
|
||||||
|
_value = p_other._internal_ptr_dont_use();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam(T_Other *p_ptr) :
|
||||||
|
_value(p_ptr) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam &operator=(T_Other *p_ptr) {
|
||||||
|
_value = p_ptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam(const Ref<T_Other> &p_ref) :
|
||||||
|
_value(p_ref) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam &operator=(const Ref<T_Other> &p_ref) {
|
||||||
|
_value = p_ref;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam(Ref<T_Other> &&p_ref) :
|
||||||
|
_value(std::move(p_ref)) {}
|
||||||
|
template <typename T_Other, std::enable_if_t<std::is_base_of_v<T, T_Other>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam &operator=(Ref<T_Other> &&p_ref) {
|
||||||
|
_value = std::move(p_ref);
|
||||||
|
return &this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam(const Variant &p_variant) :
|
||||||
|
_value(static_cast<T *>(p_variant.get_validated_object())) {}
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam &operator=(const Variant &p_variant) {
|
||||||
|
_value = static_cast<T *>(p_variant.get_validated_object());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam(const Variant &p_variant) :
|
||||||
|
_value(static_cast<T *>(p_variant.operator Object *())) {}
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
_FORCE_INLINE_ RequiredParam &operator=(const Variant &p_variant) {
|
||||||
|
_value = static_cast<T *>(p_variant.operator Object *());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, m_retval, m_msg, m_editor) \
|
||||||
|
if (unlikely(m_param._is_null_dont_use())) { \
|
||||||
|
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Required object \"" _STR(m_param) "\" is null.", m_msg, m_editor); \
|
||||||
|
return m_retval; \
|
||||||
|
} \
|
||||||
|
typename std::decay_t<decltype(m_param)>::ptr_type m_name = m_param._internal_ptr_dont_use(); \
|
||||||
|
static_assert(true)
|
||||||
|
|
||||||
|
// These macros are equivalent to the ERR_FAIL_NULL*() family of macros, only for RequiredParam<T> instead of raw pointers.
|
||||||
|
#define EXTRACT_PARAM_OR_FAIL(m_name, m_param) TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, void(), "", false)
|
||||||
|
#define EXTRACT_PARAM_OR_FAIL_MSG(m_name, m_param, m_msg) TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, void(), m_msg, false)
|
||||||
|
#define EXTRACT_PARAM_OR_FAIL_EDMSG(m_name, m_param, m_msg) TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, void(), m_msg, true)
|
||||||
|
#define EXTRACT_PARAM_OR_FAIL_V(m_name, m_param, m_retval) TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, m_retval, "", false)
|
||||||
|
#define EXTRACT_PARAM_OR_FAIL_V_MSG(m_name, m_param, m_retval, m_msg) TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, m_retval, m_msg, false)
|
||||||
|
#define EXTRACT_PARAM_OR_FAIL_V_EDMSG(m_name, m_param, m_retval, m_msg) TMPL_EXTRACT_PARAM_OR_FAIL(m_name, m_param, m_retval, m_msg, true)
|
||||||
@@ -52,6 +52,7 @@ enum Metadata {
|
|||||||
METADATA_REAL_IS_DOUBLE,
|
METADATA_REAL_IS_DOUBLE,
|
||||||
METADATA_INT_IS_CHAR16,
|
METADATA_INT_IS_CHAR16,
|
||||||
METADATA_INT_IS_CHAR32,
|
METADATA_INT_IS_CHAR32,
|
||||||
|
METADATA_OBJECT_IS_REQUIRED,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +183,44 @@ struct GetTypeInfo<T *, std::enable_if_t<std::is_base_of_v<Object, T>>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class RequiredParam;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class RequiredResult;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct GetTypeInfo<RequiredParam<T>, std::enable_if_t<std::is_base_of_v<Object, T>>> {
|
||||||
|
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
|
||||||
|
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_OBJECT_IS_REQUIRED;
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
static inline PropertyInfo get_class_info() {
|
||||||
|
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
static inline PropertyInfo get_class_info() {
|
||||||
|
return PropertyInfo(StringName(T::get_class_static()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct GetTypeInfo<RequiredResult<T>, std::enable_if_t<std::is_base_of_v<Object, T>>> {
|
||||||
|
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
|
||||||
|
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_OBJECT_IS_REQUIRED;
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
static inline PropertyInfo get_class_info() {
|
||||||
|
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, std::enable_if_t<!std::is_base_of_v<RefCounted, U>, int> = 0>
|
||||||
|
static inline PropertyInfo get_class_info() {
|
||||||
|
return PropertyInfo(StringName(T::get_class_static()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace GodotTypeInfo {
|
namespace GodotTypeInfo {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) {
|
inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) {
|
||||||
|
|||||||
@@ -608,6 +608,30 @@ struct VariantInternalAccessor<Object *> {
|
|||||||
static _FORCE_INLINE_ void set(Variant *v, const Object *p_value) { VariantInternal::object_assign(v, p_value); }
|
static _FORCE_INLINE_ void set(Variant *v, const Object *p_value) { VariantInternal::object_assign(v, p_value); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct VariantInternalAccessor<RequiredParam<T>> {
|
||||||
|
static _FORCE_INLINE_ RequiredParam<T> get(const Variant *v) { return RequiredParam<T>(Object::cast_to<T>(const_cast<Object *>(*VariantInternal::get_object(v)))); }
|
||||||
|
static _FORCE_INLINE_ void set(Variant *v, const RequiredParam<T> &p_value) { VariantInternal::object_assign(v, p_value.ptr()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct VariantInternalAccessor<const RequiredParam<T> &> {
|
||||||
|
static _FORCE_INLINE_ RequiredParam<T> get(const Variant *v) { return RequiredParam<T>(Object::cast_to<T>(*VariantInternal::get_object(v))); }
|
||||||
|
static _FORCE_INLINE_ void set(Variant *v, const RequiredParam<T> &p_value) { VariantInternal::object_assign(v, p_value.ptr()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct VariantInternalAccessor<RequiredResult<T>> {
|
||||||
|
static _FORCE_INLINE_ RequiredResult<T> get(const Variant *v) { return RequiredResult<T>(Object::cast_to<T>(const_cast<Object *>(*VariantInternal::get_object(v)))); }
|
||||||
|
static _FORCE_INLINE_ void set(Variant *v, const RequiredResult<T> &p_value) { VariantInternal::object_assign(v, p_value.ptr()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct VariantInternalAccessor<const RequiredResult<T> &> {
|
||||||
|
static _FORCE_INLINE_ RequiredResult<T> get(const Variant *v) { return RequiredResult<T>(Object::cast_to<T>(*VariantInternal::get_object(v))); }
|
||||||
|
static _FORCE_INLINE_ void set(Variant *v, const RequiredResult<T> &p_value) { VariantInternal::object_assign(v, p_value.ptr()); }
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct VariantInternalAccessor<Variant> {
|
struct VariantInternalAccessor<Variant> {
|
||||||
static _FORCE_INLINE_ Variant &get(Variant *v) { return *v; }
|
static _FORCE_INLINE_ Variant &get(Variant *v) { return *v; }
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void Tween::_stop_internal(bool p_reset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> Tween::tween_property(const Object *p_target, const NodePath &p_property, Variant p_to, double p_duration) {
|
RequiredResult<PropertyTweener> Tween::tween_property(const Object *p_target, const NodePath &p_property, Variant p_to, double p_duration) {
|
||||||
ERR_FAIL_NULL_V(p_target, nullptr);
|
ERR_FAIL_NULL_V(p_target, nullptr);
|
||||||
CHECK_VALID();
|
CHECK_VALID();
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ Ref<PropertyTweener> Tween::tween_property(const Object *p_target, const NodePat
|
|||||||
return tweener;
|
return tweener;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<IntervalTweener> Tween::tween_interval(double p_time) {
|
RequiredResult<IntervalTweener> Tween::tween_interval(double p_time) {
|
||||||
CHECK_VALID();
|
CHECK_VALID();
|
||||||
|
|
||||||
Ref<IntervalTweener> tweener;
|
Ref<IntervalTweener> tweener;
|
||||||
@@ -127,7 +127,7 @@ Ref<IntervalTweener> Tween::tween_interval(double p_time) {
|
|||||||
return tweener;
|
return tweener;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<CallbackTweener> Tween::tween_callback(const Callable &p_callback) {
|
RequiredResult<CallbackTweener> Tween::tween_callback(const Callable &p_callback) {
|
||||||
CHECK_VALID();
|
CHECK_VALID();
|
||||||
|
|
||||||
Ref<CallbackTweener> tweener;
|
Ref<CallbackTweener> tweener;
|
||||||
@@ -136,7 +136,7 @@ Ref<CallbackTweener> Tween::tween_callback(const Callable &p_callback) {
|
|||||||
return tweener;
|
return tweener;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<MethodTweener> Tween::tween_method(const Callable &p_callback, const Variant p_from, Variant p_to, double p_duration) {
|
RequiredResult<MethodTweener> Tween::tween_method(const Callable &p_callback, const Variant p_from, Variant p_to, double p_duration) {
|
||||||
CHECK_VALID();
|
CHECK_VALID();
|
||||||
|
|
||||||
if (!Animation::validate_type_match(p_from, p_to)) {
|
if (!Animation::validate_type_match(p_from, p_to)) {
|
||||||
@@ -149,7 +149,7 @@ Ref<MethodTweener> Tween::tween_method(const Callable &p_callback, const Variant
|
|||||||
return tweener;
|
return tweener;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<SubtweenTweener> Tween::tween_subtween(const Ref<Tween> &p_subtween) {
|
RequiredResult<SubtweenTweener> Tween::tween_subtween(const Ref<Tween> &p_subtween) {
|
||||||
CHECK_VALID();
|
CHECK_VALID();
|
||||||
|
|
||||||
// Ensure that the subtween being added is not null.
|
// Ensure that the subtween being added is not null.
|
||||||
@@ -221,7 +221,7 @@ void Tween::clear() {
|
|||||||
tweeners.clear();
|
tweeners.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::bind_node(const Node *p_node) {
|
RequiredResult<Tween> Tween::bind_node(const Node *p_node) {
|
||||||
ERR_FAIL_NULL_V(p_node, this);
|
ERR_FAIL_NULL_V(p_node, this);
|
||||||
|
|
||||||
bound_node = p_node->get_instance_id();
|
bound_node = p_node->get_instance_id();
|
||||||
@@ -229,7 +229,7 @@ Ref<Tween> Tween::bind_node(const Node *p_node) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_process_mode(TweenProcessMode p_mode) {
|
RequiredResult<Tween> Tween::set_process_mode(TweenProcessMode p_mode) {
|
||||||
process_mode = p_mode;
|
process_mode = p_mode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ Tween::TweenProcessMode Tween::get_process_mode() const {
|
|||||||
return process_mode;
|
return process_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_pause_mode(TweenPauseMode p_mode) {
|
RequiredResult<Tween> Tween::set_pause_mode(TweenPauseMode p_mode) {
|
||||||
pause_mode = p_mode;
|
pause_mode = p_mode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ Tween::TweenPauseMode Tween::get_pause_mode() const {
|
|||||||
return pause_mode;
|
return pause_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_ignore_time_scale(bool p_ignore) {
|
RequiredResult<Tween> Tween::set_ignore_time_scale(bool p_ignore) {
|
||||||
ignore_time_scale = p_ignore;
|
ignore_time_scale = p_ignore;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -256,13 +256,13 @@ bool Tween::is_ignoring_time_scale() const {
|
|||||||
return ignore_time_scale;
|
return ignore_time_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_parallel(bool p_parallel) {
|
RequiredResult<Tween> Tween::set_parallel(bool p_parallel) {
|
||||||
default_parallel = p_parallel;
|
default_parallel = p_parallel;
|
||||||
parallel_enabled = p_parallel;
|
parallel_enabled = p_parallel;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_loops(int p_loops) {
|
RequiredResult<Tween> Tween::set_loops(int p_loops) {
|
||||||
loops = p_loops;
|
loops = p_loops;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -275,12 +275,12 @@ int Tween::get_loops_left() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_speed_scale(float p_speed) {
|
RequiredResult<Tween> Tween::set_speed_scale(float p_speed) {
|
||||||
speed_scale = p_speed;
|
speed_scale = p_speed;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_trans(TransitionType p_trans) {
|
RequiredResult<Tween> Tween::set_trans(TransitionType p_trans) {
|
||||||
default_transition = p_trans;
|
default_transition = p_trans;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ Tween::TransitionType Tween::get_trans() const {
|
|||||||
return default_transition;
|
return default_transition;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::set_ease(EaseType p_ease) {
|
RequiredResult<Tween> Tween::set_ease(EaseType p_ease) {
|
||||||
default_ease = p_ease;
|
default_ease = p_ease;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -298,12 +298,12 @@ Tween::EaseType Tween::get_ease() const {
|
|||||||
return default_ease;
|
return default_ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::parallel() {
|
RequiredResult<Tween> Tween::parallel() {
|
||||||
parallel_enabled = true;
|
parallel_enabled = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Tween::chain() {
|
RequiredResult<Tween> Tween::chain() {
|
||||||
parallel_enabled = false;
|
parallel_enabled = false;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -554,7 +554,7 @@ double PropertyTweener::_get_custom_interpolated_value(const Variant &p_value) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::from(const Variant &p_value) {
|
RequiredResult<PropertyTweener> PropertyTweener::from(const Variant &p_value) {
|
||||||
Ref<Tween> tween = _get_tween();
|
Ref<Tween> tween = _get_tween();
|
||||||
ERR_FAIL_COND_V(tween.is_null(), nullptr);
|
ERR_FAIL_COND_V(tween.is_null(), nullptr);
|
||||||
|
|
||||||
@@ -568,32 +568,32 @@ Ref<PropertyTweener> PropertyTweener::from(const Variant &p_value) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::from_current() {
|
RequiredResult<PropertyTweener> PropertyTweener::from_current() {
|
||||||
do_continue = false;
|
do_continue = false;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::as_relative() {
|
RequiredResult<PropertyTweener> PropertyTweener::as_relative() {
|
||||||
relative = true;
|
relative = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::set_trans(Tween::TransitionType p_trans) {
|
RequiredResult<PropertyTweener> PropertyTweener::set_trans(Tween::TransitionType p_trans) {
|
||||||
trans_type = p_trans;
|
trans_type = p_trans;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::set_ease(Tween::EaseType p_ease) {
|
RequiredResult<PropertyTweener> PropertyTweener::set_ease(Tween::EaseType p_ease) {
|
||||||
ease_type = p_ease;
|
ease_type = p_ease;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::set_custom_interpolator(const Callable &p_method) {
|
RequiredResult<PropertyTweener> PropertyTweener::set_custom_interpolator(const Callable &p_method) {
|
||||||
custom_method = p_method;
|
custom_method = p_method;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PropertyTweener> PropertyTweener::set_delay(double p_delay) {
|
RequiredResult<PropertyTweener> PropertyTweener::set_delay(double p_delay) {
|
||||||
delay = p_delay;
|
delay = p_delay;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -731,7 +731,7 @@ IntervalTweener::IntervalTweener() {
|
|||||||
ERR_FAIL_MSG("IntervalTweener can't be created directly. Use the tween_interval() method in Tween.");
|
ERR_FAIL_MSG("IntervalTweener can't be created directly. Use the tween_interval() method in Tween.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<CallbackTweener> CallbackTweener::set_delay(double p_delay) {
|
RequiredResult<CallbackTweener> CallbackTweener::set_delay(double p_delay) {
|
||||||
delay = p_delay;
|
delay = p_delay;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -781,17 +781,17 @@ CallbackTweener::CallbackTweener() {
|
|||||||
ERR_FAIL_MSG("CallbackTweener can't be created directly. Use the tween_callback() method in Tween.");
|
ERR_FAIL_MSG("CallbackTweener can't be created directly. Use the tween_callback() method in Tween.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<MethodTweener> MethodTweener::set_delay(double p_delay) {
|
RequiredResult<MethodTweener> MethodTweener::set_delay(double p_delay) {
|
||||||
delay = p_delay;
|
delay = p_delay;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<MethodTweener> MethodTweener::set_trans(Tween::TransitionType p_trans) {
|
RequiredResult<MethodTweener> MethodTweener::set_trans(Tween::TransitionType p_trans) {
|
||||||
trans_type = p_trans;
|
trans_type = p_trans;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<MethodTweener> MethodTweener::set_ease(Tween::EaseType p_ease) {
|
RequiredResult<MethodTweener> MethodTweener::set_ease(Tween::EaseType p_ease) {
|
||||||
ease_type = p_ease;
|
ease_type = p_ease;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -912,7 +912,7 @@ bool SubtweenTweener::step(double &r_delta) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<SubtweenTweener> SubtweenTweener::set_delay(double p_delay) {
|
RequiredResult<SubtweenTweener> SubtweenTweener::set_delay(double p_delay) {
|
||||||
delay = p_delay;
|
delay = p_delay;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,11 +143,11 @@ protected:
|
|||||||
virtual String _to_string() override;
|
virtual String _to_string() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ref<PropertyTweener> tween_property(const Object *p_target, const NodePath &p_property, Variant p_to, double p_duration);
|
RequiredResult<PropertyTweener> tween_property(const Object *p_target, const NodePath &p_property, Variant p_to, double p_duration);
|
||||||
Ref<IntervalTweener> tween_interval(double p_time);
|
RequiredResult<IntervalTweener> tween_interval(double p_time);
|
||||||
Ref<CallbackTweener> tween_callback(const Callable &p_callback);
|
RequiredResult<CallbackTweener> tween_callback(const Callable &p_callback);
|
||||||
Ref<MethodTweener> tween_method(const Callable &p_callback, const Variant p_from, Variant p_to, double p_duration);
|
RequiredResult<MethodTweener> tween_method(const Callable &p_callback, const Variant p_from, Variant p_to, double p_duration);
|
||||||
Ref<SubtweenTweener> tween_subtween(const Ref<Tween> &p_subtween);
|
RequiredResult<SubtweenTweener> tween_subtween(const Ref<Tween> &p_subtween);
|
||||||
void append(Ref<Tweener> p_tweener);
|
void append(Ref<Tweener> p_tweener);
|
||||||
|
|
||||||
bool custom_step(double p_delta);
|
bool custom_step(double p_delta);
|
||||||
@@ -160,25 +160,25 @@ public:
|
|||||||
bool is_valid();
|
bool is_valid();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
Ref<Tween> bind_node(const Node *p_node);
|
RequiredResult<Tween> bind_node(const Node *p_node);
|
||||||
Ref<Tween> set_process_mode(TweenProcessMode p_mode);
|
RequiredResult<Tween> set_process_mode(TweenProcessMode p_mode);
|
||||||
TweenProcessMode get_process_mode() const;
|
TweenProcessMode get_process_mode() const;
|
||||||
Ref<Tween> set_pause_mode(TweenPauseMode p_mode);
|
RequiredResult<Tween> set_pause_mode(TweenPauseMode p_mode);
|
||||||
TweenPauseMode get_pause_mode() const;
|
TweenPauseMode get_pause_mode() const;
|
||||||
Ref<Tween> set_ignore_time_scale(bool p_ignore = true);
|
RequiredResult<Tween> set_ignore_time_scale(bool p_ignore = true);
|
||||||
bool is_ignoring_time_scale() const;
|
bool is_ignoring_time_scale() const;
|
||||||
|
|
||||||
Ref<Tween> set_parallel(bool p_parallel);
|
RequiredResult<Tween> set_parallel(bool p_parallel);
|
||||||
Ref<Tween> set_loops(int p_loops);
|
RequiredResult<Tween> set_loops(int p_loops);
|
||||||
int get_loops_left() const;
|
int get_loops_left() const;
|
||||||
Ref<Tween> set_speed_scale(float p_speed);
|
RequiredResult<Tween> set_speed_scale(float p_speed);
|
||||||
Ref<Tween> set_trans(TransitionType p_trans);
|
RequiredResult<Tween> set_trans(TransitionType p_trans);
|
||||||
TransitionType get_trans() const;
|
TransitionType get_trans() const;
|
||||||
Ref<Tween> set_ease(EaseType p_ease);
|
RequiredResult<Tween> set_ease(EaseType p_ease);
|
||||||
EaseType get_ease() const;
|
EaseType get_ease() const;
|
||||||
|
|
||||||
Ref<Tween> parallel();
|
RequiredResult<Tween> parallel();
|
||||||
Ref<Tween> chain();
|
RequiredResult<Tween> chain();
|
||||||
|
|
||||||
static real_t run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d);
|
static real_t run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d);
|
||||||
static Variant interpolate_variant(const Variant &p_initial_val, const Variant &p_delta_val, double p_time, double p_duration, Tween::TransitionType p_trans, Tween::EaseType p_ease);
|
static Variant interpolate_variant(const Variant &p_initial_val, const Variant &p_delta_val, double p_time, double p_duration, Tween::TransitionType p_trans, Tween::EaseType p_ease);
|
||||||
@@ -203,13 +203,13 @@ class PropertyTweener : public Tweener {
|
|||||||
double _get_custom_interpolated_value(const Variant &p_value);
|
double _get_custom_interpolated_value(const Variant &p_value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ref<PropertyTweener> from(const Variant &p_value);
|
RequiredResult<PropertyTweener> from(const Variant &p_value);
|
||||||
Ref<PropertyTweener> from_current();
|
RequiredResult<PropertyTweener> from_current();
|
||||||
Ref<PropertyTweener> as_relative();
|
RequiredResult<PropertyTweener> as_relative();
|
||||||
Ref<PropertyTweener> set_trans(Tween::TransitionType p_trans);
|
RequiredResult<PropertyTweener> set_trans(Tween::TransitionType p_trans);
|
||||||
Ref<PropertyTweener> set_ease(Tween::EaseType p_ease);
|
RequiredResult<PropertyTweener> set_ease(Tween::EaseType p_ease);
|
||||||
Ref<PropertyTweener> set_custom_interpolator(const Callable &p_method);
|
RequiredResult<PropertyTweener> set_custom_interpolator(const Callable &p_method);
|
||||||
Ref<PropertyTweener> set_delay(double p_delay);
|
RequiredResult<PropertyTweener> set_delay(double p_delay);
|
||||||
|
|
||||||
void set_tween(const Ref<Tween> &p_tween) override;
|
void set_tween(const Ref<Tween> &p_tween) override;
|
||||||
void start() override;
|
void start() override;
|
||||||
@@ -259,7 +259,7 @@ class CallbackTweener : public Tweener {
|
|||||||
GDCLASS(CallbackTweener, Tweener);
|
GDCLASS(CallbackTweener, Tweener);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ref<CallbackTweener> set_delay(double p_delay);
|
RequiredResult<CallbackTweener> set_delay(double p_delay);
|
||||||
|
|
||||||
bool step(double &r_delta) override;
|
bool step(double &r_delta) override;
|
||||||
|
|
||||||
@@ -280,9 +280,9 @@ class MethodTweener : public Tweener {
|
|||||||
GDCLASS(MethodTweener, Tweener);
|
GDCLASS(MethodTweener, Tweener);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ref<MethodTweener> set_trans(Tween::TransitionType p_trans);
|
RequiredResult<MethodTweener> set_trans(Tween::TransitionType p_trans);
|
||||||
Ref<MethodTweener> set_ease(Tween::EaseType p_ease);
|
RequiredResult<MethodTweener> set_ease(Tween::EaseType p_ease);
|
||||||
Ref<MethodTweener> set_delay(double p_delay);
|
RequiredResult<MethodTweener> set_delay(double p_delay);
|
||||||
|
|
||||||
void set_tween(const Ref<Tween> &p_tween) override;
|
void set_tween(const Ref<Tween> &p_tween) override;
|
||||||
bool step(double &r_delta) override;
|
bool step(double &r_delta) override;
|
||||||
@@ -315,7 +315,7 @@ public:
|
|||||||
void start() override;
|
void start() override;
|
||||||
bool step(double &r_delta) override;
|
bool step(double &r_delta) override;
|
||||||
|
|
||||||
Ref<SubtweenTweener> set_delay(double p_delay);
|
RequiredResult<SubtweenTweener> set_delay(double p_delay);
|
||||||
|
|
||||||
SubtweenTweener(const Ref<Tween> &p_subtween);
|
SubtweenTweener(const Ref<Tween> &p_subtween);
|
||||||
SubtweenTweener();
|
SubtweenTweener();
|
||||||
|
|||||||
@@ -1696,11 +1696,11 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name, InternalM
|
|||||||
emit_signal(SNAME("child_order_changed"));
|
emit_signal(SNAME("child_order_changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::add_child(Node *p_child, bool p_force_readable_name, InternalMode p_internal) {
|
void Node::add_child(RequiredParam<Node> rp_child, bool p_force_readable_name, InternalMode p_internal) {
|
||||||
ERR_FAIL_COND_MSG(data.tree && !Thread::is_main_thread(), "Adding children to a node inside the SceneTree is only allowed from the main thread. Use call_deferred(\"add_child\",node).");
|
ERR_FAIL_COND_MSG(data.tree && !Thread::is_main_thread(), "Adding children to a node inside the SceneTree is only allowed from the main thread. Use call_deferred(\"add_child\",node).");
|
||||||
|
|
||||||
ERR_THREAD_GUARD
|
ERR_THREAD_GUARD
|
||||||
ERR_FAIL_NULL(p_child);
|
EXTRACT_PARAM_OR_FAIL(p_child, rp_child);
|
||||||
ERR_FAIL_COND_MSG(p_child == this, vformat("Can't add child '%s' to itself.", p_child->get_name())); // adding to itself!
|
ERR_FAIL_COND_MSG(p_child == this, vformat("Can't add child '%s' to itself.", p_child->get_name())); // adding to itself!
|
||||||
ERR_FAIL_COND_MSG(p_child->data.parent, vformat("Can't add child '%s' to '%s', already has a parent '%s'.", p_child->get_name(), get_name(), p_child->data.parent->get_name())); //Fail if node has a parent
|
ERR_FAIL_COND_MSG(p_child->data.parent, vformat("Can't add child '%s' to '%s', already has a parent '%s'.", p_child->get_name(), get_name(), p_child->data.parent->get_name())); //Fail if node has a parent
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
@@ -2635,7 +2635,7 @@ void Node::_propagate_replace_owner(Node *p_owner, Node *p_by_owner) {
|
|||||||
data.blocked--;
|
data.blocked--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> Node::create_tween() {
|
RequiredResult<Tween> Node::create_tween() {
|
||||||
ERR_THREAD_GUARD_V(Ref<Tween>());
|
ERR_THREAD_GUARD_V(Ref<Tween>());
|
||||||
|
|
||||||
SceneTree *tree = data.tree;
|
SceneTree *tree = data.tree;
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ public:
|
|||||||
|
|
||||||
InternalMode get_internal_mode() const;
|
InternalMode get_internal_mode() const;
|
||||||
|
|
||||||
void add_child(Node *p_child, bool p_force_readable_name = false, InternalMode p_internal = INTERNAL_MODE_DISABLED);
|
void add_child(RequiredParam<Node> rp_child, bool p_force_readable_name = false, InternalMode p_internal = INTERNAL_MODE_DISABLED);
|
||||||
void add_sibling(Node *p_sibling, bool p_force_readable_name = false);
|
void add_sibling(Node *p_sibling, bool p_force_readable_name = false);
|
||||||
void remove_child(Node *p_child);
|
void remove_child(Node *p_child);
|
||||||
|
|
||||||
@@ -608,7 +608,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> create_tween();
|
RequiredResult<Tween> create_tween();
|
||||||
|
|
||||||
void print_tree();
|
void print_tree();
|
||||||
void print_tree_pretty();
|
void print_tree_pretty();
|
||||||
|
|||||||
@@ -1751,7 +1751,7 @@ Ref<SceneTreeTimer> SceneTree::create_timer(double p_delay_sec, bool p_process_a
|
|||||||
return stt;
|
return stt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Tween> SceneTree::create_tween() {
|
RequiredResult<Tween> SceneTree::create_tween() {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
Ref<Tween> tween;
|
Ref<Tween> tween;
|
||||||
tween.instantiate(this);
|
tween.instantiate(this);
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ public:
|
|||||||
void unload_current_scene();
|
void unload_current_scene();
|
||||||
|
|
||||||
Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false);
|
Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false);
|
||||||
Ref<Tween> create_tween();
|
RequiredResult<Tween> create_tween();
|
||||||
void remove_tween(const Ref<Tween> &p_tween);
|
void remove_tween(const Ref<Tween> &p_tween);
|
||||||
TypedArray<Tween> get_processed_tweens();
|
TypedArray<Tween> get_processed_tweens();
|
||||||
|
|
||||||
|
|||||||
@@ -596,4 +596,28 @@ TEST_CASE("[Object] Destruction at the end of the call chain is safe") {
|
|||||||
"Object was tail-deleted without crashes.");
|
"Object was tail-deleted without crashes.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int required_param_compare(const Ref<RefCounted> &p_ref, const RequiredParam<RefCounted> &p_required) {
|
||||||
|
EXTRACT_PARAM_OR_FAIL_V(extract, p_required, false);
|
||||||
|
ERR_FAIL_COND_V(p_ref->get_reference_count() != extract->get_reference_count(), -1);
|
||||||
|
return p_ref->get_reference_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Object] RequiredParam Ref<T>") {
|
||||||
|
Ref<RefCounted> ref;
|
||||||
|
ref.instantiate();
|
||||||
|
|
||||||
|
RequiredParam<RefCounted> required = ref;
|
||||||
|
EXTRACT_PARAM_OR_FAIL(extract, required);
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<decltype(ref), decltype(extract)>);
|
||||||
|
|
||||||
|
CHECK_EQ(ref->get_reference_count(), extract->get_reference_count());
|
||||||
|
|
||||||
|
const int count = required_param_compare(ref, ref);
|
||||||
|
CHECK_NE(count, -1);
|
||||||
|
CHECK_NE(count, ref->get_reference_count());
|
||||||
|
|
||||||
|
CHECK_EQ(ref->get_reference_count(), extract->get_reference_count());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace TestObject
|
} // namespace TestObject
|
||||||
|
|||||||
Reference in New Issue
Block a user