summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub4
-rw-r--r--core/bind/core_bind.cpp2
-rw-r--r--core/class_db.cpp4
-rw-r--r--core/core_string_names.cpp2
-rw-r--r--core/global_config.cpp (renamed from core/globals.cpp)137
-rw-r--r--core/global_config.h (renamed from core/globals.h)4
-rw-r--r--core/hash_map.h61
-rw-r--r--core/hashfuncs.h42
-rw-r--r--core/input_map.cpp2
-rw-r--r--core/io/file_access_memory.cpp2
-rw-r--r--core/io/file_access_network.cpp2
-rw-r--r--core/io/file_access_pack.cpp6
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/resource_format_binary.cpp51
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/resource_import.cpp6
-rw-r--r--core/io/resource_loader.cpp10
-rw-r--r--core/io/resource_saver.cpp2
-rw-r--r--core/math/geometry.h28
-rw-r--r--core/math/math_2d.cpp7
-rw-r--r--core/math/math_2d.h3
-rw-r--r--core/math/math_funcs.h1
-rw-r--r--core/math/plane.cpp5
-rw-r--r--core/math/plane.h1
-rw-r--r--core/math/quat.cpp19
-rw-r--r--core/math/quat.h2
-rw-r--r--core/math/vector3.cpp11
-rw-r--r--core/math/vector3.h1
-rw-r--r--core/message_queue.cpp2
-rw-r--r--core/object.cpp8
-rw-r--r--core/object.h2
-rw-r--r--core/os/dir_access.cpp2
-rw-r--r--core/os/file_access.cpp2
-rw-r--r--core/os/input.cpp2
-rw-r--r--core/os/os.cpp2
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/script_debugger_remote.cpp2
-rw-r--r--core/translation.cpp2
-rw-r--r--core/ustring.cpp47
-rw-r--r--core/ustring.h2
-rw-r--r--core/variant.cpp187
-rw-r--r--core/variant.h5
-rw-r--r--core/variant_op.cpp76
43 files changed, 494 insertions, 268 deletions
diff --git a/core/SCsub b/core/SCsub
index 8d89f6427b..a9721a1052 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -13,7 +13,7 @@ for x in env.global_defaults:
gd_inc += '#include "platform/' + x + '/globals/global_defaults.h"\n'
gd_call += "\tregister_" + x + "_global_defaults();\n"
-gd_cpp = '#include "globals.h"\n'
+gd_cpp = '#include "global_config.h"\n'
gd_cpp += gd_inc
gd_cpp += "void GlobalConfig::register_global_defaults() {\n" + gd_call + "\n}\n"
@@ -45,7 +45,7 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
print("Invalid AES256 encryption key, not 64 bits hex: " + e)
f = open("script_encryption_key.cpp", "wb")
-f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
+f.write("#include \"global_config.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
f.close()
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 7bd652349d..54ab51657b 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -31,7 +31,7 @@
#include "geometry.h"
#include "io/marshalls.h"
#include "io/base64.h"
-#include "core/globals.h"
+#include "core/global_config.h"
#include "io/file_access_encrypted.h"
#include "os/keyboard.h"
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 2eff8c07c7..4bdae45fb9 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -295,7 +295,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
OBJTYPE_RLOCK;
#ifdef DEBUG_METHODS_ENABLED
- uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME));
+ uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_NAME));
List<StringName> names;
@@ -1256,7 +1256,7 @@ void ClassDB::get_extensions_for_type(const StringName& p_class,List<String> *p_
while((K=resource_base_extensions.next(K))) {
StringName cmp = resource_base_extensions[*K];
- if (is_parent_class(cmp,p_class))
+ if (is_parent_class(p_class,cmp))
p_extensions->push_back(*K);
}
}
diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp
index a173f98602..f8c6f47797 100644
--- a/core/core_string_names.cpp
+++ b/core/core_string_names.cpp
@@ -35,7 +35,7 @@ CoreStringNames::CoreStringNames() {
_free=StaticCString::create("free");
changed=StaticCString::create("changed");
_meta=StaticCString::create("__meta__");
- _script=StaticCString::create("script/script");
+ _script=StaticCString::create("script");
script_changed=StaticCString::create("script_changed");
___pdcdata=StaticCString::create("___pdcdata");
__getvar=StaticCString::create("__getvar");
diff --git a/core/globals.cpp b/core/global_config.cpp
index 0c35a9f89a..b76991c04e 100644
--- a/core/globals.cpp
+++ b/core/global_config.cpp
@@ -26,7 +26,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "globals.h"
+#include "global_config.h"
#include "os/dir_access.h"
#include "os/file_access.h"
@@ -247,9 +247,22 @@ bool GlobalConfig::_load_resource_pack(const String& p_pack) {
Error GlobalConfig::setup(const String& p_path,const String & p_main_pack) {
- //an absolute mess of a function, must be cleaned up and reorganized somehow at some point
+ //If looking for files in network, just use network!
- //_load_settings(p_path+"/override.cfg");
+ if (FileAccessNetworkClient::get_singleton()) {
+
+ if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
+
+ _load_settings("res://override.cfg");
+
+ }
+
+ return OK;
+ }
+
+ String exec_path = OS::get_singleton()->get_executable_path();
+
+ //Attempt with a passed main pack first
if (p_main_pack!="") {
@@ -257,8 +270,8 @@ Error GlobalConfig::setup(const String& p_path,const String & p_main_pack) {
ERR_FAIL_COND_V(!ok,ERR_CANT_OPEN);
if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
-
- _load_settings("res://override.cfg");
+ //load override from location of the main pack
+ _load_settings(p_main_pack.get_base_dir().plus_file("override.cfg"));
}
@@ -266,21 +279,15 @@ Error GlobalConfig::setup(const String& p_path,const String & p_main_pack) {
}
- if (OS::get_singleton()->get_executable_path()!="") {
+ //Attempt with execname.pck
+ if (exec_path!="") {
- if (_load_resource_pack(OS::get_singleton()->get_executable_path())) {
- if (p_path!="") {
- resource_path=p_path;
- } else {
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- resource_path=d->get_current_dir();
- memdelete(d);
+ if (_load_resource_pack(exec_path.get_basename()+".pck")) {
- }
if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
-
- _load_settings("res://override.cfg");
+ //load override from location of executable
+ _load_settings(exec_path.get_base_dir().plus_file("override.cfg"));
}
@@ -292,31 +299,19 @@ Error GlobalConfig::setup(const String& p_path,const String & p_main_pack) {
}
- if (FileAccessNetworkClient::get_singleton()) {
-
- if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
-
- _load_settings("res://override.cfg");
-
- }
-
- return OK;
- }
-
+ //Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this)
if (OS::get_singleton()->get_resource_dir()!="") {
- //OS will call Globals->get_resource_path which will be empty if not overriden!
+ //OS will call Globals->get_resource_path which will be empty if not overriden!
//if the OS would rather use somewhere else, then it will not be empty.
+
resource_path=OS::get_singleton()->get_resource_dir().replace("\\","/");
if (resource_path.length() && resource_path[ resource_path.length()-1]=='/')
resource_path=resource_path.substr(0,resource_path.length()-1); // chop end
- print_line("has res dir: "+resource_path);
- if (!_load_resource_pack("res://data.pck"))
- _load_resource_pack("res://data.zip");
- // make sure this is load from the resource path
- print_line("exists engine cfg? "+itos(FileAccess::exists("/godot.cfg")));
+ // data.pck and data.zip are deprecated and no longer supported, apologies.
+ // make sure this is loaded from the resource path
+
if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
- print_line("loaded godot.cfg");
_load_settings("res://override.cfg");
}
@@ -324,67 +319,41 @@ Error GlobalConfig::setup(const String& p_path,const String & p_main_pack) {
return OK;
}
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- if (!d) {
-
- resource_path = p_path;
-
- } else {
-
- d->change_dir(p_path);
-
- String candidate = d->get_current_dir();
- String current_dir = d->get_current_dir();
- String exec_name = OS::get_singleton()->get_executable_path().get_file().get_basename();
- bool found = false;
- bool first_time=true;
-
- while(true) {
- //try to load settings in ascending through dirs shape!
-
- //tries to open pack, but only first time
- if (first_time && (_load_resource_pack(current_dir+"/"+exec_name+".pck") || _load_resource_pack(current_dir+"/"+exec_name+".zip") )) {
- if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
+ //Nothing was found, try to find a godot.cfg somewhere!
- _load_settings("res://override.cfg");
- found=true;
-
-
- }
- break;
- } else if (first_time && (_load_resource_pack(current_dir+"/data.pck") || _load_resource_pack(current_dir+"/data.zip") )) {
- if (_load_settings("res://godot.cfg")==OK || _load_settings_binary("res://godot.cfb")==OK) {
+ DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ ERR_FAIL_COND_V(!d,ERR_CANT_CREATE);
- _load_settings("res://override.cfg");
- found=true;
+ d->change_dir(p_path);
+ String candidate = d->get_current_dir();
+ String current_dir = d->get_current_dir();
+ bool found = false;
- }
- break;
- } else if (_load_settings(current_dir+"/godot.cfg")==OK || _load_settings_binary(current_dir+"/godot.cfb")==OK) {
+ while(true) {
+ //try to load settings in ascending through dirs shape!
- _load_settings(current_dir+"/override.cfg");
- candidate=current_dir;
- found=true;
- break;
- }
+ if (_load_settings(current_dir+"/godot.cfg")==OK || _load_settings_binary(current_dir+"/godot.cfb")==OK) {
- d->change_dir("..");
- if (d->get_current_dir()==current_dir)
- break; //not doing anything useful
- current_dir=d->get_current_dir();
- first_time=false;
+ _load_settings(current_dir+"/override.cfg");
+ candidate=current_dir;
+ found=true;
+ break;
}
+ d->change_dir("..");
+ if (d->get_current_dir()==current_dir)
+ break; //not doing anything useful
+ current_dir=d->get_current_dir();
+ }
- resource_path=candidate;
- resource_path = resource_path.replace("\\","/"); // windows path to unix path just in case
- memdelete(d);
- if (!found)
- return ERR_FILE_NOT_FOUND;
- };
+ resource_path=candidate;
+ resource_path = resource_path.replace("\\","/"); // windows path to unix path just in case
+ memdelete(d);
+ if (!found)
+ return ERR_FILE_NOT_FOUND;
if (resource_path.length() && resource_path[ resource_path.length()-1]=='/')
resource_path=resource_path.substr(0,resource_path.length()-1); // chop end
diff --git a/core/globals.h b/core/global_config.h
index faf077f2a5..471f1ff885 100644
--- a/core/globals.h
+++ b/core/global_config.h
@@ -26,8 +26,8 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GLOBALS_H
-#define GLOBALS_H
+#ifndef GLOBAL_CONFIG_H
+#define GLOBAL_CONFIG_H
#include "object.h"
#include "set.h"
diff --git a/core/hash_map.h b/core/hash_map.h
index 0d55206935..515fc6c4fe 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -30,40 +30,45 @@
#define HASH_MAP_H
#include "hashfuncs.h"
+#include "math_funcs.h"
#include "error_macros.h"
#include "ustring.h"
#include "os/memory.h"
#include "list.h"
-
-class HashMapHahserDefault {
-public:
-
+struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
- static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
- uint64_t v=p_int;
- v = (~v) + (v << 18); // v = (v << 18) - v - 1;
- v = v ^ (v >> 31);
- v = v * 21; // v = (v + (v << 2)) + (v << 4);
- v = v ^ (v >> 11);
- v = v + (v << 6);
- v = v ^ (v >> 22);
- return (int) v;
- }
- static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
+ static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
-
- static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
+ static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
+ static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_djb2_one_float(p_float); }
+ static _FORCE_INLINE_ uint32_t hash(const double p_double){ return hash_djb2_one_float(p_double); }
+ static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return (uint32_t)p_int; }
- static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
+ static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
- static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
- static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
+ static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
+ static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar){ return (uint32_t)p_wchar; }
//static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
};
+template <typename T>
+struct HashMapComparatorDefault {
+ static bool compare(const T& p_lhs, const T& p_rhs) {
+ return p_lhs == p_rhs;
+ }
+
+ bool compare(const float& p_lhs, const float& p_rhs) {
+ return (p_lhs == p_rhs) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs));
+ }
+
+ bool compare(const double& p_lhs, const double& p_rhs) {
+ return (p_lhs == p_rhs) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs));
+ }
+};
+
/**
* @class HashMap
* @author Juan Linietsky <reduzio@gmail.com>
@@ -74,13 +79,14 @@ public:
* @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=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
+template<class TKey, class TData, class Hasher=HashMapHasherDefault, class Comparator=HashMapComparatorDefault<TKey>, uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
class HashMap {
public:
@@ -194,7 +200,6 @@ private:
}
-
/* I want to have only one function.. */
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
@@ -206,7 +211,7 @@ private:
while (e) {
/* checking hash first avoids comparing key, which may take longer */
- if (e->hash == hash && e->pair.key == p_key ) {
+ if (e->hash == hash && Comparator::compare(e->pair.key,p_key) ) {
/* the pair exists in this hashtable, so just update data */
return e;
@@ -253,7 +258,6 @@ private:
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
hash_table[i]=NULL;
- /* elements will be in the reverse order, but it doesn't matter */
const Entry *e = p_t.hash_table[i];
@@ -385,7 +389,7 @@ public:
while (e) {
/* checking hash first avoids comparing key, which may take longer */
- if (e->hash == hash && e->pair.key == p_custom_key ) {
+ 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;
@@ -411,7 +415,7 @@ public:
while (e) {
/* checking hash first avoids comparing key, which may take longer */
- if (e->hash == hash && e->pair.key == p_custom_key ) {
+ 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;
@@ -442,7 +446,7 @@ public:
while (e) {
/* checking hash first avoids comparing key, which may take longer */
- if (e->hash == hash && e->pair.key == p_key ) {
+ if (e->hash == hash && Comparator::compare(e->pair.key,p_key) ) {
if (p) {
@@ -637,7 +641,8 @@ public:
clear();
}
-
};
+
+
#endif
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index e9e57d8b42..121d7e8c59 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -29,7 +29,8 @@
#ifndef HASHFUNCS_H
#define HASHFUNCS_H
-
+#include "math_funcs.h"
+#include "math_defs.h"
#include "typedefs.h"
/**
@@ -69,19 +70,52 @@ static inline uint32_t hash_djb2_one_32(uint32_t p_in,uint32_t p_prev=5381) {
return ((p_prev<<5)+p_prev)+p_in;
}
+static inline uint32_t hash_one_uint64(const uint64_t p_int) {
+ uint64_t v=p_int;
+ v = (~v) + (v << 18); // v = (v << 18) - v - 1;
+ v = v ^ (v >> 31);
+ v = v * 21; // v = (v + (v << 2)) + (v << 4);
+ v = v ^ (v >> 11);
+ v = v + (v << 6);
+ v = v ^ (v >> 22);
+ return (int) v;
+}
+
static inline uint32_t hash_djb2_one_float(float p_in,uint32_t p_prev=5381) {
union {
float f;
uint32_t i;
} u;
- // handle -0 case
- if (p_in==0.0f) u.f=0.0f;
- else u.f=p_in;
+ // Normalize +/- 0.0 and NaN values so they hash the same.
+ if (p_in==0.0f)
+ u.f=0.0;
+ else if (Math::is_nan(p_in))
+ u.f=Math_NAN;
+ else
+ u.f=p_in;
return ((p_prev<<5)+p_prev)+u.i;
}
+// Overload for real_t size changes
+static inline uint32_t hash_djb2_one_float(double p_in,uint32_t p_prev=5381) {
+ union {
+ double d;
+ uint64_t i;
+ } u;
+
+ // Normalize +/- 0.0 and NaN values so they hash the same.
+ if (p_in==0.0f)
+ u.d=0.0;
+ else if (Math::is_nan(p_in))
+ u.d=Math_NAN;
+ else
+ u.d=p_in;
+
+ return ((p_prev<<5)+p_prev) + hash_one_uint64(u.i);
+}
+
template<class T>
static inline uint32_t make_uint32_t(T p_in) {
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 249c75cea0..444c55cac6 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "input_map.h"
-#include "globals.h"
+#include "global_config.h"
#include "os/keyboard.h"
InputMap *InputMap::singleton=NULL;
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 32eb003228..b4ba14ddc9 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -30,7 +30,7 @@
#include "os/dir_access.h"
#include "os/copymem.h"
-#include "globals.h"
+#include "global_config.h"
#include "map.h"
static Map<String, Vector<uint8_t> >* files = NULL;
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 7bf750f6e1..d9fdc9cedc 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "file_access_network.h"
#include "marshalls.h"
-#include "globals.h"
+#include "global_config.h"
#include "os/os.h"
#include "io/ip.h"
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index d63539a7a5..fa1bebde16 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -31,7 +31,7 @@
#include <stdio.h>
-#define PACK_VERSION 0
+#define PACK_VERSION 1
Error PackedData::add_pack(const String& p_path) {
@@ -167,8 +167,8 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
uint32_t ver_minor = f->get_32();
uint32_t ver_rev = f->get_32();
- ERR_EXPLAIN("Pack version newer than supported by engine: "+itos(version));
- ERR_FAIL_COND_V( version > PACK_VERSION, ERR_INVALID_DATA);
+ ERR_EXPLAIN("Pack version unsupported: "+itos(version));
+ ERR_FAIL_COND_V( version != PACK_VERSION, ERR_INVALID_DATA);
ERR_EXPLAIN("Pack created with a newer version of the engine: "+itos(ver_major)+"."+itos(ver_minor)+"."+itos(ver_rev));
ERR_FAIL_COND_V( ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index aca095b6a5..cf5883121f 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -29,7 +29,7 @@
#include "packet_peer.h"
#include "io/marshalls.h"
-#include "globals.h"
+#include "global_config.h"
/* helpers / binders */
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index c75e476764..2d733842fa 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "version.h"
#include "resource_format_binary.h"
-#include "globals.h"
+#include "global_config.h"
#include "io/file_access_compressed.h"
#include "io/marshalls.h"
#include "os/dir_access.h"
@@ -98,6 +98,27 @@ void ResourceInteractiveLoaderBinary::_advance_padding(uint32_t p_len) {
}
+
+StringName ResourceInteractiveLoaderBinary::_get_string() {
+
+ uint32_t id = f->get_32();
+ if (id&0x80000000) {
+ uint32_t len = id&0x7FFFFFFF;
+ if (len>str_buf.size()) {
+ str_buf.resize(len);
+ }
+ if (len==0)
+ return StringName();
+ f->get_buffer((uint8_t*)&str_buf[0],len);
+ String s;
+ s.parse_utf8(&str_buf[0]);
+ return s;
+ }
+
+ return string_map[id];
+
+}
+
Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
@@ -272,8 +293,8 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
Image::Format fmt=Image::Format(format&format_version_mask); //if format changes, we can add a compatibility bit on top
-
uint32_t datalen = f->get_32();
+ print_line("image format: "+String(Image::get_format_name(fmt))+" datalen "+itos(datalen));
PoolVector<uint8_t> imgdata;
imgdata.resize(datalen);
@@ -282,6 +303,14 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
_advance_padding(datalen);
w=PoolVector<uint8_t>::Write();
+#ifdef TOOLS_ENABLED
+//compatibility
+ int correct_size = Image::get_image_data_size(width,height,fmt,mipmaps?-1:0);
+ if (correct_size < datalen) {
+ WARN_PRINT("Image data was too large, shrinking for compatibility")
+ imgdata.resize(correct_size);
+ }
+#endif
r_v=Image(width,height,mipmaps,fmt,imgdata);
} else {
@@ -323,10 +352,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
for(int i=0;i<name_count;i++)
- names.push_back(string_map[f->get_32()]);
+ names.push_back(_get_string());
for(uint32_t i=0;i<subname_count;i++)
- subnames.push_back(string_map[f->get_32()]);
- property=string_map[f->get_32()];
+ subnames.push_back(_get_string());
+ property=_get_string();
NodePath np = NodePath(names,subnames,absolute,property);
//print_line("got path: "+String(np));
@@ -641,6 +670,8 @@ Error ResourceInteractiveLoaderBinary::poll(){
if (s<external_resources.size()) {
String path = external_resources[s].path;
+
+ print_line("load external res: "+path);
if (remaps.has(path)) {
path=remaps[path];
}
@@ -711,6 +742,8 @@ Error ResourceInteractiveLoaderBinary::poll(){
String t = get_unicode_string();
+// print_line("loading resource of type "+t+" path is "+path);
+
Object *obj = ClassDB::instance(t);
if (!obj) {
error=ERR_FILE_CORRUPT;
@@ -737,8 +770,8 @@ Error ResourceInteractiveLoaderBinary::poll(){
for(int i=0;i<pc;i++) {
- uint32_t name_idx = f->get_32();
- if (name_idx>=(uint32_t)string_map.size()) {
+ StringName name = _get_string();
+ if (name==StringName()) {
error=ERR_FILE_CORRUPT;
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
@@ -749,7 +782,7 @@ Error ResourceInteractiveLoaderBinary::poll(){
if (error)
return error;
- res->set(string_map[name_idx],value);
+ res->set(name,value);
}
#ifdef TOOLS_ENABLED
res->set_edited(false);
@@ -2143,6 +2176,8 @@ void ResourceFormatSaverBinary::get_recognized_extensions(const RES& p_resource,
String base = p_resource->get_base_extension().to_lower();
p_extensions->push_back(base);
+ if (base!="res")
+ p_extensions->push_back("res");
}
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 1dac51cc5c..1fab6144d5 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -54,6 +54,8 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
//Map<int,StringName> string_map;
Vector<StringName> string_map;
+ StringName _get_string();
+
struct ExtResoucre {
String path;
String type;
diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp
index 556dff3125..892c2988dc 100644
--- a/core/io/resource_import.cpp
+++ b/core/io/resource_import.cpp
@@ -81,8 +81,10 @@ RES ResourceFormatImporter::load(const String &p_path,const String& p_original_p
RES res = ResourceLoader::load(pat.path,pat.type,false,r_error);
#ifdef TOOLS_ENABLED
- res->set_import_last_modified_time( res->get_last_modified_time() ); //pass this, if used
- res->set_import_path(pat.path);
+ if (res.is_valid()) {
+ res->set_import_last_modified_time( res->get_last_modified_time() ); //pass this, if used
+ res->set_import_path(pat.path);
+ }
#endif
return res;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 3199f05ff8..c14389eefa 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "resource_loader.h"
#include "print_string.h"
-#include "globals.h"
+#include "global_config.h"
#include "path_remap.h"
#include "os/file_access.h"
#include "os/os.h"
@@ -61,6 +61,7 @@ bool ResourceFormatLoader::recognize_path(const String& p_path,const String& p_f
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
+
if (E->get().nocasecmp_to(extension)==0)
return true;
}
@@ -191,12 +192,15 @@ RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p
for (int i=0;i<loader_count;i++) {
- if (!loader[i]->recognize_path(local_path,p_type_hint))
+ if (!loader[i]->recognize_path(local_path,p_type_hint)) {
+ print_line("path not recognized");
continue;
+ }
found=true;
RES res = loader[i]->load(local_path,local_path,r_error);
- if (res.is_null())
+ if (res.is_null()) {
continue;
+ }
if (!p_no_cache)
res->set_path(local_path);
#ifdef TOOLS_ENABLED
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 222d3e6bc0..f0bea30051 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "resource_saver.h"
-#include "globals.h"
+#include "global_config.h"
#include "os/file_access.h"
#include "script_language.h"
#include "resource_loader.h"
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 13cbbdce6f..1dd7df038d 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -109,6 +109,7 @@ public:
static void get_closest_points_between_segments(const Vector3& p1,const Vector3& p2,const Vector3& q1,const Vector3& q2,Vector3& c1, Vector3& c2)
{
+#if 0
//do the function 'd' as defined by pb. I think is is dot product of some sort
#define d_of(m,n,o,p) ( (m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z) )
@@ -123,6 +124,33 @@ public:
if (mub > 1) mub = 1;
c1 = p1.linear_interpolate(p2,mua);
c2 = q1.linear_interpolate(q2,mub);
+#endif
+
+ Vector3 u = p2 - p1;
+ Vector3 v = q2 - q1;
+ Vector3 w = p1 - q1;
+ float a = u.dot(u);
+ float b = u.dot(v);
+ float c = v.dot(v); // always >= 0
+ float d = u.dot(w);
+ float e = v.dot(w);
+ float D = a*c - b*b; // always >= 0
+ float sc, tc;
+
+ // compute the line parameters of the two closest points
+ if (D < CMP_EPSILON) { // the lines are almost parallel
+ sc = 0.0;
+ tc = (b>c ? d/b : e/c); // use the largest denominator
+ }
+ else {
+ sc = (b*e - c*d) / D;
+ tc = (a*e - b*d) / D;
+ }
+
+ c1 = w + sc * u;
+ c2 = w + tc * v;
+ // get the difference of the two closest points
+ //Vector dP = w + (sc * u) - (tc * v); // = L1(sc) - L2(tc)
}
static real_t get_closest_distance_between_segments( const Vector3& p_from_a,const Vector3& p_to_a, const Vector3& p_from_b,const Vector3& p_to_b) {
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp
index 995cb0834a..76eeece688 100644
--- a/core/math/math_2d.cpp
+++ b/core/math/math_2d.cpp
@@ -157,13 +157,6 @@ bool Vector2::operator!=(const Vector2& p_vec2) const {
return x!=p_vec2.x || y!=p_vec2.y;
}
-bool Vector2::nan_equals(const Vector2& p_vec2) const {
-
- return (x==p_vec2.x && y==p_vec2.y) ||
- (x==p_vec2.x && isnan(y) && isnan(p_vec2.y)) ||
- (isnan(x) && isnan(p_vec2.x) && y == p_vec2.y);
-}
-
Vector2 Vector2::floor() const {
return Vector2( Math::floor(x), Math::floor(y) );
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index 6dd8799ba2..a24c4266ee 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -133,7 +133,6 @@ struct Vector2 {
bool operator<(const Vector2& p_vec2) const { return (x==p_vec2.x)?(y<p_vec2.y):(x<p_vec2.x); }
bool operator<=(const Vector2& p_vec2) const { return (x==p_vec2.x)?(y<=p_vec2.y):(x<=p_vec2.x); }
- bool nan_equals(const Vector2& p_vec2) const;
real_t angle() const;
void set_rotation(real_t p_radians) {
@@ -320,8 +319,6 @@ struct Rect2 {
bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; }
bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; }
- bool nan_equals(const Rect2& p_rect) const { return pos.nan_equals(p_rect.pos) && size == p_rect.size; }
-
inline Rect2 grow(real_t p_by) const {
Rect2 g=*this;
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 511af91835..51877891e3 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -39,6 +39,7 @@
#define Math_PI 3.14159265358979323846
#define Math_SQRT12 0.7071067811865475244008443621048490
#define Math_LN2 0.693147180559945309417
+#define Math_NAN NAN
class Math {
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index 0d446059c4..2a97932049 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -164,8 +164,3 @@ Plane::operator String() const {
return normal.operator String() + ", " + rtos(d);
}
-
-bool Plane::nan_equals(const Plane& p_plane) const {
-
- return normal.nan_equals(p_plane.normal) && d == p_plane.d;
-}
diff --git a/core/math/plane.h b/core/math/plane.h
index 13cfc265bc..8235c59135 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -73,7 +73,6 @@ public:
_FORCE_INLINE_ bool operator==(const Plane& p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane& p_plane) const;
- bool nan_equals(const Plane& p_plane) const;
operator String() const;
_FORCE_INLINE_ Plane() { d=0; }
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 5ba5a7706b..4085f9b84a 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -284,22 +284,3 @@ Quat::Quat(const Vector3& axis, const real_t& angle) {
cos_angle);
}
}
-
-bool Quat::nan_equals(const Quat& q2) const {
- return (x == q2.x && y == q2.y && z == q2.z && w == q2.w) ||
- (x == q2.x && y == q2.y && z == q2.z && isnan(w) && isnan(q2.w)) ||
- (x == q2.x && y == q2.y && isnan(z) && isnan(q2.z) && w == q2.w) ||
- (x == q2.x && y == q2.y && isnan(z) && isnan(q2.z) && isnan(w) && isnan(q2.w)) ||
- (x == q2.x && isnan(y) && isnan(q2.y) && z == q2.z && w == q2.w) ||
- (x == q2.x && isnan(y) && isnan(q2.y) && z == q2.z && isnan(w) && isnan(q2.w)) ||
- (x == q2.x && isnan(y) && isnan(q2.y) && isnan(z) && isnan(q2.z) && w == q2.w) ||
- (x == q2.x && isnan(y) && isnan(q2.y) && isnan(z) && isnan(q2.z) && isnan(w) && isnan(q2.w)) ||
- (isnan(x) && isnan(q2.x) && y == q2.y && z == q2.z && w == q2.w) ||
- (isnan(x) && isnan(q2.x) && y == q2.y && z == q2.z && isnan(w) && isnan(q2.w)) ||
- (isnan(x) && isnan(q2.x) && y == q2.y && isnan(z) && isnan(q2.z) && w == q2.w) ||
- (isnan(x) && isnan(q2.x) && y == q2.y && isnan(z) && isnan(q2.z) && isnan(w) && isnan(q2.w)) ||
- (isnan(x) && isnan(q2.x) && isnan(y) && isnan(q2.y) && z == q2.z && w == q2.w) ||
- (isnan(x) && isnan(q2.x) && isnan(y) && isnan(q2.y) && z == q2.z && isnan(w) && isnan(q2.w)) ||
- (isnan(x) && isnan(q2.x) && isnan(y) && isnan(q2.y) && isnan(z) && isnan(q2.z) && w == q2.w) ||
- (isnan(x) && isnan(q2.x) && isnan(y) && isnan(q2.y) && isnan(z) && isnan(q2.z) && isnan(w) && isnan(q2.w));
-}
diff --git a/core/math/quat.h b/core/math/quat.h
index 5d91bb1d36..d3a50343a3 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -93,7 +93,6 @@ public:
_FORCE_INLINE_ Quat operator*(const real_t& s) const;
_FORCE_INLINE_ Quat operator/(const real_t& s) const;
- bool nan_equals(const Quat& q2) const;
_FORCE_INLINE_ bool operator==(const Quat& p_quat) const;
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
@@ -194,4 +193,5 @@ bool Quat::operator!=(const Quat& p_quat) const {
return x!=p_quat.x || y!=p_quat.y || z!=p_quat.z || w!=p_quat.w;
}
+
#endif
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 7fdb54bb69..2ab5fa0465 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -176,17 +176,6 @@ Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, co
return out;
}
# endif
-bool Vector3::nan_equals(const Vector3& p_v) const {
- return (x == p_v.x && y == p_v.y && z == p_v.z) ||
- (x == p_v.x && y == p_v.y && isnan(z) && isnan(p_v.z)) ||
- (x == p_v.x && isnan(y) && isnan(p_v.y) && z == p_v.z) ||
- (isnan(x) && isnan(p_v.x) && y == p_v.y && z == p_v.z) ||
- (x == p_v.x && isnan(y) && isnan(p_v.y) && isnan(z) && isnan(p_v.z)) ||
- (isnan(x) && isnan(p_v.x) && y == p_v.y && isnan(z) && isnan(p_v.z)) ||
- (isnan(x) && isnan(p_v.x) && isnan(y) && isnan(p_v.y) && z == p_v.z) ||
- (isnan(x) && isnan(p_v.x) && isnan(y) && isnan(p_v.y) && isnan(z) && isnan(p_v.z));
-}
-
Vector3::operator String() const {
return (rtos(x)+", "+rtos(y)+", "+rtos(z));
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 938b1b16cb..a289f9bf4c 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -134,7 +134,6 @@ struct Vector3 {
_FORCE_INLINE_ bool operator<(const Vector3& p_v) const;
_FORCE_INLINE_ bool operator<=(const Vector3& p_v) const;
- bool nan_equals(const Vector3& p_v) const;
operator String() const;
_FORCE_INLINE_ Vector3() { x=y=z=0; }
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index 668d321e05..50b52e4970 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "message_queue.h"
-#include "globals.h"
+#include "global_config.h"
#include "script_language.h"
MessageQueue *MessageQueue::singleton=NULL;
diff --git a/core/object.cpp b/core/object.cpp
index 730b4209fe..79905a6be6 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -383,7 +383,7 @@ void Object::set(const String& p_name, const Variant& p_value) {
if (p_name=="__meta__") {
metadata=p_value;
- } else if (p_name=="script/script") {
+ } else if (p_name=="script") {
set_script(p_value);
} else if (script_instance) {
script_instance->set(p_name,p_value);
@@ -516,7 +516,7 @@ Variant Object::get(const String& p_name) const {
if (p_name=="__meta__")
return metadata;
- else if (p_name=="script/script")
+ else if (p_name=="script")
return script;
if (script_instance) {
@@ -539,7 +539,7 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
if (!is_class("Script")) // can still be set, but this is for userfriendlyness
- p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
+ p_list->push_back( PropertyInfo( Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
if (!metadata.empty())
p_list->push_back( PropertyInfo( Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_STORE_IF_NONZERO));
if (script_instance && !p_reversed) {
@@ -1041,7 +1041,7 @@ void Object::set_script(const RefPtr& p_script) {
}
- _change_notify("script/script");
+ _change_notify("script");
emit_signal(CoreStringNames::get_singleton()->script_changed);
}
diff --git a/core/object.h b/core/object.h
index ba4fa62e1a..3fe31bee6b 100644
--- a/core/object.h
+++ b/core/object.h
@@ -680,7 +680,7 @@ class ObjectDB {
unsigned long i;
} u;
u.p=p_obj;
- return HashMapHahserDefault::hash((uint64_t)u.i);
+ return HashMapHasherDefault::hash((uint64_t)u.i);
}
};
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 804fe15c39..974225a3e8 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -30,7 +30,7 @@
#include "os/file_access.h"
#include "os/memory.h"
#include "os/os.h"
-#include "globals.h"
+#include "global_config.h"
String DirAccess::_get_root_path() const {
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 06723c5131..ae592720e8 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "file_access.h"
-#include "globals.h"
+#include "global_config.h"
#include "os/os.h"
#include "core/io/marshalls.h"
#include "io/md5.h"
diff --git a/core/os/input.cpp b/core/os/input.cpp
index e20c966ff2..34883e63ba 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -29,7 +29,7 @@
#include "input.h"
#include "input_map.h"
#include "os/os.h"
-#include "globals.h"
+#include "global_config.h"
Input *Input::singleton=NULL;
Input *Input::get_singleton() {
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 3a8e15a692..912f7f0b0f 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -29,7 +29,7 @@
#include "os.h"
#include "dir_access.h"
-#include "globals.h"
+#include "global_config.h"
#include "input.h"
#include "os/file_access.h"
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index ab94b56cdc..00f6f8662f 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -35,7 +35,7 @@
#include "io/packet_peer.h"
#include "math/a_star.h"
#include "math/triangle_mesh.h"
-#include "globals.h"
+#include "global_config.h"
#include "class_db.h"
#include "geometry.h"
#include "bind/core_bind.h"
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 62d14c4e5a..b14eb51b6c 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -30,7 +30,7 @@
#include "os/os.h"
#include "io/ip.h"
-#include "globals.h"
+#include "global_config.h"
#include "os/input.h"
void ScriptDebuggerRemote::_send_video_memory() {
diff --git a/core/translation.cpp b/core/translation.cpp
index 655bfd36b8..d9d4fe7784 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "translation.h"
-#include "globals.h"
+#include "global_config.h"
#include "io/resource_loader.h"
#include "os/os.h"
diff --git a/core/ustring.cpp b/core/ustring.cpp
index a0d26ea0af..7d88989d04 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -52,8 +52,40 @@
#define UPPERCASE(m_c) (((m_c)>='a' && (m_c)<='z')?((m_c)-('a'-'A')):(m_c))
#define LOWERCASE(m_c) (((m_c)>='A' && (m_c)<='Z')?((m_c)+('a'-'A')):(m_c))
+
+
+
/** STRING **/
+bool CharString::operator<(const CharString& p_right) const {
+
+ if (length()==0) {
+ return p_right.length()!=0;
+ }
+
+
+ const char *this_str=get_data();
+ const char *that_str=get_data();
+ while (true) {
+
+ if (*that_str==0 && *this_str==0)
+ return false; //this can't be equal, sadly
+ else if (*this_str==0)
+ return true; //if this is empty, and the other one is not, then we're less.. I think?
+ else if (*that_str==0)
+ return false; //otherwise the other one is smaller..
+ else if (*this_str < *that_str ) //more than
+ return true;
+ else if (*this_str > *that_str ) //less than
+ return false;
+
+ this_str++;
+ that_str++;
+ }
+
+ return false; //should never reach here anyway
+}
+
const char *CharString::get_data() const {
if (size())
@@ -4069,12 +4101,8 @@ String String::sprintf(const Array& values, bool* error) const {
case 'X': base = 16; capitalize = true; break;
}
// Get basic number.
- String str = String::num_int64(value, base, capitalize);
-
- // Sign.
- if (show_sign && value >= 0) {
- str = str.insert(0, "+");
- }
+ String str = String::num_int64(ABS(value), base, capitalize);
+ int number_len = str.length();
// Padding.
String pad_char = pad_with_zeroes ? String("0") : String(" ");
@@ -4084,6 +4112,13 @@ String String::sprintf(const Array& values, bool* error) const {
str = str.lpad(min_chars, pad_char);
}
+ // Sign.
+ if (show_sign && value >= 0) {
+ str = str.insert(pad_with_zeroes?0:str.length()-number_len, "+");
+ } else if (value < 0) {
+ str = str.insert(pad_with_zeroes?0:str.length()-number_len, "-");
+ }
+
formatted += str;
++value_index;
in_format = false;
diff --git a/core/ustring.h b/core/ustring.h
index 5665a23112..87289f9e16 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -41,6 +41,8 @@
class CharString : public Vector<char> {
public:
+
+ bool operator<(const CharString& p_right) const;
int length() const { return size() ? size()-1 : 0; }
const char *get_data() const;
operator const char*() {return get_data();};
diff --git a/core/variant.cpp b/core/variant.cpp
index 103c8f6746..132d7a1c88 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -28,6 +28,7 @@
/*************************************************************************/
#include "variant.h"
+#include "math_funcs.h"
#include "resource.h"
#include "print_string.h"
#include "scene/main/node.h"
@@ -2674,14 +2675,10 @@ uint32_t Variant::hash() const {
case INT: {
return _data._int;
-
} break;
case REAL: {
- MarshallFloat mf;
- mf.f=_data._real;
- return mf.i;
-
+ return hash_djb2_one_float(_data._real);
} break;
case STRING: {
@@ -2921,6 +2918,186 @@ uint32_t Variant::hash() const {
}
+#define hash_compare_scalar(p_lhs, p_rhs)\
+ ((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) == Math::is_nan(p_rhs))
+
+#define hash_compare_vector2(p_lhs, p_rhs)\
+ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
+ (hash_compare_scalar((p_lhs).y, (p_rhs).y))
+
+#define hash_compare_vector3(p_lhs, p_rhs)\
+ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
+ (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \
+ (hash_compare_scalar((p_lhs).z, (p_rhs).z))
+
+#define hash_compare_quat(p_lhs, p_rhs)\
+ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
+ (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \
+ (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \
+ (hash_compare_scalar((p_lhs).w, (p_rhs).w))
+
+#define hash_compare_color(p_lhs, p_rhs)\
+ (hash_compare_scalar((p_lhs).r, (p_rhs).r)) && \
+ (hash_compare_scalar((p_lhs).g, (p_rhs).g)) && \
+ (hash_compare_scalar((p_lhs).b, (p_rhs).b)) && \
+ (hash_compare_scalar((p_lhs).a, (p_rhs).a))
+
+#define hash_compare_pool_array(p_lhs, p_rhs, p_type, p_compare_func)\
+ const PoolVector<p_type>& l = *reinterpret_cast<const PoolVector<p_type>*>(p_lhs);\
+ const PoolVector<p_type>& r = *reinterpret_cast<const PoolVector<p_type>*>(p_rhs);\
+ \
+ if(l.size() != r.size()) \
+ return false; \
+ \
+ PoolVector<p_type>::Read lr = l.read(); \
+ PoolVector<p_type>::Read rr = r.read(); \
+ \
+ for(int i = 0; i < l.size(); ++i) { \
+ if(! p_compare_func((lr[0]), (rr[0]))) \
+ return false; \
+ }\
+ \
+ return true
+
+bool Variant::hash_compare(const Variant& p_variant) const {
+ if (type != p_variant.type)
+ return false;
+
+ switch( type ) {
+ case REAL: {
+ return hash_compare_scalar(_data._real, p_variant._data._real);
+ } break;
+
+ case VECTOR2: {
+ const Vector2* l = reinterpret_cast<const Vector2*>(_data._mem);
+ const Vector2* r = reinterpret_cast<const Vector2*>(p_variant._data._mem);
+
+ return hash_compare_vector2(*l, *r);
+ } break;
+
+ case RECT2: {
+ const Rect2* l = reinterpret_cast<const Rect2*>(_data._mem);
+ const Rect2* r = reinterpret_cast<const Rect2*>(p_variant._data._mem);
+
+ return (hash_compare_vector2(l->pos, r->pos)) &&
+ (hash_compare_vector2(l->size, r->size));
+ } break;
+
+ case TRANSFORM2D: {
+ Transform2D* l = _data._transform2d;
+ Transform2D* r = p_variant._data._transform2d;
+
+ for(int i=0;i<3;i++) {
+ if (! (hash_compare_vector2(l->elements[i], r->elements[i])))
+ return false;
+ }
+
+ return true;
+ } break;
+
+ case VECTOR3: {
+ const Vector3* l = reinterpret_cast<const Vector3*>(_data._mem);
+ const Vector3* r = reinterpret_cast<const Vector3*>(p_variant._data._mem);
+
+ return hash_compare_vector3(*l, *r);
+ } break;
+
+ case PLANE: {
+ const Plane* l = reinterpret_cast<const Plane*>(_data._mem);
+ const Plane* r = reinterpret_cast<const Plane*>(p_variant._data._mem);
+
+ return (hash_compare_vector3(l->normal, r->normal)) &&
+ (hash_compare_scalar(l->d, r->d));
+ } break;
+
+ case RECT3: {
+ const Rect3* l = _data._rect3;
+ const Rect3* r = p_variant._data._rect3;
+
+ return (hash_compare_vector3(l->pos, r->pos) &&
+ (hash_compare_vector3(l->size, r->size)));
+
+ } break;
+
+ case QUAT: {
+ const Quat* l = reinterpret_cast<const Quat*>(_data._mem);
+ const Quat* r = reinterpret_cast<const Quat*>(p_variant._data._mem);
+
+ return hash_compare_quat(*l, *r);
+ } break;
+
+ case BASIS: {
+ const Basis* l = _data._basis;
+ const Basis* r = p_variant._data._basis;
+
+ for(int i=0;i<3;i++) {
+ if (! (hash_compare_vector3(l->elements[i], r->elements[i])))
+ return false;
+ }
+
+ return true;
+ } break;
+
+ case TRANSFORM: {
+ const Transform* l = _data._transform;
+ const Transform* r = p_variant._data._transform;
+
+ for(int i=0;i<3;i++) {
+ if (! (hash_compare_vector3(l->basis.elements[i], r->basis.elements[i])))
+ return false;
+ }
+
+ return hash_compare_vector3(l->origin, r->origin);
+ } break;
+
+ case COLOR: {
+ const Color* l = reinterpret_cast<const Color*>(_data._mem);
+ const Color* r = reinterpret_cast<const Color*>(p_variant._data._mem);
+
+ return hash_compare_color(*l, *r);
+ } break;
+
+ case ARRAY: {
+ const Array& l = *(reinterpret_cast<const Array*>(_data._mem));
+ const Array& r = *(reinterpret_cast<const Array*>(p_variant._data._mem));
+
+ if(l.size() != r.size())
+ return false;
+
+ for(int i = 0; i < l.size(); ++i) {
+ if(! l[0].hash_compare(r[0]))
+ return false;
+ }
+
+ return true;
+ } break;
+
+ case POOL_REAL_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, real_t, hash_compare_scalar);
+ } break;
+
+ case POOL_VECTOR2_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, Vector2, hash_compare_vector2);
+ } break;
+
+ case POOL_VECTOR3_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, Vector3, hash_compare_vector3);
+ } break;
+
+ case POOL_COLOR_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, Color, hash_compare_color);
+ } break;
+
+ default:
+ bool v;
+ Variant r;
+ evaluate(OP_EQUAL,*this,p_variant,r,v);
+ return r;
+ }
+
+ return false;
+}
+
bool Variant::is_ref() const {
diff --git a/core/variant.h b/core/variant.h
index 5936325c1b..f9ceca1ca0 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -421,6 +421,7 @@ public:
bool operator<(const Variant& p_variant) const;
uint32_t hash() const;
+ bool hash_compare(const Variant& p_variant) const;
bool booleanize(bool &valid) const;
void static_assign(const Variant& p_variant);
@@ -459,6 +460,10 @@ struct VariantHasher {
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
};
+struct VariantComparator {
+
+ static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); }
+};
Variant::ObjData& Variant::_get_obj() {
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 465de1faed..6ed8a3dd85 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -93,18 +93,6 @@ case m_name: {\
return;\
};
-#define DEFAULT_OP_NUM_NAN(m_op,m_name,m_type)\
-case m_name: {\
- switch(p_b.type) {\
- case BOOL: _RETURN((p_a._data.m_type m_op p_b._data._bool) || (isnan(p_a._data.m_type) && isnan(p_a._data._bool)));\
- case INT: _RETURN((p_a._data.m_type m_op p_b._data._int) || (isnan(p_a._data.m_type) && isnan(p_a._data._int)));\
- case REAL: _RETURN((p_a._data.m_type m_op p_b._data._real) || (isnan(p_a._data.m_type) && isnan(p_a._data._real)));\
- default: {}\
- }\
- r_valid=false;\
- return;\
-};
-
#define DEFAULT_OP_NUM_NEG(m_name,m_type)\
case m_name: {\
\
@@ -144,12 +132,13 @@ case m_name: {\
#define DEFAULT_OP_LOCALMEM(m_op,m_name,m_type)\
case m_name: {switch(p_b.type) {\
- case m_name: _RETURN( (*reinterpret_cast<const m_type*>(p_a._data._mem))m_op(*reinterpret_cast<const m_type*>(p_b._data._mem)));\
+ case m_name: _RETURN( *reinterpret_cast<const m_type*>(p_a._data._mem) m_op *reinterpret_cast<const m_type*>(p_b._data._mem));\
default: {}\
}\
r_valid=false;\
return;}
+
#define DEFAULT_OP_LOCALMEM_NEG(m_name,m_type)\
case m_name: {\
_RETURN( -*reinterpret_cast<const m_type*>(p_a._data._mem));\
@@ -188,28 +177,13 @@ r_valid=false;\
return;}
#define DEFAULT_OP_ARRAY_EQ(m_name,m_type)\
-DEFAULT_OP_ARRAY_OP(m_name,m_type,!=,!=,true,false,false,true)
-
-#define DEFAULT_OP_ARRAY_EQ_NAN(m_name,m_type)\
- DEFAULT_ARRAY_OP_HEAD(m_name,m_type,!=,false,false)\
- if ((ra[i] != rb[i]) && (isnan(ra[i]) != isnan(rb[i])))\
- _RETURN(false);\
- DEFAULT_ARRAY_OP_FOOT(true)
-
-#define DEFAULT_OP_ARRAY_EQ_NAN_V(m_name,m_type)\
-DEFAULT_OP_ARRAY_OP(m_name,m_type,!=,.nan_equals,true,false,false,false)
+DEFAULT_OP_ARRAY_OP(m_name,m_type,!=,!=,true,false,false)
#define DEFAULT_OP_ARRAY_LT(m_name,m_type)\
-DEFAULT_OP_ARRAY_OP(m_name,m_type,<,!=,false,a_len<array_b.size(),true,true)
+DEFAULT_OP_ARRAY_OP(m_name,m_type,<,!=,false,a_len<array_b.size(),true)
-#define DEFAULT_OP_ARRAY_OP(m_name,m_type,m_opa,m_opb,m_ret_def,m_ret_s,m_ret_f,m_neg)\
- DEFAULT_ARRAY_OP_HEAD(m_name,m_type,m_opa,m_ret_s,m_ret_f)\
- if ((((ra[i])m_opb(rb[i]))==m_neg))\
- _RETURN(m_ret_f);\
- DEFAULT_ARRAY_OP_FOOT(m_ret_def)
-
-#define DEFAULT_ARRAY_OP_HEAD(m_name,m_type,m_opa,m_ret_s,m_ret_f)\
- case m_name: { \
+#define DEFAULT_OP_ARRAY_OP(m_name,m_type,m_opa,m_opb,m_ret_def,m_ret_s,m_ret_f)\
+case m_name: { \
if (p_a.type!=p_b.type) {\
r_valid=false;\
return;\
@@ -220,17 +194,17 @@ DEFAULT_OP_ARRAY_OP(m_name,m_type,<,!=,false,a_len<array_b.size(),true,true)
int a_len = array_a.size();\
if (a_len m_opa array_b.size()){\
_RETURN( m_ret_s);\
- } else {\
+ }else {\
\
PoolVector<m_type>::Read ra = array_a.read();\
PoolVector<m_type>::Read rb = array_b.read();\
\
for(int i=0;i<a_len;i++) {\
-
-#define DEFAULT_ARRAY_OP_FOOT(m_ret_def)\
+ if (ra[i] m_opb rb[i])\
+ _RETURN( m_ret_f);\
}\
\
- _RETURN(m_ret_def);\
+ _RETURN( m_ret_def);\
}\
}
@@ -284,16 +258,16 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
_RETURN(p_b.type==NIL || (p_b.type==Variant::OBJECT && !p_b._get_obj().obj));
} break;
- DEFAULT_OP_NUM_NAN(==,BOOL,_bool);
- DEFAULT_OP_NUM_NAN(==,INT,_int);
- DEFAULT_OP_NUM_NAN(==,REAL,_real);
+ DEFAULT_OP_NUM(==,BOOL,_bool);
+ DEFAULT_OP_NUM(==,INT,_int);
+ DEFAULT_OP_NUM(==,REAL,_real);
DEFAULT_OP_STR(==,STRING,String);
- DEFAULT_OP_LOCALMEM(.nan_equals,VECTOR2,Vector2);
- DEFAULT_OP_LOCALMEM(.nan_equals,RECT2,Rect2);
+ DEFAULT_OP_LOCALMEM(==,VECTOR2,Vector2);
+ DEFAULT_OP_LOCALMEM(==,RECT2,Rect2);
DEFAULT_OP_PTRREF(==,TRANSFORM2D,_transform2d);
- DEFAULT_OP_LOCALMEM(.nan_equals,VECTOR3,Vector3);
- DEFAULT_OP_LOCALMEM(.nan_equals,PLANE,Plane);
- DEFAULT_OP_LOCALMEM(.nan_equals,QUAT,Quat);
+ DEFAULT_OP_LOCALMEM(==,VECTOR3,Vector3);
+ DEFAULT_OP_LOCALMEM(==,PLANE,Plane);
+ DEFAULT_OP_LOCALMEM(==,QUAT,Quat);
DEFAULT_OP_PTRREF(==,RECT3,_rect3);
DEFAULT_OP_PTRREF(==,BASIS,_basis);
DEFAULT_OP_PTRREF(==,TRANSFORM,_transform);
@@ -345,11 +319,11 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
DEFAULT_OP_ARRAY_EQ(POOL_BYTE_ARRAY,uint8_t);
- DEFAULT_OP_ARRAY_EQ_NAN(POOL_INT_ARRAY,int);
- DEFAULT_OP_ARRAY_EQ_NAN(POOL_REAL_ARRAY,real_t);
+ DEFAULT_OP_ARRAY_EQ(POOL_INT_ARRAY,int);
+ DEFAULT_OP_ARRAY_EQ(POOL_REAL_ARRAY,real_t);
DEFAULT_OP_ARRAY_EQ(POOL_STRING_ARRAY,String);
- DEFAULT_OP_ARRAY_EQ_NAN_V(POOL_VECTOR2_ARRAY,Vector3);
- DEFAULT_OP_ARRAY_EQ_NAN_V(POOL_VECTOR3_ARRAY,Vector3);
+ DEFAULT_OP_ARRAY_EQ(POOL_VECTOR2_ARRAY,Vector3);
+ DEFAULT_OP_ARRAY_EQ(POOL_VECTOR3_ARRAY,Vector3);
DEFAULT_OP_ARRAY_EQ(POOL_COLOR_ARRAY,Color);
case VARIANT_MAX: {
@@ -442,9 +416,9 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
switch(p_a.type) {
DEFAULT_OP_FAIL(NIL);
- DEFAULT_OP_NUM_NAN(<=,BOOL,_bool);
- DEFAULT_OP_NUM_NAN(<=,INT,_int);
- DEFAULT_OP_NUM_NAN(<=,REAL,_real);
+ DEFAULT_OP_NUM(<=,BOOL,_bool);
+ DEFAULT_OP_NUM(<=,INT,_int);
+ DEFAULT_OP_NUM(<=,REAL,_real);
DEFAULT_OP_STR(<=,STRING,String);
DEFAULT_OP_LOCALMEM(<=,VECTOR2,Vector2);
DEFAULT_OP_FAIL(RECT2);