diff options
Diffstat (limited to 'core')
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); |