From e8fc6bfeb53801447de25c12ba7536f574d121f4 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 8 Jul 2022 15:01:02 +0200 Subject: [Core] Make ImageFormatLoader extensible. --- core/io/image_loader.cpp | 54 +++++++++++++++++++++++++++++++++++++++++------- core/io/image_loader.h | 51 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 85 insertions(+), 20 deletions(-) (limited to 'core/io') diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index d09697b951..d6854666c0 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -32,6 +32,12 @@ #include "core/string/print_string.h" +void ImageFormatLoader::_bind_methods() { + BIND_BITFIELD_FLAG(FLAG_NONE); + BIND_BITFIELD_FLAG(FLAG_FORCE_LINEAR); + BIND_BITFIELD_FLAG(FLAG_CONVERT_COLORS); +} + bool ImageFormatLoader::recognize(const String &p_extension) const { List extensions; get_recognized_extensions(&extensions); @@ -44,7 +50,39 @@ bool ImageFormatLoader::recognize(const String &p_extension) const { return false; } -Error ImageLoader::load_image(String p_file, Ref p_image, Ref p_custom, uint32_t p_flags, float p_scale) { +Error ImageFormatLoaderExtension::load_image(Ref p_image, Ref p_fileaccess, BitField p_flags, float p_scale) { + Error err; + if (GDVIRTUAL_CALL(_load_image, p_image, p_fileaccess, p_flags, p_scale, err)) { + return err; + } + return ERR_UNAVAILABLE; +} + +void ImageFormatLoaderExtension::get_recognized_extensions(List *p_extension) const { + PackedStringArray ext; + if (GDVIRTUAL_CALL(_get_recognized_extensions, ext)) { + for (int i = 0; i < ext.size(); i++) { + p_extension->push_back(ext[i]); + } + } +} + +void ImageFormatLoaderExtension::add_format_loader() { + ImageLoader::add_image_format_loader(this); +} + +void ImageFormatLoaderExtension::remove_format_loader() { + ImageLoader::remove_image_format_loader(this); +} + +void ImageFormatLoaderExtension::_bind_methods() { + GDVIRTUAL_BIND(_get_recognized_extensions); + GDVIRTUAL_BIND(_load_image, "image", "fileaccess", "flags", "scale"); + ClassDB::bind_method(D_METHOD("add_format_loader"), &ImageFormatLoaderExtension::add_format_loader); + ClassDB::bind_method(D_METHOD("remove_format_loader"), &ImageFormatLoaderExtension::remove_format_loader); +} + +Error ImageLoader::load_image(String p_file, Ref p_image, Ref p_custom, BitField p_flags, float p_scale) { ERR_FAIL_COND_V_MSG(p_image.is_null(), ERR_INVALID_PARAMETER, "It's not a reference to a valid Image object."); Ref f = p_custom; @@ -60,7 +98,7 @@ Error ImageLoader::load_image(String p_file, Ref p_image, Ref if (!loader[i]->recognize(extension)) { continue; } - Error err = loader[i]->load_image(p_image, f, p_flags, p_scale); + Error err = loader.write[i]->load_image(p_image, f, p_flags, p_scale); if (err != OK) { ERR_PRINT("Error loading image: " + p_file); } @@ -79,7 +117,7 @@ void ImageLoader::get_recognized_extensions(List *p_extensions) { } } -ImageFormatLoader *ImageLoader::recognize(const String &p_extension) { +Ref ImageLoader::recognize(const String &p_extension) { for (int i = 0; i < loader.size(); i++) { if (loader[i]->recognize(p_extension)) { return loader[i]; @@ -89,17 +127,17 @@ ImageFormatLoader *ImageLoader::recognize(const String &p_extension) { return nullptr; } -Vector ImageLoader::loader; +Vector> ImageLoader::loader; -void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) { +void ImageLoader::add_image_format_loader(Ref p_loader) { loader.push_back(p_loader); } -void ImageLoader::remove_image_format_loader(ImageFormatLoader *p_loader) { +void ImageLoader::remove_image_format_loader(Ref p_loader) { loader.erase(p_loader); } -const Vector &ImageLoader::get_image_format_loaders() { +const Vector> &ImageLoader::get_image_format_loaders() { return loader; } @@ -152,7 +190,7 @@ Ref ResourceFormatLoaderImage::load(const String &p_path, const String Ref image; image.instantiate(); - Error err = ImageLoader::loader[idx]->load_image(image, f); + Error err = ImageLoader::loader.write[idx]->load_image(image, f); if (err != OK) { if (r_error) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index bf78005e40..f70fdf22aa 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -31,23 +31,23 @@ #ifndef IMAGE_LOADER_H #define IMAGE_LOADER_H +#include "core/core_bind.h" #include "core/io/file_access.h" #include "core/io/image.h" #include "core/io/resource_loader.h" +#include "core/object/gdvirtual.gen.inc" #include "core/string/ustring.h" #include "core/templates/list.h" +#include "core/variant/binder_common.h" class ImageLoader; -class ImageFormatLoader { +class ImageFormatLoader : public RefCounted { + GDCLASS(ImageFormatLoader, RefCounted); + friend class ImageLoader; friend class ResourceFormatLoaderImage; -protected: - virtual Error load_image(Ref p_image, Ref p_fileaccess, uint32_t p_flags = (uint32_t)FLAG_NONE, float p_scale = 1.0) = 0; - virtual void get_recognized_extensions(List *p_extensions) const = 0; - bool recognize(const String &p_extension) const; - public: enum LoaderFlags { FLAG_NONE = 0, @@ -55,23 +55,50 @@ public: FLAG_CONVERT_COLORS = 2, }; +protected: + static void _bind_methods(); + + virtual Error load_image(Ref p_image, Ref p_fileaccess, BitField p_flags = FLAG_NONE, float p_scale = 1.0) = 0; + virtual void get_recognized_extensions(List *p_extensions) const = 0; + bool recognize(const String &p_extension) const; + +public: virtual ~ImageFormatLoader() {} }; +VARIANT_BITFIELD_CAST(ImageFormatLoader::LoaderFlags); + +class ImageFormatLoaderExtension : public ImageFormatLoader { + GDCLASS(ImageFormatLoaderExtension, ImageFormatLoader); + +protected: + static void _bind_methods(); + +public: + virtual Error load_image(Ref p_image, Ref p_fileaccess, BitField p_flags = FLAG_NONE, float p_scale = 1.0) override; + virtual void get_recognized_extensions(List *p_extensions) const override; + + void add_format_loader(); + void remove_format_loader(); + + GDVIRTUAL0RC(PackedStringArray, _get_recognized_extensions); + GDVIRTUAL4R(Error, _load_image, Ref, Ref, BitField, float); +}; + class ImageLoader { - static Vector loader; + static Vector> loader; friend class ResourceFormatLoaderImage; protected: public: - static Error load_image(String p_file, Ref p_image, Ref p_custom = Ref(), uint32_t p_flags = (uint32_t)ImageFormatLoader::FLAG_NONE, float p_scale = 1.0); + static Error load_image(String p_file, Ref p_image, Ref p_custom = Ref(), BitField p_flags = ImageFormatLoader::FLAG_NONE, float p_scale = 1.0); static void get_recognized_extensions(List *p_extensions); - static ImageFormatLoader *recognize(const String &p_extension); + static Ref recognize(const String &p_extension); - static void add_image_format_loader(ImageFormatLoader *p_loader); - static void remove_image_format_loader(ImageFormatLoader *p_loader); + static void add_image_format_loader(Ref p_loader); + static void remove_image_format_loader(Ref p_loader); - static const Vector &get_image_format_loaders(); + static const Vector> &get_image_format_loaders(); static void cleanup(); }; -- cgit v1.2.3