mirror of
https://github.com/Relintai/sfw.git
synced 2024-11-08 07:52:09 +01:00
Fixed building Variant. Also added more goodies to object.
This commit is contained in:
parent
c6f3a8b245
commit
c87f9fd541
@ -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 \
|
||||
|
3
main.cpp
3
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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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
579
sfw/core/og_hash_map.h
Normal 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
|
@ -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
285
sfw/core/ordered_hash_map.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
49
sfw/object/core_string_names.cpp
Normal file
49
sfw/object/core_string_names.cpp
Normal 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")) {
|
||||
}
|
66
sfw/object/core_string_names.h
Normal file
66
sfw/object/core_string_names.h
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user