mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 07:53:26 +00:00
Compare commits
33 commits
295e465fe4
...
16a11ac88b
Author | SHA1 | Date | |
---|---|---|---|
![]() |
16a11ac88b | ||
![]() |
3e1af9a12a | ||
![]() |
e33f89fe27 | ||
![]() |
d10eca9c59 | ||
![]() |
edcbdc5706 | ||
![]() |
89ce203427 | ||
![]() |
99ab454a64 | ||
![]() |
c417769226 | ||
![]() |
4ea49aecaf | ||
![]() |
d4a87d9bb3 | ||
![]() |
8150cb9200 | ||
![]() |
d598753c1a | ||
![]() |
dd3b17de88 | ||
![]() |
cf9e2ea6da | ||
![]() |
21e5b41642 | ||
![]() |
fb01d80e88 | ||
![]() |
b9f7f2d767 | ||
![]() |
0a584250ae | ||
![]() |
56abd0ece3 | ||
![]() |
3a003b2d96 | ||
![]() |
09ad9e535b | ||
![]() |
fdecca2f18 | ||
![]() |
dae2122388 | ||
![]() |
3a3894e22c | ||
![]() |
4ba09aceb9 | ||
![]() |
d2ee378d1c | ||
![]() |
2adecffbc3 | ||
![]() |
c3fdc85d16 | ||
![]() |
12f8c78231 | ||
![]() |
0be2a77156 | ||
![]() |
e90cea9250 | ||
![]() |
31b5375a1c | ||
![]() |
c3476b8205 |
46 changed files with 504 additions and 340 deletions
|
@ -76,6 +76,17 @@ void JSON::_stringify(String &r_result, const Variant &p_var, const String &p_in
|
|||
case Variant::FLOAT: {
|
||||
const double num = p_var;
|
||||
|
||||
// JSON does not support NaN or Infinity, so use extremely large numbers for infinity.
|
||||
if (!Math::is_finite(num)) {
|
||||
if (num == Math::INF) {
|
||||
r_result += "1e99999";
|
||||
} else if (num == -Math::INF) {
|
||||
r_result += "-1e99999";
|
||||
} else {
|
||||
r_result += "\"NaN\"";
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Only for exactly 0. If we have approximately 0 let the user decide how much
|
||||
// precision they want.
|
||||
if (num == double(0.0)) {
|
||||
|
|
|
@ -1047,18 +1047,8 @@ String Object::to_string() {
|
|||
return "<" + get_class() + "#" + itos(get_instance_id()) + ">";
|
||||
}
|
||||
|
||||
void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) {
|
||||
//this function is not meant to be used in any of these ways
|
||||
ERR_FAIL_COND(p_script.is_null());
|
||||
ERR_FAIL_NULL(p_instance);
|
||||
ERR_FAIL_COND(script_instance != nullptr || !script.is_null());
|
||||
|
||||
script = p_script;
|
||||
script_instance = p_instance;
|
||||
}
|
||||
|
||||
void Object::set_script(const Variant &p_script) {
|
||||
if (script == p_script) {
|
||||
if (get_script() == p_script) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1068,8 +1058,6 @@ void Object::set_script(const Variant &p_script) {
|
|||
ERR_FAIL_COND_MSG(s->is_abstract(), vformat("Cannot set object script. Script '%s' should not be abstract.", s->get_path()));
|
||||
}
|
||||
|
||||
script = p_script;
|
||||
|
||||
if (script_instance) {
|
||||
memdelete(script_instance);
|
||||
script_instance = nullptr;
|
||||
|
@ -1099,16 +1087,10 @@ void Object::set_script_instance(ScriptInstance *p_instance) {
|
|||
}
|
||||
|
||||
script_instance = p_instance;
|
||||
|
||||
if (p_instance) {
|
||||
script = p_instance->get_script();
|
||||
} else {
|
||||
script = Variant();
|
||||
}
|
||||
}
|
||||
|
||||
Variant Object::get_script() const {
|
||||
return script;
|
||||
return script_instance ? Variant(script_instance->get_script()) : Variant();
|
||||
}
|
||||
|
||||
bool Object::has_meta(const StringName &p_name) const {
|
||||
|
@ -1291,7 +1273,7 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int
|
|||
#ifdef DEBUG_ENABLED
|
||||
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_name);
|
||||
//check in script
|
||||
ERR_FAIL_COND_V_MSG(!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name), ERR_UNAVAILABLE, vformat("Can't emit non-existing signal \"%s\".", p_name));
|
||||
ERR_FAIL_COND_V_MSG(!signal_is_valid && script_instance && !script_instance->get_script()->has_script_signal(p_name), ERR_UNAVAILABLE, vformat("Can't emit non-existing signal \"%s\".", p_name));
|
||||
#endif
|
||||
//not connected? just return
|
||||
return ERR_UNAVAILABLE;
|
||||
|
@ -1361,7 +1343,7 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int
|
|||
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool())) {
|
||||
if (flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (!script_instance || !script_instance->get_script()->is_tool())) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
@ -1465,11 +1447,8 @@ TypedArray<Dictionary> Object::_get_incoming_connections() const {
|
|||
}
|
||||
|
||||
bool Object::has_signal(const StringName &p_name) const {
|
||||
if (!script.is_null()) {
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_valid() && scr->has_script_signal(p_name)) {
|
||||
return true;
|
||||
}
|
||||
if (script_instance && script_instance->get_script()->has_script_signal(p_name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ClassDB::has_signal(get_class_name(), p_name)) {
|
||||
|
@ -1486,11 +1465,8 @@ bool Object::has_signal(const StringName &p_name) const {
|
|||
void Object::get_signal_list(List<MethodInfo> *p_signals) const {
|
||||
OBJ_SIGNAL_LOCK
|
||||
|
||||
if (!script.is_null()) {
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_valid()) {
|
||||
scr->get_script_signal_list(p_signals);
|
||||
}
|
||||
if (script_instance) {
|
||||
script_instance->get_script()->get_script_signal_list(p_signals);
|
||||
}
|
||||
|
||||
ClassDB::get_signal_list(get_class_name(), p_signals);
|
||||
|
@ -1571,14 +1547,14 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, ui
|
|||
if (!s) {
|
||||
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
|
||||
//check in script
|
||||
if (!signal_is_valid && !script.is_null()) {
|
||||
if (Ref<Script>(script)->has_script_signal(p_signal)) {
|
||||
if (!signal_is_valid && script_instance) {
|
||||
if (script_instance->get_script()->has_script_signal(p_signal)) {
|
||||
signal_is_valid = true;
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
else {
|
||||
//allow connecting signals anyway if script is invalid, see issue #17070
|
||||
if (!Ref<Script>(script)->is_valid()) {
|
||||
if (!script_instance->get_script()->is_valid()) {
|
||||
signal_is_valid = true;
|
||||
}
|
||||
}
|
||||
|
@ -1634,7 +1610,7 @@ bool Object::is_connected(const StringName &p_signal, const Callable &p_callable
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)) {
|
||||
if (script_instance && script_instance->get_script()->has_script_signal(p_signal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1654,7 +1630,7 @@ bool Object::has_connections(const StringName &p_signal) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)) {
|
||||
if (script_instance && script_instance->get_script()->has_script_signal(p_signal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1675,7 +1651,7 @@ bool Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
|
|||
SignalData *s = signal_map.getptr(p_signal);
|
||||
if (!s) {
|
||||
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal) ||
|
||||
(!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal));
|
||||
(script_instance && script_instance->get_script()->has_script_signal(p_signal));
|
||||
ERR_FAIL_COND_V_MSG(signal_is_valid, false, vformat("Attempt to disconnect a nonexistent connection from '%s'. Signal: '%s', callable: '%s'.", to_string(), p_signal, p_callable));
|
||||
}
|
||||
ERR_FAIL_NULL_V_MSG(s, false, vformat("Disconnecting nonexistent signal '%s' in '%s'.", p_signal, to_string()));
|
||||
|
|
|
@ -670,7 +670,6 @@ private:
|
|||
HashSet<String> editor_section_folding;
|
||||
#endif
|
||||
ScriptInstance *script_instance = nullptr;
|
||||
Variant script; // Reference does not exist yet, store it in a Variant.
|
||||
HashMap<StringName, Variant> metadata;
|
||||
HashMap<StringName, Variant *> metadata_properties;
|
||||
mutable const GDType *_gdtype_ptr = nullptr;
|
||||
|
@ -926,22 +925,22 @@ public:
|
|||
|
||||
/* SCRIPT */
|
||||
|
||||
// When in debug, some non-virtual functions can be overridden for multithreaded guards.
|
||||
// When in debug, some non-virtual functions can be overridden.
|
||||
#ifdef DEBUG_ENABLED
|
||||
#define MTVIRTUAL virtual
|
||||
#define DEBUG_VIRTUAL virtual
|
||||
#else
|
||||
#define MTVIRTUAL
|
||||
#define DEBUG_VIRTUAL
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
MTVIRTUAL void set_script(const Variant &p_script);
|
||||
MTVIRTUAL Variant get_script() const;
|
||||
DEBUG_VIRTUAL void set_script(const Variant &p_script);
|
||||
DEBUG_VIRTUAL Variant get_script() const;
|
||||
|
||||
MTVIRTUAL bool has_meta(const StringName &p_name) const;
|
||||
MTVIRTUAL void set_meta(const StringName &p_name, const Variant &p_value);
|
||||
MTVIRTUAL void remove_meta(const StringName &p_name);
|
||||
MTVIRTUAL Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const;
|
||||
MTVIRTUAL void get_meta_list(List<StringName> *p_list) const;
|
||||
MTVIRTUAL void merge_meta_from(const Object *p_src);
|
||||
DEBUG_VIRTUAL bool has_meta(const StringName &p_name) const;
|
||||
DEBUG_VIRTUAL void set_meta(const StringName &p_name, const Variant &p_value);
|
||||
DEBUG_VIRTUAL void remove_meta(const StringName &p_name);
|
||||
DEBUG_VIRTUAL Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const;
|
||||
DEBUG_VIRTUAL void get_meta_list(List<StringName> *p_list) const;
|
||||
DEBUG_VIRTUAL void merge_meta_from(const Object *p_src);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void set_edited(bool p_edited);
|
||||
|
@ -953,9 +952,6 @@ public:
|
|||
void set_script_instance(ScriptInstance *p_instance);
|
||||
_FORCE_INLINE_ ScriptInstance *get_script_instance() const { return script_instance; }
|
||||
|
||||
// Some script languages can't control instance creation, so this function eases the process.
|
||||
void set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance);
|
||||
|
||||
void add_user_signal(const MethodInfo &p_signal);
|
||||
|
||||
template <typename... VarArgs>
|
||||
|
@ -968,18 +964,18 @@ public:
|
|||
return emit_signalp(p_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
|
||||
}
|
||||
|
||||
MTVIRTUAL Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount);
|
||||
MTVIRTUAL bool has_signal(const StringName &p_name) const;
|
||||
MTVIRTUAL void get_signal_list(List<MethodInfo> *p_signals) const;
|
||||
MTVIRTUAL void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
|
||||
MTVIRTUAL void get_all_signal_connections(List<Connection> *p_connections) const;
|
||||
MTVIRTUAL int get_persistent_signal_connection_count() const;
|
||||
MTVIRTUAL void get_signals_connected_to_this(List<Connection> *p_connections) const;
|
||||
DEBUG_VIRTUAL Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount);
|
||||
DEBUG_VIRTUAL bool has_signal(const StringName &p_name) const;
|
||||
DEBUG_VIRTUAL void get_signal_list(List<MethodInfo> *p_signals) const;
|
||||
DEBUG_VIRTUAL void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
|
||||
DEBUG_VIRTUAL void get_all_signal_connections(List<Connection> *p_connections) const;
|
||||
DEBUG_VIRTUAL int get_persistent_signal_connection_count() const;
|
||||
DEBUG_VIRTUAL void get_signals_connected_to_this(List<Connection> *p_connections) const;
|
||||
|
||||
MTVIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
|
||||
MTVIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable);
|
||||
MTVIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
|
||||
MTVIRTUAL bool has_connections(const StringName &p_signal) const;
|
||||
DEBUG_VIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
|
||||
DEBUG_VIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable);
|
||||
DEBUG_VIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
|
||||
DEBUG_VIRTUAL bool has_connections(const StringName &p_signal) const;
|
||||
|
||||
template <typename... VarArgs>
|
||||
void call_deferred(const StringName &p_name, VarArgs... p_args) {
|
||||
|
|
|
@ -53,6 +53,7 @@ class FixedVector {
|
|||
|
||||
public:
|
||||
_FORCE_INLINE_ constexpr FixedVector() = default;
|
||||
|
||||
constexpr FixedVector(std::initializer_list<T> p_init) {
|
||||
ERR_FAIL_COND(p_init.size() > CAPACITY);
|
||||
for (const T &element : p_init) {
|
||||
|
@ -60,9 +61,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template <uint32_t p_capacity>
|
||||
constexpr FixedVector(const FixedVector<T, p_capacity> &p_from) {
|
||||
ERR_FAIL_COND(p_from.size() > CAPACITY);
|
||||
constexpr FixedVector(const FixedVector &p_from) {
|
||||
if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
// Copy size and all provided elements at once.
|
||||
memcpy((void *)&_size, (void *)&p_from._size, sizeof(_size) + DATA_PADDING + p_from.size() * sizeof(T));
|
||||
|
@ -73,15 +72,48 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template <uint32_t p_capacity>
|
||||
constexpr FixedVector(FixedVector<T, p_capacity> &&p_from) {
|
||||
ERR_FAIL_COND(p_from.size() > CAPACITY);
|
||||
constexpr FixedVector(FixedVector &&p_from) {
|
||||
// Copy size and all provided elements at once.
|
||||
// Note: Assumes trivial relocatability.
|
||||
memcpy((void *)&_size, (void *)&p_from._size, sizeof(_size) + DATA_PADDING + p_from.size() * sizeof(T));
|
||||
p_from._size = 0;
|
||||
}
|
||||
|
||||
constexpr FixedVector &operator=(const FixedVector &p_from) {
|
||||
if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
// Copy size and all provided elements at once.
|
||||
memcpy((void *)&_size, (void *)&p_from._size, sizeof(_size) + DATA_PADDING + p_from.size() * sizeof(T));
|
||||
} else {
|
||||
// Destruct extraneous elements.
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
for (uint32_t i = p_from.size(); i < _size; i++) {
|
||||
ptr()[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
_size = 0; // Loop-assign the rest.
|
||||
for (const T &element : p_from) {
|
||||
ptr()[_size++] = element;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr FixedVector &operator=(FixedVector &&p_from) {
|
||||
// Destruct extraneous elements.
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
for (uint32_t i = p_from.size(); i < _size; i++) {
|
||||
ptr()[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
// Relocate elements (and size) into our buffer.
|
||||
memcpy((void *)&_size, (void *)&p_from._size, sizeof(_size) + DATA_PADDING + p_from.size() * sizeof(T));
|
||||
p_from._size = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FixedVector() {
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
for (uint32_t i = 0; i < _size; i++) {
|
||||
|
@ -138,6 +170,12 @@ public:
|
|||
_size++;
|
||||
}
|
||||
|
||||
constexpr void push_back(T &&p_val) {
|
||||
ERR_FAIL_COND(_size >= CAPACITY);
|
||||
memnew_placement(ptr() + _size, T(std::move(p_val)));
|
||||
_size++;
|
||||
}
|
||||
|
||||
constexpr void pop_back() {
|
||||
ERR_FAIL_COND(_size == 0);
|
||||
_size--;
|
||||
|
|
|
@ -47,7 +47,7 @@ STATIC_ASSERT_INCOMPLETE_TYPE(class, String);
|
|||
struct DictionaryPrivate {
|
||||
SafeRefCount refcount;
|
||||
Variant *read_only = nullptr; // If enabled, a pointer is used to a temporary value that is used to return read-only values.
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator> variant_map;
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator> variant_map;
|
||||
ContainerTypeValidate typed_key;
|
||||
ContainerTypeValidate typed_value;
|
||||
Variant *typed_fallback = nullptr; // Allows a typed dictionary to return dummy values when attempting an invalid access.
|
||||
|
@ -131,8 +131,10 @@ const Variant &Dictionary::operator[](const Variant &p_key) const {
|
|||
VariantInternal::initialize(_p->typed_fallback, _p->typed_value.type);
|
||||
return *_p->typed_fallback;
|
||||
} else {
|
||||
// Will not insert key, so no initialization is necessary.
|
||||
return _p->variant_map[key];
|
||||
static Variant empty;
|
||||
const Variant *value = _p->variant_map.getptr(key);
|
||||
ERR_FAIL_COND_V_MSG(!value, empty, "Bug: Dictionary::operator[] used when there was no value for the given key, please report.");
|
||||
return *value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +143,7 @@ const Variant *Dictionary::getptr(const Variant &p_key) const {
|
|||
if (unlikely(!_p->typed_key.validate(key, "getptr"))) {
|
||||
return nullptr;
|
||||
}
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(key));
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(key));
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -154,7 +156,7 @@ Variant *Dictionary::getptr(const Variant &p_key) {
|
|||
if (unlikely(!_p->typed_key.validate(key, "getptr"))) {
|
||||
return nullptr;
|
||||
}
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::Iterator E(_p->variant_map.find(key));
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>::Iterator E(_p->variant_map.find(key));
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ Variant *Dictionary::getptr(const Variant &p_key) {
|
|||
Variant Dictionary::get_valid(const Variant &p_key) const {
|
||||
Variant key = p_key;
|
||||
ERR_FAIL_COND_V(!_p->typed_key.validate(key, "get_valid"), Variant());
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(key));
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(key));
|
||||
|
||||
if (!E) {
|
||||
return Variant();
|
||||
|
@ -278,7 +280,7 @@ bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_c
|
|||
}
|
||||
recursion_count++;
|
||||
for (const KeyValue<Variant, Variant> &this_E : _p->variant_map) {
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator other_E(p_dictionary._p->variant_map.find(this_E.key));
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>::ConstIterator other_E(p_dictionary._p->variant_map.find(this_E.key));
|
||||
if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count, false)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -436,7 +438,7 @@ void Dictionary::assign(const Dictionary &p_dictionary) {
|
|||
}
|
||||
|
||||
int size = p_dictionary._p->variant_map.size();
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator> variant_map = HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>(size);
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator> variant_map = HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>(size);
|
||||
|
||||
Vector<Variant> key_array;
|
||||
key_array.resize(size);
|
||||
|
@ -569,7 +571,7 @@ const Variant *Dictionary::next(const Variant *p_key) const {
|
|||
}
|
||||
Variant key = *p_key;
|
||||
ERR_FAIL_COND_V(!_p->typed_key.validate(key, "next"), nullptr);
|
||||
HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::Iterator E = _p->variant_map.find(key);
|
||||
HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>::Iterator E = _p->variant_map.find(key);
|
||||
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
|
|
|
@ -42,7 +42,6 @@ struct ContainerType;
|
|||
struct ContainerTypeValidate;
|
||||
struct DictionaryPrivate;
|
||||
struct StringLikeVariantComparator;
|
||||
struct VariantHasher;
|
||||
|
||||
class Dictionary {
|
||||
mutable DictionaryPrivate *_p;
|
||||
|
@ -51,7 +50,7 @@ class Dictionary {
|
|||
void _unref() const;
|
||||
|
||||
public:
|
||||
using ConstIterator = HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator;
|
||||
using ConstIterator = HashMap<Variant, Variant, HashMapHasherDefault, StringLikeVariantComparator>::ConstIterator;
|
||||
|
||||
ConstIterator begin() const;
|
||||
ConstIterator end() const;
|
||||
|
|
|
@ -884,12 +884,9 @@ Vector<Variant> varray(VarArgs... p_args) {
|
|||
return Vector<Variant>{ p_args... };
|
||||
}
|
||||
|
||||
struct VariantHasher {
|
||||
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
|
||||
};
|
||||
|
||||
struct VariantComparator {
|
||||
static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); }
|
||||
template <>
|
||||
struct HashMapComparatorDefault<Variant> {
|
||||
static bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); }
|
||||
};
|
||||
|
||||
struct StringLikeVariantComparator {
|
||||
|
|
|
@ -19,5 +19,8 @@
|
|||
<member name="recording_properties" type="bool" setter="set_recording_properties" getter="is_recording_properties">
|
||||
If [code]true[/code], allows new properties to be set along with existing ones. If [code]false[/code], only existing properties' values can be set, and new properties cannot be added.
|
||||
</member>
|
||||
<member name="recording_signals" type="bool" setter="set_recording_signals" getter="is_recording_signals">
|
||||
If [code]true[/code], allows new signals to be connected to along with existing ones. If [code]false[/code], only existing signals can be connected to, and new signals cannot be added.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
|
@ -560,7 +560,7 @@ void vertex_shader(vec4 vertex_angle_attrib_input,
|
|||
#if defined(UV_USED)
|
||||
vec2 uv_attrib_input,
|
||||
#endif
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(RENDER_MATERIAL)
|
||||
vec2 uv2_attrib_input,
|
||||
#endif
|
||||
#ifdef USE_MULTIVIEW
|
||||
|
@ -915,7 +915,7 @@ void main() {
|
|||
#if defined(UV_USED)
|
||||
uv_attrib,
|
||||
#endif
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(RENDER_MATERIAL)
|
||||
uv2_attrib,
|
||||
#endif
|
||||
#ifdef USE_MULTIVIEW
|
||||
|
@ -948,7 +948,7 @@ void main() {
|
|||
#if defined(UV_USED)
|
||||
uv_attrib,
|
||||
#endif
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(RENDER_MATERIAL)
|
||||
uv2_attrib,
|
||||
#endif
|
||||
#ifdef USE_MULTIVIEW
|
||||
|
|
|
@ -8280,10 +8280,10 @@ AnimationTrackEditor::AnimationTrackEditor() {
|
|||
transition_selection->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Translation context is needed.
|
||||
ease_selection = memnew(OptionButton);
|
||||
ease_selection->set_accessibility_name(TTRC("Ease Type:"));
|
||||
ease_selection->add_item(TTR("In", "Ease Type"), Tween::EASE_IN);
|
||||
ease_selection->add_item(TTR("Out", "Ease Type"), Tween::EASE_OUT);
|
||||
ease_selection->add_item(TTR("InOut", "Ease Type"), Tween::EASE_IN_OUT);
|
||||
ease_selection->add_item(TTR("OutIn", "Ease Type"), Tween::EASE_OUT_IN);
|
||||
ease_selection->add_item(TTR("Ease In", "Ease Type"), Tween::EASE_IN);
|
||||
ease_selection->add_item(TTR("Ease Out", "Ease Type"), Tween::EASE_OUT);
|
||||
ease_selection->add_item(TTR("Ease In-Out", "Ease Type"), Tween::EASE_IN_OUT);
|
||||
ease_selection->add_item(TTR("Ease Out-In", "Ease Type"), Tween::EASE_OUT_IN);
|
||||
ease_selection->select(Tween::EASE_IN_OUT); // Default
|
||||
ease_selection->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Translation context is needed.
|
||||
ease_fps = memnew(SpinBox);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "debug_adapter_parser.h"
|
||||
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_types.h"
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_protocol.h"
|
||||
#include "editor/debugger/editor_debugger_node.h"
|
||||
#include "editor/debugger/script_editor_debugger.h"
|
||||
#include "editor/export/editor_export_platform.h"
|
||||
|
|
|
@ -32,8 +32,7 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/debugger/remote_debugger.h"
|
||||
#include "debug_adapter_protocol.h"
|
||||
#include "debug_adapter_types.h"
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_types.h"
|
||||
|
||||
struct DAPeer;
|
||||
class DebugAdapterProtocol;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "core/debugger/debugger_marshalls.h"
|
||||
#include "core/io/json.h"
|
||||
#include "core/io/marshalls.h"
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_parser.h"
|
||||
#include "editor/debugger/script_editor_debugger.h"
|
||||
#include "editor/editor_log.h"
|
||||
#include "editor/editor_node.h"
|
||||
|
|
|
@ -31,11 +31,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/debugger/debugger_marshalls.h"
|
||||
#include "core/debugger/remote_debugger.h"
|
||||
#include "core/io/stream_peer_tcp.h"
|
||||
#include "core/io/tcp_server.h"
|
||||
|
||||
#include "debug_adapter_parser.h"
|
||||
#include "debug_adapter_types.h"
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_types.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
|
||||
#define DAP_MAX_BUFFER_SIZE 4194304 // 4MB
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "debug_adapter_protocol.h"
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_protocol.h"
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
|
||||
class DebugAdapterServer : public EditorPlugin {
|
||||
|
|
|
@ -1796,22 +1796,42 @@ void EditorPropertyEasing::_spin_focus_exited() {
|
|||
void EditorPropertyEasing::setup(bool p_positive_only, bool p_flip) {
|
||||
flip = p_flip;
|
||||
positive_only = p_positive_only;
|
||||
|
||||
// Names need translation context, so they are set in NOTIFICATION_TRANSLATION_CHANGED.
|
||||
preset->add_item("", EASING_LINEAR);
|
||||
preset->add_item("", EASING_IN);
|
||||
preset->add_item("", EASING_OUT);
|
||||
preset->add_item("", EASING_ZERO);
|
||||
if (!positive_only) {
|
||||
preset->add_item("", EASING_IN_OUT);
|
||||
preset->add_item("", EASING_OUT_IN);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPropertyEasing::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
preset->clear();
|
||||
preset->add_icon_item(get_editor_theme_icon(SNAME("CurveLinear")), "Linear", EASING_LINEAR);
|
||||
preset->add_icon_item(get_editor_theme_icon(SNAME("CurveIn")), "Ease In", EASING_IN);
|
||||
preset->add_icon_item(get_editor_theme_icon(SNAME("CurveOut")), "Ease Out", EASING_OUT);
|
||||
preset->add_icon_item(get_editor_theme_icon(SNAME("CurveConstant")), "Zero", EASING_ZERO);
|
||||
preset->set_item_icon(preset->get_item_index(EASING_LINEAR), get_editor_theme_icon(SNAME("CurveLinear")));
|
||||
preset->set_item_icon(preset->get_item_index(EASING_IN), get_editor_theme_icon(SNAME("CurveIn")));
|
||||
preset->set_item_icon(preset->get_item_index(EASING_OUT), get_editor_theme_icon(SNAME("CurveOut")));
|
||||
preset->set_item_icon(preset->get_item_index(EASING_ZERO), get_editor_theme_icon(SNAME("CurveConstant")));
|
||||
if (!positive_only) {
|
||||
preset->add_icon_item(get_editor_theme_icon(SNAME("CurveInOut")), "Ease In-Out", EASING_IN_OUT);
|
||||
preset->add_icon_item(get_editor_theme_icon(SNAME("CurveOutIn")), "Ease Out-In", EASING_OUT_IN);
|
||||
preset->set_item_icon(preset->get_item_index(EASING_IN_OUT), get_editor_theme_icon(SNAME("CurveInOut")));
|
||||
preset->set_item_icon(preset->get_item_index(EASING_OUT_IN), get_editor_theme_icon(SNAME("CurveOutIn")));
|
||||
}
|
||||
easing_draw->set_custom_minimum_size(Size2(0, get_theme_font(SceneStringName(font), SNAME("Label"))->get_height(get_theme_font_size(SceneStringName(font_size), SNAME("Label"))) * 2));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||
preset->set_item_text(preset->get_item_index(EASING_LINEAR), TTR("Linear", "Ease Type"));
|
||||
preset->set_item_text(preset->get_item_index(EASING_IN), TTR("Ease In", "Ease Type"));
|
||||
preset->set_item_text(preset->get_item_index(EASING_OUT), TTR("Ease Out", "Ease Type"));
|
||||
preset->set_item_text(preset->get_item_index(EASING_ZERO), TTR("Zero", "Ease Type"));
|
||||
if (!positive_only) {
|
||||
preset->set_item_text(preset->get_item_index(EASING_IN_OUT), TTR("Ease In-Out", "Ease Type"));
|
||||
preset->set_item_text(preset->get_item_index(EASING_OUT_IN), TTR("Ease Out-In", "Ease Type"));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1823,6 +1843,7 @@ EditorPropertyEasing::EditorPropertyEasing() {
|
|||
add_child(easing_draw);
|
||||
|
||||
preset = memnew(PopupMenu);
|
||||
preset->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
add_child(preset);
|
||||
preset->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyEasing::_set_preset));
|
||||
|
||||
|
|
|
@ -4246,108 +4246,113 @@ void TileMapLayerEditor::_draw_overlay() {
|
|||
Transform2D xform_inv = xform.affine_inverse();
|
||||
Vector2i tile_shape_size = tile_set->get_tile_size();
|
||||
|
||||
// Draw tiles with invalid IDs in the grid.
|
||||
TypedArray<Vector2i> used_cells = edited_layer->get_used_cells();
|
||||
for (int i = 0; i < used_cells.size(); i++) {
|
||||
Vector2i coords = used_cells[i];
|
||||
int tile_source_id = edited_layer->get_cell_source_id(coords);
|
||||
if (tile_source_id >= 0) {
|
||||
Vector2i tile_atlas_coords = edited_layer->get_cell_atlas_coords(coords);
|
||||
int tile_alternative_tile = edited_layer->get_cell_alternative_tile(coords);
|
||||
// Fade the overlay out when size too small.
|
||||
Vector2 hint_distance = xform.get_scale() * tile_shape_size;
|
||||
float scale_fading = MIN(1, (MIN(hint_distance.x, hint_distance.y) - 5) / 5);
|
||||
if (scale_fading > 0) {
|
||||
// Draw tiles with invalid IDs in the grid.
|
||||
TypedArray<Vector2i> used_cells = edited_layer->get_used_cells();
|
||||
for (int i = 0; i < used_cells.size(); i++) {
|
||||
Vector2i coords = used_cells[i];
|
||||
int tile_source_id = edited_layer->get_cell_source_id(coords);
|
||||
if (tile_source_id >= 0) {
|
||||
Vector2i tile_atlas_coords = edited_layer->get_cell_atlas_coords(coords);
|
||||
int tile_alternative_tile = edited_layer->get_cell_alternative_tile(coords);
|
||||
|
||||
TileSetSource *source = nullptr;
|
||||
if (tile_set->has_source(tile_source_id)) {
|
||||
source = *tile_set->get_source(tile_source_id);
|
||||
}
|
||||
TileSetSource *source = nullptr;
|
||||
if (tile_set->has_source(tile_source_id)) {
|
||||
source = *tile_set->get_source(tile_source_id);
|
||||
}
|
||||
|
||||
if (!source || !source->has_tile(tile_atlas_coords) || !source->has_alternative_tile(tile_atlas_coords, tile_alternative_tile)) {
|
||||
// Generate a random color from the hashed identifier of the tiles.
|
||||
Array to_hash = { tile_source_id, tile_atlas_coords, tile_alternative_tile };
|
||||
uint32_t hash = RandomPCG(to_hash.hash()).rand();
|
||||
if (!source || !source->has_tile(tile_atlas_coords) || !source->has_alternative_tile(tile_atlas_coords, tile_alternative_tile)) {
|
||||
// Generate a random color from the hashed identifier of the tiles.
|
||||
Array to_hash = { tile_source_id, tile_atlas_coords, tile_alternative_tile };
|
||||
uint32_t hash = RandomPCG(to_hash.hash()).rand();
|
||||
|
||||
Color color;
|
||||
color = color.from_hsv(
|
||||
(float)((hash >> 24) & 0xFF) / 256.0,
|
||||
Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
|
||||
Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
|
||||
0.8);
|
||||
Color color;
|
||||
color = color.from_hsv(
|
||||
(float)((hash >> 24) & 0xFF) / 256.0,
|
||||
Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
|
||||
Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
|
||||
0.8 * scale_fading);
|
||||
|
||||
// Display the warning pattern.
|
||||
Transform2D tile_xform;
|
||||
tile_xform.set_origin(tile_set->map_to_local(coords));
|
||||
tile_xform.set_scale(tile_shape_size);
|
||||
tile_set->draw_tile_shape(custom_overlay, xform * tile_xform, color, true, warning_pattern_texture);
|
||||
// Display the warning pattern.
|
||||
Transform2D tile_xform;
|
||||
tile_xform.set_origin(tile_set->map_to_local(coords));
|
||||
tile_xform.set_scale(tile_shape_size);
|
||||
tile_set->draw_tile_shape(custom_overlay, xform * tile_xform, color, true, warning_pattern_texture);
|
||||
|
||||
// Draw the warning icon.
|
||||
Vector2::Axis min_axis = missing_tile_texture->get_size().min_axis_index();
|
||||
Vector2 icon_size;
|
||||
icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
|
||||
icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
|
||||
Rect2 rect = Rect2(xform.xform(tile_set->map_to_local(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale());
|
||||
custom_overlay->draw_texture_rect(missing_tile_texture, rect);
|
||||
// Draw the warning icon.
|
||||
Vector2::Axis min_axis = missing_tile_texture->get_size().min_axis_index();
|
||||
Vector2 icon_size;
|
||||
icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
|
||||
icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
|
||||
Rect2 rect = Rect2(xform.xform(tile_set->map_to_local(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale());
|
||||
custom_overlay->draw_texture_rect(missing_tile_texture, rect, false, Color(1, 1, 1, scale_fading));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fading on the border.
|
||||
const int fading = 5;
|
||||
// Fading on the border.
|
||||
const int fading = 5;
|
||||
|
||||
// Determine the drawn area.
|
||||
Size2 screen_size = custom_overlay->get_size();
|
||||
Rect2i screen_rect;
|
||||
screen_rect.position = tile_set->local_to_map(xform_inv.xform(Vector2()));
|
||||
screen_rect.expand_to(tile_set->local_to_map(xform_inv.xform(Vector2(0, screen_size.height))));
|
||||
screen_rect.expand_to(tile_set->local_to_map(xform_inv.xform(Vector2(screen_size.width, 0))));
|
||||
screen_rect.expand_to(tile_set->local_to_map(xform_inv.xform(screen_size)));
|
||||
screen_rect = screen_rect.grow(1);
|
||||
// Determine the drawn area.
|
||||
Size2 screen_size = custom_overlay->get_size();
|
||||
Rect2i screen_rect;
|
||||
screen_rect.position = tile_set->local_to_map(xform_inv.xform(Vector2()));
|
||||
screen_rect.expand_to(tile_set->local_to_map(xform_inv.xform(Vector2(0, screen_size.height))));
|
||||
screen_rect.expand_to(tile_set->local_to_map(xform_inv.xform(Vector2(screen_size.width, 0))));
|
||||
screen_rect.expand_to(tile_set->local_to_map(xform_inv.xform(screen_size)));
|
||||
screen_rect = screen_rect.grow(1);
|
||||
|
||||
Rect2i tilemap_used_rect = edited_layer->get_used_rect();
|
||||
Rect2i tilemap_used_rect = edited_layer->get_used_rect();
|
||||
|
||||
Rect2i displayed_rect = tilemap_used_rect.intersection(screen_rect);
|
||||
displayed_rect = displayed_rect.grow(fading);
|
||||
Rect2i displayed_rect = tilemap_used_rect.intersection(screen_rect);
|
||||
displayed_rect = displayed_rect.grow(fading);
|
||||
|
||||
// Reduce the drawn area to avoid crashes if needed.
|
||||
int max_size = 100;
|
||||
if (displayed_rect.size.x > max_size) {
|
||||
displayed_rect = displayed_rect.grow_individual(-(displayed_rect.size.x - max_size) / 2, 0, -(displayed_rect.size.x - max_size) / 2, 0);
|
||||
}
|
||||
if (displayed_rect.size.y > max_size) {
|
||||
displayed_rect = displayed_rect.grow_individual(0, -(displayed_rect.size.y - max_size) / 2, 0, -(displayed_rect.size.y - max_size) / 2);
|
||||
}
|
||||
// Reduce the drawn area to avoid crashes if needed.
|
||||
int max_size = 100;
|
||||
if (displayed_rect.size.x > max_size) {
|
||||
displayed_rect = displayed_rect.grow_individual(-(displayed_rect.size.x - max_size) / 2, 0, -(displayed_rect.size.x - max_size) / 2, 0);
|
||||
}
|
||||
if (displayed_rect.size.y > max_size) {
|
||||
displayed_rect = displayed_rect.grow_individual(0, -(displayed_rect.size.y - max_size) / 2, 0, -(displayed_rect.size.y - max_size) / 2);
|
||||
}
|
||||
|
||||
// Draw the grid.
|
||||
bool display_grid = EDITOR_GET("editors/tiles_editor/display_grid");
|
||||
if (display_grid) {
|
||||
Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color");
|
||||
// Draw the grid.
|
||||
bool display_grid = EDITOR_GET("editors/tiles_editor/display_grid");
|
||||
if (display_grid) {
|
||||
Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color");
|
||||
for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) {
|
||||
for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) {
|
||||
Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position;
|
||||
|
||||
// Fade out the border of the grid.
|
||||
float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
|
||||
float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f);
|
||||
float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
|
||||
float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f);
|
||||
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
|
||||
|
||||
Transform2D tile_xform;
|
||||
tile_xform.set_origin(tile_set->map_to_local(Vector2(x, y)));
|
||||
tile_xform.set_scale(tile_shape_size);
|
||||
Color color = grid_color;
|
||||
color.a = color.a * opacity * scale_fading;
|
||||
tile_set->draw_tile_shape(custom_overlay, xform * tile_xform, color, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the IDs for debug.
|
||||
/*Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Label"));
|
||||
for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) {
|
||||
for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) {
|
||||
Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position;
|
||||
|
||||
// Fade out the border of the grid.
|
||||
float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
|
||||
float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f);
|
||||
float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
|
||||
float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f);
|
||||
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
|
||||
|
||||
Transform2D tile_xform;
|
||||
tile_xform.set_origin(tile_set->map_to_local(Vector2(x, y)));
|
||||
tile_xform.set_scale(tile_shape_size);
|
||||
Color color = grid_color;
|
||||
color.a = color.a * opacity;
|
||||
tile_set->draw_tile_shape(custom_overlay, xform * tile_xform, color, false);
|
||||
custom_overlay->draw_string(font, xform.xform(tile_set->map_to_local(Vector2(x, y))) + Vector2i(-tile_shape_size.x / 2, 0), vformat("%s", Vector2(x, y)));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// Draw the IDs for debug.
|
||||
/*Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Label"));
|
||||
for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) {
|
||||
for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) {
|
||||
custom_overlay->draw_string(font, xform.xform(tile_set->map_to_local(Vector2(x, y))) + Vector2i(-tile_shape_size.x / 2, 0), vformat("%s", Vector2(x, y)));
|
||||
}
|
||||
}*/
|
||||
|
||||
// Draw the plugins.
|
||||
tabs_plugins[tabs_bar->get_current_tab()]->forward_canvas_draw_over_viewport(custom_overlay);
|
||||
}
|
||||
|
|
|
@ -1444,7 +1444,7 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
|
|||
if (auto_expand_selected) {
|
||||
// Make visible when it's collapsed.
|
||||
TreeItem *node = item->get_parent();
|
||||
while (node && node != tree->get_root()) {
|
||||
while (node) {
|
||||
node->set_collapsed(false);
|
||||
node = node->get_parent();
|
||||
}
|
||||
|
|
|
@ -2263,9 +2263,9 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
|||
move_down->connect(SceneStringName(pressed), callable_mp(this, &SpriteFramesEditor::_down_pressed));
|
||||
|
||||
load->set_shortcut_context(frame_list);
|
||||
load->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_file", TTRC("Add frame from file"), KeyModifierMask::CMD_OR_CTRL | Key::O));
|
||||
load->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_file", TTRC("Add Frame from File"), KeyModifierMask::CMD_OR_CTRL | Key::O));
|
||||
load_sheet->set_shortcut_context(frame_list);
|
||||
load_sheet->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_sheet", TTRC("Add frames from sprite sheet"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::O));
|
||||
load_sheet->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_sheet", TTRC("Add Frames from Sprite Sheet"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::O));
|
||||
delete_frame->set_shortcut_context(frame_list);
|
||||
delete_frame->set_shortcut(ED_SHORTCUT("sprite_frames/delete", TTRC("Delete Frame"), Key::KEY_DELETE));
|
||||
copy->set_shortcut_context(frame_list);
|
||||
|
|
|
@ -82,15 +82,6 @@ private:
|
|||
|
||||
Ref<ArrayMesh> root_mesh;
|
||||
|
||||
struct Vector3Hasher {
|
||||
_ALWAYS_INLINE_ uint32_t hash(const Vector3 &p_vec3) const {
|
||||
uint32_t h = hash_murmur3_one_float(p_vec3.x);
|
||||
h = hash_murmur3_one_float(p_vec3.y, h);
|
||||
h = hash_murmur3_one_float(p_vec3.z, h);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShapeUpdateSurface {
|
||||
Vector<Vector3> vertices;
|
||||
Vector<Vector3> normals;
|
||||
|
|
|
@ -3833,7 +3833,7 @@ void GDScriptAnalyzer::reduce_cast(GDScriptParser::CastNode *p_cast) {
|
|||
}
|
||||
|
||||
void GDScriptAnalyzer::reduce_dictionary(GDScriptParser::DictionaryNode *p_dictionary) {
|
||||
HashMap<Variant, GDScriptParser::ExpressionNode *, VariantHasher, StringLikeVariantComparator> elements;
|
||||
HashMap<Variant, GDScriptParser::ExpressionNode *, HashMapHasherDefault, StringLikeVariantComparator> elements;
|
||||
|
||||
for (int i = 0; i < p_dictionary->elements.size(); i++) {
|
||||
const GDScriptParser::DictionaryNode::Pair &element = p_dictionary->elements[i];
|
||||
|
|
|
@ -104,7 +104,7 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
|
|||
List<int> temp_stack;
|
||||
#endif
|
||||
|
||||
HashMap<Variant, int, VariantHasher, VariantComparator> constant_map;
|
||||
HashMap<Variant, int> constant_map;
|
||||
RBMap<StringName, int> name_map;
|
||||
#ifdef TOOLS_ENABLED
|
||||
Vector<StringName> named_globals;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "core/io/compression.h"
|
||||
#include "core/io/marshalls.h"
|
||||
|
||||
int GDScriptTokenizerBuffer::_token_to_binary(const Token &p_token, Vector<uint8_t> &r_buffer, int p_start, HashMap<StringName, uint32_t> &r_identifiers_map, HashMap<Variant, uint32_t, VariantHasher, VariantComparator> &r_constants_map) {
|
||||
int GDScriptTokenizerBuffer::_token_to_binary(const Token &p_token, Vector<uint8_t> &r_buffer, int p_start, HashMap<StringName, uint32_t> &r_identifiers_map, HashMap<Variant, uint32_t> &r_constants_map) {
|
||||
int pos = p_start;
|
||||
|
||||
int token_type = p_token.type & TOKEN_MASK;
|
||||
|
@ -239,7 +239,7 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
|
|||
|
||||
Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code, CompressMode p_compress_mode) {
|
||||
HashMap<StringName, uint32_t> identifier_map;
|
||||
HashMap<Variant, uint32_t, VariantHasher, VariantComparator> constant_map;
|
||||
HashMap<Variant, uint32_t> constant_map;
|
||||
Vector<uint8_t> token_buffer;
|
||||
HashMap<uint32_t, uint32_t> token_lines;
|
||||
HashMap<uint32_t, uint32_t> token_columns;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
HashMap<int, CommentData> dummy;
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
static int _token_to_binary(const Token &p_token, Vector<uint8_t> &r_buffer, int p_start, HashMap<StringName, uint32_t> &r_identifiers_map, HashMap<Variant, uint32_t, VariantHasher, VariantComparator> &r_constants_map);
|
||||
static int _token_to_binary(const Token &p_token, Vector<uint8_t> &r_buffer, int p_start, HashMap<StringName, uint32_t> &r_identifiers_map, HashMap<Variant, uint32_t> &r_constants_map);
|
||||
Token _binary_to_token(const uint8_t *p_buffer);
|
||||
|
||||
public:
|
||||
|
|
|
@ -1432,7 +1432,7 @@ void CSharpLanguage::tie_user_managed_to_unmanaged(GCHandleIntPtr p_gchandle_int
|
|||
|
||||
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(p_unmanaged, script.ptr(), gchandle);
|
||||
|
||||
p_unmanaged->set_script_and_instance(script, csharp_instance);
|
||||
p_unmanaged->set_script_instance(csharp_instance);
|
||||
|
||||
csharp_instance->connect_event_signals();
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ SnapshotDataObject::SnapshotDataObject(SceneDebuggerObject &p_obj, GameStateSnap
|
|||
if (scr.is_valid()) {
|
||||
ScriptInstance *scr_instance = scr->placeholder_instance_create(this);
|
||||
if (scr_instance) {
|
||||
set_script_and_instance(pvalue, scr_instance);
|
||||
set_script_instance(scr_instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -535,7 +535,7 @@ class TextServerAdvanced : public TextServerExtension {
|
|||
Rect2 rect;
|
||||
double baseline = 0;
|
||||
};
|
||||
HashMap<Variant, EmbeddedObject, VariantHasher, VariantComparator> objects;
|
||||
HashMap<Variant, EmbeddedObject> objects;
|
||||
|
||||
/* Shaped data */
|
||||
TextServer::Direction para_direction = DIRECTION_LTR; // Detected text direction.
|
||||
|
|
|
@ -458,7 +458,7 @@ class TextServerFallback : public TextServerExtension {
|
|||
Rect2 rect;
|
||||
double baseline = 0;
|
||||
};
|
||||
HashMap<Variant, EmbeddedObject, VariantHasher, VariantComparator> objects;
|
||||
HashMap<Variant, EmbeddedObject> objects;
|
||||
|
||||
/* Shaped data */
|
||||
TextServer::Direction para_direction = DIRECTION_LTR; // Detected text direction.
|
||||
|
|
|
@ -43,7 +43,6 @@ if env["dbus"]:
|
|||
if env["library_type"] == "static_library":
|
||||
prog = env.add_library("#bin/godot", common_linuxbsd)
|
||||
elif env["library_type"] == "shared_library":
|
||||
env.Append(CCFLAGS=["-fPIC"])
|
||||
prog = env.add_shared_library("#bin/godot", common_linuxbsd)
|
||||
else:
|
||||
prog = env.add_program("#bin/godot", common_linuxbsd)
|
||||
|
|
|
@ -182,6 +182,9 @@ def configure(env: "SConsEnvironment"):
|
|||
|
||||
env.Append(CCFLAGS=["-ffp-contract=off"])
|
||||
|
||||
if env["library_type"] == "shared_library":
|
||||
env.Append(CCFLAGS=["-fPIC"])
|
||||
|
||||
# LTO
|
||||
|
||||
if env["lto"] == "auto": # Enable LTO for production.
|
||||
|
|
|
@ -3,6 +3,8 @@ from misc.utility.scons_hints import *
|
|||
|
||||
Import("env")
|
||||
|
||||
File = env.File
|
||||
|
||||
# TODO: Add warning to headers and code about their autogenerated status.
|
||||
if env["use_sowrap"]:
|
||||
# We have to implement separate builders for so wrappers as the
|
||||
|
@ -41,14 +43,14 @@ else:
|
|||
|
||||
|
||||
def generate_from_xml(name, path):
|
||||
header = env.WAYLAND_API_HEADER(f"protocol/{name}.gen.h", path)
|
||||
source = env.WAYLAND_API_CODE(f"protocol/{name}.gen.c", path)
|
||||
header = env.WAYLAND_API_HEADER(File(f"protocol/{name}.gen.h"), path)
|
||||
source = env.WAYLAND_API_CODE(File(f"protocol/{name}.gen.c"), path)
|
||||
env.NoCache(header, source)
|
||||
|
||||
return env.Object(f"protocol/{name}.gen.c")
|
||||
return source
|
||||
|
||||
|
||||
objects = [
|
||||
generated_sources = [
|
||||
# Core protocol
|
||||
generate_from_xml("wayland", "#thirdparty/wayland/protocol/wayland.xml"),
|
||||
# Stable protocols
|
||||
|
@ -97,34 +99,31 @@ objects = [
|
|||
),
|
||||
]
|
||||
|
||||
source_files = [
|
||||
"detect_prime_egl.cpp",
|
||||
"display_server_wayland.cpp",
|
||||
"key_mapping_xkb.cpp",
|
||||
"wayland_thread.cpp",
|
||||
source_files = generated_sources + [
|
||||
File("detect_prime_egl.cpp"),
|
||||
File("display_server_wayland.cpp"),
|
||||
File("key_mapping_xkb.cpp"),
|
||||
File("wayland_thread.cpp"),
|
||||
]
|
||||
|
||||
if env["use_sowrap"]:
|
||||
source_files.append(
|
||||
[
|
||||
"dynwrappers/wayland-cursor-so_wrap.c",
|
||||
"dynwrappers/wayland-client-core-so_wrap.c",
|
||||
"dynwrappers/wayland-egl-core-so_wrap.c",
|
||||
File("dynwrappers/wayland-cursor-so_wrap.c"),
|
||||
File("dynwrappers/wayland-client-core-so_wrap.c"),
|
||||
File("dynwrappers/wayland-egl-core-so_wrap.c"),
|
||||
]
|
||||
)
|
||||
|
||||
if env["libdecor"]:
|
||||
source_files.append("dynwrappers/libdecor-so_wrap.c")
|
||||
source_files.append(File("dynwrappers/libdecor-so_wrap.c"))
|
||||
|
||||
|
||||
if env["vulkan"]:
|
||||
source_files.append("rendering_context_driver_vulkan_wayland.cpp")
|
||||
source_files.append(File("rendering_context_driver_vulkan_wayland.cpp"))
|
||||
|
||||
if env["opengl3"]:
|
||||
source_files.append("egl_manager_wayland.cpp")
|
||||
source_files.append("egl_manager_wayland_gles.cpp")
|
||||
source_files.append(File("egl_manager_wayland.cpp"))
|
||||
source_files.append(File("egl_manager_wayland_gles.cpp"))
|
||||
|
||||
for source_file in source_files:
|
||||
objects.append(env.Object(source_file))
|
||||
|
||||
Return("objects")
|
||||
Return("source_files")
|
||||
|
|
|
@ -3,36 +3,38 @@ from misc.utility.scons_hints import *
|
|||
|
||||
Import("env")
|
||||
|
||||
File = env.File
|
||||
|
||||
source_files = [
|
||||
"display_server_x11.cpp",
|
||||
"key_mapping_x11.cpp",
|
||||
File("display_server_x11.cpp"),
|
||||
File("key_mapping_x11.cpp"),
|
||||
]
|
||||
|
||||
if env["use_sowrap"]:
|
||||
source_files.append(
|
||||
[
|
||||
"dynwrappers/xlib-so_wrap.c",
|
||||
"dynwrappers/xcursor-so_wrap.c",
|
||||
"dynwrappers/xinerama-so_wrap.c",
|
||||
"dynwrappers/xinput2-so_wrap.c",
|
||||
"dynwrappers/xrandr-so_wrap.c",
|
||||
"dynwrappers/xrender-so_wrap.c",
|
||||
"dynwrappers/xext-so_wrap.c",
|
||||
File("dynwrappers/xlib-so_wrap.c"),
|
||||
File("dynwrappers/xcursor-so_wrap.c"),
|
||||
File("dynwrappers/xinerama-so_wrap.c"),
|
||||
File("dynwrappers/xinput2-so_wrap.c"),
|
||||
File("dynwrappers/xrandr-so_wrap.c"),
|
||||
File("dynwrappers/xrender-so_wrap.c"),
|
||||
File("dynwrappers/xext-so_wrap.c"),
|
||||
]
|
||||
)
|
||||
|
||||
if env["vulkan"]:
|
||||
source_files.append("rendering_context_driver_vulkan_x11.cpp")
|
||||
source_files.append(File("rendering_context_driver_vulkan_x11.cpp"))
|
||||
|
||||
if env["opengl3"]:
|
||||
env.Append(CPPDEFINES=["GLAD_GLX_NO_X11"])
|
||||
source_files.append(
|
||||
["gl_manager_x11_egl.cpp", "gl_manager_x11.cpp", "detect_prime_x11.cpp", "#thirdparty/glad/glx.c"]
|
||||
[
|
||||
File("gl_manager_x11_egl.cpp"),
|
||||
File("gl_manager_x11.cpp"),
|
||||
File("detect_prime_x11.cpp"),
|
||||
File("#thirdparty/glad/glx.c"),
|
||||
]
|
||||
)
|
||||
|
||||
objects = []
|
||||
|
||||
for source_file in source_files:
|
||||
objects.append(env.Object(source_file))
|
||||
|
||||
Return("objects")
|
||||
Return("source_files")
|
||||
|
|
|
@ -1917,9 +1917,22 @@ void DisplayServerX11::show_window(WindowID p_id) {
|
|||
|
||||
DEBUG_LOG_X11("show_window: %lu (%u) \n", wd.x11_window, p_id);
|
||||
|
||||
// Setup initial minimize/maximize state.
|
||||
// `_NET_WM_STATE` can be set directly when the window is unmapped.
|
||||
LocalVector<Atom> hints;
|
||||
if (wd.maximized) {
|
||||
hints.push_back(XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False));
|
||||
hints.push_back(XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False));
|
||||
}
|
||||
if (wd.minimized) {
|
||||
hints.push_back(XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False));
|
||||
}
|
||||
XChangeProperty(x11_display, wd.x11_window, XInternAtom(x11_display, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)hints.ptr(), hints.size());
|
||||
|
||||
XMapWindow(x11_display, wd.x11_window);
|
||||
XSync(x11_display, False);
|
||||
_validate_mode_on_map(p_id);
|
||||
|
||||
_validate_fullscreen_on_map(p_id);
|
||||
|
||||
if (p_id == MAIN_WINDOW_ID) {
|
||||
// Get main window size for boot splash drawing.
|
||||
|
@ -2448,6 +2461,52 @@ void DisplayServerX11::_update_actions_hints(WindowID p_window) {
|
|||
}
|
||||
}
|
||||
|
||||
void DisplayServerX11::_update_wm_state_hints(WindowID p_window) {
|
||||
WindowData &wd = windows[p_window];
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long len;
|
||||
unsigned long remaining;
|
||||
unsigned char *data = nullptr;
|
||||
|
||||
int result = XGetWindowProperty(
|
||||
x11_display,
|
||||
wd.x11_window,
|
||||
XInternAtom(x11_display, "_NET_WM_STATE", False),
|
||||
0,
|
||||
1024,
|
||||
False,
|
||||
XA_ATOM,
|
||||
&type,
|
||||
&format,
|
||||
&len,
|
||||
&remaining,
|
||||
&data);
|
||||
if (result != Success) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalVector<Atom> hints;
|
||||
if (data) {
|
||||
hints.resize(len);
|
||||
Atom *atoms = (Atom *)data;
|
||||
for (unsigned long i = 0; i < len; i++) {
|
||||
hints[i] = atoms[i];
|
||||
}
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
Atom fullscreen_atom = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
Atom maximized_horz_atom = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
Atom maximized_vert_atom = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
Atom hidden_atom = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False);
|
||||
|
||||
wd.fullscreen = hints.has(fullscreen_atom);
|
||||
wd.maximized = hints.has(maximized_horz_atom) && hints.has(maximized_vert_atom);
|
||||
wd.minimized = hints.has(hidden_atom);
|
||||
}
|
||||
|
||||
Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
@ -2855,15 +2914,11 @@ bool DisplayServerX11::_window_fullscreen_check(WindowID p_window) const {
|
|||
return retval;
|
||||
}
|
||||
|
||||
void DisplayServerX11::_validate_mode_on_map(WindowID p_window) {
|
||||
void DisplayServerX11::_validate_fullscreen_on_map(WindowID p_window) {
|
||||
// Check if we applied any window modes that didn't take effect while unmapped
|
||||
const WindowData &wd = windows[p_window];
|
||||
if (wd.fullscreen && !_window_fullscreen_check(p_window)) {
|
||||
_set_wm_fullscreen(p_window, true, wd.exclusive_fullscreen);
|
||||
} else if (wd.maximized && !_window_maximize_check(p_window, "_NET_WM_STATE")) {
|
||||
_set_wm_maximized(p_window, true);
|
||||
} else if (wd.minimized && !_window_minimize_check(p_window)) {
|
||||
_set_wm_minimized(p_window, true);
|
||||
}
|
||||
|
||||
if (wd.on_top) {
|
||||
|
@ -3062,13 +3117,15 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
|
|||
|
||||
} break;
|
||||
case WINDOW_MODE_MAXIMIZED: {
|
||||
_set_wm_maximized(p_window, false);
|
||||
// Varies between target modes, so do nothing here.
|
||||
} break;
|
||||
}
|
||||
|
||||
switch (p_mode) {
|
||||
case WINDOW_MODE_WINDOWED: {
|
||||
//do nothing
|
||||
if (wd.maximized) {
|
||||
_set_wm_maximized(p_window, false);
|
||||
}
|
||||
} break;
|
||||
case WINDOW_MODE_MINIMIZED: {
|
||||
_set_wm_minimized(p_window, true);
|
||||
|
@ -3102,28 +3159,21 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c
|
|||
ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED);
|
||||
const WindowData &wd = windows[p_window];
|
||||
|
||||
if (wd.fullscreen) { //if fullscreen, it's not in another mode
|
||||
if (wd.exclusive_fullscreen) {
|
||||
return WINDOW_MODE_EXCLUSIVE_FULLSCREEN;
|
||||
} else {
|
||||
return WINDOW_MODE_FULLSCREEN;
|
||||
}
|
||||
if (_window_minimize_check(p_window)) {
|
||||
return WINDOW_MODE_MINIMIZED;
|
||||
}
|
||||
|
||||
if (wd.fullscreen) {
|
||||
if (wd.exclusive_fullscreen) {
|
||||
return WINDOW_MODE_EXCLUSIVE_FULLSCREEN;
|
||||
}
|
||||
return WINDOW_MODE_FULLSCREEN;
|
||||
}
|
||||
|
||||
// Test maximized.
|
||||
// Using EWMH -- Extended Window Manager Hints
|
||||
if (_window_maximize_check(p_window, "_NET_WM_STATE")) {
|
||||
return WINDOW_MODE_MAXIMIZED;
|
||||
}
|
||||
|
||||
{
|
||||
if (_window_minimize_check(p_window)) {
|
||||
return WINDOW_MODE_MINIMIZED;
|
||||
}
|
||||
}
|
||||
|
||||
// All other discarded, return windowed.
|
||||
|
||||
return WINDOW_MODE_WINDOWED;
|
||||
}
|
||||
|
||||
|
@ -4402,11 +4452,6 @@ void DisplayServerX11::_window_changed(XEvent *event) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Query display server about a possible new window state.
|
||||
wd.fullscreen = _window_fullscreen_check(window_id);
|
||||
wd.maximized = _window_maximize_check(window_id, "_NET_WM_STATE") && !wd.fullscreen;
|
||||
wd.minimized = _window_minimize_check(window_id) && !wd.fullscreen && !wd.maximized;
|
||||
|
||||
// Readjusting the window position if the window is being reparented by the window manager for decoration
|
||||
Window root, parent, *children;
|
||||
unsigned int nchildren;
|
||||
|
@ -5037,7 +5082,7 @@ void DisplayServerX11::process_events() {
|
|||
}
|
||||
|
||||
// Have we failed to set fullscreen while the window was unmapped?
|
||||
_validate_mode_on_map(window_id);
|
||||
_validate_fullscreen_on_map(window_id);
|
||||
|
||||
// On KDE Plasma, when the parent window of an embedded process is restored after being minimized,
|
||||
// only the embedded window receives the Map notification, causing it to
|
||||
|
@ -5058,24 +5103,6 @@ void DisplayServerX11::process_events() {
|
|||
Main::force_redraw();
|
||||
} break;
|
||||
|
||||
case NoExpose: {
|
||||
DEBUG_LOG_X11("[%u] NoExpose drawable=%lu (%u) \n", frame, event.xnoexpose.drawable, window_id);
|
||||
if (ime_window_event) {
|
||||
break;
|
||||
}
|
||||
|
||||
windows[window_id].minimized = true;
|
||||
} break;
|
||||
|
||||
case VisibilityNotify: {
|
||||
DEBUG_LOG_X11("[%u] VisibilityNotify window=%lu (%u), state=%u \n", frame, event.xvisibility.window, window_id, event.xvisibility.state);
|
||||
if (ime_window_event) {
|
||||
break;
|
||||
}
|
||||
|
||||
windows[window_id].minimized = _window_minimize_check(window_id);
|
||||
} break;
|
||||
|
||||
case LeaveNotify: {
|
||||
DEBUG_LOG_X11("[%u] LeaveNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode);
|
||||
if (ime_window_event) {
|
||||
|
@ -5219,6 +5246,12 @@ void DisplayServerX11::process_events() {
|
|||
_window_changed(&event);
|
||||
} break;
|
||||
|
||||
case PropertyNotify: {
|
||||
if (event.xproperty.atom == XInternAtom(x11_display, "_NET_WM_STATE", False)) {
|
||||
_update_wm_state_hints(window_id);
|
||||
}
|
||||
} break;
|
||||
|
||||
case ButtonPress:
|
||||
case ButtonRelease: {
|
||||
if (ime_window_event || ignore_events) {
|
||||
|
|
|
@ -352,9 +352,10 @@ class DisplayServerX11 : public DisplayServer {
|
|||
bool _window_maximize_check(WindowID p_window, const char *p_atom_name) const;
|
||||
bool _window_fullscreen_check(WindowID p_window) const;
|
||||
bool _window_minimize_check(WindowID p_window) const;
|
||||
void _validate_mode_on_map(WindowID p_window);
|
||||
void _validate_fullscreen_on_map(WindowID p_window);
|
||||
void _update_size_hints(WindowID p_window);
|
||||
void _update_actions_hints(WindowID p_window);
|
||||
void _update_wm_state_hints(WindowID p_window);
|
||||
void _set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive);
|
||||
void _set_wm_maximized(WindowID p_window, bool p_enabled);
|
||||
void _set_wm_minimized(WindowID p_window, bool p_enabled);
|
||||
|
|
|
@ -58,6 +58,17 @@ void MissingNode::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Error MissingNode::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) {
|
||||
if (is_recording_signals()) {
|
||||
if (!has_signal(p_signal)) {
|
||||
add_user_signal(MethodInfo(p_signal));
|
||||
}
|
||||
}
|
||||
return Object::connect(p_signal, p_callable, p_flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MissingNode::set_original_class(const String &p_class) {
|
||||
original_class = p_class;
|
||||
}
|
||||
|
@ -82,6 +93,14 @@ bool MissingNode::is_recording_properties() const {
|
|||
return recording_properties;
|
||||
}
|
||||
|
||||
void MissingNode::set_recording_signals(bool p_enable) {
|
||||
recording_signals = p_enable;
|
||||
}
|
||||
|
||||
bool MissingNode::is_recording_signals() const {
|
||||
return recording_signals;
|
||||
}
|
||||
|
||||
PackedStringArray MissingNode::get_configuration_warnings() const {
|
||||
// The mere existence of this node is warning.
|
||||
PackedStringArray warnings = Node::get_configuration_warnings();
|
||||
|
@ -107,10 +126,14 @@ void MissingNode::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_recording_properties", "enable"), &MissingNode::set_recording_properties);
|
||||
ClassDB::bind_method(D_METHOD("is_recording_properties"), &MissingNode::is_recording_properties);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_recording_signals", "enable"), &MissingNode::set_recording_signals);
|
||||
ClassDB::bind_method(D_METHOD("is_recording_signals"), &MissingNode::is_recording_signals);
|
||||
|
||||
// Expose, but not save.
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "original_class", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_original_class", "get_original_class");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "original_scene", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_original_scene", "get_original_scene");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recording_properties", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_recording_properties", "is_recording_properties");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recording_signals", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_recording_signals", "is_recording_signals");
|
||||
}
|
||||
|
||||
MissingNode::MissingNode() {
|
||||
|
|
|
@ -39,12 +39,17 @@ class MissingNode : public Node {
|
|||
String original_class;
|
||||
String original_scene;
|
||||
bool recording_properties = false;
|
||||
bool recording_signals = false;
|
||||
|
||||
protected:
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
virtual Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0) override;
|
||||
#endif
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
@ -57,6 +62,9 @@ public:
|
|||
void set_recording_properties(bool p_enable);
|
||||
bool is_recording_properties() const;
|
||||
|
||||
void set_recording_signals(bool p_enable);
|
||||
bool is_recording_signals() const;
|
||||
|
||||
virtual PackedStringArray get_configuration_warnings() const override;
|
||||
|
||||
MissingNode();
|
||||
|
|
|
@ -695,7 +695,7 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
|
||||
// Let users override potential loop points from the WAV.
|
||||
// We parse the WAV loop points only with "Detect From WAV" (0).
|
||||
int import_loop_mode = p_options["edit/loop_mode"];
|
||||
int import_loop_mode = p_options.get("edit/loop_mode", 0);
|
||||
|
||||
uint16_t format_bits = 0;
|
||||
uint16_t format_channels = 0;
|
||||
|
@ -933,8 +933,8 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
|
||||
//apply frequency limit
|
||||
|
||||
bool limit_rate = p_options["force/max_rate"];
|
||||
uint32_t limit_rate_hz = p_options["force/max_rate_hz"];
|
||||
bool limit_rate = p_options.get("force/max_rate", false);
|
||||
uint32_t limit_rate_hz = p_options.get("force/max_rate_hz", 0);
|
||||
if (limit_rate && rate > limit_rate_hz && rate > 0 && frames > 0) {
|
||||
// resample!
|
||||
int64_t new_data_frames = (int64_t)(frames * (float)limit_rate_hz / (float)rate);
|
||||
|
@ -975,7 +975,7 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
frames = new_data_frames;
|
||||
}
|
||||
|
||||
bool normalize = p_options["edit/normalize"];
|
||||
bool normalize = p_options.get("edit/normalize", false);
|
||||
|
||||
if (normalize) {
|
||||
float max = 0.0;
|
||||
|
@ -994,7 +994,7 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
}
|
||||
}
|
||||
|
||||
bool trim = p_options["edit/trim"];
|
||||
bool trim = p_options.get("edit/trim", false);
|
||||
|
||||
if (trim && (loop_mode == AudioStreamWAV::LOOP_DISABLED) && format_channels > 0) {
|
||||
int64_t first = 0;
|
||||
|
@ -1042,8 +1042,8 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
|
||||
if (import_loop_mode >= 2) {
|
||||
loop_mode = (AudioStreamWAV::LoopMode)(import_loop_mode - 1);
|
||||
loop_begin = p_options["edit/loop_begin"];
|
||||
loop_end = p_options["edit/loop_end"];
|
||||
loop_begin = p_options.get("edit/loop_begin", 0);
|
||||
loop_end = p_options.get("edit/loop_end", 0);
|
||||
// Wrap around to max frames, so `-1` can be used to select the end, etc.
|
||||
if (loop_begin < 0) {
|
||||
loop_begin = CLAMP(loop_begin + frames, 0, frames - 1);
|
||||
|
@ -1053,8 +1053,8 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
}
|
||||
}
|
||||
|
||||
int compression = p_options["compress/mode"];
|
||||
bool force_mono = p_options["force/mono"];
|
||||
int compression = p_options.get("compress/mode", 0);
|
||||
bool force_mono = p_options.get("force/mono", false);
|
||||
|
||||
if (force_mono && format_channels == 2) {
|
||||
Vector<float> new_data;
|
||||
|
@ -1067,7 +1067,7 @@ Ref<AudioStreamWAV> AudioStreamWAV::load_from_buffer(const Vector<uint8_t> &p_st
|
|||
format_channels = 1;
|
||||
}
|
||||
|
||||
bool force_8_bit = p_options["force/8_bit"];
|
||||
bool force_8_bit = p_options.get("force/8_bit", false);
|
||||
if (force_8_bit) {
|
||||
is16 = false;
|
||||
}
|
||||
|
|
|
@ -775,7 +775,7 @@ static int _nm_get_string(const String &p_string, HashMap<StringName, int> &name
|
|||
return idx;
|
||||
}
|
||||
|
||||
static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map) {
|
||||
static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int> &variant_map) {
|
||||
if (variant_map.has(p_variant)) {
|
||||
return variant_map[p_variant];
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, Varia
|
|||
return idx;
|
||||
}
|
||||
|
||||
Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, HashMap<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map, HashSet<int32_t> &ids_saved) {
|
||||
Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, HashMap<StringName, int> &name_map, HashMap<Variant, int> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map, HashSet<int32_t> &ids_saved) {
|
||||
// this function handles all the work related to properly packing scenes, be it
|
||||
// instantiated or inherited.
|
||||
// given the complexity of this process, an attempt will be made to properly
|
||||
|
@ -1133,7 +1133,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
|
|||
return OK;
|
||||
}
|
||||
|
||||
Error SceneState::_parse_connections(Node *p_owner, Node *p_node, HashMap<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map) {
|
||||
Error SceneState::_parse_connections(Node *p_owner, Node *p_node, HashMap<StringName, int> &name_map, HashMap<Variant, int> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map) {
|
||||
// Ignore nodes that are within a scene instance.
|
||||
if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
|
||||
return OK;
|
||||
|
@ -1347,7 +1347,7 @@ Error SceneState::pack(Node *p_scene) {
|
|||
Node *scene = p_scene;
|
||||
|
||||
HashMap<StringName, int> name_map;
|
||||
HashMap<Variant, int, VariantHasher, VariantComparator> variant_map;
|
||||
HashMap<Variant, int> variant_map;
|
||||
HashMap<Node *, int> node_map;
|
||||
HashMap<Node *, int> nodepath_map;
|
||||
HashSet<int32_t> ids_saved;
|
||||
|
|
|
@ -90,8 +90,8 @@ class SceneState : public RefCounted {
|
|||
|
||||
Vector<ConnectionData> connections;
|
||||
|
||||
Error _parse_node(Node *p_owner, Node *p_node, int p_parent_idx, HashMap<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map, HashSet<int32_t> &ids_saved);
|
||||
Error _parse_connections(Node *p_owner, Node *p_node, HashMap<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map);
|
||||
Error _parse_node(Node *p_owner, Node *p_node, int p_parent_idx, HashMap<StringName, int> &name_map, HashMap<Variant, int> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map, HashSet<int32_t> &ids_saved);
|
||||
Error _parse_connections(Node *p_owner, Node *p_node, HashMap<StringName, int> &name_map, HashMap<Variant, int> &variant_map, HashMap<Node *, int> &node_map, HashMap<Node *, int> &nodepath_map);
|
||||
|
||||
String path;
|
||||
|
||||
|
|
|
@ -2085,6 +2085,12 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
}
|
||||
}
|
||||
|
||||
void VisualShader::_validate_property(PropertyInfo &p_property) const {
|
||||
if (p_property.name == "code") {
|
||||
p_property.usage = PROPERTY_USAGE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringBuilder *p_global_code_per_node, HashMap<Type, StringBuilder> *p_global_code_per_func, StringBuilder &r_code, Vector<VisualShader::DefaultTextureParam> &r_def_tex_params, const HashMap<ConnectionKey, const List<Connection>::Element *> &p_input_connections, int p_node, HashSet<int> &r_processed, bool p_for_preview, HashSet<StringName> &r_classes) const {
|
||||
const Ref<VisualShaderNode> vsnode = graph[type].nodes[p_node].node;
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@ protected:
|
|||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
|
||||
virtual void reset_state() override;
|
||||
|
||||
|
|
|
@ -795,12 +795,12 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i
|
|||
#ifdef REAL_T_IS_DOUBLE
|
||||
// Split the origin into two components, the float approximation and the missing precision.
|
||||
// In the shader we will combine these back together to restore the lost precision.
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.x, &instance_data.transform[12], &instance_data.model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.y, &instance_data.transform[13], &instance_data.model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.z, &instance_data.transform[14], &instance_data.model_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.x, &instance_data.prev_transform[12], &instance_data.prev_model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.y, &instance_data.prev_transform[13], &instance_data.prev_model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.z, &instance_data.prev_transform[14], &instance_data.prev_model_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.x, &instance_data.transform[3], &instance_data.model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.y, &instance_data.transform[7], &instance_data.model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.z, &instance_data.transform[11], &instance_data.model_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.x, &instance_data.prev_transform[3], &instance_data.prev_model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.y, &instance_data.prev_transform[7], &instance_data.prev_model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.z, &instance_data.prev_transform[11], &instance_data.prev_model_precision[2]);
|
||||
#endif
|
||||
} else {
|
||||
RendererRD::MaterialStorage::store_transform_transposed_3x4(Transform3D(), instance_data.transform);
|
||||
|
|
|
@ -1946,12 +1946,12 @@ void RenderForwardMobile::_fill_instance_data(RenderListType p_render_list, uint
|
|||
#ifdef REAL_T_IS_DOUBLE
|
||||
// Split the origin into two components, the float approximation and the missing precision.
|
||||
// In the shader we will combine these back together to restore the lost precision.
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.x, &instance_data.transform[12], &instance_data.model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.y, &instance_data.transform[13], &instance_data.model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.z, &instance_data.transform[14], &instance_data.model_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.x, &instance_data.prev_transform[12], &instance_data.prev_model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.y, &instance_data.prev_transform[13], &instance_data.prev_model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.z, &instance_data.prev_transform[14], &instance_data.prev_model_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.x, &instance_data.transform[3], &instance_data.model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.y, &instance_data.transform[7], &instance_data.model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->transform.origin.z, &instance_data.transform[11], &instance_data.model_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.x, &instance_data.prev_transform[3], &instance_data.prev_model_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.y, &instance_data.prev_transform[7], &instance_data.prev_model_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(inst->prev_transform.origin.z, &instance_data.prev_transform[11], &instance_data.prev_model_precision[2]);
|
||||
#endif
|
||||
} else {
|
||||
RendererRD::MaterialStorage::store_transform_transposed_3x4(Transform3D(), instance_data.transform);
|
||||
|
|
|
@ -91,9 +91,9 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
|
|||
RendererRD::MaterialStorage::store_transform_transposed_3x4(cam_transform.affine_inverse(), ubo.view_matrix);
|
||||
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
RendererRD::MaterialStorage::split_double(-cam_transform.origin.x, &ubo.inv_view_matrix[12], &ubo.inv_view_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(-cam_transform.origin.y, &ubo.inv_view_matrix[13], &ubo.inv_view_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(-cam_transform.origin.z, &ubo.inv_view_matrix[14], &ubo.inv_view_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(-cam_transform.origin.x, &ubo.inv_view_matrix[3], &ubo.inv_view_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(-cam_transform.origin.y, &ubo.inv_view_matrix[7], &ubo.inv_view_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(-cam_transform.origin.z, &ubo.inv_view_matrix[11], &ubo.inv_view_precision[2]);
|
||||
#endif
|
||||
|
||||
for (uint32_t v = 0; v < view_count; v++) {
|
||||
|
@ -270,9 +270,9 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
|
|||
RendererRD::MaterialStorage::store_transform_transposed_3x4(prev_cam_transform.affine_inverse(), prev_ubo.view_matrix);
|
||||
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.x, &prev_ubo.inv_view_matrix[12], &prev_ubo.inv_view_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.y, &prev_ubo.inv_view_matrix[13], &prev_ubo.inv_view_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.z, &prev_ubo.inv_view_matrix[14], &prev_ubo.inv_view_precision[2]);
|
||||
RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.x, &prev_ubo.inv_view_matrix[3], &prev_ubo.inv_view_precision[0]);
|
||||
RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.y, &prev_ubo.inv_view_matrix[7], &prev_ubo.inv_view_precision[1]);
|
||||
RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.z, &prev_ubo.inv_view_matrix[11], &prev_ubo.inv_view_precision[2]);
|
||||
#endif
|
||||
|
||||
for (uint32_t v = 0; v < view_count; v++) {
|
||||
|
|
|
@ -75,7 +75,18 @@ TEST_CASE("[JSON] Stringify arrays") {
|
|||
full_precision_array.push_back(0.12345678901234568);
|
||||
CHECK(JSON::stringify(full_precision_array, "", true, true) == "[0.12345678901234568]");
|
||||
|
||||
Array non_finite_array;
|
||||
non_finite_array.push_back(Math::INF);
|
||||
non_finite_array.push_back(-Math::INF);
|
||||
non_finite_array.push_back(Math::NaN);
|
||||
CHECK(JSON::stringify(non_finite_array) == "[1e99999,-1e99999,\"NaN\"]");
|
||||
|
||||
ERR_PRINT_OFF
|
||||
Array non_finite_round_trip = JSON::parse_string(JSON::stringify(non_finite_array));
|
||||
CHECK(non_finite_round_trip[0] == Variant(Math::INF));
|
||||
CHECK(non_finite_round_trip[1] == Variant(-Math::INF));
|
||||
CHECK(non_finite_round_trip[2].get_type() == Variant::STRING);
|
||||
|
||||
Array self_array;
|
||||
self_array.push_back(self_array);
|
||||
CHECK(JSON::stringify(self_array) == "[\"[...]\"]");
|
||||
|
@ -113,7 +124,18 @@ TEST_CASE("[JSON] Stringify dictionaries") {
|
|||
full_precision_dictionary["key"] = 0.12345678901234568;
|
||||
CHECK(JSON::stringify(full_precision_dictionary, "", true, true) == "{\"key\":0.12345678901234568}");
|
||||
|
||||
Dictionary non_finite_dictionary;
|
||||
non_finite_dictionary["-inf"] = -Math::INF;
|
||||
non_finite_dictionary["inf"] = Math::INF;
|
||||
non_finite_dictionary["nan"] = Math::NaN;
|
||||
CHECK(JSON::stringify(non_finite_dictionary) == "{\"-inf\":-1e99999,\"inf\":1e99999,\"nan\":\"NaN\"}");
|
||||
|
||||
ERR_PRINT_OFF
|
||||
Dictionary non_finite_round_trip = JSON::parse_string(JSON::stringify(non_finite_dictionary));
|
||||
CHECK(non_finite_round_trip["-inf"] == Variant(-Math::INF));
|
||||
CHECK(non_finite_round_trip["inf"] == Variant(Math::INF));
|
||||
CHECK(non_finite_round_trip["nan"].get_type() == Variant::STRING);
|
||||
|
||||
Dictionary self_dictionary;
|
||||
self_dictionary["key"] = self_dictionary;
|
||||
CHECK(JSON::stringify(self_dictionary) == "{\"key\":\"{...}\"}");
|
||||
|
|
|
@ -36,6 +36,30 @@
|
|||
|
||||
namespace TestFixedVector {
|
||||
|
||||
struct MoveOnly {
|
||||
bool is_alive = true;
|
||||
|
||||
MoveOnly() = default;
|
||||
MoveOnly(const MoveOnly &p) = delete;
|
||||
MoveOnly &operator=(const MoveOnly &p) = delete;
|
||||
|
||||
MoveOnly(MoveOnly &&p) {
|
||||
is_alive = p.is_alive;
|
||||
p.is_alive = false;
|
||||
}
|
||||
MoveOnly &operator=(MoveOnly &&p) {
|
||||
if (&p == this) {
|
||||
return *this;
|
||||
}
|
||||
is_alive = p.is_alive;
|
||||
p.is_alive = false;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(!std::is_trivially_copyable_v<MoveOnly>);
|
||||
static_assert(!std::is_trivially_constructible_v<MoveOnly>);
|
||||
|
||||
TEST_CASE("[FixedVector] Basic Checks") {
|
||||
FixedVector<uint16_t, 1> vector;
|
||||
CHECK_EQ(vector.capacity(), 1);
|
||||
|
@ -62,12 +86,6 @@ TEST_CASE("[FixedVector] Basic Checks") {
|
|||
CHECK_EQ(vector1[0], 1);
|
||||
CHECK_EQ(vector1[1], 2);
|
||||
|
||||
FixedVector<uint16_t, 3> vector2(vector1);
|
||||
CHECK_EQ(vector2.capacity(), 3);
|
||||
CHECK_EQ(vector2.size(), 2);
|
||||
CHECK_EQ(vector2[0], 1);
|
||||
CHECK_EQ(vector2[1], 2);
|
||||
|
||||
FixedVector<Variant, 3> vector_variant;
|
||||
CHECK_EQ(vector_variant.size(), 0);
|
||||
CHECK_EQ(vector_variant.capacity(), 3);
|
||||
|
@ -79,6 +97,17 @@ TEST_CASE("[FixedVector] Basic Checks") {
|
|||
CHECK_EQ(vector_variant[0], "Test");
|
||||
CHECK_EQ(vector_variant[1], Variant(1));
|
||||
CHECK_EQ(vector_variant[2].get_type(), Variant::NIL);
|
||||
|
||||
// Test that move-only types are transferred.
|
||||
FixedVector<MoveOnly, 1> a;
|
||||
a.push_back(MoveOnly());
|
||||
CHECK_EQ(a.size(), 1);
|
||||
FixedVector<MoveOnly, 1> b(std::move(a));
|
||||
CHECK_EQ(a.size(), 0);
|
||||
CHECK_EQ(b.size(), 1);
|
||||
a = std::move(b);
|
||||
CHECK_EQ(a.size(), 1);
|
||||
CHECK_EQ(b.size(), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("[FixedVector] Alignment Checks") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue