Fixed building Variant. Also added more goodies to object.

This commit is contained in:
Relintai 2023-12-31 19:32:44 +01:00
parent c6f3a8b245
commit c87f9fd541
21 changed files with 1257 additions and 684 deletions

View File

@ -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 \

View File

@ -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;
}

View File

@ -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());

View File

@ -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);

579
sfw/core/og_hash_map.h Normal file
View File

@ -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 <reduzio@gmail.com>
*
* 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 <class TKey, class TData, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<TKey>, 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<Element *>(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<Element *>(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<Element *>(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<Element *>(get_element(p_key));
return e;
}
Element *find(const TKey &p_key) {
if (unlikely(!hash_table)) {
return nullptr;
}
Element *e = const_cast<Element *>(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 <class C>
_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 <class C>
_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<Element *>(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<TKey> *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

View File

@ -5,7 +5,7 @@
#include <string>
#include "core/containers/vector.h"
#include "core/vector.h"
#ifndef DEFAULT_DIRECTORY_SEPARATOR
#define DEFAULT_DIRECTORY_SEPARATOR '/'

285
sfw/core/ordered_hash_map.h Normal file
View File

@ -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 <class K, class V, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<K>, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8>
class OrderedHashMap {
typedef List<Pair<const K *, V>> InternalList;
typedef OGHashMap<K, typename InternalList::Element *, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP> InternalMap;
InternalList list;
InternalMap map;
public:
class Element {
friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
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<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
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<const K *, V>(&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

View File

@ -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;
}

View File

@ -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<Variant, _ArrayVariantSortCustom, true> 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);
}

View File

@ -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);

View File

@ -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")) {
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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<String> *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<String> *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<String> *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<String> *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<String> *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<ObjectRC *> _rc;
//Dictionary metadata;
Dictionary metadata;
};
bool predelete_handler(Object *p_object);

View File

@ -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<StaticSignalEntry *>(e);
if (se->func == func) {
entries.remove_keep_order(i);
entries.remove(i);
return;
}
}

View File

@ -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<ClassSignalEntry *>(e);
if (se->get_obj_ptr() == obj_ptr && se->get_func_ptr() == func_ptr) {
entries.remove_keep_order(i);
entries.remove(i);
return;
}
}

View File

@ -69,18 +69,6 @@ bool RefPtr::is_null() const {
return ref->is_null();
}
RID RefPtr::get_rid() const {
Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
if (ref->is_null()) {
return RID();
}
Resource *res = Object::cast_to<Resource>(ref->ptr());
if (res) {
return res->get_rid();
}
return RID();
}
void RefPtr::unref() {
Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
ref->unref();

View File

@ -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<const Color *>(_data._mem) == Color();
} break;
case NODE_PATH: {
return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
} break;
case RID: {
return *reinterpret_cast<const ::RID *>(_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<const Color *>(p_variant._data._mem)));
} break;
case NODE_PATH: {
memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem)));
} break;
case RID: {
memnew_placement(_data._mem, ::RID(*reinterpret_cast<const ::RID *>(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<NodePath *>(_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<const StringName *>(_data._mem);
} else if (type == NODE_PATH) {
return reinterpret_cast<const NodePath *>(_data._mem)->get_sname();
}
return StringName(operator String());
@ -1726,9 +1667,6 @@ String Variant::stringify(List<const void *> &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<const NodePath *>(_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<const ::RID *>(_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<Node>(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<Control>(obj);
}
return nullptr;
}
Variant::operator Dictionary() const {
if (type == DICTIONARY) {
return *reinterpret_cast<const Dictionary *>(_data._mem);
} else {
return Dictionary();
}
}
template <class DA, class SA>
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<const Dictionary *>(_data._mem);
} else {
return Dictionary();
}
}
Variant::operator Array() const {
if (type == ARRAY) {
return *reinterpret_cast<const Array *>(_data._mem);
@ -2298,16 +2186,6 @@ Variant::operator PoolVector<Color>() 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<Plane>() const {
Array va = operator Array();
PoolVector<Plane> 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<int> addr = operator PoolVector<int>();
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<Object *>(p_object);
@ -2782,18 +2639,6 @@ Variant::Variant(const Vector<Plane> &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<uint8_t> &p_raw_array) {
type = POOL_BYTE_ARRAY;
memnew_placement(_data._mem, PoolVector<uint8_t>(p_raw_array));
@ -3115,12 +2960,6 @@ void Variant::operator=(const Variant &p_variant) {
case COLOR: {
*reinterpret_cast<Color *>(_data._mem) = *reinterpret_cast<const Color *>(p_variant._data._mem);
} break;
case NODE_PATH: {
*reinterpret_cast<NodePath *>(_data._mem) = *reinterpret_cast<const NodePath *>(p_variant._data._mem);
} break;
case RID: {
*reinterpret_cast<::RID *>(_data._mem) = *reinterpret_cast<const ::RID *>(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<const NodePath *>(_data._mem)->hash();
} break;
case RID: {
return hash_one_uint64(reinterpret_cast<const ::RID *>(_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<Variant> 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<Script> script = p_base->get_script();
if (script.is_valid() && script->get_path().is_resource_file()) {
class_name += "(" + script->get_path().get_file() + ")";
}
return "'" + class_name + "::" + String(p_method) + "': " + err_text;
}
String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
Array args;
if (p1.get_type() != Variant::NIL) {
@ -3979,7 +3728,10 @@ String vformat(const String &p_text, const Variant &p1, const Variant &p2, const
}
bool error = false;
String fmt = p_text.sprintf(args, &error);
//TODO
//String fmt = p_text.sprintf(args, &error);
String fmt;
ERR_FAIL_COND_V_MSG(error, String(), fmt);

View File

@ -23,6 +23,8 @@
#include "core/vector4i.h"
#include "object/array.h"
#include "object/dictionary.h"
#include "object/ref_ptr.h"
#include "object/object_id.h"
class Object;
class ObjectRC;
@ -279,7 +281,6 @@ public:
Variant(const Transform2D &p_transform);
Variant(const Transform &p_transform);
Variant(const Color &p_color);
Variant(const NodePath &p_node_path);
Variant(const RefPtr &p_resource);
Variant(const Object *p_object);
Variant(const Dictionary &p_dictionary);
@ -309,7 +310,6 @@ public:
Variant(const Vector<Vector3i> &p_array);
Variant(const Vector<Color> &p_array);
Variant(const Vector<Plane> &p_array);
Variant(const Vector<::RID> &p_array);
Variant(const Vector<Vector2> &p_array);
Variant(const Vector<Vector2i> &p_array);
Variant(const Vector<Vector4> &p_array);

View File

@ -5,10 +5,10 @@
#include "variant.h"
#include "core/core_string_names.h"
#include "core/object/object.h"
#include "core/object/object_rc.h"
#include "core/object/script_language.h"
#include "object/core_string_names.h"
#include "object/object.h"
#include "object/object_rc.h"
#include "object/resource.h"
#define CASE_TYPE_ALL(PREFIX, OP) \
CASE_TYPE(PREFIX, OP, INT) \
@ -35,8 +35,6 @@
CASE_TYPE(PREFIX, OP, TRANSFORM2D) \
CASE_TYPE(PREFIX, OP, PROJECTION) \
CASE_TYPE(PREFIX, OP, COLOR) \
CASE_TYPE(PREFIX, OP, NODE_PATH) \
CASE_TYPE(PREFIX, OP, RID) \
CASE_TYPE(PREFIX, OP, OBJECT) \
CASE_TYPE(PREFIX, OP, STRING_NAME) \
CASE_TYPE(PREFIX, OP, DICTIONARY) \
@ -80,8 +78,6 @@
TYPE(PREFIX, OP, TRANSFORM2D), \
TYPE(PREFIX, OP, PROJECTION), \
TYPE(PREFIX, OP, COLOR), \
TYPE(PREFIX, OP, NODE_PATH), \
TYPE(PREFIX, OP, RID), \
TYPE(PREFIX, OP, OBJECT), \
TYPE(PREFIX, OP, STRING_NAME), \
TYPE(PREFIX, OP, DICTIONARY), \
@ -256,8 +252,6 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
if (p_b.type == STRING_NAME) \
_RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \
if (p_b.type == NODE_PATH) \
_RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
\
_RETURN_FAIL \
};
@ -268,8 +262,6 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
if (p_b.type == STRING_NAME) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
if (p_b.type == NODE_PATH) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
\
_RETURN_FAIL \
};
@ -280,24 +272,20 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
if (p_b.type == STRING_NAME) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
if (p_b.type == NODE_PATH) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
if (p_b.type == NIL) \
_RETURN(!(p_b.type m_op NIL)); \
\
_RETURN_FAIL \
};
#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
if (p_b.type == STRING) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
if (p_b.type == NODE_PATH) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
if (p_b.type == NIL) \
_RETURN(!(p_b.type m_op NIL)); \
\
_RETURN_FAIL \
#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
if (p_b.type == STRING) \
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
if (p_b.type == NIL) \
_RETURN(!(p_b.type m_op NIL)); \
\
_RETURN_FAIL \
};
#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \
@ -533,9 +521,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM2D, ==, _transform2d);
DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, PROJECTION, ==, _projection);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, COLOR, ==, Color);
DEFAULT_OP_STR_NULL_NP(math, OP_EQUAL, NODE_PATH, ==, NodePath);
DEFAULT_OP_STR_NULL_SN(math, OP_EQUAL, STRING_NAME, ==, StringName);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, RID, ==, ::RID);
DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_BYTE_ARRAY, uint8_t);
DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_INT_ARRAY, int);
@ -635,9 +621,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM2D, !=, _transform2d);
DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, PROJECTION, !=, _projection);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, COLOR, !=, Color);
DEFAULT_OP_STR_NULL_NP(math, OP_NOT_EQUAL, NODE_PATH, !=, NodePath);
DEFAULT_OP_STR_NULL_SN(math, OP_NOT_EQUAL, STRING_NAME, !=, StringName);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, RID, !=, ::RID);
DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_BYTE_ARRAY, uint8_t);
DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_INT_ARRAY, int);
@ -700,7 +684,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR3I, <, Vector3i);
DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR4, <, Vector4);
DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR4I, <, Vector4i);
DEFAULT_OP_LOCALMEM(math, OP_LESS, RID, <, ::RID);
DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_BYTE_ARRAY, uint8_t);
DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_INT_ARRAY, int);
@ -726,7 +709,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_LESS, PROJECTION)
CASE_TYPE(math, OP_LESS, STRING_NAME)
CASE_TYPE(math, OP_LESS, COLOR)
CASE_TYPE(math, OP_LESS, NODE_PATH)
CASE_TYPE(math, OP_LESS, DICTIONARY)
_RETURN_FAIL;
}
@ -747,7 +729,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR3I, <=, Vector3i);
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR4, <=, Vector4);
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR4I, <=, Vector4i);
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, RID, <=, ::RID);
CASE_TYPE(math, OP_LESS_EQUAL, NIL)
CASE_TYPE(math, OP_LESS_EQUAL, BOOL)
@ -761,7 +742,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM2D)
CASE_TYPE(math, OP_LESS_EQUAL, PROJECTION)
CASE_TYPE(math, OP_LESS_EQUAL, COLOR)
CASE_TYPE(math, OP_LESS_EQUAL, NODE_PATH)
CASE_TYPE(math, OP_LESS_EQUAL, STRING_NAME)
CASE_TYPE(math, OP_LESS_EQUAL, DICTIONARY)
CASE_TYPE(math, OP_LESS_EQUAL, ARRAY)
@ -827,7 +807,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR3I, <, Vector3i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR4, <, Vector4);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR4I, <, Vector4i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, RID, <, ::RID);
DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_BYTE_ARRAY, uint8_t);
DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_INT_ARRAY, int);
DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_REAL_ARRAY, real_t);
@ -852,7 +831,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_GREATER, TRANSFORM2D)
CASE_TYPE(math, OP_GREATER, PROJECTION)
CASE_TYPE(math, OP_GREATER, COLOR)
CASE_TYPE(math, OP_GREATER, NODE_PATH)
CASE_TYPE(math, OP_GREATER, DICTIONARY)
_RETURN_FAIL;
}
@ -873,7 +851,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR3I, <=, Vector3i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR4, <=, Vector4);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR4I, <=, Vector4i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, RID, <=, ::RID);
CASE_TYPE(math, OP_GREATER_EQUAL, NIL)
CASE_TYPE(math, OP_GREATER_EQUAL, BOOL)
@ -887,7 +864,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM2D)
CASE_TYPE(math, OP_GREATER_EQUAL, PROJECTION)
CASE_TYPE(math, OP_GREATER_EQUAL, COLOR)
CASE_TYPE(math, OP_GREATER_EQUAL, NODE_PATH)
CASE_TYPE(math, OP_GREATER_EQUAL, DICTIONARY)
CASE_TYPE(math, OP_GREATER_EQUAL, STRING_NAME)
CASE_TYPE(math, OP_GREATER_EQUAL, ARRAY)
@ -959,8 +935,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_ADD, TRANSFORM)
CASE_TYPE(math, OP_ADD, TRANSFORM2D)
CASE_TYPE(math, OP_ADD, PROJECTION)
CASE_TYPE(math, OP_ADD, NODE_PATH)
CASE_TYPE(math, OP_ADD, RID)
CASE_TYPE(math, OP_ADD, OBJECT)
CASE_TYPE(math, OP_ADD, DICTIONARY)
CASE_TYPE(math, OP_ADD, STRING_NAME)
@ -990,8 +964,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_SUBTRACT, TRANSFORM)
CASE_TYPE(math, OP_SUBTRACT, TRANSFORM2D)
CASE_TYPE(math, OP_SUBTRACT, PROJECTION)
CASE_TYPE(math, OP_SUBTRACT, NODE_PATH)
CASE_TYPE(math, OP_SUBTRACT, RID)
CASE_TYPE(math, OP_SUBTRACT, OBJECT)
CASE_TYPE(math, OP_SUBTRACT, STRING_NAME)
CASE_TYPE(math, OP_SUBTRACT, DICTIONARY)
@ -1114,8 +1086,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_MULTIPLY, RECT2I)
CASE_TYPE(math, OP_MULTIPLY, PLANE)
CASE_TYPE(math, OP_MULTIPLY, AABB)
CASE_TYPE(math, OP_MULTIPLY, NODE_PATH)
CASE_TYPE(math, OP_MULTIPLY, RID)
CASE_TYPE(math, OP_MULTIPLY, OBJECT)
CASE_TYPE(math, OP_MULTIPLY, STRING_NAME)
CASE_TYPE(math, OP_MULTIPLY, DICTIONARY)
@ -1168,8 +1138,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_DIVIDE, TRANSFORM)
CASE_TYPE(math, OP_DIVIDE, TRANSFORM2D)
CASE_TYPE(math, OP_DIVIDE, PROJECTION)
CASE_TYPE(math, OP_DIVIDE, NODE_PATH)
CASE_TYPE(math, OP_DIVIDE, RID)
CASE_TYPE(math, OP_DIVIDE, OBJECT)
CASE_TYPE(math, OP_DIVIDE, STRING_NAME)
CASE_TYPE(math, OP_DIVIDE, DICTIONARY)
@ -1211,8 +1179,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_POSITIVE, TRANSFORM2D)
CASE_TYPE(math, OP_POSITIVE, PROJECTION)
CASE_TYPE(math, OP_POSITIVE, COLOR)
CASE_TYPE(math, OP_POSITIVE, NODE_PATH)
CASE_TYPE(math, OP_POSITIVE, RID)
CASE_TYPE(math, OP_POSITIVE, OBJECT)
CASE_TYPE(math, OP_POSITIVE, STRING_NAME)
CASE_TYPE(math, OP_POSITIVE, DICTIONARY)
@ -1255,8 +1221,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_NEGATE, TRANSFORM)
CASE_TYPE(math, OP_NEGATE, TRANSFORM2D)
CASE_TYPE(math, OP_NEGATE, PROJECTION)
CASE_TYPE(math, OP_NEGATE, NODE_PATH)
CASE_TYPE(math, OP_NEGATE, RID)
CASE_TYPE(math, OP_NEGATE, OBJECT)
CASE_TYPE(math, OP_NEGATE, STRING_NAME)
CASE_TYPE(math, OP_NEGATE, DICTIONARY)
@ -1296,12 +1260,14 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
if (p_b.type == ARRAY) {
// e.g. "frog %s %d" % ["fish", 12]
const Array *args = reinterpret_cast<const Array *>(p_b._data._mem);
result = format->sprintf(*args, &error);
//TODO
//result = format->sprintf(*args, &error);
} else {
// e.g. "frog %d" % 12
Array args;
args.push_back(p_b);
result = format->sprintf(args, &error);
//TODO
//result = format->sprintf(args, &error);
}
r_valid = !error;
_RETURN(result);
@ -1326,8 +1292,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_MODULE, TRANSFORM2D)
CASE_TYPE(math, OP_MODULE, PROJECTION)
CASE_TYPE(math, OP_MODULE, COLOR)
CASE_TYPE(math, OP_MODULE, NODE_PATH)
CASE_TYPE(math, OP_MODULE, RID)
CASE_TYPE(math, OP_MODULE, OBJECT)
CASE_TYPE(math, OP_MODULE, STRING_NAME)
CASE_TYPE(math, OP_MODULE, DICTIONARY)
@ -3246,10 +3210,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
}
} break;
case NODE_PATH: {
} break; // 15
case RID: {
} break;
case OBJECT: {
Object *obj = _OBJ_PTR(*this);
@ -3263,11 +3223,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
}
if (p_index.get_type() != Variant::STRING_NAME && p_index.get_type() != Variant::STRING) {
obj->setvar(p_index, p_value, r_valid);
return;
}
obj->set(p_index, p_value, r_valid);
return;
} break;
@ -4022,10 +3977,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
}
} break;
case NODE_PATH: {
} break; // 15
case RID: {
} break;
case OBJECT: {
Object *obj = _OBJ_PTR(*this);
@ -4039,11 +3990,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
return Variant();
}
if (p_index.get_type() != Variant::STRING && p_index.get_type() != Variant::STRING_NAME) {
return obj->getvar(p_index, r_valid);
} else {
return obj->get(p_index, r_valid);
}
return obj->get(p_index, r_valid);
} break;
case STRING_NAME: {
@ -4106,11 +4053,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
bool result;
if (p_index.get_type() != Variant::STRING && p_index.get_type() != Variant::STRING_NAME) {
obj->getvar(p_index, &result);
} else {
obj->get(p_index, &result);
}
obj->get(p_index, &result);
return result;
} break;
case DICTIONARY: {
@ -4346,160 +4289,6 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
return false;
}
void Variant::get_property_list(List<PropertyInfo> *p_list) const {
switch (type) {
case RECT2: {
p_list->push_back(PropertyInfo(Variant::VECTOR2, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "end"));
} break;
case RECT2I: {
p_list->push_back(PropertyInfo(Variant::VECTOR2I, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR2I, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR2I, "end"));
} break;
case VECTOR2: {
p_list->push_back(PropertyInfo(Variant::REAL, "x"));
p_list->push_back(PropertyInfo(Variant::REAL, "y"));
} break;
case VECTOR2I: {
p_list->push_back(PropertyInfo(Variant::INT, "x"));
p_list->push_back(PropertyInfo(Variant::INT, "y"));
} break;
case VECTOR3: {
p_list->push_back(PropertyInfo(Variant::REAL, "x"));
p_list->push_back(PropertyInfo(Variant::REAL, "y"));
p_list->push_back(PropertyInfo(Variant::REAL, "z"));
} break;
case VECTOR3I: {
p_list->push_back(PropertyInfo(Variant::INT, "x"));
p_list->push_back(PropertyInfo(Variant::INT, "y"));
p_list->push_back(PropertyInfo(Variant::INT, "z"));
} break;
case VECTOR4: {
p_list->push_back(PropertyInfo(Variant::REAL, "x"));
p_list->push_back(PropertyInfo(Variant::REAL, "y"));
p_list->push_back(PropertyInfo(Variant::REAL, "z"));
p_list->push_back(PropertyInfo(Variant::REAL, "w"));
} break;
case VECTOR4I: {
p_list->push_back(PropertyInfo(Variant::INT, "x"));
p_list->push_back(PropertyInfo(Variant::INT, "y"));
p_list->push_back(PropertyInfo(Variant::INT, "z"));
p_list->push_back(PropertyInfo(Variant::INT, "w"));
} break;
case PLANE: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "normal"));
p_list->push_back(PropertyInfo(Variant::REAL, "x"));
p_list->push_back(PropertyInfo(Variant::REAL, "y"));
p_list->push_back(PropertyInfo(Variant::REAL, "z"));
p_list->push_back(PropertyInfo(Variant::REAL, "d"));
} break;
case QUATERNION: {
p_list->push_back(PropertyInfo(Variant::REAL, "x"));
p_list->push_back(PropertyInfo(Variant::REAL, "y"));
p_list->push_back(PropertyInfo(Variant::REAL, "z"));
p_list->push_back(PropertyInfo(Variant::REAL, "w"));
} break;
case AABB: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "end"));
} break;
case BASIS: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "x"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "y"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "z"));
} break;
case TRANSFORM: {
p_list->push_back(PropertyInfo(Variant::BASIS, "basis"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "origin"));
} break;
case TRANSFORM2D: {
p_list->push_back(PropertyInfo(Variant::VECTOR2, "x"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "y"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "origin"));
} break;
case PROJECTION: {
p_list->push_back(PropertyInfo(Variant::VECTOR4, "x"));
p_list->push_back(PropertyInfo(Variant::VECTOR4, "y"));
p_list->push_back(PropertyInfo(Variant::VECTOR4, "z"));
p_list->push_back(PropertyInfo(Variant::VECTOR4, "w"));
} break;
case COLOR: {
p_list->push_back(PropertyInfo(Variant::REAL, "r"));
p_list->push_back(PropertyInfo(Variant::REAL, "g"));
p_list->push_back(PropertyInfo(Variant::REAL, "b"));
p_list->push_back(PropertyInfo(Variant::REAL, "a"));
p_list->push_back(PropertyInfo(Variant::REAL, "h"));
p_list->push_back(PropertyInfo(Variant::REAL, "s"));
p_list->push_back(PropertyInfo(Variant::REAL, "v"));
p_list->push_back(PropertyInfo(Variant::INT, "r8"));
p_list->push_back(PropertyInfo(Variant::INT, "g8"));
p_list->push_back(PropertyInfo(Variant::INT, "b8"));
p_list->push_back(PropertyInfo(Variant::INT, "a8"));
} break;
case NODE_PATH: {
} break;
case RID: {
} break;
case OBJECT: {
Object *obj = _OBJ_PTR(*this);
if (unlikely(!obj)) {
#ifdef DEBUG_ENABLED
if (_get_obj().rc) {
ERR_PRINT("Attempted get property list on a deleted object.");
}
#endif
return;
}
obj->get_property_list(p_list);
} break;
case DICTIONARY: {
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
List<Variant> keys;
dic->get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
if (E->get().get_type() == Variant::STRING) {
p_list->push_back(PropertyInfo(Variant::STRING, E->get()));
}
}
} break;
case ARRAY: // 20
case POOL_BYTE_ARRAY:
case POOL_INT_ARRAY:
case POOL_REAL_ARRAY:
case POOL_STRING_ARRAY:
case POOL_VECTOR2_ARRAY:
case POOL_VECTOR2I_ARRAY:
case POOL_VECTOR3_ARRAY:
case POOL_VECTOR3I_ARRAY:
case POOL_VECTOR4_ARRAY:
case POOL_VECTOR4I_ARRAY:
case POOL_COLOR_ARRAY: {
//nothing
} break;
default: {
}
}
}
bool Variant::iter_init(Variant &r_iter, bool &valid) const {
valid = true;
switch (type) {
@ -4559,34 +4348,6 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
}
//return true;
} break;
case OBJECT: {
Object *obj = _OBJ_PTR(*this);
if (unlikely(!obj)) {
valid = false;
#ifdef DEBUG_ENABLED
if (_get_obj().rc) {
ERR_PRINT("Attempted iteration start on a deleted object.");
}
#endif
return false;
}
Variant::CallError ce;
ce.error = Variant::CallError::CALL_OK;
Array ref;
ref.push_back(r_iter);
Variant vref = ref;
const Variant *refp[] = { &vref };
Variant ret = obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
valid = false;
return false;
}
r_iter = ref[0];
return ret;
} break;
case STRING: {
const String *str = reinterpret_cast<const String *>(_data._mem);
if (str->empty()) {
@ -4796,35 +4557,6 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
r_iter = idx;
return true;
} break;
case OBJECT: {
Object *obj = _OBJ_PTR(*this);
if (unlikely(!obj)) {
valid = false;
#ifdef DEBUG_ENABLED
if (_get_obj().rc) {
ERR_PRINT("Attempted iteration check next on a deleted object.");
}
#endif
return false;
}
Variant::CallError ce;
ce.error = Variant::CallError::CALL_OK;
Array ref;
ref.push_back(r_iter);
Variant vref = ref;
const Variant *refp[] = { &vref };
Variant ret = obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
valid = false;
return false;
}
r_iter = ref[0];
return ret;
} break;
case STRING: {
const String *str = reinterpret_cast<const String *>(_data._mem);
int idx = r_iter;
@ -4998,32 +4730,6 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
case VECTOR3I: {
return r_iter;
} break;
case OBJECT: {
Object *obj = _OBJ_PTR(*this);
if (unlikely(!obj)) {
r_valid = false;
#ifdef DEBUG_ENABLED
if (_get_obj().rc) {
ERR_PRINT("Attempted iteration get next on a deleted object.");
}
#endif
return Variant();
}
Variant::CallError ce;
ce.error = Variant::CallError::CALL_OK;
const Variant *refp[] = { &r_iter };
Variant ret = obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
if (ce.error != Variant::CallError::CALL_OK) {
r_valid = false;
return Variant();
}
//r_iter=ref[0];
return ret;
} break;
case STRING: {
const String *str = reinterpret_cast<const String *>(_data._mem);
return str->substr(r_iter, 1);
@ -5548,14 +5254,6 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = reinterpret_cast<const Color *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Color *>(b._data._mem), c);
}
return;
case NODE_PATH: {
r_dst = a;
}
return;
case RID: {
r_dst = a;
}
return;
case OBJECT: {
r_dst = a;
}
@ -5823,3 +5521,49 @@ String Variant::get_operator_name(Operator p_op) {
ERR_FAIL_INDEX_V(p_op, OP_MAX, "");
return _op_names[p_op];
}
#undef CASE_TYPE_ALL
#undef CASE_TYPE_ALL_BUT_INT
#undef TYPE
#undef TYPES
#undef CASES
#undef SWITCH
#undef SWITCH_OP
#undef CASE_TYPE
#undef CASES
#undef SWITCH
#undef SWITCH_OP
#undef CASE_TYPE
#undef _RETURN
#undef _RETURN_FAIL
#undef DEFAULT_OP_NUM
#undef DEFAULT_OP_NUM_NULL
#undef DEFAULT_OP_NUM_DIV
#undef DEFAULT_OP_NUM_DIV
#undef DEFAULT_OP_NUM_NEG
#undef DEFAULT_OP_NUM_POS
#undef DEFAULT_OP_NUM_VEC
#undef DEFAULT_OP_STR_REV
#undef DEFAULT_OP_STR
#undef DEFAULT_OP_STR_NULL
#undef DEFAULT_OP_STR_NULL_NP
#undef DEFAULT_OP_STR_NULL_SN
#undef DEFAULT_OP_LOCALMEM_REV
#undef DEFAULT_OP_LOCALMEM
#undef DEFAULT_OP_LOCALMEM_NULL
#undef DEFAULT_OP_LOCALMEM_NEG
#undef DEFAULT_OP_LOCALMEM_POS
#undef DEFAULT_OP_LOCALMEM_NUM
#undef DEFAULT_OP_PTR
#undef DEFAULT_OP_PTRREF
#undef DEFAULT_OP_PTRREF_NULL
#undef DEFAULT_OP_ARRAY_EQ
#undef DEFAULT_OP_ARRAY_NEQ
#undef DEFAULT_OP_ARRAY_LT
#undef DEFAULT_OP_ARRAY_GT
#undef DEFAULT_OP_ARRAY_OP
#undef DEFAULT_OP_ARRAY_OP_BODY
#undef DEFAULT_OP_ARRAY_ADD
#undef DEFAULT_OP_ARRAY_CMD
#undef DEFAULT_OP_DVECTOR_SET
#undef DEFAULT_OP_DVECTOR_GET