From c87f9fd5417ed3fcf0701750218055d64585ffe3 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 31 Dec 2023 19:32:44 +0100 Subject: [PATCH] Fixed building Variant. Also added more goodies to object. --- compile_linux.sh | 11 +- main.cpp | 3 + sfw/core/logger.cpp | 3 + sfw/core/logger.h | 1 + sfw/core/og_hash_map.h | 579 +++++++++++++++++++++++++++++++ sfw/core/old/old/string.h | 2 +- sfw/core/ordered_hash_map.h | 285 +++++++++++++++ sfw/core/ustring.cpp | 2 +- sfw/object/array.cpp | 17 +- sfw/object/array.h | 2 +- sfw/object/core_string_names.cpp | 49 +++ sfw/object/core_string_names.h | 66 ++++ sfw/object/dictionary.cpp | 7 +- sfw/object/object.cpp | 59 +++- sfw/object/object.h | 165 +++++---- sfw/object/psignal.cpp | 4 +- sfw/object/psignal.h | 8 +- sfw/object/ref_ptr.cpp | 12 - sfw/object/variant.cpp | 278 +-------------- sfw/object/variant.h | 4 +- sfw/object/variant_op.cpp | 384 ++++---------------- 21 files changed, 1257 insertions(+), 684 deletions(-) create mode 100644 sfw/core/og_hash_map.h create mode 100644 sfw/core/ordered_hash_map.h create mode 100644 sfw/object/core_string_names.cpp create mode 100644 sfw/object/core_string_names.h diff --git a/compile_linux.sh b/compile_linux.sh index 7d1178e..3cb023d 100755 --- a/compile_linux.sh +++ b/compile_linux.sh @@ -42,6 +42,13 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/core/stime.cpp -o sfw/core/stime.o ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/object.cpp -o sfw/object/object.o ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/reference.cpp -o sfw/object/reference.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/core_string_names.cpp -o sfw/object/core_string_names.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/variant.cpp -o sfw/object/variant.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/variant_op.cpp -o sfw/object/variant_op.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/psignal.cpp -o sfw/object/psignal.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/array.cpp -o sfw/object/array.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/dictionary.cpp -o sfw/object/dictionary.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/object/ref_ptr.cpp -o sfw/object/ref_ptr.o ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/application.cpp -o sfw/render_core/application.o ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/scene.cpp -o sfw/render_core/scene.o @@ -76,7 +83,9 @@ ccache g++ -Wall -lm -ldl -lpthread -lX11 -D_REENTRANT -g sfw/core/aabb.o sfw/c sfw/core/vector2.o sfw/core/vector2i.o sfw/core/vector3.o \ sfw/core/vector3i.o sfw/core/vector4.o sfw/core/vector4i.o \ sfw/core/pool_vector.o sfw/core/pool_allocator.o sfw/core/mutex.o sfw/core/stime.o \ - sfw/object/object.o sfw/object/reference.o \ + sfw/object/object.o sfw/object/reference.o sfw/object/core_string_names.o \ + sfw/object/variant.o sfw/object/variant_op.o sfw/object/psignal.o \ + sfw/object/array.o sfw/object/dictionary.o sfw/object/ref_ptr.o \ sfw/render_core/image.o \ sfw/render_core/application.o sfw/render_core/scene.o sfw/render_core/window.o \ sfw/render_core/shader.o sfw/render_core/material.o sfw/render_core/mesh.o \ diff --git a/main.cpp b/main.cpp index 0088989..9fcc169 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include "core/pool_vector.h" #include "core/string_name.h" +#include "object/core_string_names.h" Application *application = NULL; @@ -21,6 +22,7 @@ int main(int argc, char **argv) { //TODO centralize these StringName::setup(); MemoryPool::setup(); + CoreStringNames::create(); AppWindow *w = memnew(AppWindow()); w->create(100, 0); @@ -52,6 +54,7 @@ int main(int argc, char **argv) { StringName::cleanup(); MemoryPool::cleanup(); + CoreStringNames::free(); return 0; } diff --git a/sfw/core/logger.cpp b/sfw/core/logger.cpp index 0ba16d0..673f3f7 100644 --- a/sfw/core/logger.cpp +++ b/sfw/core/logger.cpp @@ -123,6 +123,9 @@ void RLogger::log_msg_error(const char *p_function, const char *p_file, int p_li void RLogger::log_index_error(const char *p_function, const char *p_file, int p_line, const int index, const int size, const char *str) { printf("E (INDEX) | %s::%s:%d | :: index: %d/%d. %s\n", p_file, p_function, p_line, index, size, str); } +void RLogger::log_index_error(const char *p_function, const char *p_file, int p_line, const int index, const int size, const String &str) { + printf("E (INDEX) | %s::%s:%d | :: index: %d/%d. %s\n", p_file, p_function, p_line, index, size, str.utf8().get_data()); +} String *RLogger::get_string_ptr(const int p_default_size) { return memnew(String()); diff --git a/sfw/core/logger.h b/sfw/core/logger.h index c45aa32..40cb856 100644 --- a/sfw/core/logger.h +++ b/sfw/core/logger.h @@ -54,6 +54,7 @@ public: static void log_error(const char *p_function, const char *p_file, int p_line, const String &str); static void log_msg_error(const char *p_function, const char *p_file, int p_line, const char *p_msg, const char *str); static void log_index_error(const char *p_function, const char *p_file, int p_line, const int index, const int size, const char *str); + static void log_index_error(const char *p_function, const char *p_file, int p_line, const int index, const int size, const String &str); static String *get_string_ptr(const int p_default_size = 100); static String *get_string_ptr(const char *p_function, const char *p_file, int p_line, const int p_default_size = 300); diff --git a/sfw/core/og_hash_map.h b/sfw/core/og_hash_map.h new file mode 100644 index 0000000..bb2235b --- /dev/null +++ b/sfw/core/og_hash_map.h @@ -0,0 +1,579 @@ +#ifndef GHASH_MAP_H +#define GHASH_MAP_H + +/*************************************************************************/ +/* og_hash_map.h */ +/* From https://github.com/Relintai/pandemonium_engine (MIT) */ +/*************************************************************************/ + +#include "core/hashfuncs.h" +#include "core/list.h" +#include "core/error_macros.h" +#include "core/math_funcs.h" +#include "core/memory.h" +#include "core/ustring.h" + +/** + * @class OGHashMap + * @author Juan Linietsky + * + * Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key. + * The implementation provides hashers for the default types, if you need a special kind of hasher, provide + * your own. + * @param TKey Key, search is based on it, needs to be hasheable. It is unique in this container. + * @param TData Data, data associated with the key + * @param Hasher Hasher object, needs to provide a valid static hash function for TKey + * @param Comparator comparator object, needs to be able to safely compare two TKey values. It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. + * @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter. + * @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP + * times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER. + * + */ + +template , uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8> +class OGHashMap { +public: + struct Pair { + TKey key; + TData data; + + Pair(const TKey &p_key) : + key(p_key), + data() {} + Pair(const TKey &p_key, const TData &p_data) : + key(p_key), + data(p_data) { + } + }; + + struct Element { + private: + friend class OGHashMap; + + uint32_t hash; + Element *next; + Element() { next = nullptr; } + Pair pair; + + public: + const TKey &key() const { + return pair.key; + } + + TData &value() { + return pair.data; + } + + const TData &value() const { + return pair.data; + } + + TData &get() { + return pair.data; + }; + const TData &get() const { + return pair.data; + }; + + Element(const TKey &p_key) : + pair(p_key) {} + Element(const Element &p_other) : + hash(p_other.hash), + pair(p_other.pair.key, p_other.pair.data) {} + }; + +private: + Element **hash_table; + uint8_t hash_table_power; + uint32_t elements; + + void make_hash_table() { + ERR_FAIL_COND(hash_table); + + hash_table = memnew_arr(Element *, (1 << MIN_HASH_TABLE_POWER)); + + hash_table_power = MIN_HASH_TABLE_POWER; + elements = 0; + for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++) { + hash_table[i] = nullptr; + } + } + + void erase_hash_table() { + ERR_FAIL_COND_MSG(elements, "Cannot erase hash table if there are still elements inside."); + + memdelete_arr(hash_table); + hash_table = nullptr; + hash_table_power = 0; + elements = 0; + } + + void check_hash_table() { + int new_hash_table_power = -1; + + if ((int)elements > ((1 << hash_table_power) * RELATIONSHIP)) { + /* rehash up */ + new_hash_table_power = hash_table_power + 1; + + while ((int)elements > ((1 << new_hash_table_power) * RELATIONSHIP)) { + new_hash_table_power++; + } + + } else if ((hash_table_power > (int)MIN_HASH_TABLE_POWER) && ((int)elements < ((1 << (hash_table_power - 1)) * RELATIONSHIP))) { + /* rehash down */ + new_hash_table_power = hash_table_power - 1; + + while ((int)elements < ((1 << (new_hash_table_power - 1)) * RELATIONSHIP)) { + new_hash_table_power--; + } + + if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER) { + new_hash_table_power = MIN_HASH_TABLE_POWER; + } + } + + if (new_hash_table_power == -1) { + return; + } + + Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power)); + ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory."); + + for (int i = 0; i < (1 << new_hash_table_power); i++) { + new_hash_table[i] = nullptr; + } + + if (hash_table) { + for (int i = 0; i < (1 << hash_table_power); i++) { + while (hash_table[i]) { + Element *se = hash_table[i]; + hash_table[i] = se->next; + int new_pos = se->hash & ((1 << new_hash_table_power) - 1); + se->next = new_hash_table[new_pos]; + new_hash_table[new_pos] = se; + } + } + + memdelete_arr(hash_table); + } + hash_table = new_hash_table; + hash_table_power = new_hash_table_power; + } + + /* I want to have only one function.. */ + _FORCE_INLINE_ const Element *get_element(const TKey &p_key) const { + uint32_t hash = Hasher::hash(p_key); + uint32_t index = hash & ((1 << hash_table_power) - 1); + + Element *e = hash_table[index]; + + while (e) { + /* checking hash first avoids comparing key, which may take longer */ + if (e->hash == hash && Comparator::compare(e->pair.key, p_key)) { + /* the pair exists in this hashtable, so just update data */ + return e; + } + + e = e->next; + } + + return nullptr; + } + + Element *create_element(const TKey &p_key) { + /* if element doesn't exist, create it */ + Element *e = memnew(Element(p_key)); + ERR_FAIL_COND_V_MSG(!e, nullptr, "Out of memory."); + uint32_t hash = Hasher::hash(p_key); + uint32_t index = hash & ((1 << hash_table_power) - 1); + e->next = hash_table[index]; + e->hash = hash; + + hash_table[index] = e; + elements++; + + return e; + } + + void copy_from(const OGHashMap &p_t) { + if (&p_t == this) { + return; /* much less bother with that */ + } + + clear(); + + if (!p_t.hash_table || p_t.hash_table_power == 0) { + return; /* not copying from empty table */ + } + + hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power); + hash_table_power = p_t.hash_table_power; + elements = p_t.elements; + + for (int i = 0; i < (1 << p_t.hash_table_power); i++) { + hash_table[i] = nullptr; + + const Element *e = p_t.hash_table[i]; + + while (e) { + Element *le = memnew(Element(*e)); /* local element */ + + /* add to list and reassign pointers */ + le->next = hash_table[i]; + hash_table[i] = le; + + e = e->next; + } + } + } + +public: + Element *set(const TKey &p_key, const TData &p_data) { + return set(Pair(p_key, p_data)); + } + + Element *set(const Pair &p_pair) { + Element *e = nullptr; + if (!hash_table) { + make_hash_table(); // if no table, make one + } else { + e = const_cast(get_element(p_pair.key)); + } + + /* if we made it up to here, the pair doesn't exist, create and assign */ + + if (!e) { + e = create_element(p_pair.key); + if (!e) { + return nullptr; + } + check_hash_table(); // perform mantenience routine + } + + e->pair.data = p_pair.data; + return e; + } + + bool has(const TKey &p_key) const { + return getptr(p_key) != nullptr; + } + + /** + * Get a key from data, return a const reference. + * WARNING: this doesn't check errors, use either getptr and check NULL, or check + * first with has(key) + */ + + const TData &get(const TKey &p_key) const { + const TData *res = getptr(p_key); + CRASH_COND_MSG(!res, "Map key not found."); + return *res; + } + + TData &get(const TKey &p_key) { + TData *res = getptr(p_key); + CRASH_COND_MSG(!res, "Map key not found."); + return *res; + } + + /** + * Same as get, except it can return NULL when item was not found. + * This is mainly used for speed purposes. + */ + + _FORCE_INLINE_ TData *getptr(const TKey &p_key) { + if (unlikely(!hash_table)) { + return nullptr; + } + + Element *e = const_cast(get_element(p_key)); + + if (e) { + return &e->pair.data; + } + + return nullptr; + } + + _FORCE_INLINE_ const TData *getptr(const TKey &p_key) const { + if (unlikely(!hash_table)) { + return nullptr; + } + + const Element *e = const_cast(get_element(p_key)); + + if (e) { + return &e->pair.data; + } + + return nullptr; + } + + const Element *find(const TKey &p_key) const { + if (unlikely(!hash_table)) { + return nullptr; + } + + const Element *e = const_cast(get_element(p_key)); + + return e; + } + + Element *find(const TKey &p_key) { + if (unlikely(!hash_table)) { + return nullptr; + } + + Element *e = const_cast(get_element(p_key)); + + return e; + } + + /** + * Same as get, except it can return NULL when item was not found. + * This version is custom, will take a hash and a custom key (that should support operator==() + */ + + template + _FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) { + if (unlikely(!hash_table)) { + return nullptr; + } + + uint32_t hash = p_custom_hash; + uint32_t index = hash & ((1 << hash_table_power) - 1); + + Element *e = hash_table[index]; + + while (e) { + /* checking hash first avoids comparing key, which may take longer */ + if (e->hash == hash && Comparator::compare(e->pair.key, p_custom_key)) { + /* the pair exists in this hashtable, so just update data */ + return &e->pair.data; + } + + e = e->next; + } + + return nullptr; + } + + template + _FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const { + if (unlikely(!hash_table)) { + return NULL; + } + + uint32_t hash = p_custom_hash; + uint32_t index = hash & ((1 << hash_table_power) - 1); + + const Element *e = hash_table[index]; + + while (e) { + /* checking hash first avoids comparing key, which may take longer */ + if (e->hash == hash && Comparator::compare(e->pair.key, p_custom_key)) { + /* the pair exists in this hashtable, so just update data */ + return &e->pair.data; + } + + e = e->next; + } + + return NULL; + } + + /** + * Erase an item, return true if erasing was successful + */ + + bool erase(const TKey &p_key) { + if (unlikely(!hash_table)) { + return false; + } + + uint32_t hash = Hasher::hash(p_key); + uint32_t index = hash & ((1 << hash_table_power) - 1); + + Element *e = hash_table[index]; + Element *p = nullptr; + while (e) { + /* checking hash first avoids comparing key, which may take longer */ + if (e->hash == hash && Comparator::compare(e->pair.key, p_key)) { + if (p) { + p->next = e->next; + } else { + //begin of list + hash_table[index] = e->next; + } + + memdelete(e); + elements--; + + if (elements == 0) { + erase_hash_table(); + } else { + check_hash_table(); + } + return true; + } + + p = e; + e = e->next; + } + + return false; + } + + inline const TData &operator[](const TKey &p_key) const { //constref + + return get(p_key); + } + inline TData &operator[](const TKey &p_key) { //assignment + + Element *e = nullptr; + if (!hash_table) { + make_hash_table(); // if no table, make one + } else { + e = const_cast(get_element(p_key)); + } + + /* if we made it up to here, the pair doesn't exist, create */ + if (!e) { + e = create_element(p_key); + CRASH_COND(!e); + check_hash_table(); // perform mantenience routine + } + + return e->pair.data; + } + + /** + * Get the next key to p_key, and the first key if p_key is null. + * Returns a pointer to the next key if found, NULL otherwise. + * Adding/Removing elements while iterating will, of course, have unexpected results, don't do it. + * + * Example: + * + * const TKey *k=NULL; + * + * while( (k=table.next(k)) ) { + * + * print( *k ); + * } + * + */ + const TKey *next(const TKey *p_key) const { + if (unlikely(!hash_table)) { + return nullptr; + } + + if (!p_key) { /* get the first key */ + + for (int i = 0; i < (1 << hash_table_power); i++) { + if (hash_table[i]) { + return &hash_table[i]->pair.key; + } + } + + } else { /* get the next key */ + + const Element *e = get_element(*p_key); + ERR_FAIL_COND_V_MSG(!e, nullptr, "Invalid key supplied."); + if (e->next) { + /* if there is a "next" in the list, return that */ + return &e->next->pair.key; + } else { + /* go to next elements */ + uint32_t index = e->hash & ((1 << hash_table_power) - 1); + index++; + for (int i = index; i < (1 << hash_table_power); i++) { + if (hash_table[i]) { + return &hash_table[i]->pair.key; + } + } + } + + /* nothing found, was at end */ + } + + return nullptr; /* nothing found */ + } + + inline unsigned int size() const { + return elements; + } + + inline bool empty() const { + return elements == 0; + } + + void clear() { + /* clean up */ + if (hash_table) { + for (int i = 0; i < (1 << hash_table_power); i++) { + while (hash_table[i]) { + Element *e = hash_table[i]; + hash_table[i] = e->next; + memdelete(e); + } + } + + memdelete_arr(hash_table); + } + + hash_table = nullptr; + hash_table_power = 0; + elements = 0; + } + + void operator=(const OGHashMap &p_table) { + copy_from(p_table); + } + + OGHashMap() { + hash_table = nullptr; + elements = 0; + hash_table_power = 0; + } + + void get_key_value_ptr_array(const Pair **p_pairs) const { + if (unlikely(!hash_table)) { + return; + } + for (int i = 0; i < (1 << hash_table_power); i++) { + Element *e = hash_table[i]; + while (e) { + *p_pairs = &e->pair; + p_pairs++; + e = e->next; + } + } + } + + void get_key_list(List *p_keys) const { + if (unlikely(!hash_table)) { + return; + } + for (int i = 0; i < (1 << hash_table_power); i++) { + Element *e = hash_table[i]; + while (e) { + p_keys->push_back(e->pair.key); + e = e->next; + } + } + } + + OGHashMap(const OGHashMap &p_table) { + hash_table = nullptr; + elements = 0; + hash_table_power = 0; + + copy_from(p_table); + } + + ~OGHashMap() { + clear(); + } +}; + +#endif diff --git a/sfw/core/old/old/string.h b/sfw/core/old/old/string.h index 680c54f..a0294b9 100644 --- a/sfw/core/old/old/string.h +++ b/sfw/core/old/old/string.h @@ -5,7 +5,7 @@ #include -#include "core/containers/vector.h" +#include "core/vector.h" #ifndef DEFAULT_DIRECTORY_SEPARATOR #define DEFAULT_DIRECTORY_SEPARATOR '/' diff --git a/sfw/core/ordered_hash_map.h b/sfw/core/ordered_hash_map.h new file mode 100644 index 0000000..b75c39d --- /dev/null +++ b/sfw/core/ordered_hash_map.h @@ -0,0 +1,285 @@ +#ifndef ORDERED_HASH_MAP_H +#define ORDERED_HASH_MAP_H + +/*************************************************************************/ +/* ordered_hash_map.h */ +/* From https://github.com/Relintai/pandemonium_engine (MIT) */ +/*************************************************************************/ + +#include "core/list.h" +#include "core/og_hash_map.h" +#include "core/pair.h" + +/** + * A hash map which allows to iterate elements in insertion order. + * Insertion, lookup, deletion have O(1) complexity. + * The API aims to be consistent with Map rather than HashMap, because the + * former is more frequently used and is more coherent with the rest of the + * codebase. + * Deletion during iteration is safe and will preserve the order. + */ +template , uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8> +class OrderedHashMap { + typedef List> InternalList; + typedef OGHashMap InternalMap; + + InternalList list; + InternalMap map; + +public: + class Element { + friend class OrderedHashMap; + + typename InternalList::Element *list_element; + typename InternalList::Element *prev_element; + typename InternalList::Element *next_element; + + Element(typename InternalList::Element *p_element) { + list_element = p_element; + + if (list_element) { + next_element = list_element->next(); + prev_element = list_element->prev(); + } + } + + public: + _FORCE_INLINE_ Element() : + list_element(nullptr), + prev_element(nullptr), + next_element(nullptr) { + } + + Element next() const { + return Element(next_element); + } + + Element prev() const { + return Element(prev_element); + } + + Element(const Element &other) : + list_element(other.list_element), + prev_element(other.prev_element), + next_element(other.next_element) { + } + + Element &operator=(const Element &other) { + list_element = other.list_element; + next_element = other.next_element; + prev_element = other.prev_element; + return *this; + } + + _FORCE_INLINE_ bool operator==(const Element &p_other) const { + return this->list_element == p_other.list_element; + } + _FORCE_INLINE_ bool operator!=(const Element &p_other) const { + return this->list_element != p_other.list_element; + } + + operator bool() const { + return (list_element != nullptr); + } + + const K &key() const { + CRASH_COND(!list_element); + return *(list_element->get().first); + }; + + V &value() { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + const V &value() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + V &get() { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + const V &get() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + }; + + class ConstElement { + friend class OrderedHashMap; + + const typename InternalList::Element *list_element; + + ConstElement(const typename InternalList::Element *p_element) : + list_element(p_element) { + } + + public: + _FORCE_INLINE_ ConstElement() : + list_element(NULL) { + } + + ConstElement(const ConstElement &other) : + list_element(other.list_element) { + } + + ConstElement &operator=(const ConstElement &other) { + list_element = other.list_element; + return *this; + } + + ConstElement next() const { + return ConstElement(list_element ? list_element->next() : nullptr); + } + + ConstElement prev() const { + return ConstElement(list_element ? list_element->prev() : NULL); + } + + _FORCE_INLINE_ bool operator==(const ConstElement &p_other) const { + return this->list_element == p_other.list_element; + } + _FORCE_INLINE_ bool operator!=(const ConstElement &p_other) const { + return this->list_element != p_other.list_element; + } + + operator bool() const { + return (list_element != nullptr); + } + + const K &key() const { + CRASH_COND(!list_element); + return *(list_element->get().first); + }; + + const V &value() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + const V &get() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + }; + + ConstElement find(const K &p_key) const { + typename InternalList::Element *const *list_element = map.getptr(p_key); + if (list_element) { + return ConstElement(*list_element); + } + return ConstElement(nullptr); + } + + Element find(const K &p_key) { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + return Element(*list_element); + } + return Element(nullptr); + } + + Element insert(const K &p_key, const V &p_value) { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + (*list_element)->get().second = p_value; + return Element(*list_element); + } + // Incorrectly set the first value of the pair with a value that will + // be invalid as soon as we leave this function... + typename InternalList::Element *new_element = list.push_back(Pair(&p_key, p_value)); + // ...this is needed here in case the hashmap recursively reference itself... + typename InternalMap::Element *e = map.set(p_key, new_element); + // ...now we can set the right value ! + new_element->get().first = &e->key(); + + return Element(new_element); + } + + void erase(Element &p_element) { + map.erase(p_element.key()); + list.erase(p_element.list_element); + p_element.list_element = nullptr; + } + + bool erase(const K &p_key) { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + list.erase(*list_element); + map.erase(p_key); + return true; + } + return false; + } + + inline bool has(const K &p_key) const { + return map.has(p_key); + } + + const V &operator[](const K &p_key) const { + ConstElement e = find(p_key); + CRASH_COND(!e); + return e.value(); + } + + V &operator[](const K &p_key) { + Element e = find(p_key); + if (!e) { + // consistent with Map behaviour + e = insert(p_key, V()); + } + return e.value(); + } + + inline Element front() { + return Element(list.front()); + } + + inline Element back() { + return Element(list.back()); + } + + inline ConstElement front() const { + return ConstElement(list.front()); + } + + inline ConstElement back() const { + return ConstElement(list.back()); + } + + inline bool empty() const { return list.empty(); } + inline int size() const { return list.size(); } + + const void *id() const { + return list.id(); + } + + void clear() { + map.clear(); + list.clear(); + } + +private: + void _copy_from(const OrderedHashMap &p_map) { + for (ConstElement E = p_map.front(); E; E = E.next()) { + insert(E.key(), E.value()); + } + } + +public: + void operator=(const OrderedHashMap &p_map) { + _copy_from(p_map); + } + + OrderedHashMap(const OrderedHashMap &p_map) { + _copy_from(p_map); + } + + _FORCE_INLINE_ OrderedHashMap() { + } +}; + +#endif // ORDERED_HASH_MAP_H diff --git a/sfw/core/ustring.cpp b/sfw/core/ustring.cpp index d6a72ad..65c74ca 100644 --- a/sfw/core/ustring.cpp +++ b/sfw/core/ustring.cpp @@ -1872,7 +1872,7 @@ String String::sprintf(const Array &values, bool *error) const { } else { if (c == '0' && min_chars == 0) { if (left_justified) { - WARN_PRINT("'0' flag ignored with '-' flag in string format"); + LOG_WARN("'0' flag ignored with '-' flag in string format"); } else { pad_with_zeros = true; } diff --git a/sfw/object/array.cpp b/sfw/object/array.cpp index 7408e09..6de4828 100644 --- a/sfw/object/array.cpp +++ b/sfw/object/array.cpp @@ -288,24 +288,16 @@ Array &Array::sort() { struct _ArrayVariantSortCustom { Object *obj; - StringName func; _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { - const Variant *args[2] = { &p_l, &p_r }; - Variant::CallError err; - bool res = obj->call(func, args, 2, err); - if (err.error != Variant::CallError::CALL_OK) { - res = false; - } - return res; + return obj->lt(p_l, p_r); } }; -Array &Array::sort_custom(Object *p_obj, const StringName &p_function) { - ERR_FAIL_NULL_V(p_obj, *this); +Array &Array::sort_custom(Object *p_obj) { + ERR_FAIL_COND_V(!p_obj, *this); SortArray avs; avs.compare.obj = p_obj; - avs.compare.func = p_function; avs.sort(_p->array.ptrw(), _p->array.size()); return *this; } @@ -355,11 +347,10 @@ int Array::bsearch(const Variant &p_value, bool p_before) { } int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { - ERR_FAIL_NULL_V(p_obj, 0); + ERR_FAIL_COND_V(!p_obj, 0); _ArrayVariantSortCustom less; less.obj = p_obj; - less.func = p_function; return bisect(_p->array, p_value, p_before, less); } diff --git a/sfw/object/array.h b/sfw/object/array.h index 720e31a..bc298fd 100644 --- a/sfw/object/array.h +++ b/sfw/object/array.h @@ -51,7 +51,7 @@ public: Variant back() const; Array &sort(); - Array &sort_custom(Object *p_obj, const StringName &p_function); + Array &sort_custom(Object *p_obj); void shuffle(); int bsearch(const Variant &p_value, bool p_before = true); int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true); diff --git a/sfw/object/core_string_names.cpp b/sfw/object/core_string_names.cpp new file mode 100644 index 0000000..2741fee --- /dev/null +++ b/sfw/object/core_string_names.cpp @@ -0,0 +1,49 @@ +/*************************************************************************/ +/* core_string_names.cpp */ +/* From https://github.com/Relintai/pandemonium_engine (MIT) */ +/*************************************************************************/ + +#include "core_string_names.h" + +CoreStringNames *CoreStringNames::singleton = nullptr; + +CoreStringNames::CoreStringNames() : + _free(StaticCString::create("free")), + changed(StaticCString::create("changed")), + _meta(StaticCString::create("__meta__")), + _script(StaticCString::create("script")), + script_changed(StaticCString::create("script_changed")), + ___pdcdata(StaticCString::create("___pdcdata")), + __getvar(StaticCString::create("__getvar")), + _iter_init(StaticCString::create("_iter_init")), + _iter_next(StaticCString::create("_iter_next")), + _iter_get(StaticCString::create("_iter_get")), + get_rid(StaticCString::create("get_rid")), + _to_string(StaticCString::create("_to_string")), +#ifdef TOOLS_ENABLED + _sections_unfolded(StaticCString::create("_sections_unfolded")), +#endif + _custom_features(StaticCString::create("_custom_features")), + x(StaticCString::create("x")), + y(StaticCString::create("y")), + z(StaticCString::create("z")), + w(StaticCString::create("w")), + r(StaticCString::create("r")), + g(StaticCString::create("g")), + b(StaticCString::create("b")), + a(StaticCString::create("a")), + position(StaticCString::create("position")), + size(StaticCString::create("size")), + end(StaticCString::create("end")), + basis(StaticCString::create("basis")), + origin(StaticCString::create("origin")), + normal(StaticCString::create("normal")), + d(StaticCString::create("d")), + h(StaticCString::create("h")), + s(StaticCString::create("s")), + v(StaticCString::create("v")), + r8(StaticCString::create("r8")), + g8(StaticCString::create("g8")), + b8(StaticCString::create("b8")), + a8(StaticCString::create("a8")) { +} diff --git a/sfw/object/core_string_names.h b/sfw/object/core_string_names.h new file mode 100644 index 0000000..a55d5e4 --- /dev/null +++ b/sfw/object/core_string_names.h @@ -0,0 +1,66 @@ +#ifndef CORE_STRING_NAMES_H +#define CORE_STRING_NAMES_H + +/*************************************************************************/ +/* core_string_names.h */ +/* From https://github.com/Relintai/pandemonium_engine (MIT) */ +/*************************************************************************/ + +#include "core/string_name.h" + +class CoreStringNames { +public: + static void create() { singleton = memnew(CoreStringNames); } + static void free() { + memdelete(singleton); + singleton = nullptr; + } + + CoreStringNames(); + + _FORCE_INLINE_ static CoreStringNames *get_singleton() { return singleton; } + + static CoreStringNames *singleton; + + StringName _free; + StringName changed; + StringName _meta; + StringName _script; + StringName script_changed; + StringName ___pdcdata; + StringName __getvar; + StringName _iter_init; + StringName _iter_next; + StringName _iter_get; + StringName get_rid; + StringName _to_string; +#ifdef TOOLS_ENABLED + StringName _sections_unfolded; +#endif + StringName _custom_features; + + StringName x; + StringName y; + StringName z; + StringName w; + StringName r; + StringName g; + StringName b; + StringName a; + StringName position; + StringName size; + StringName end; + StringName basis; + StringName origin; + StringName normal; + StringName d; + StringName h; + StringName s; + StringName v; + StringName r8; + StringName g8; + StringName b8; + StringName a8; +}; + +#endif // SCENE_STRING_NAMES_H diff --git a/sfw/object/dictionary.cpp b/sfw/object/dictionary.cpp index dc2e92c..8a7e84c 100644 --- a/sfw/object/dictionary.cpp +++ b/sfw/object/dictionary.cpp @@ -5,9 +5,10 @@ #include "dictionary.h" -#include "core/containers/ordered_hash_map.h" -#include "core/os/safe_refcount.h" -#include "core/variant/variant.h" +#include "core/ordered_hash_map.h" +#include "core/safe_refcount.h" + +#include "object/variant.h" struct DictionaryPrivate { SafeRefCount refcount; diff --git a/sfw/object/object.cpp b/sfw/object/object.cpp index 3c4bb0e..44459e1 100644 --- a/sfw/object/object.cpp +++ b/sfw/object/object.cpp @@ -2,8 +2,65 @@ #include "core/error_macros.h" #include "core/logger.h" +#include "object/core_string_names.h" #include "object/object_rc.h" +void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid) { + if (p_name == CoreStringNames::get_singleton()->_meta) { + //set_meta(p_name,p_value); + metadata = p_value.duplicate(); + if (r_valid) { + *r_valid = true; + } + return; + } + + //something inside the object... :| + bool success = _setv(p_name, p_value); + if (success) { + if (r_valid) { + *r_valid = true; + } + return; + } + + if (r_valid) { + *r_valid = false; + } +} + +Variant Object::get(const StringName &p_name, bool *r_valid) const { + Variant ret; + + if (p_name == CoreStringNames::get_singleton()->_meta) { + ret = metadata; + if (r_valid) { + *r_valid = true; + } + return ret; + + } else { + //something inside the object... :| + bool success = _getv(p_name, ret); + if (success) { + if (r_valid) { + *r_valid = true; + } + return ret; + } + + if (r_valid) { + *r_valid = false; + } + + return Variant(); + } +} + +bool Object::lt(const Variant &p_value_l, const Variant &p_value_r) { + return p_value_l < p_value_r; +} + void Object::notification(int p_notification, bool p_reversed) { _notificationv(p_notification, p_reversed); } @@ -26,7 +83,6 @@ void Object::_postinitialize() { notification(NOTIFICATION_POSTINITIALIZE); } -/* bool Object::has_meta(const String &p_name) const { return metadata.has(p_name); } @@ -50,7 +106,6 @@ Variant Object::get_meta(const String &p_name, const Variant &p_default) const { void Object::remove_meta(const String &p_name) { metadata.erase(p_name); } -*/ void Object::cancel_free() { _predelete_ok = 0; diff --git a/sfw/object/object.h b/sfw/object/object.h index 59719f5..1badc0d 100644 --- a/sfw/object/object.h +++ b/sfw/object/object.h @@ -7,8 +7,9 @@ #include "core/ustring.h" #include "core/vector.h" #include "object/object_id.h" +#include "object/variant.h" -//#include "object/dictionary.h" +#include "object/dictionary.h" /*************************************************************************/ /* object.h */ @@ -17,61 +18,82 @@ class ObjectRC; -#define SFW_OBJECT(m_class, m_inherits) \ -private: \ - void operator=(const m_class &p_rval) {} \ - \ -public: \ - virtual String get_class() const override { \ - return String(#m_class); \ - } \ - virtual const StringName *_get_class_namev() const { \ - if (!_class_name) \ - _class_name = get_class_static(); \ - return &_class_name; \ - } \ - static void *get_class_ptr_static() { \ - static int ptr; \ - return &ptr; \ - } \ - static String get_class_static() { \ - return String(#m_class); \ - } \ - static String get_parent_class_static() { \ - return m_inherits::get_class_static(); \ - } \ - static void get_inheritance_list_static(Vector *p_inheritance_list) { \ - m_inherits::get_inheritance_list_static(p_inheritance_list); \ - p_inheritance_list->push_back(String(#m_class)); \ - } \ - static String inherits_static() { \ - return String(#m_inherits); \ - } \ - virtual bool is_class(const String &p_class) const override { \ - return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); \ - } \ - virtual bool is_class_ptr(void *p_ptr) const override { \ - return (p_ptr == get_class_ptr_static()) ? true : m_inherits::is_class_ptr(p_ptr); \ - } \ - static void get_valid_parents_static(Vector *p_parents) { \ - if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \ - m_class::_get_valid_parents_static(p_parents); \ - } \ - m_inherits::get_valid_parents_static(p_parents); \ - } \ - _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \ - return (void(Object::*)(int)) & m_class::_notification; \ - } \ - virtual void _notificationv(int p_notification, bool p_reversed) { \ - if (!p_reversed) \ - m_inherits::_notificationv(p_notification, p_reversed); \ - if (m_class::_get_notification() != m_inherits::_get_notification()) { \ - _notification(p_notification); \ - } \ - if (p_reversed) \ - m_inherits::_notificationv(p_notification, p_reversed); \ - } \ - \ +#define SFW_OBJECT(m_class, m_inherits) \ +private: \ + void operator=(const m_class &p_rval) {} \ + \ +public: \ + virtual String get_class() const override { \ + return String(#m_class); \ + } \ + virtual const StringName *_get_class_namev() const { \ + if (!_class_name) \ + _class_name = get_class_static(); \ + return &_class_name; \ + } \ + static void *get_class_ptr_static() { \ + static int ptr; \ + return &ptr; \ + } \ + static String get_class_static() { \ + return String(#m_class); \ + } \ + static String get_parent_class_static() { \ + return m_inherits::get_class_static(); \ + } \ + static void get_inheritance_list_static(Vector *p_inheritance_list) { \ + m_inherits::get_inheritance_list_static(p_inheritance_list); \ + p_inheritance_list->push_back(String(#m_class)); \ + } \ + static String inherits_static() { \ + return String(#m_inherits); \ + } \ + virtual bool is_class(const String &p_class) const override { \ + return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); \ + } \ + virtual bool is_class_ptr(void *p_ptr) const override { \ + return (p_ptr == get_class_ptr_static()) ? true : m_inherits::is_class_ptr(p_ptr); \ + } \ + static void get_valid_parents_static(Vector *p_parents) { \ + if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \ + m_class::_get_valid_parents_static(p_parents); \ + } \ + m_inherits::get_valid_parents_static(p_parents); \ + } \ + _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \ + return (void(Object::*)(int)) & m_class::_notification; \ + } \ + virtual void _notificationv(int p_notification, bool p_reversed) { \ + if (!p_reversed) \ + m_inherits::_notificationv(p_notification, p_reversed); \ + if (m_class::_get_notification() != m_inherits::_get_notification()) { \ + _notification(p_notification); \ + } \ + if (p_reversed) \ + m_inherits::_notificationv(p_notification, p_reversed); \ + } \ + _FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &) const { \ + return (bool(Object::*)(const StringName &, Variant &) const) & m_class::_get; \ + } \ + virtual bool _getv(const StringName &p_name, Variant &r_ret) const { \ + if (m_class::_get_get() != m_inherits::_get_get()) { \ + if (_get(p_name, r_ret)) \ + return true; \ + } \ + return m_inherits::_getv(p_name, r_ret); \ + } \ + _FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) { \ + return (bool(Object::*)(const StringName &, const Variant &)) & m_class::_set; \ + } \ + virtual bool _setv(const StringName &p_name, const Variant &p_property) { \ + if (m_inherits::_setv(p_name, p_property)) \ + return true; \ + if (m_class::_get_set() != m_inherits::_get_set()) { \ + return _set(p_name, p_property); \ + } \ + return false; \ + } \ + \ private: class Object { @@ -81,6 +103,12 @@ public: NOTIFICATION_PREDELETE = 1 }; + void set(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr); + Variant get(const StringName &p_name, bool *r_valid = nullptr) const; + + //less than. < "operator" used for cutrom sorting Arrays. + virtual bool lt(const Variant &p_value_l, const Variant &p_value_r); + virtual String get_class() const { return "Object"; } static void *get_class_ptr_static() { static int ptr; @@ -129,13 +157,11 @@ public: void cancel_free(); - /* bool has_meta(const String &p_name) const; void set_meta(const String &p_name, const Variant &p_value); void remove_meta(const String &p_name); Variant get_meta(const String &p_name, const Variant &p_default = Variant()) const; void get_meta_list(List *p_list) const; - */ Object(); virtual ~Object(); @@ -165,6 +191,27 @@ protected: return &Object::_notification; } + bool _set(const StringName &p_name, const Variant &p_property) { + return false; + }; + bool _get(const StringName &p_name, Variant &r_property) const { + return false; + }; + + virtual bool _setv(const StringName &p_name, const Variant &p_property) { + return false; + }; + virtual bool _getv(const StringName &p_name, Variant &r_property) const { + return false; + }; + + _FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &r_ret) const { + return &Object::_get; + } + _FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) { + return &Object::_set; + } + virtual void _notificationv(int p_notification, bool p_reversed){}; void _notification(int p_notification){}; @@ -181,7 +228,7 @@ protected: ObjectID _instance_id; std::atomic _rc; - //Dictionary metadata; + Dictionary metadata; }; bool predelete_handler(Object *p_object); diff --git a/sfw/object/psignal.cpp b/sfw/object/psignal.cpp index d0f294c..aa8307c 100644 --- a/sfw/object/psignal.cpp +++ b/sfw/object/psignal.cpp @@ -1,4 +1,4 @@ -#include "signal.h" +#include "psignal.h" void Signal::connect_static(void (*func)(Signal *)) { StaticSignalEntry *se = new StaticSignalEntry(); @@ -14,7 +14,7 @@ void Signal::disconnect_static(void (*func)(Signal *)) { StaticSignalEntry *se = static_cast(e); if (se->func == func) { - entries.remove_keep_order(i); + entries.remove(i); return; } } diff --git a/sfw/object/psignal.h b/sfw/object/psignal.h index 7845c06..22bf01b 100644 --- a/sfw/object/psignal.h +++ b/sfw/object/psignal.h @@ -1,10 +1,10 @@ #ifndef SIGNAL_H #define SIGNAL_H -#include "core/containers/vector.h" -#include "core/string.h" -#include "core/variant.h" +#include "core/vector.h" +#include "core/ustring.h" +#include "object/variant.h" #include "object/reference.h" class Signal { @@ -138,7 +138,7 @@ void Signal::disconnect(T *obj, void (*func)(T*, Signal *)) { ClassSignalEntry *se = static_cast(e); if (se->get_obj_ptr() == obj_ptr && se->get_func_ptr() == func_ptr) { - entries.remove_keep_order(i); + entries.remove(i); return; } } diff --git a/sfw/object/ref_ptr.cpp b/sfw/object/ref_ptr.cpp index 0ea1e21..a5c3dff 100644 --- a/sfw/object/ref_ptr.cpp +++ b/sfw/object/ref_ptr.cpp @@ -69,18 +69,6 @@ bool RefPtr::is_null() const { return ref->is_null(); } -RID RefPtr::get_rid() const { - Ref *ref = reinterpret_cast *>(&data[0]); - if (ref->is_null()) { - return RID(); - } - Resource *res = Object::cast_to(ref->ptr()); - if (res) { - return res->get_rid(); - } - return RID(); -} - void RefPtr::unref() { Ref *ref = reinterpret_cast *>(&data[0]); ref->unref(); diff --git a/sfw/object/variant.cpp b/sfw/object/variant.cpp index c4a9063..0beefd6 100644 --- a/sfw/object/variant.cpp +++ b/sfw/object/variant.cpp @@ -10,10 +10,11 @@ #include "core/math_funcs.h" +#include "object/core_string_names.h" +#include "object/object.h" #include "object/object_rc.h" #include "object/resource.h" - String Variant::get_type_name(Variant::Type p_type) { switch (p_type) { case NIL: { @@ -88,12 +89,6 @@ String Variant::get_type_name(Variant::Type p_type) { case COLOR: { return "Color"; } break; - case NODE_PATH: { - return "NodePath"; - } break; - case RID: { - return "RID"; - } break; case OBJECT: { return "Object"; } break; @@ -328,22 +323,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { valid_types = valid; } break; - case NODE_PATH: { - static const Type valid[] = { - STRING, - NIL - }; - - valid_types = valid; - } break; - case RID: { - static const Type valid[] = { - OBJECT, - NIL - }; - - valid_types = valid; - } break; case OBJECT: { static const Type valid[] = { NIL @@ -539,7 +518,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type } break; case STRING: { static const Type valid[] = { - NODE_PATH, STRING_NAME, NIL }; @@ -668,22 +646,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type valid_types = valid; } break; - case NODE_PATH: { - static const Type valid[] = { - STRING, - NIL - }; - - valid_types = valid; - } break; - case RID: { - static const Type valid[] = { - OBJECT, - NIL - }; - - valid_types = valid; - } break; case OBJECT: { static const Type valid[] = { NIL @@ -958,12 +920,6 @@ bool Variant::is_zero() const { case COLOR: { return *reinterpret_cast(_data._mem) == Color(); } break; - case NODE_PATH: { - return reinterpret_cast(_data._mem)->is_empty(); - } break; - case RID: { - return *reinterpret_cast(_data._mem) == ::RID(); - } break; case OBJECT: { return _UNSAFE_OBJ_PROXY_PTR(*this) == nullptr; } break; @@ -1173,12 +1129,6 @@ void Variant::reference(const Variant &p_variant) { case COLOR: { memnew_placement(_data._mem, Color(*reinterpret_cast(p_variant._data._mem))); } break; - case NODE_PATH: { - memnew_placement(_data._mem, NodePath(*reinterpret_cast(p_variant._data._mem))); - } break; - case RID: { - memnew_placement(_data._mem, ::RID(*reinterpret_cast(p_variant._data._mem))); - } break; case OBJECT: { memnew_placement(_data._mem, ObjData(p_variant._get_obj())); if (likely(_get_obj().rc)) { @@ -1334,13 +1284,6 @@ void Variant::clear() { //COLOR // misc types - case NODE_PATH: { - reinterpret_cast(_data._mem)->~NodePath(); - } break; - case RID: { - // not much need probably - reinterpret_cast<::RID *>(_data._mem)->~RID(); - } break; case OBJECT: { if (likely(_get_obj().rc)) { if (unlikely(_get_obj().rc->decrement())) { @@ -1645,8 +1588,6 @@ Variant::operator double() const { Variant::operator StringName() const { if (type == STRING_NAME) { return *reinterpret_cast(_data._mem); - } else if (type == NODE_PATH) { - return reinterpret_cast(_data._mem)->get_sname(); } return StringName(operator String()); @@ -1726,9 +1667,6 @@ String Variant::stringify(List &stack) const { return operator Projection(); case COLOR: return operator Color(); - case NODE_PATH: - return operator NodePath(); - //RID case OBJECT: { Object *obj = _OBJ_PTR(*this); if (likely(obj)) { @@ -2077,16 +2015,6 @@ Variant::operator Color() const { } } -Variant::operator NodePath() const { - if (type == NODE_PATH) { - return *reinterpret_cast(_data._mem); - } else if (type == STRING) { - return NodePath(operator String()); - } else { - return NodePath(); - } -} - Variant::operator RefPtr() const { if (type == OBJECT) { return _get_obj().ref; @@ -2095,33 +2023,6 @@ Variant::operator RefPtr() const { } } -Variant::operator ::RID() const { - if (type == RID) { - return *reinterpret_cast(_data._mem); - } else if (type == OBJECT) { - if (!_get_obj().ref.is_null()) { - return _get_obj().ref.get_rid(); - } else { - Object *obj = likely(_get_obj().rc) ? _get_obj().rc->get_ptr() : nullptr; - if (unlikely(!obj)) { - if (_get_obj().rc) { - ERR_PRINT("Attempted get RID on a deleted object."); - } - return ::RID(); - } - Variant::CallError ce; - Variant ret = obj->call(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); - if (ce.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::RID) { - return ret; - } else { - return ::RID(); - } - } - } else { - return ::RID(); - } -} - Variant::operator Object *() const { if (type == OBJECT) { return _OBJ_PTR(*this); @@ -2129,28 +2030,6 @@ Variant::operator Object *() const { return nullptr; } } -Variant::operator Node *() const { - if (type == OBJECT) { - Object *obj = _get_obj().rc ? _get_obj().rc->get_ptr() : nullptr; - return Object::cast_to(obj); - } - return nullptr; -} -Variant::operator Control *() const { - if (type == OBJECT) { - Object *obj = _get_obj().rc ? _get_obj().rc->get_ptr() : nullptr; - return Object::cast_to(obj); - } - return nullptr; -} - -Variant::operator Dictionary() const { - if (type == DICTIONARY) { - return *reinterpret_cast(_data._mem); - } else { - return Dictionary(); - } -} template inline DA _convert_array(const SA &p_array) { @@ -2209,6 +2088,15 @@ inline DA _convert_array_from_variant(const Variant &p_variant) { } } +Variant::operator Dictionary() const { + if (type == DICTIONARY) { + return *reinterpret_cast(_data._mem); + } else { + return Dictionary(); + } +} + + Variant::operator Array() const { if (type == ARRAY) { return *reinterpret_cast(_data._mem); @@ -2298,16 +2186,6 @@ Variant::operator PoolVector() const { /* helpers */ -Variant::operator Vector<::RID>() const { - Array va = operator Array(); - Vector<::RID> rids; - rids.resize(va.size()); - for (int i = 0; i < rids.size(); i++) { - rids.write[i] = va[i]; - } - return rids; -} - Variant::operator PoolVector() const { Array va = operator Array(); PoolVector planes; @@ -2544,17 +2422,6 @@ Variant::operator Orientation() const { return (Orientation) operator int(); } -Variant::operator IP_Address() const { - if (type == POOL_REAL_ARRAY || type == POOL_INT_ARRAY || type == POOL_BYTE_ARRAY) { - PoolVector addr = operator PoolVector(); - if (addr.size() == 4) { - return IP_Address(addr.get(0), addr.get(1), addr.get(2), addr.get(3)); - } - } - - return IP_Address(operator String()); -} - Variant::Variant(bool p_bool) { type = BOOL; _data._bool = p_bool; @@ -2717,11 +2584,6 @@ Variant::Variant(const Color &p_color) { memnew_placement(_data._mem, Color(p_color)); } -Variant::Variant(const NodePath &p_node_path) { - type = NODE_PATH; - memnew_placement(_data._mem, NodePath(p_node_path)); -} - Variant::Variant(const RefPtr &p_resource) { type = OBJECT; memnew_placement(_data._mem, ObjData); @@ -2729,11 +2591,6 @@ Variant::Variant(const RefPtr &p_resource) { _get_obj().ref = p_resource; } -Variant::Variant(const ::RID &p_rid) { - type = RID; - memnew_placement(_data._mem, ::RID(p_rid)); -} - Variant::Variant(const Object *p_object) { type = OBJECT; Object *obj = const_cast(p_object); @@ -2782,18 +2639,6 @@ Variant::Variant(const Vector &p_array) { } } -Variant::Variant(const Vector<::RID> &p_array) { - type = ARRAY; - - Array *rid_array = memnew_placement(_data._mem, Array); - - rid_array->resize(p_array.size()); - - for (int i = 0; i < p_array.size(); i++) { - rid_array->set(i, Variant(p_array[i])); - } -} - Variant::Variant(const PoolVector &p_raw_array) { type = POOL_BYTE_ARRAY; memnew_placement(_data._mem, PoolVector(p_raw_array)); @@ -3115,12 +2960,6 @@ void Variant::operator=(const Variant &p_variant) { case COLOR: { *reinterpret_cast(_data._mem) = *reinterpret_cast(p_variant._data._mem); } break; - case NODE_PATH: { - *reinterpret_cast(_data._mem) = *reinterpret_cast(p_variant._data._mem); - } break; - case RID: { - *reinterpret_cast<::RID *>(_data._mem) = *reinterpret_cast(p_variant._data._mem); - } break; case OBJECT: { if (likely(_get_obj().rc)) { if (unlikely(_get_obj().rc->decrement())) { @@ -3181,11 +3020,6 @@ void Variant::operator=(const Variant &p_variant) { } } -Variant::Variant(const IP_Address &p_address) { - type = STRING; - memnew_placement(_data._mem, String(p_address)); -} - Variant::Variant(const Variant &p_variant) { type = NIL; reference(p_variant); @@ -3341,12 +3175,6 @@ uint32_t Variant::recursive_hash(int p_recursion_count) const { h = hash_murmur3_one_float(c.a, h); return hash_fmix32(h); } break; - case NODE_PATH: { - return reinterpret_cast(_data._mem)->hash(); - } break; - case RID: { - return hash_one_uint64(reinterpret_cast(_data._mem)->get_id()); - } break; case OBJECT: { return hash_one_uint64(hash_make_uint64_t(_UNSAFE_OBJ_PROXY_PTR(*this))); } break; @@ -3862,9 +3690,6 @@ Vector varray(const Variant &p_arg1, const Variant &p_arg2, const Varia return v; } -void Variant::static_assign(const Variant &p_variant) { -} - bool Variant::is_shared() const { switch (type) { case OBJECT: @@ -3880,82 +3705,6 @@ bool Variant::is_shared() const { return false; } -Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - CallError error; - - Variant ret = call(p_method, argptr, argc, error); - - switch (error.error) { - case CallError::CALL_ERROR_INVALID_ARGUMENT: { - String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(error.expected) + "'."; - ERR_PRINT(err.utf8().get_data()); - - } break; - case CallError::CALL_ERROR_INVALID_METHOD: { - String err = "Invalid method '" + p_method + "' for type '" + Variant::get_type_name(type) + "'."; - ERR_PRINT(err.utf8().get_data()); - } break; - case CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { - String err = "Too many arguments for method '" + p_method + "'"; - ERR_PRINT(err.utf8().get_data()); - } break; - default: { - } - } - - return ret; -} - -void Variant::construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct, void *p_construct_ud) { - r_value = Variant(); -} - -String Variant::get_construct_string() const { - String vars; - VariantWriter::write_to_string(*this, vars); - - return vars; -} - -String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Variant::CallError &ce) { - String err_text; - - if (ce.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(ce.expected) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(ce.expected) + "."; - } - } else if (ce.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Variant::CallError::CALL_OK) { - return "Call OK"; - } - - String class_name = p_base->get_class(); - Ref