diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/config/project_settings.cpp | 19 | ||||
-rw-r--r-- | core/extension/gdnative_interface.h | 2 | ||||
-rw-r--r-- | core/extension/native_extension.cpp | 2 | ||||
-rw-r--r-- | core/io/image.cpp | 51 | ||||
-rw-r--r-- | core/io/image.h | 18 | ||||
-rw-r--r-- | core/io/zip_io.cpp | 12 | ||||
-rw-r--r-- | core/object/class_db.cpp | 5 | ||||
-rw-r--r-- | core/object/object.h | 2 | ||||
-rw-r--r-- | core/string/ustring.cpp | 11 | ||||
-rw-r--r-- | core/variant/array.cpp | 6 | ||||
-rw-r--r-- | core/variant/array.h | 1 | ||||
-rw-r--r-- | core/variant/container_type_validate.h | 15 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 1 |
13 files changed, 99 insertions, 46 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 001a351e0b..beef773699 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -153,8 +153,23 @@ const PackedStringArray ProjectSettings::_trim_to_supported_features(const Packe #endif // TOOLS_ENABLED String ProjectSettings::localize_path(const String &p_path) const { - if (resource_path.is_empty() || p_path.begins_with("res://") || p_path.begins_with("user://") || - (p_path.is_absolute_path() && !p_path.begins_with(resource_path))) { + if (resource_path.is_empty() || (p_path.is_absolute_path() && !p_path.begins_with(resource_path))) { + return p_path.simplify_path(); + } + + // Check if we have a special path (like res://) or a protocol identifier. + int p = p_path.find("://"); + bool found = false; + if (p > 0) { + found = true; + for (int i = 0; i < p; i++) { + if (!is_ascii_alphanumeric_char(p_path[i])) { + found = false; + break; + } + } + } + if (found) { return p_path.simplify_path(); } diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 4513c66ab5..1ce50bc186 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -234,6 +234,8 @@ typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtension typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name); typedef struct { + GDNativeBool is_virtual; + GDNativeBool is_abstract; GDNativeExtensionClassSet set_func; GDNativeExtensionClassGet get_func; GDNativeExtensionClassGetPropertyList get_property_list_func; diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index 6418da2235..cc019584a5 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -152,6 +152,8 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr extension->native_extension.parent_class_name = parent_class_name; extension->native_extension.class_name = class_name; extension->native_extension.editor_class = self->level_initialized == INITIALIZATION_LEVEL_EDITOR; + extension->native_extension.is_virtual = p_extension_funcs->is_virtual; + extension->native_extension.is_abstract = p_extension_funcs->is_abstract; extension->native_extension.set = p_extension_funcs->set_func; extension->native_extension.get = p_extension_funcs->get_func; extension->native_extension.get_property_list = p_extension_funcs->get_property_list_func; diff --git a/core/io/image.cpp b/core/io/image.cpp index 4be624a5a8..3450eb7abd 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -982,7 +982,7 @@ void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) { } void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { - ERR_FAIL_COND_MSG(data.size() == 0, "Cannot resize image before creating it, use create() or create_from_data() first."); + ERR_FAIL_COND_MSG(data.size() == 0, "Cannot resize image before creating it, use set_data() first."); ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats."); bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */; @@ -1017,7 +1017,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } bool interpolate_mipmaps = mipmap_aware && mip1 != mip2; if (interpolate_mipmaps) { - dst2.create(p_width, p_height, false, format); + dst2.initialize_data(p_width, p_height, false, format); } bool had_mipmaps = mipmaps; @@ -2016,9 +2016,7 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con uint8_t* wr = imgdata.ptrw(); memcpy(wr.ptr(), ptr, size); wr = uint8_t*(); - Ref<Image> im; - im.instantiate(); - im->create(w, h, false, format, imgdata); + Ref<Image> im = Image::create_from_data(w, h, false, format, imgdata); im->save_png("res://mipmap_" + itos(i) + ".png"); } #endif @@ -2051,7 +2049,25 @@ Vector<uint8_t> Image::get_data() const { return data; } -void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { +Ref<Image> Image::create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { + Ref<Image> image; + image.instantiate(); + image->initialize_data(p_width, p_height, p_use_mipmaps, p_format); + return image; +} + +Ref<Image> Image::create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { + Ref<Image> image; + image.instantiate(); + image->initialize_data(p_width, p_height, p_use_mipmaps, p_format, p_data); + return image; +} + +void Image::set_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { + initialize_data(p_width, p_height, p_use_mipmaps, p_format, p_data); +} + +void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels."); ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels."); ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, @@ -2077,7 +2093,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma format = p_format; } -void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { +void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels."); ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels."); ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, @@ -2115,7 +2131,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma mipmaps = p_use_mipmaps; } -void Image::create(const char **p_xpm) { +void Image::initialize_data(const char **p_xpm) { int size_width = 0; int size_height = 0; int pixelchars = 0; @@ -2230,7 +2246,7 @@ void Image::create(const char **p_xpm) { } if (line == colormap_size) { status = READING_PIXELS; - create(size_width, size_height, false, has_alpha ? FORMAT_RGBA8 : FORMAT_RGB8); + initialize_data(size_width, size_height, false, has_alpha ? FORMAT_RGBA8 : FORMAT_RGB8); data_write = data.ptrw(); pixel_size = has_alpha ? 4 : 3; } @@ -2559,7 +2575,7 @@ Image::Image(const char **p_xpm) { mipmaps = false; format = FORMAT_L8; - create(p_xpm); + initialize_data(p_xpm); } Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { @@ -2568,7 +2584,7 @@ Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { mipmaps = p_use_mipmaps; format = FORMAT_L8; - create(p_width, p_height, p_use_mipmaps, p_format); + initialize_data(p_width, p_height, p_use_mipmaps, p_format); } Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { @@ -2577,7 +2593,7 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const V mipmaps = p_mipmaps; format = FORMAT_L8; - create(p_width, p_height, p_mipmaps, p_format, p_data); + initialize_data(p_width, p_height, p_mipmaps, p_format, p_data); } Rect2i Image::get_used_rect() const { @@ -2931,7 +2947,7 @@ void Image::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(ddformat == FORMAT_MAX); - create(dwidth, dheight, dmipmaps, ddformat, ddata); + initialize_data(dwidth, dheight, dmipmaps, ddformat, ddata); } Dictionary Image::_get_data() const { @@ -3294,8 +3310,9 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_mipmaps", "renormalize"), &Image::generate_mipmaps, DEFVAL(false)); ClassDB::bind_method(D_METHOD("clear_mipmaps"), &Image::clear_mipmaps); - ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::create_empty); - ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::create_from_data); + ClassDB::bind_static_method("Image", D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::create_empty); + ClassDB::bind_static_method("Image", D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::create_from_data); + ClassDB::bind_method(D_METHOD("set_data", "width", "height", "use_mipmaps", "format", "data"), &Image::set_data); ClassDB::bind_method(D_METHOD("is_empty"), &Image::is_empty); @@ -3460,9 +3477,7 @@ Ref<Image> Image::rgbe_to_srgb() { ERR_FAIL_COND_V(format != FORMAT_RGBE9995, Ref<Image>()); - Ref<Image> new_image; - new_image.instantiate(); - new_image->create(width, height, false, Image::FORMAT_RGB8); + Ref<Image> new_image = create_empty(width, height, false, Image::FORMAT_RGB8); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { diff --git a/core/io/image.h b/core/io/image.h index fd264a7a38..194ee05bc7 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -279,12 +279,12 @@ public: void normalize(); //for normal maps /** - * Create a new image of a given size and format. Current image will be lost + * Creates new internal image data of a given size and format. Current image will be lost. */ - void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format); - void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); + void initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format); + void initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); + void initialize_data(const char **p_xpm); - void create(const char **p_xpm); /** * returns true when the image is empty (0,0) in size */ @@ -303,13 +303,9 @@ public: Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const; Vector<uint8_t> save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const; - void create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { - create(p_width, p_height, p_use_mipmaps, p_format); - } - - void create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { - create(p_width, p_height, p_use_mipmaps, p_format, p_data); - } + static Ref<Image> create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format); + static Ref<Image> create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); + void set_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); /** * create an empty image diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index e573e8de19..200e5f5e83 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -37,11 +37,17 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) { String fname; fname.parse_utf8(p_fname); + int file_access_mode = 0; if (mode & ZLIB_FILEFUNC_MODE_WRITE) { - (*fa) = FileAccess::open(fname, FileAccess::WRITE); - } else { - (*fa) = FileAccess::open(fname, FileAccess::READ); + file_access_mode |= FileAccess::WRITE; } + if (mode & ZLIB_FILEFUNC_MODE_READ) { + file_access_mode |= FileAccess::READ; + } + if (mode & ZLIB_FILEFUNC_MODE_CREATE) { + file_access_mode |= FileAccess::WRITE_READ; + } + (*fa) = FileAccess::open(fname, file_access_mode); if (fa->is_null()) { return nullptr; diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index ca56add2ab..41585943b3 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1528,7 +1528,10 @@ void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) { c.api = p_extension->editor_class ? API_EDITOR_EXTENSION : API_EXTENSION; c.native_extension = p_extension; c.name = p_extension->class_name; - c.creation_func = parent->creation_func; + c.is_virtual = p_extension->is_virtual; + if (!p_extension->is_abstract) { + c.creation_func = parent->creation_func; + } c.inherits = parent->name; c.class_ptr = parent->class_ptr; c.inherits_ptr = parent; diff --git a/core/object/object.h b/core/object/object.h index 5ba5453b31..359ab0f211 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -295,6 +295,8 @@ struct ObjectNativeExtension { StringName parent_class_name; StringName class_name; bool editor_class = false; + bool is_virtual = false; + bool is_abstract = false; GDNativeExtensionClassSet set; GDNativeExtensionClassGet get; GDNativeExtensionClassGetPropertyList get_property_list; diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 671b06f0ed..c86c8316fe 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1567,10 +1567,11 @@ String String::num_real(double p_num, bool p_trailing) { #else int decimals = 6; #endif - // We want to align the digits to the above sane default, so we only - // need to subtract log10 for numbers with a positive power of ten. - if (p_num > 10) { - decimals -= (int)floor(log10(p_num)); + // We want to align the digits to the above sane default, so we only need + // to subtract log10 for numbers with a positive power of ten magnitude. + double abs_num = Math::abs(p_num); + if (abs_num > 10) { + decimals -= (int)floor(log10(abs_num)); } return num(p_num, decimals); } @@ -3674,7 +3675,7 @@ String String::simplify_path() const { if (p > 0) { bool only_chars = true; for (int i = 0; i < p; i++) { - if (!is_ascii_char(s[i])) { + if (!is_ascii_alphanumeric_char(s[i])) { only_chars = false; break; } diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 8b958814db..c6bbd43dc4 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -31,6 +31,7 @@ #include "array.h" #include "container_type_validate.h" +#include "core/math/math_funcs.h" #include "core/object/class_db.h" #include "core/object/script_language.h" #include "core/templates/hashfuncs.h" @@ -299,6 +300,11 @@ Variant Array::back() const { return operator[](_p->array.size() - 1); } +Variant Array::pick_random() const { + ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array."); + return operator[](Math::rand() % _p->array.size()); +} + int Array::find(const Variant &p_value, int p_from) const { ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1); return _p->array.find(p_value, p_from); diff --git a/core/variant/array.h b/core/variant/array.h index 3d9a794969..ee265a9ffd 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -79,6 +79,7 @@ public: Variant front() const; Variant back() const; + Variant pick_random() const; void sort(); void sort_custom(const Callable &p_callable); diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h index 6171c8c88f..427a337aab 100644 --- a/core/variant/container_type_validate.h +++ b/core/variant/container_type_validate.h @@ -79,9 +79,12 @@ struct ContainerTypeValidate { return true; } - ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); if (type != p_variant.get_type()) { - return false; + if (p_variant.get_type() == Variant::NIL && type == Variant::OBJECT) { + return true; + } + + ERR_FAIL_V_MSG(false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); } if (type != Variant::OBJECT) { @@ -90,7 +93,7 @@ struct ContainerTypeValidate { #ifdef DEBUG_ENABLED ObjectID object_id = p_variant; if (object_id == ObjectID()) { - return true; //fine its null; + return true; // This is fine, it's null. } Object *object = ObjectDB::get_instance(object_id); ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + "."); @@ -101,7 +104,7 @@ struct ContainerTypeValidate { } #endif if (class_name == StringName()) { - return true; //all good, no class type requested + return true; // All good, no class type requested. } StringName obj_class = object->get_class_name(); @@ -110,12 +113,12 @@ struct ContainerTypeValidate { } if (script.is_null()) { - return true; //all good + return true; // All good, no script requested. } Ref<Script> other_script = object->get_script(); - //check base script.. + // Check base script.. ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 900e3d8e77..ef4807ba71 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -2053,6 +2053,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, erase, sarray("value"), varray()); bind_method(Array, front, sarray(), varray()); bind_method(Array, back, sarray(), varray()); + bind_method(Array, pick_random, sarray(), varray()); bind_method(Array, find, sarray("what", "from"), varray(0)); bind_method(Array, rfind, sarray("what", "from"), varray(-1)); bind_method(Array, find_last, sarray("value"), varray()); |