diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/etc/SCsub | 6 | ||||
| -rw-r--r-- | modules/etc/image_etc.cpp | 2 | ||||
| -rw-r--r-- | modules/gdnative/SCsub | 12 | ||||
| -rw-r--r-- | modules/gdnative/config.py | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative.cpp | 42 | ||||
| -rw-r--r-- | modules/gdnative/gdnative.h | 24 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/array.cpp (renamed from modules/gdnative/godot/array.cpp) | 16 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/basis.cpp (renamed from modules/gdnative/godot/basis.cpp) | 20 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/color.cpp (renamed from modules/gdnative/godot/color.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/dictionary.cpp (renamed from modules/gdnative/godot/dictionary.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/gdnative.cpp (renamed from modules/gdnative/godot/gdnative.cpp) | 3 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/node_path.cpp (renamed from modules/gdnative/godot/node_path.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/plane.cpp (renamed from modules/gdnative/godot/plane.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/pool_arrays.cpp (renamed from modules/gdnative/godot/pool_arrays.cpp) | 16 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/quat.cpp (renamed from modules/gdnative/godot/quat.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/rect2.cpp (renamed from modules/gdnative/godot/rect2.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/rect3.cpp (renamed from modules/gdnative/godot/rect3.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/rid.cpp (renamed from modules/gdnative/godot/rid.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/string.cpp (renamed from modules/gdnative/godot/string.cpp) | 4 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/transform.cpp (renamed from modules/gdnative/godot/transform.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/transform2d.cpp (renamed from modules/gdnative/godot/transform2d.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/variant.cpp (renamed from modules/gdnative/godot/variant.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/vector2.cpp (renamed from modules/gdnative/godot/vector2.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/gdnative/vector3.cpp (renamed from modules/gdnative/godot/vector3.cpp) | 2 | ||||
| -rw-r--r-- | modules/gdnative/godot/icon.png.import | 23 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/array.h (renamed from modules/gdnative/godot/array.h) | 8 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/basis.h (renamed from modules/gdnative/godot/basis.h) | 12 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/color.h (renamed from modules/gdnative/godot/color.h) | 4 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/dictionary.h (renamed from modules/gdnative/godot/dictionary.h) | 8 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/gdnative.h (renamed from modules/gdnative/godot/gdnative.h) | 62 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/node_path.h (renamed from modules/gdnative/godot/node_path.h) | 6 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/plane.h (renamed from modules/gdnative/godot/plane.h) | 4 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/pool_arrays.h (renamed from modules/gdnative/godot/pool_arrays.h) | 24 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/quat.h (renamed from modules/gdnative/godot/quat.h) | 4 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/rect2.h (renamed from modules/gdnative/godot/rect2.h) | 4 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/rect3.h (renamed from modules/gdnative/godot/rect3.h) | 6 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/rid.h (renamed from modules/gdnative/godot/rid.h) | 4 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/string.h (renamed from modules/gdnative/godot/string.h) | 8 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/transform.h (renamed from modules/gdnative/godot/transform.h) | 8 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/transform2d.h (renamed from modules/gdnative/godot/transform2d.h) | 6 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/variant.h (renamed from modules/gdnative/godot/variant.h) | 40 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/vector2.h (renamed from modules/gdnative/godot/vector2.h) | 2 | ||||
| -rw-r--r-- | modules/gdnative/include/gdnative/vector3.h (renamed from modules/gdnative/godot/vector3.h) | 4 | ||||
| -rw-r--r-- | modules/gdnative/include/nativescript/godot_nativescript.h (renamed from modules/nativescript/godot_nativescript.h) | 6 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/SCsub (renamed from modules/nativescript/SCsub) | 0 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/api_generator.cpp (renamed from modules/nativescript/api_generator.cpp) | 82 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/api_generator.h (renamed from modules/nativescript/api_generator.h) | 0 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/godot_nativescript.cpp (renamed from modules/nativescript/godot_nativescript.cpp) | 8 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/nativescript.cpp (renamed from modules/nativescript/nativescript.cpp) | 4 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/nativescript.h (renamed from modules/nativescript/nativescript.h) | 2 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/register_types.cpp (renamed from modules/nativescript/register_types.cpp) | 0 | ||||
| -rw-r--r-- | modules/gdnative/nativescript/register_types.h (renamed from modules/nativescript/register_types.h) | 0 | ||||
| -rw-r--r-- | modules/gdnative/register_types.cpp | 176 | ||||
| -rw-r--r-- | modules/gdscript/gd_editor.cpp | 10 | ||||
| -rw-r--r-- | modules/gdscript/gd_function.cpp | 8 | ||||
| -rw-r--r-- | modules/gdscript/gd_functions.cpp | 32 | ||||
| -rw-r--r-- | modules/gdscript/gd_parser.cpp | 8 | ||||
| -rw-r--r-- | modules/gdscript/gd_script.h | 1 | ||||
| -rw-r--r-- | modules/gridmap/grid_map.cpp | 6 | ||||
| -rw-r--r-- | modules/gridmap/grid_map_editor_plugin.cpp | 4 | ||||
| -rw-r--r-- | modules/hdr/image_loader_hdr.cpp | 2 | ||||
| -rw-r--r-- | modules/hdr/image_loader_hdr.h | 2 | ||||
| -rw-r--r-- | modules/nativescript/config.py | 8 | ||||
| -rw-r--r-- | modules/openssl/SCsub | 2 | ||||
| -rw-r--r-- | modules/regex/SCsub | 50 | ||||
| -rw-r--r-- | modules/regex/regex.cpp | 1560 | ||||
| -rw-r--r-- | modules/regex/regex.h | 47 | ||||
| -rw-r--r-- | modules/squish/image_compress_squish.cpp | 6 | ||||
| -rw-r--r-- | modules/stb_vorbis/audio_stream_ogg_vorbis.cpp | 5 | ||||
| -rw-r--r-- | modules/stb_vorbis/audio_stream_ogg_vorbis.h | 3 | ||||
| -rw-r--r-- | modules/svg/image_loader_svg.cpp | 51 | ||||
| -rw-r--r-- | modules/svg/image_loader_svg.h | 7 | ||||
| -rw-r--r-- | modules/tga/image_loader_tga.cpp | 12 | ||||
| -rw-r--r-- | modules/tga/image_loader_tga.h | 2 | ||||
| -rw-r--r-- | modules/tinyexr/image_loader_tinyexr.cpp | 2 | ||||
| -rw-r--r-- | modules/tinyexr/image_loader_tinyexr.h | 2 | ||||
| -rw-r--r-- | modules/visual_script/visual_script.h | 1 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_editor.cpp | 28 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_expression.cpp | 2 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_nodes.cpp | 9 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_nodes.h | 2 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_yield_nodes.cpp | 2 | ||||
| -rw-r--r-- | modules/webm/video_stream_webm.cpp | 2 | ||||
| -rw-r--r-- | modules/webm/video_stream_webm.h | 2 |
84 files changed, 922 insertions, 1644 deletions
diff --git a/modules/etc/SCsub b/modules/etc/SCsub index 8f5937017e..9c3e703f11 100644 --- a/modules/etc/SCsub +++ b/modules/etc/SCsub @@ -34,4 +34,8 @@ env_etc.Append(CPPPATH=[thirdparty_dir]) env_etc.add_source_files(env.modules_sources, "*.cpp") # upstream uses c++11 -env_etc.Append(CXXFLAGS="-std=gnu++11") +env_etc.Append(CCFLAGS="-std=gnu++11") +# -ffast-math seems to be incompatible with ec2comp on recent versions of +# GCC and Clang +if '-ffast-math' in env_etc['CCFLAGS']: + env_etc['CCFLAGS'].remove('-ffast-math') diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index 9a15beb6eb..e86fd06d81 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -117,7 +117,7 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f return; } - int imgw = p_img->get_width(), imgh = p_img->get_height(); + uint32_t imgw = p_img->get_width(), imgh = p_img->get_height(); ERR_FAIL_COND(next_power_of_2(imgw) != imgw || next_power_of_2(imgh) != imgh); Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels); diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 65970d48c1..f386f2b542 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -2,12 +2,16 @@ Import('env') -env.add_source_files(env.modules_sources, "*.cpp") -env.add_source_files(env.modules_sources, "godot/*.cpp") +gdn_env = env.Clone() -env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN']) -env.Append(CPPPATH=['#modules/gdnative/']) +gdn_env.add_source_files(env.modules_sources, "*.cpp") +gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp") +gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp") + +gdn_env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN']) +gdn_env.Append(CPPPATH=['#modules/gdnative/include/']) if "platform" in env and env["platform"] == "x11": # there has to be a better solution? env.Append(LINKFLAGS=["-rdynamic"]) + env.use_ptrcall = True diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py index 4f89ca0d4c..9f57b9bb74 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -1,7 +1,7 @@ def can_build(platform): - return False + return True def configure(env): diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 7faf21c5a1..6da538844a 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -40,7 +40,7 @@ const String init_symbol = "godot_gdnative_init"; const String terminate_symbol = "godot_gdnative_terminate"; -String GDNativeLibrary::platform_names[NUM_PLATFORMS] = { +String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = { "X11_32bit", "X11_64bit", "Windows_32bit", @@ -48,11 +48,15 @@ String GDNativeLibrary::platform_names[NUM_PLATFORMS] = { "OSX", "Android", - "iOS", - "WebAssembly" + "iOS_32bit", + "iOS_64bit", + + "WebAssembly", + + "" }; -String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = { +String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = { "so", "so", "dll", @@ -60,21 +64,30 @@ String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = { "dylib", "so", + + "dylib", "dylib", - "wasm" + "wasm", + + "" }; -// TODO(karroffel): make this actually do the right thing. GDNativeLibrary::Platform GDNativeLibrary::current_platform = #if defined(X11_ENABLED) - X11_64BIT; + (sizeof(void *) == 8 ? X11_64BIT : X11_32BIT); #elif defined(WINDOWS_ENABLED) - WINDOWS_64BIT; + (sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT); #elif defined(OSX_ENABLED) OSX; +#elif defined(IPHONE_ENABLED) + (sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT); +#elif defined(ANDROID_ENABLED) + ANDROID; +#elif defined(JAVASCRIPT_ENABLED) + WASM; #else - X11_64BIT; // need a sensible default.. + NUM_PLATFORMS; #endif GDNativeLibrary::GDNativeLibrary() @@ -87,6 +100,11 @@ GDNativeLibrary::~GDNativeLibrary() { void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_library_path", "platform", "path"), &GDNativeLibrary::set_library_path); ClassDB::bind_method(D_METHOD("get_library_path", "platform"), &GDNativeLibrary::get_library_path); + + ClassDB::bind_method(D_METHOD("is_singleton_gdnative"), &GDNativeLibrary::is_singleton_gdnative); + ClassDB::bind_method(D_METHOD("set_singleton_gdnative", "singleton"), &GDNativeLibrary::set_singleton_gdnative); + + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton_gdnative"), "set_singleton_gdnative", "is_singleton_gdnative"); } bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_value) { @@ -151,7 +169,10 @@ String GDNativeLibrary::get_library_path(StringName p_platform) const { } String GDNativeLibrary::get_active_library_path() const { - return library_paths[GDNativeLibrary::current_platform]; + if (GDNativeLibrary::current_platform != NUM_PLATFORMS) { + return library_paths[GDNativeLibrary::current_platform]; + } + return ""; } GDNative::GDNative() { @@ -159,7 +180,6 @@ GDNative::GDNative() { } GDNative::~GDNative() { - // TODO(karroffel): implement ALL the things! } extern "C" void _api_anchor(); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index bec746a441..4753c7efe5 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -35,7 +35,7 @@ #include "os/thread_safe.h" #include "resource.h" -#include <godot/gdnative.h> +#include "gdnative/gdnative.h" class GDNativeLibrary : public Resource { GDCLASS(GDNativeLibrary, Resource) @@ -48,11 +48,17 @@ class GDNativeLibrary : public Resource { // NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only OSX, - // TODO(karroffel): all different android versions and archs + // Android .so files must be located in directories corresponding to Android ABI names: + // https://developer.android.com/ndk/guides/abis.html + // Android runtime will select the matching library depending on the device. + // The value here must simply point to the .so name, for example: + // "res://libmy_gdnative.so" or "libmy_gdnative.so", + // while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so", + // "lib/android/arm64-v8a/libmy_gdnative.so". ANDROID, - // TODO(karroffe): all different iOS versions and archs - IOS, + IOS_32BIT, + IOS_64BIT, // TODO(karroffel): figure out how to deal with web stuff at all... WASM, @@ -64,14 +70,15 @@ class GDNativeLibrary : public Resource { }; - static String platform_names[NUM_PLATFORMS]; - static String platform_lib_ext[NUM_PLATFORMS]; + static String platform_names[NUM_PLATFORMS + 1]; + static String platform_lib_ext[NUM_PLATFORMS + 1]; - // TODO(karroffel): make this actually do something lol. static Platform current_platform; String library_paths[NUM_PLATFORMS]; + bool singleton_gdnative = false; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -87,6 +94,9 @@ public: String get_library_path(StringName p_platform) const; String get_active_library_path() const; + + _FORCE_INLINE_ bool is_singleton_gdnative() const { return singleton_gdnative; } + _FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; } }; typedef godot_variant (*native_call_cb)(void *, godot_string *, godot_array *); diff --git a/modules/gdnative/godot/array.cpp b/modules/gdnative/gdnative/array.cpp index c15ba30ca2..51c023981f 100644 --- a/modules/gdnative/godot/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/array.h> +#include "gdnative/array.h" #include "core/array.h" #include "core/os/memory.h" @@ -61,7 +61,7 @@ void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_poo memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } @@ -73,7 +73,7 @@ void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_p memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } @@ -85,7 +85,7 @@ void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_p memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } @@ -97,7 +97,7 @@ void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_po memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } @@ -109,7 +109,7 @@ void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } @@ -121,7 +121,7 @@ void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_ memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } @@ -133,7 +133,7 @@ void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool memnew_placement(dest, Array); dest->resize(pca->size()); - for (size_t i = 0; i < dest->size(); i++) { + for (int i = 0; i < dest->size(); i++) { Variant v = pca->operator[](i); dest->operator[](i) = v; } diff --git a/modules/gdnative/godot/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 8433355c12..b1327cdaef 100644 --- a/modules/gdnative/godot/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/basis.h> +#include "gdnative/basis.h" #include "core/math/matrix3.h" #include "core/variant.h" @@ -107,24 +107,6 @@ godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vect return dest; } -void GDAPI godot_basis_set_scale(godot_basis *p_self, const godot_vector3 *p_scale) { - Basis *self = (Basis *)p_self; - const Vector3 *scale = (const Vector3 *)p_scale; - self->set_scale(*scale); -} - -void GDAPI godot_basis_set_rotation_euler(godot_basis *p_self, const godot_vector3 *p_euler) { - Basis *self = (Basis *)p_self; - const Vector3 *euler = (const Vector3 *)p_euler; - self->set_rotation_euler(*euler); -} - -void GDAPI godot_basis_set_rotation_axis_angle(godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_angle) { - Basis *self = (Basis *)p_self; - const Vector3 *axis = (const Vector3 *)p_axis; - self->set_rotation_axis_angle(*axis, p_angle); -} - godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self) { godot_vector3 dest; const Basis *self = (const Basis *)p_self; diff --git a/modules/gdnative/godot/color.cpp b/modules/gdnative/gdnative/color.cpp index 3677fdc265..3f8912d896 100644 --- a/modules/gdnative/godot/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/color.h> +#include "gdnative/color.h" #include "core/color.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index 2996cc78a3..ed98cdbb00 100644 --- a/modules/gdnative/godot/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/dictionary.h> +#include "gdnative/dictionary.h" #include "core/variant.h" // core/variant.h before to avoid compile errors with MSVC diff --git a/modules/gdnative/godot/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 7cd52da34d..cf1f6a4f16 100644 --- a/modules/gdnative/godot/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -27,11 +27,10 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/gdnative.h> +#include "gdnative/gdnative.h" #include "class_db.h" #include "error_macros.h" -#include "gdnative.h" #include "global_constants.h" #include "os/os.h" #include "project_settings.h" diff --git a/modules/gdnative/godot/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp index 2309588a81..50fade5b94 100644 --- a/modules/gdnative/godot/node_path.cpp +++ b/modules/gdnative/gdnative/node_path.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/node_path.h> +#include "gdnative/node_path.h" #include "core/node_path.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/plane.cpp b/modules/gdnative/gdnative/plane.cpp index f3d4b6971e..a5e05ffa6b 100644 --- a/modules/gdnative/godot/plane.cpp +++ b/modules/gdnative/gdnative/plane.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/plane.h> +#include "gdnative/plane.h" #include "core/math/plane.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp index 2e533077f6..1393374da2 100644 --- a/modules/gdnative/godot/pool_arrays.cpp +++ b/modules/gdnative/gdnative/pool_arrays.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/pool_arrays.h> +#include "gdnative/pool_arrays.h" #include "array.h" #include "core/variant.h" @@ -65,7 +65,7 @@ void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, c memnew_placement(dest, PoolVector<uint8_t>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } @@ -144,7 +144,7 @@ void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, con memnew_placement(dest, PoolVector<godot_int>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } @@ -223,7 +223,7 @@ void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, c memnew_placement(dest, PoolVector<godot_real>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } @@ -302,7 +302,7 @@ void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_des memnew_placement(dest, PoolVector<String>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } @@ -389,7 +389,7 @@ void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_d memnew_placement(dest, PoolVector<Vector2>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } @@ -475,7 +475,7 @@ void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_d memnew_placement(dest, PoolVector<Vector3>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } @@ -561,7 +561,7 @@ void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest, memnew_placement(dest, PoolVector<Color>); dest->resize(a->size()); - for (size_t i = 0; i < a->size(); i++) { + for (int i = 0; i < a->size(); i++) { dest->set(i, (*a)[i]); } } diff --git a/modules/gdnative/godot/quat.cpp b/modules/gdnative/gdnative/quat.cpp index e6bea78b60..7db7847da1 100644 --- a/modules/gdnative/godot/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/quat.h> +#include "gdnative/quat.h" #include "core/math/quat.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index 98e7855dc9..ecd8cce9ca 100644 --- a/modules/gdnative/godot/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/rect2.h> +#include "gdnative/rect2.h" #include "core/math/math_2d.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/rect3.cpp b/modules/gdnative/gdnative/rect3.cpp index 88952ab49c..d34d964db9 100644 --- a/modules/gdnative/godot/rect3.cpp +++ b/modules/gdnative/gdnative/rect3.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/rect3.h> +#include "gdnative/rect3.h" #include "core/math/rect3.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/rid.cpp b/modules/gdnative/gdnative/rid.cpp index 51c8aaa1b3..f05c39906c 100644 --- a/modules/gdnative/godot/rid.cpp +++ b/modules/gdnative/gdnative/rid.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/rid.h> +#include "gdnative/rid.h" #include "core/resource.h" #include "core/rid.h" diff --git a/modules/gdnative/godot/string.cpp b/modules/gdnative/gdnative/string.cpp index 3790b6ea95..9b715ce36a 100644 --- a/modules/gdnative/godot/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/string.h> +#include "gdnative/string.h" #include "core/variant.h" #include "string_db.h" @@ -232,7 +232,7 @@ godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string return self->findn(*what, p_from); } -godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what) { +godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what) { const String *self = (const String *)p_self; String *what = (String *)&p_what; diff --git a/modules/gdnative/godot/transform.cpp b/modules/gdnative/gdnative/transform.cpp index a965067b77..d7a3e78d3f 100644 --- a/modules/gdnative/godot/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/transform.h> +#include "gdnative/transform.h" #include "core/math/transform.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index 9fc44ecdfa..dcb54f7a53 100644 --- a/modules/gdnative/godot/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/transform2d.h> +#include "gdnative/transform2d.h" #include "core/math/math_2d.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 582544b3a0..b61f80b1f9 100644 --- a/modules/gdnative/godot/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/variant.h> +#include "gdnative/variant.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 78ed5f06a9..67f858997f 100644 --- a/modules/gdnative/godot/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/vector2.h> +#include "gdnative/vector2.h" #include "core/math/math_2d.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index 5faeac2864..c85a3f1c08 100644 --- a/modules/gdnative/godot/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/vector3.h> +#include "gdnative/vector3.h" #include "core/variant.h" #include "core/vector.h" diff --git a/modules/gdnative/godot/icon.png.import b/modules/gdnative/godot/icon.png.import deleted file mode 100644 index 27920124f9..0000000000 --- a/modules/gdnative/godot/icon.png.import +++ /dev/null @@ -1,23 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/icon.png-aa47d037a37fb38b3b7e7828e4eec407.stex" - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -stream=false -size_limit=0 -detect_3d=true diff --git a/modules/gdnative/godot/array.h b/modules/gdnative/include/gdnative/array.h index 434ce958c9..edab028cba 100644 --- a/modules/gdnative/godot/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -37,7 +37,7 @@ extern "C" { #include <stdint.h> -#define GODOT_ARRAY_SIZE 8 +#define GODOT_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED @@ -46,10 +46,10 @@ typedef struct { } godot_array; #endif -#include <godot/pool_arrays.h> -#include <godot/variant.h> +#include <gdnative/pool_arrays.h> +#include <gdnative/variant.h> -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> void GDAPI godot_array_new(godot_array *r_dest); void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src); diff --git a/modules/gdnative/godot/basis.h b/modules/gdnative/include/gdnative/basis.h index d336bb9bc1..8ff6a6f541 100644 --- a/modules/gdnative/godot/basis.h +++ b/modules/gdnative/include/gdnative/basis.h @@ -45,9 +45,9 @@ typedef struct { } godot_basis; #endif -#include <godot/gdnative.h> -#include <godot/quat.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/quat.h> +#include <gdnative/vector3.h> void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis); void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi); @@ -67,12 +67,6 @@ godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vec godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale); -void GDAPI godot_basis_set_scale(godot_basis *p_self, const godot_vector3 *p_scale); - -void GDAPI godot_basis_set_rotation_euler(godot_basis *p_self, const godot_vector3 *p_euler); - -void GDAPI godot_basis_set_rotation_axis_angle(godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_angle); - godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self); godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self); diff --git a/modules/gdnative/godot/color.h b/modules/gdnative/include/gdnative/color.h index 5d550e40b3..90dccf75aa 100644 --- a/modules/gdnative/godot/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -45,8 +45,8 @@ typedef struct { } godot_color; #endif -#include <godot/gdnative.h> -#include <godot/string.h> +#include <gdnative/gdnative.h> +#include <gdnative/string.h> void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a); void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b); diff --git a/modules/gdnative/godot/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index bbe40f23c3..c85c3f3830 100644 --- a/modules/gdnative/godot/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_DICTIONARY_SIZE 8 +#define GODOT_DICTIONARY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED @@ -45,9 +45,9 @@ typedef struct { } godot_dictionary; #endif -#include <godot/array.h> -#include <godot/gdnative.h> -#include <godot/variant.h> +#include <gdnative/array.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> void GDAPI godot_dictionary_new(godot_dictionary *r_dest); void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src); diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 8b289da1f5..c574c56d5a 100644 --- a/modules/gdnative/godot/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -56,7 +56,7 @@ extern "C" { #define GDAPI GDCALLINGCONV #endif #else -#define GDCALLINGCONV __attribute__((sysv_abi)) +#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default"))) #define GDAPI GDCALLINGCONV #endif @@ -146,100 +146,74 @@ typedef float godot_real; /////// Object (forward declared) typedef void godot_object; -/////// Brute force forward declarations for the rest -/* -typedef struct godot_variant godot_variant; -typedef struct godot_string godot_string; -typedef struct godot_vector2 godot_vector2; -typedef struct godot_rect2 godot_rect2; -typedef struct godot_vector3 godot_vector3; -typedef struct godot_transform2d godot_transform2d; -typedef struct godot_plane godot_plane; -typedef struct godot_quat godot_quat; -typedef struct godot_rect3 godot_rect3; -typedef struct godot_basis godot_basis; -typedef struct godot_transform godot_transform; -typedef struct godot_color godot_color; -typedef struct godot_node_path godot_node_path; -typedef struct godot_rid godot_rid; -typedef struct godot_dictionary godot_dictionary; -typedef struct godot_array godot_array; -typedef struct godot_pool_byte_array godot_pool_byte_array; -typedef struct godot_pool_int_array godot_pool_int_array; -typedef struct godot_pool_real_array godot_pool_real_array; -typedef struct godot_pool_string_array godot_pool_string_array; -typedef struct godot_pool_vector2_array godot_pool_vector2_array; -typedef struct godot_pool_vector3_array godot_pool_vector3_array; -typedef struct godot_pool_color_array godot_pool_color_array; -*/ /////// String -#include <godot/string.h> +#include <gdnative/string.h> ////// Vector2 -#include <godot/vector2.h> +#include <gdnative/vector2.h> ////// Rect2 -#include <godot/rect2.h> +#include <gdnative/rect2.h> ////// Vector3 -#include <godot/vector3.h> +#include <gdnative/vector3.h> ////// Transform2D -#include <godot/transform2d.h> +#include <gdnative/transform2d.h> /////// Plane -#include <godot/plane.h> +#include <gdnative/plane.h> /////// Quat -#include <godot/quat.h> +#include <gdnative/quat.h> /////// Rect3 -#include <godot/rect3.h> +#include <gdnative/rect3.h> /////// Basis -#include <godot/basis.h> +#include <gdnative/basis.h> /////// Transform -#include <godot/transform.h> +#include <gdnative/transform.h> /////// Color -#include <godot/color.h> +#include <gdnative/color.h> /////// NodePath -#include <godot/node_path.h> +#include <gdnative/node_path.h> /////// RID -#include <godot/rid.h> +#include <gdnative/rid.h> /////// Dictionary -#include <godot/dictionary.h> +#include <gdnative/dictionary.h> /////// Array -#include <godot/array.h> +#include <gdnative/array.h> // single API file for Pool*Array -#include <godot/pool_arrays.h> +#include <gdnative/pool_arrays.h> void GDAPI godot_object_destroy(godot_object *p_o); ////// Variant -#include <godot/variant.h> +#include <gdnative/variant.h> ////// Singleton API diff --git a/modules/gdnative/godot/node_path.h b/modules/gdnative/include/gdnative/node_path.h index 3e2a99e461..0cfdbc1127 100644 --- a/modules/gdnative/godot/node_path.h +++ b/modules/gdnative/include/gdnative/node_path.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_NODE_PATH_SIZE 8 +#define GODOT_NODE_PATH_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED #define GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED @@ -45,8 +45,8 @@ typedef struct { } godot_node_path; #endif -#include <godot/gdnative.h> -#include <godot/string.h> +#include <gdnative/gdnative.h> +#include <gdnative/string.h> void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from); void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src); diff --git a/modules/gdnative/godot/plane.h b/modules/gdnative/include/gdnative/plane.h index 27548c8b0c..6a8915e08b 100644 --- a/modules/gdnative/godot/plane.h +++ b/modules/gdnative/include/gdnative/plane.h @@ -45,8 +45,8 @@ typedef struct { } godot_plane; #endif -#include <godot/gdnative.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/vector3.h> void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d); void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3); diff --git a/modules/gdnative/godot/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h index ecd85ddfe8..cb1095ee8c 100644 --- a/modules/gdnative/godot/pool_arrays.h +++ b/modules/gdnative/include/gdnative/pool_arrays.h @@ -38,7 +38,7 @@ extern "C" { /////// PoolByteArray -#define GODOT_POOL_BYTE_ARRAY_SIZE 8 +#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED @@ -49,7 +49,7 @@ typedef struct { /////// PoolIntArray -#define GODOT_POOL_INT_ARRAY_SIZE 8 +#define GODOT_POOL_INT_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED @@ -60,7 +60,7 @@ typedef struct { /////// PoolRealArray -#define GODOT_POOL_REAL_ARRAY_SIZE 8 +#define GODOT_POOL_REAL_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED @@ -71,7 +71,7 @@ typedef struct { /////// PoolStringArray -#define GODOT_POOL_STRING_ARRAY_SIZE 8 +#define GODOT_POOL_STRING_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED @@ -82,7 +82,7 @@ typedef struct { /////// PoolVector2Array -#define GODOT_POOL_VECTOR2_ARRAY_SIZE 8 +#define GODOT_POOL_VECTOR2_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED @@ -93,7 +93,7 @@ typedef struct { /////// PoolVector3Array -#define GODOT_POOL_VECTOR3_ARRAY_SIZE 8 +#define GODOT_POOL_VECTOR3_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED @@ -104,7 +104,7 @@ typedef struct { /////// PoolColorArray -#define GODOT_POOL_COLOR_ARRAY_SIZE 8 +#define GODOT_POOL_COLOR_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED @@ -113,12 +113,12 @@ typedef struct { } godot_pool_color_array; #endif -#include <godot/array.h> -#include <godot/color.h> -#include <godot/vector2.h> -#include <godot/vector3.h> +#include <gdnative/array.h> +#include <gdnative/color.h> +#include <gdnative/vector2.h> +#include <gdnative/vector3.h> -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> // byte diff --git a/modules/gdnative/godot/quat.h b/modules/gdnative/include/gdnative/quat.h index 9a3238a337..4ffb96eb26 100644 --- a/modules/gdnative/godot/quat.h +++ b/modules/gdnative/include/gdnative/quat.h @@ -45,8 +45,8 @@ typedef struct { } godot_quat; #endif -#include <godot/gdnative.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/vector3.h> void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w); void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle); diff --git a/modules/gdnative/godot/rect2.h b/modules/gdnative/include/gdnative/rect2.h index 8ceeddf1b4..9e6cf60342 100644 --- a/modules/gdnative/godot/rect2.h +++ b/modules/gdnative/include/gdnative/rect2.h @@ -43,8 +43,8 @@ typedef struct godot_rect2 { } godot_rect2; #endif -#include <godot/gdnative.h> -#include <godot/vector2.h> +#include <gdnative/gdnative.h> +#include <gdnative/vector2.h> void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size); void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height); diff --git a/modules/gdnative/godot/rect3.h b/modules/gdnative/include/gdnative/rect3.h index ca96aadd5c..f94b6fea25 100644 --- a/modules/gdnative/godot/rect3.h +++ b/modules/gdnative/include/gdnative/rect3.h @@ -45,9 +45,9 @@ typedef struct { } godot_rect3; #endif -#include <godot/gdnative.h> -#include <godot/plane.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/plane.h> +#include <gdnative/vector3.h> void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size); diff --git a/modules/gdnative/godot/rid.h b/modules/gdnative/include/gdnative/rid.h index b685157cec..d9b5336fc9 100644 --- a/modules/gdnative/godot/rid.h +++ b/modules/gdnative/include/gdnative/rid.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_RID_SIZE 8 +#define GODOT_RID_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED #define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED @@ -45,7 +45,7 @@ typedef struct { } godot_rid; #endif -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> void GDAPI godot_rid_new(godot_rid *r_dest); diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/include/gdnative/string.h index f41626faa1..aca23a81d8 100644 --- a/modules/gdnative/godot/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -37,7 +37,7 @@ extern "C" { #include <stdint.h> #include <wchar.h> -#define GODOT_STRING_SIZE 8 +#define GODOT_STRING_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED #define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED @@ -46,8 +46,8 @@ typedef struct { } godot_string; #endif -#include <godot/gdnative.h> -#include <godot/variant.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> void GDAPI godot_string_new(godot_string *r_dest); void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src); @@ -82,7 +82,7 @@ godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key); godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what); godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from); -godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what); godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values); godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder); godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len); diff --git a/modules/gdnative/godot/transform.h b/modules/gdnative/include/gdnative/transform.h index 60788e3d57..656afae129 100644 --- a/modules/gdnative/godot/transform.h +++ b/modules/gdnative/include/gdnative/transform.h @@ -45,10 +45,10 @@ typedef struct { } godot_transform; #endif -#include <godot/basis.h> -#include <godot/gdnative.h> -#include <godot/variant.h> -#include <godot/vector3.h> +#include <gdnative/basis.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> +#include <gdnative/vector3.h> void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin); void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin); diff --git a/modules/gdnative/godot/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h index c0f5725eed..a945868b17 100644 --- a/modules/gdnative/godot/transform2d.h +++ b/modules/gdnative/include/gdnative/transform2d.h @@ -45,9 +45,9 @@ typedef struct { } godot_transform2d; #endif -#include <godot/gdnative.h> -#include <godot/variant.h> -#include <godot/vector2.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> +#include <gdnative/vector2.h> void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos); void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin); diff --git a/modules/gdnative/godot/variant.h b/modules/gdnative/include/gdnative/variant.h index fda24db8d4..969506585d 100644 --- a/modules/gdnative/godot/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_VARIANT_SIZE 24 +#define GODOT_VARIANT_SIZE (16 + sizeof(void *)) #ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED @@ -99,25 +99,25 @@ typedef struct godot_variant_call_error { godot_variant_type expected; } godot_variant_call_error; -#include <godot/array.h> -#include <godot/basis.h> -#include <godot/color.h> -#include <godot/dictionary.h> -#include <godot/node_path.h> -#include <godot/plane.h> -#include <godot/pool_arrays.h> -#include <godot/quat.h> -#include <godot/rect2.h> -#include <godot/rect3.h> -#include <godot/rid.h> -#include <godot/string.h> -#include <godot/transform.h> -#include <godot/transform2d.h> -#include <godot/variant.h> -#include <godot/vector2.h> -#include <godot/vector3.h> - -#include <godot/gdnative.h> +#include <gdnative/array.h> +#include <gdnative/basis.h> +#include <gdnative/color.h> +#include <gdnative/dictionary.h> +#include <gdnative/node_path.h> +#include <gdnative/plane.h> +#include <gdnative/pool_arrays.h> +#include <gdnative/quat.h> +#include <gdnative/rect2.h> +#include <gdnative/rect3.h> +#include <gdnative/rid.h> +#include <gdnative/string.h> +#include <gdnative/transform.h> +#include <gdnative/transform2d.h> +#include <gdnative/variant.h> +#include <gdnative/vector2.h> +#include <gdnative/vector3.h> + +#include <gdnative/gdnative.h> godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v); diff --git a/modules/gdnative/godot/vector2.h b/modules/gdnative/include/gdnative/vector2.h index 98e9700e32..0af4abae27 100644 --- a/modules/gdnative/godot/vector2.h +++ b/modules/gdnative/include/gdnative/vector2.h @@ -45,7 +45,7 @@ typedef struct { } godot_vector2; #endif -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y); diff --git a/modules/gdnative/godot/vector3.h b/modules/gdnative/include/gdnative/vector3.h index b76ca11a9c..a27d516ec5 100644 --- a/modules/gdnative/godot/vector3.h +++ b/modules/gdnative/include/gdnative/vector3.h @@ -45,8 +45,8 @@ typedef struct { } godot_vector3; #endif -#include <godot/basis.h> -#include <godot/gdnative.h> +#include <gdnative/basis.h> +#include <gdnative/gdnative.h> typedef enum { GODOT_VECTOR3_AXIS_X, diff --git a/modules/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 1eaf459570..96f213ead7 100644 --- a/modules/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* godot.h */ +/* godot_nativescript.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,7 +30,7 @@ #ifndef GODOT_NATIVESCRIPT_H #define GODOT_NATIVESCRIPT_H -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> #ifdef __cplusplus extern "C" { @@ -58,7 +58,7 @@ extern "C" { #define GDAPI GDCALLINGCONV #endif #else -#define GDCALLINGCONV __attribute__((sysv_abi)) +#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default"))) #define GDAPI GDCALLINGCONV #endif diff --git a/modules/nativescript/SCsub b/modules/gdnative/nativescript/SCsub index e980e40e8e..e980e40e8e 100644 --- a/modules/nativescript/SCsub +++ b/modules/gdnative/nativescript/SCsub diff --git a/modules/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 4490197bdb..fdd5a2ea19 100644 --- a/modules/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -33,6 +33,7 @@ #include "class_db.h" #include "core/global_constants.h" +#include "core/pair.h" #include "core/project_settings.h" #include "os/file_access.h" @@ -93,6 +94,11 @@ struct SignalAPI { Map<int, Variant> default_arguments; }; +struct EnumAPI { + String name; + List<Pair<int, String> > values; +}; + struct ClassAPI { String class_name; String super_class_name; @@ -109,8 +115,28 @@ struct ClassAPI { List<PropertyAPI> properties; List<ConstantAPI> constants; List<SignalAPI> signals_; + List<EnumAPI> enums; }; +static String get_type_name(const PropertyInfo &info) { + if (info.type == Variant::INT && (info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) { + return String("enum.") + String(info.class_name).replace(".", "::"); + } + if (info.class_name != StringName()) { + return info.class_name; + } + if (info.hint == PROPERTY_HINT_RESOURCE_TYPE) { + return info.hint_string; + } + if (info.type == Variant::NIL && (info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) { + return "Variant"; + } + if (info.type == Variant::NIL) { + return "void"; + } + return Variant::get_type_name(info.type); +} + /* * Reads the entire Godot API to a list */ @@ -194,12 +220,8 @@ List<ClassAPI> generate_c_api_classes() { if (argument.name.find(":") != -1) { type = argument.name.get_slice(":", 1); name = argument.name.get_slice(":", 0); - } else if (argument.hint == PROPERTY_HINT_RESOURCE_TYPE) { - type = argument.hint_string; - } else if (argument.type == Variant::NIL) { - type = "Variant"; } else { - type = Variant::get_type_name(argument.type); + type = get_type_name(argument); } signal.argument_names.push_back(name); @@ -233,12 +255,8 @@ List<ClassAPI> generate_c_api_classes() { if (p->get().name.find(":") != -1) { property_api.type = p->get().name.get_slice(":", 1); property_api.name = p->get().name.get_slice(":", 0); - } else if (p->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { - property_api.type = p->get().hint_string; - } else if (p->get().type == Variant::NIL) { - property_api.type = "Variant"; } else { - property_api.type = Variant::get_type_name(p->get().type); + property_api.type = get_type_name(p->get()); } if (!property_api.setter.empty() || !property_api.getter.empty()) { @@ -260,17 +278,11 @@ List<ClassAPI> generate_c_api_classes() { //method name method_api.method_name = m->get().name; //method return type - if (method_bind && method_bind->get_return_type() != StringName()) { - method_api.return_type = method_bind->get_return_type(); - } else if (method_api.method_name.find(":") != -1) { + if (method_api.method_name.find(":") != -1) { method_api.return_type = method_api.method_name.get_slice(":", 1); method_api.method_name = method_api.method_name.get_slice(":", 0); - } else if (m->get().return_val.type != Variant::NIL) { - method_api.return_type = m->get().return_val.hint == PROPERTY_HINT_RESOURCE_TYPE ? m->get().return_val.hint_string : Variant::get_type_name(m->get().return_val.type); - } else if (m->get().return_val.name != "") { - method_api.return_type = m->get().return_val.name; } else { - method_api.return_type = "void"; + method_api.return_type = get_type_name(m->get().return_val); } method_api.argument_count = method_info.arguments.size(); @@ -321,6 +333,25 @@ List<ClassAPI> generate_c_api_classes() { } } + // enums + { + List<EnumAPI> enums; + List<StringName> enum_names; + ClassDB::get_enum_list(class_name, &enum_names, true); + for (List<StringName>::Element *E = enum_names.front(); E; E = E->next()) { + List<StringName> value_names; + EnumAPI enum_api; + enum_api.name = E->get(); + ClassDB::get_enum_constants(class_name, E->get(), &value_names, true); + for (List<StringName>::Element *val_e = value_names.front(); val_e; val_e = val_e->next()) { + int int_val = ClassDB::get_integer_constant(class_name, val_e->get(), NULL); + enum_api.values.push_back(Pair<int, String>(int_val, val_e->get())); + } + enum_api.values.sort_custom<PairSort<int, String> >(); + class_api.enums.push_back(enum_api); + } + } + api.push_back(class_api); } @@ -410,11 +441,24 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { source.push_back("\t\t\t\t]\n"); source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n"); } + source.push_back("\t\t],\n"); + + source.push_back("\t\t\"enums\": [\n"); + for (List<EnumAPI>::Element *e = api.enums.front(); e; e = e->next()) { + source.push_back("\t\t\t{\n"); + source.push_back("\t\t\t\t\"name\": \"" + e->get().name + "\",\n"); + source.push_back("\t\t\t\t\"values\": {\n"); + for (List<Pair<int, String> >::Element *val_e = e->get().values.front(); val_e; val_e = val_e->next()) { + source.push_back("\t\t\t\t\t\"" + val_e->get().second + "\": " + itos(val_e->get().first)); + source.push_back(String((val_e->next() ? "," : "")) + "\n"); + } + source.push_back("\t\t\t\t}\n"); + source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n"); + } source.push_back("\t\t]\n"); source.push_back(String("\t}") + (c->next() ? "," : "") + "\n"); } - source.push_back("]"); return source; diff --git a/modules/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h index 56c2d786e6..56c2d786e6 100644 --- a/modules/nativescript/api_generator.h +++ b/modules/gdnative/nativescript/api_generator.h diff --git a/modules/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index 926b3261b2..61ac13b796 100644 --- a/modules/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -27,17 +27,17 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "godot_nativescript.h" - -#include "nativescript.h" +#include "nativescript/godot_nativescript.h" #include "class_db.h" #include "error_macros.h" -#include "gdnative.h" +#include "gdnative/gdnative.h" #include "global_constants.h" #include "project_settings.h" #include "variant.h" +#include "nativescript.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/modules/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 3799ce31f8..724b8390da 100644 --- a/modules/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "nativescript.h" -#include "modules/gdnative/godot/gdnative.h" +#include "gdnative/gdnative.h" #include "global_constants.h" #include "io/file_access_encrypted.h" @@ -994,6 +994,8 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { #endif // See if this library was "registered" already. const String &lib_path = lib->get_active_library_path(); + ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform"); + ERR_FAIL_COND(lib_path.length() == 0); Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path); if (!E) { diff --git a/modules/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 571a3c9cc7..6c55e3e327 100644 --- a/modules/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -38,8 +38,8 @@ #include "script_language.h" #include "self_list.h" -#include "godot_nativescript.h" #include "modules/gdnative/gdnative.h" +#include <nativescript/godot_nativescript.h> #ifndef NO_THREADS #include "os/mutex.h" diff --git a/modules/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp index b846710ab8..b846710ab8 100644 --- a/modules/nativescript/register_types.cpp +++ b/modules/gdnative/nativescript/register_types.cpp diff --git a/modules/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h index 7ac558f68f..7ac558f68f 100644 --- a/modules/nativescript/register_types.h +++ b/modules/gdnative/nativescript/register_types.h diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 9ad05b7194..d809109987 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -28,12 +28,99 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_types.h" +#include "gdnative/gdnative.h" + #include "gdnative.h" #include "io/resource_loader.h" #include "io/resource_saver.h" +#include "nativescript/register_types.h" + +#include "core/engine.h" #include "core/os/os.h" +#include "core/project_settings.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" + +// Class used to discover singleton gdnative files + +void actual_discoverer_handler(); + +class GDNativeSingletonDiscover : public Object { + // GDCLASS(GDNativeSingletonDiscover, Object) + + virtual String get_class() const { + // okay, this is a really dirty hack. + // We're overriding get_class so we can connect it to a signal + // This works because get_class is a virtual method, so we don't + // need to register a new class to ClassDB just for this one + // little signal. + + actual_discoverer_handler(); + + return "Object"; + } +}; + +Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) { + + Set<String> file_paths; + + // check children + + for (int i = 0; i < p_dir->get_file_count(); i++) { + String file_name = p_dir->get_file(i); + String file_type = p_dir->get_file_type(i); + + if (file_type != "GDNativeLibrary") { + continue; + } + + Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i)); + if (lib.is_valid() && lib->is_singleton_gdnative()) { + file_paths.insert(p_dir->get_file_path(i)); + } + } + + // check subdirectories + for (int i = 0; i < p_dir->get_subdir_count(); i++) { + Set<String> paths = get_gdnative_singletons(p_dir->get_subdir(i)); + + for (Set<String>::Element *E = paths.front(); E; E = E->next()) { + file_paths.insert(E->get()); + } + } + + return file_paths; +} + +void actual_discoverer_handler() { + EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->get_filesystem(); + + Set<String> file_paths = get_gdnative_singletons(dir); + + Array files; + files.resize(file_paths.size()); + int i = 0; + for (Set<String>::Element *E = file_paths.front(); E; i++, E = E->next()) { + files.set(i, E->get()); + } + + ProjectSettings::get_singleton()->set("gdnative/singletons", files); + + ProjectSettings::get_singleton()->save(); +} + +GDNativeSingletonDiscover *discoverer = NULL; + +void discoverer_callback() { + discoverer = memnew(GDNativeSingletonDiscover); + EditorFileSystem::get_singleton()->connect("filesystem_changed", discoverer, "get_class"); +} + +#endif godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot_array *p_args) { if (handle == NULL) { @@ -62,21 +149,110 @@ godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot return proc(NULL, p_args); } +void cb_singleton_call( + void *p_handle, + godot_string *p_proc_name, + void *p_data, + int p_num_args, + void **p_args, + void *r_return) { + if (p_handle == NULL) { + ERR_PRINT("No valid library handle, can't call singleton procedure"); + return; + } + + void *singleton_proc; + Error err = OS::get_singleton()->get_dynamic_library_symbol_handle( + p_handle, + *(String *)p_proc_name, + singleton_proc); + + if (err != OK) { + return; + } + + void (*singleton_procedure_ptr)() = (void (*)())singleton_proc; + singleton_procedure_ptr(); +} + GDNativeCallRegistry *GDNativeCallRegistry::singleton; +Vector<Ref<GDNative> > singleton_gdnatives; + void register_gdnative_types() { +#ifdef TOOLS_ENABLED + + if (Engine::get_singleton()->is_editor_hint()) { + EditorNode::add_init_callback(discoverer_callback); + } +#endif + ClassDB::register_class<GDNativeLibrary>(); ClassDB::register_class<GDNative>(); GDNativeCallRegistry::singleton = memnew(GDNativeCallRegistry); GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall); + + GDNativeCallRegistry::singleton->register_native_raw_call_type("gdnative_singleton_call", cb_singleton_call); + + register_nativescript_types(); + + // run singletons + + Array singletons = ProjectSettings::get_singleton()->get("gdnative/singletons"); + + singleton_gdnatives.resize(singletons.size()); + + for (int i = 0; i < singletons.size(); i++) { + String path = singletons[i]; + + Ref<GDNativeLibrary> lib = ResourceLoader::load(path); + + singleton_gdnatives[i].instance(); + singleton_gdnatives[i]->set_library(lib); + + if (!singleton_gdnatives[i]->initialize()) { + // Can't initialize. Don't make a native_call then + continue; + } + + singleton_gdnatives[i]->call_native_raw( + "gdnative_singleton_call", + "godot_gdnative_singleton", + NULL, + 0, + NULL, + NULL); + } } void unregister_gdnative_types() { + + for (int i = 0; i < singleton_gdnatives.size(); i++) { + + if (singleton_gdnatives[i].is_null()) { + continue; + } + + if (!singleton_gdnatives[i]->is_initialized()) { + continue; + } + + singleton_gdnatives[i]->terminate(); + } + + unregister_nativescript_types(); + memdelete(GDNativeCallRegistry::singleton); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + memdelete(discoverer); + } +#endif + // This is for printing out the sizes of the core types /* diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index b10694ddfd..70e7da5748 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -297,23 +297,25 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const //not really "functions", but.. { MethodInfo mi; - mi.name = "preload:Resource"; + mi.name = "preload"; mi.arguments.push_back(PropertyInfo(Variant::STRING, "path")); mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "Resource"); p_functions->push_back(mi); } { MethodInfo mi; - mi.name = "yield:GDFunctionState"; + mi.name = "yield"; mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object")); mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal")); mi.default_arguments.push_back(Variant::NIL); mi.default_arguments.push_back(Variant::STRING); + mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "GDFunctionState"); p_functions->push_back(mi); } { MethodInfo mi; mi.name = "assert"; + mi.return_val.type = Variant::NIL; mi.arguments.push_back(PropertyInfo(Variant::BOOL, "condition")); p_functions->push_back(mi); } @@ -1901,11 +1903,11 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N arghint += ", "; else arghint += " "; - if (i == p_argidx) { + if (i == p_argidx || (mi.flags & METHOD_FLAG_VARARG && i > p_argidx)) { arghint += String::chr(0xFFFF); } arghint += _get_visual_datatype(mi.arguments[i]) + " " + mi.arguments[i].name; - if (i == p_argidx) { + if (i == p_argidx || (mi.flags & METHOD_FLAG_VARARG && i > p_argidx)) { arghint += String::chr(0xFFFF); } } diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp index e6f65fe0c2..ddee7b2521 100644 --- a/modules/gdscript/gd_function.cpp +++ b/modules/gdscript/gd_function.cpp @@ -290,8 +290,8 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a #ifdef DEBUG_ENABLED - uint64_t function_start_time; - uint64_t function_call_time; + uint64_t function_start_time = 0; + uint64_t function_call_time = 0; if (GDScriptLanguage::get_singleton()->profiling) { function_start_time = OS::get_singleton()->get_ticks_usec(); @@ -691,7 +691,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #ifdef DEBUG_ENABLED - uint64_t call_time; + uint64_t call_time = 0; if (GDScriptLanguage::get_singleton()->profiling) { call_time = OS::get_singleton()->get_ticks_usec(); @@ -1026,7 +1026,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } case OPCODE_ITERATE_BEGIN: { - CHECK_SPACE(8); //space for this an regular iterate + CHECK_SPACE(8); //space for this a regular iterate GET_VARIANT_PTR(counter, 1); GET_VARIANT_PTR(container, 2); diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index 3bd0ce3fab..f0cfdd6258 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -1572,43 +1572,49 @@ MethodInfo GDFunctions::get_info(Function p_func) { } break; case TEXT_STR: { - MethodInfo mi("str", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("str"); mi.return_val.type = Variant::STRING; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case TEXT_PRINT: { - MethodInfo mi("print", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("print"); mi.return_val.type = Variant::NIL; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case TEXT_PRINT_TABBED: { - MethodInfo mi("printt", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("printt"); mi.return_val.type = Variant::NIL; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case TEXT_PRINT_SPACED: { - MethodInfo mi("prints", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("prints"); mi.return_val.type = Variant::NIL; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case TEXT_PRINTERR: { - MethodInfo mi("printerr", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("printerr"); mi.return_val.type = Variant::NIL; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case TEXT_PRINTRAW: { - MethodInfo mi("printraw", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("printraw"); mi.return_val.type = Variant::NIL; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; @@ -1620,8 +1626,9 @@ MethodInfo GDFunctions::get_info(Function p_func) { } break; case STR_TO_VAR: { - MethodInfo mi("str2var:Variant", PropertyInfo(Variant::STRING, "string")); + MethodInfo mi(Variant::NIL, "str2var", PropertyInfo(Variant::STRING, "string")); mi.return_val.type = Variant::NIL; + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case VAR_TO_BYTES: { @@ -1632,14 +1639,16 @@ MethodInfo GDFunctions::get_info(Function p_func) { } break; case BYTES_TO_VAR: { - MethodInfo mi("bytes2var:Variant", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes")); + MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes")); mi.return_val.type = Variant::NIL; + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case GEN_RANGE: { - MethodInfo mi("range", PropertyInfo(Variant::NIL, "...")); + MethodInfo mi("range"); mi.return_val.type = Variant::ARRAY; + mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case RESOURCE_LOAD: { @@ -1663,14 +1672,15 @@ MethodInfo GDFunctions::get_info(Function p_func) { } break; case VALIDATE_JSON: { - MethodInfo mi("validate_json:Variant", PropertyInfo(Variant::STRING, "json")); + MethodInfo mi("validate_json", PropertyInfo(Variant::STRING, "json")); mi.return_val.type = Variant::STRING; return mi; } break; case PARSE_JSON: { - MethodInfo mi("parse_json:Variant", PropertyInfo(Variant::STRING, "json")); + MethodInfo mi(Variant::NIL, "parse_json", PropertyInfo(Variant::STRING, "json")); mi.return_val.type = Variant::NIL; + mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case TO_JSON: { diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 072937a521..72c3f9612a 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1284,7 +1284,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (expression[next_op + 1].is_op) { // this is not invalid and can really appear // but it becomes invalid anyway because no binary op - // can be followed by an unary op in a valid combination, + // can be followed by a unary op in a valid combination, // due to how precedence works, unaries will always disappear first _set_error("Unexpected two consecutive operators after ternary if."); @@ -1294,7 +1294,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (expression[next_op + 3].is_op) { // this is not invalid and can really appear // but it becomes invalid anyway because no binary op - // can be followed by an unary op in a valid combination, + // can be followed by a unary op in a valid combination, // due to how precedence works, unaries will always disappear first _set_error("Unexpected two consecutive operators after ternary else."); @@ -1331,7 +1331,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool if (expression[next_op + 1].is_op) { // this is not invalid and can really appear // but it becomes invalid anyway because no binary op - // can be followed by an unary op in a valid combination, + // can be followed by a unary op in a valid combination, // due to how precedence works, unaries will always disappear first _set_error("Unexpected two consecutive operators."); @@ -1857,7 +1857,7 @@ GDParser::PatternNode *GDParser::_parse_pattern(bool p_static) { tokenizer->advance(1); break; } else { - _set_error("'..' pattern only allowed at the end of an dictionary pattern"); + _set_error("'..' pattern only allowed at the end of a dictionary pattern"); return NULL; } } diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 6f05a4770b..5e1a8b19ac 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -389,7 +389,6 @@ public: virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return OK; } virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint); #ifdef TOOLS_ENABLED virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result); diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 0de2cf80ea..ced1c3ca12 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -155,7 +155,7 @@ void GridMap::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary")); p_list->push_back(PropertyInfo(Variant::NIL, "Cell", PROPERTY_HINT_NONE, "cell_", PROPERTY_USAGE_GROUP)); - p_list->push_back(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.01,16384,0.01")); + p_list->push_back(PropertyInfo(Variant::VECTOR3, "cell_size")); p_list->push_back(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1")); p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_x")); p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_y")); @@ -184,6 +184,7 @@ Ref<MeshLibrary> GridMap::get_theme() const { void GridMap::set_cell_size(const Vector3 &p_size) { + ERR_FAIL_COND(p_size.x < 0.001 || p_size.y < 0.001 || p_size.z < 0.001); cell_size = p_size; _recreate_octant_data(); } @@ -395,8 +396,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Map<int, List<Pair<Transform, IndexKey> > > multimesh_items; - print_line("updating octant " + itos(p_key.x) + ", " + itos(p_key.y) + ", " + itos(p_key.z) + " cells: " + itos(g.cells.size())); - for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) { ERR_CONTINUE(!cell_map.has(E->get())); @@ -463,7 +462,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) { //update multimeshes for (Map<int, List<Pair<Transform, IndexKey> > >::Element *E = multimesh_items.front(); E; E = E->next()) { - print_line("multimesh item " + itos(E->key()) + " transforms " + itos(E->get().size())); Octant::MultimeshInstance mmi; RID mm = VS::get_singleton()->multimesh_create(); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 6f0a13e07f..f6a76ad2a1 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1159,14 +1159,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { outer_mat.instance(); outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8)); - outer_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); + outer_mat->set_on_top_of_alpha(); outer_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); outer_mat->set_line_width(3.0); outer_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); selection_floor_mat.instance(); selection_floor_mat->set_albedo(Color(0.80, 0.80, 1.0, 1)); - selection_floor_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); + selection_floor_mat->set_on_top_of_alpha(); selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); selection_floor_mat->set_line_width(3.0); //selection_floor_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index d883b0f280..92d88207b3 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.cpp */ +/* image_loader_hdr.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h index e6703dc142..569978d28d 100644 --- a/modules/hdr/image_loader_hdr.h +++ b/modules/hdr/image_loader_hdr.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.h */ +/* image_loader_hdr.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/nativescript/config.py b/modules/nativescript/config.py deleted file mode 100644 index 4f89ca0d4c..0000000000 --- a/modules/nativescript/config.py +++ /dev/null @@ -1,8 +0,0 @@ - - -def can_build(platform): - return False - - -def configure(env): - env.use_ptrcall = True diff --git a/modules/openssl/SCsub b/modules/openssl/SCsub index add7d4dcfc..eb3c0e64d8 100644 --- a/modules/openssl/SCsub +++ b/modules/openssl/SCsub @@ -655,7 +655,7 @@ if (env['builtin_openssl'] != 'no'): env_openssl.add_source_files(env.modules_sources, thirdparty_sources) - # FIXME: Clone the environment to make a env_openssl and not pollute the modules env + # FIXME: Clone the environment to make env_openssl and not pollute the modules env thirdparty_include_paths = [ "", "crypto", diff --git a/modules/regex/SCsub b/modules/regex/SCsub index 0882406761..2dfc2739e9 100644 --- a/modules/regex/SCsub +++ b/modules/regex/SCsub @@ -1,7 +1,53 @@ #!/usr/bin/env python Import('env') +Import('env_modules') -env.add_source_files(env.modules_sources, "*.cpp") +env_regex = env_modules.Clone() +env_regex.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=0"]) +env_regex.add_source_files(env.modules_sources, "*.cpp") -Export('env') +if (env['builtin_pcre2'] != 'no'): + jit_blacklist = ['javascript'] + thirdparty_dir = '#thirdparty/pcre2/src/' + thirdparty_flags = ['-DPCRE2_STATIC', '-DHAVE_CONFIG_H'] + if 'platform' in env and env['platform'] not in jit_blacklist: + thirdparty_flags.append('-DSUPPORT_JIT') + thirdparty_sources = [ + "pcre2_auto_possess.c", + "pcre2_chartables.c", + "pcre2_compile.c", + "pcre2_config.c", + "pcre2_context.c", + "pcre2_dfa_match.c", + "pcre2_error.c", + "pcre2_find_bracket.c", + "pcre2_jit_compile.c", + "pcre2_maketables.c", + "pcre2_match.c", + "pcre2_match_data.c", + "pcre2_newline.c", + "pcre2_ord2utf.c", + "pcre2_pattern_info.c", + "pcre2_serialize.c", + "pcre2_string_utils.c", + "pcre2_study.c", + "pcre2_substitute.c", + "pcre2_substring.c", + "pcre2_tables.c", + "pcre2_ucd.c", + "pcre2_valid_utf.c", + "pcre2_xclass.c", + ] + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + env_regex.Append(CPPPATH=[thirdparty_dir]) + env_regex.Append(CPPFLAGS=thirdparty_flags) + def pcre2_builtin(width): + env_pcre2 = env_modules.Clone() + env_pcre2["OBJSUFFIX"] = "_" + width + env_pcre2["OBJSUFFIX"] + env_pcre2.Append(CPPPATH=[thirdparty_dir]) + env_pcre2.add_source_files(env.modules_sources, thirdparty_sources) + env_pcre2.Append(CPPFLAGS=thirdparty_flags) + env_pcre2.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=" + width]) + pcre2_builtin("16") + pcre2_builtin("32") diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index de0a6b7e21..00e8ce0f54 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -29,1479 +29,469 @@ /*************************************************************************/ #include "regex.h" -#include <wchar.h> -#include <wctype.h> - -static int RegEx_hex2int(const CharType c) { - if ('0' <= c && c <= '9') - return int(c - '0'); - else if ('a' <= c && c <= 'f') - return int(c - 'a') + 10; - else if ('A' <= c && c <= 'F') - return int(c - 'A') + 10; - return -1; -} - -struct RegExSearch { - - Ref<RegExMatch> match; - const CharType *str; - int end; - int eof; - - // For standard quantifier behaviour, test_parent is used to check the - // rest of the pattern. If the pattern matches, to prevent the parent - // from testing again, the complete flag is used as a shortcut out. - bool complete; - - // With lookahead, the position needs to rewind to its starting position - // when test_parent is used. Due to functional programming, this state - // has to be kept as a parameter. - Vector<int> lookahead_pos; - - CharType at(int p_pos) { - return str[p_pos]; - } - - RegExSearch(Ref<RegExMatch> &p_match, int p_end, int p_lookahead) - : match(p_match) { - - str = p_match->string.c_str(); - end = p_end; - eof = p_match->string.length(); - complete = false; - lookahead_pos.resize(p_lookahead); - } -}; - -struct RegExNode { - - RegExNode *next; - RegExNode *previous; - RegExNode *parent; - bool quantifiable; - int length; - - RegExNode() { - - next = NULL; - previous = NULL; - parent = NULL; - quantifiable = false; - length = -1; - } - - virtual ~RegExNode() { - - if (next) - memdelete(next); - } +#include "core/os/memory.h" - // For avoiding RTTI - virtual bool is_look_behind() { return false; } - - virtual int test(RegExSearch &s, int pos) const { - - return next ? next->test(s, pos) : -1; - } - - virtual int test_parent(RegExSearch &s, int pos) const { - - if (next) - pos = next->test(s, pos); - - if (pos >= 0) { - s.complete = true; - if (parent) - pos = parent->test_parent(s, pos); - } - - if (pos < 0) - s.complete = false; - - return pos; - } - - void increment_length(int amount, bool subtract = false) { - - if (amount >= 0 && length >= 0) { - if (!subtract) - length += amount; - else - length -= amount; - } else { - length = -1; - } +extern "C" { +#include <pcre2.h> +} - if (parent) - parent->increment_length(amount, subtract); - } -}; +static void *_regex_malloc(PCRE2_SIZE size, void *user) { -struct RegExNodeChar : public RegExNode { + return memalloc(size); +} - CharType ch; +static void _regex_free(void *ptr, void *user) { - RegExNodeChar(CharType p_char) { + memfree(ptr); +} - length = 1; - quantifiable = true; - ch = p_char; - } +int RegExMatch::_find(const Variant &p_name) const { - virtual int test(RegExSearch &s, int pos) const { + if (p_name.is_num()) { - if (s.end <= pos || 0 > pos || s.at(pos) != ch) + int i = (int)p_name; + if (i >= data.size()) return -1; + return i; - return next ? next->test(s, pos + 1) : pos + 1; - } + } else if (p_name.get_type() == Variant::STRING) { - static CharType parse_escape(const CharType *&c) { - - int point = 0; - switch (c[1]) { - case 'x': - for (int i = 2; i <= 3; ++i) { - int res = RegEx_hex2int(c[i]); - if (res == -1) - return '\0'; - point = (point << 4) + res; - } - c = &c[3]; - return CharType(point); - case 'u': - for (int i = 2; i <= 5; ++i) { - int res = RegEx_hex2int(c[i]); - if (res == -1) - return '\0'; - point = (point << 4) + res; - } - c = &c[5]; - return CharType(point); - case '0': ++c; return '\0'; - case 'a': ++c; return '\a'; - case 'e': ++c; return '\e'; - case 'f': ++c; return '\f'; - case 'n': ++c; return '\n'; - case 'r': ++c; return '\r'; - case 't': ++c; return '\t'; - case 'v': ++c; return '\v'; - case 'b': ++c; return '\b'; - default: break; - } - return (++c)[0]; + const Map<String, int>::Element *found = names.find((String)p_name); + if (found) + return found->value(); } -}; -struct RegExNodeRange : public RegExNode { + return -1; +} - CharType start; - CharType end; +String RegExMatch::get_subject() const { - RegExNodeRange(CharType p_start, CharType p_end) { + return subject; +} - length = 1; - quantifiable = true; - start = p_start; - end = p_end; - } +int RegExMatch::get_group_count() const { - virtual int test(RegExSearch &s, int pos) const { + if (data.size() == 0) + return 0; + return data.size() - 1; +} - if (s.end <= pos || 0 > pos) - return -1; +Dictionary RegExMatch::get_names() const { - CharType c = s.at(pos); - if (c < start || end < c) - return -1; + Dictionary result; - return next ? next->test(s, pos + 1) : pos + 1; + for (const Map<String, int>::Element *i = names.front(); i != NULL; i = i->next()) { + result[i->key()] = i->value(); } -}; - -struct RegExNodeShorthand : public RegExNode { - CharType repr; + return result; +} - RegExNodeShorthand(CharType p_repr) { +Array RegExMatch::get_strings() const { - length = 1; - quantifiable = true; - repr = p_repr; - } + Array result; - virtual int test(RegExSearch &s, int pos) const { + int size = data.size(); - if (s.end <= pos || 0 > pos) - return -1; + for (int i = 0; i < size; i++) { - bool found = false; - bool invert = false; - CharType c = s.at(pos); - switch (repr) { - case '.': - found = true; - break; - case 'W': - invert = true; - case 'w': - found = (c == '_' || iswalnum(c) != 0); - break; - case 'D': - invert = true; - case 'd': - found = ('0' <= c && c <= '9'); - break; - case 'S': - invert = true; - case 's': - found = (iswspace(c) != 0); - break; - default: - break; - } + int start = data[i].start; - if (found == invert) - return -1; - - return next ? next->test(s, pos + 1) : pos + 1; - } -}; - -struct RegExNodeClass : public RegExNode { - - enum Type { - Type_none, - Type_alnum, - Type_alpha, - Type_ascii, - Type_blank, - Type_cntrl, - Type_digit, - Type_graph, - Type_lower, - Type_print, - Type_punct, - Type_space, - Type_upper, - Type_xdigit, - Type_word - }; - - Type type; - - bool test_class(CharType c) const { - - static Vector<CharType> REGEX_NODE_SPACE = String(" \t\r\n\f"); - static Vector<CharType> REGEX_NODE_PUNCT = String("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"); - - switch (type) { - case Type_alnum: - if ('0' <= c && c <= '9') return true; - if ('a' <= c && c <= 'z') return true; - if ('A' <= c && c <= 'Z') return true; - return false; - case Type_alpha: - if ('a' <= c && c <= 'z') return true; - if ('A' <= c && c <= 'Z') return true; - return false; - case Type_ascii: - return (0x00 <= c && c <= 0x7F); - case Type_blank: - return (c == ' ' || c == '\t'); - case Type_cntrl: - return ((0x00 <= c && c <= 0x1F) || c == 0x7F); - case Type_digit: - return ('0' <= c && c <= '9'); - case Type_graph: - return (0x20 < c && c < 0x7F); - case Type_lower: - return ('a' <= c && c <= 'z'); - case Type_print: - return (0x20 < c && c < 0x7f); - case Type_punct: - return (REGEX_NODE_PUNCT.find(c) >= 0); - case Type_space: - return (REGEX_NODE_SPACE.find(c) >= 0); - case Type_upper: - return ('A' <= c && c <= 'Z'); - case Type_xdigit: - if ('0' <= c && c <= '9') return true; - if ('a' <= c && c <= 'f') return true; - if ('A' <= c && c <= 'F') return true; - return false; - case Type_word: - if ('0' <= c && c <= '9') return true; - if ('a' <= c && c <= 'z') return true; - if ('A' <= c && c <= 'Z') return true; - return (c == '_'); - default: - return false; + if (start == -1) { + result.append(String()); + continue; } - return false; - } - - RegExNodeClass(Type p_type) { - - length = 1; - quantifiable = true; - type = p_type; - } - - virtual int test(RegExSearch &s, int pos) const { - - if (s.end <= pos || 0 > pos) - return -1; - - if (!test_class(s.at(pos))) - return -1; - - return next ? next->test(s, pos + 1) : pos + 1; - } - -#define REGEX_CMP_CLASS(POS, NAME) \ - if (cmp_class(POS, #NAME)) return Type_##NAME - - static Type parse_type(const CharType *&p_pos) { - - REGEX_CMP_CLASS(p_pos, alnum); - REGEX_CMP_CLASS(p_pos, alpha); - REGEX_CMP_CLASS(p_pos, ascii); - REGEX_CMP_CLASS(p_pos, blank); - REGEX_CMP_CLASS(p_pos, cntrl); - REGEX_CMP_CLASS(p_pos, digit); - REGEX_CMP_CLASS(p_pos, graph); - REGEX_CMP_CLASS(p_pos, lower); - REGEX_CMP_CLASS(p_pos, print); - REGEX_CMP_CLASS(p_pos, punct); - REGEX_CMP_CLASS(p_pos, space); - REGEX_CMP_CLASS(p_pos, upper); - REGEX_CMP_CLASS(p_pos, xdigit); - REGEX_CMP_CLASS(p_pos, word); - return Type_none; - } - - static bool cmp_class(const CharType *&p_pos, const char *p_text) { - - unsigned int i = 0; - for (i = 0; p_text[i] != '\0'; ++i) - if (p_pos[i] != p_text[i]) - return false; - - if (p_pos[i++] != ':' || p_pos[i] != ']') - return false; - - p_pos = &p_pos[i]; - return true; - } -}; - -struct RegExNodeAnchorStart : public RegExNode { - RegExNodeAnchorStart() { + int length = data[i].end - start; - length = 0; + result.append(subject.substr(start, length)); } - virtual int test(RegExSearch &s, int pos) const { + return result; +} - if (pos != 0) - return -1; +String RegExMatch::get_string(const Variant &p_name) const { - return next ? next->test(s, pos) : pos; - } -}; + int id = _find(p_name); -struct RegExNodeAnchorEnd : public RegExNode { + if (id < 0) + return String(); - RegExNodeAnchorEnd() { + int start = data[id].start; - length = 0; - } + if (start == -1) + return String(); - virtual int test(RegExSearch &s, int pos) const { + int length = data[id].end - start; - if (pos != s.eof) - return -1; + return subject.substr(start, length); +} - return next ? next->test(s, pos) : pos; - } -}; +int RegExMatch::get_start(const Variant &p_name) const { -struct RegExNodeWordBoundary : public RegExNode { + int id = _find(p_name); - bool inverse; + if (id < 0) + return -1; - RegExNodeWordBoundary(bool p_inverse) { + return data[id].start; +} - length = 0; - inverse = p_inverse; - } +int RegExMatch::get_end(const Variant &p_name) const { - virtual int test(RegExSearch &s, int pos) const { + int id = _find(p_name); - bool left = false; - bool right = false; + if (id < 0) + return -1; - if (pos != 0) { - CharType c = s.at(pos - 1); - if (c == '_' || iswalnum(c)) - left = true; - } + return data[id].end; +} - if (pos != s.eof) { - CharType c = s.at(pos); - if (c == '_' || iswalnum(c)) - right = true; - } +void RegExMatch::_bind_methods() { - if ((left == right) != inverse) - return -1; + ClassDB::bind_method(D_METHOD("get_subject"), &RegExMatch::get_subject); + ClassDB::bind_method(D_METHOD("get_group_count"), &RegExMatch::get_group_count); + ClassDB::bind_method(D_METHOD("get_names"), &RegExMatch::get_names); + ClassDB::bind_method(D_METHOD("get_strings"), &RegExMatch::get_strings); + ClassDB::bind_method(D_METHOD("get_string", "name"), &RegExMatch::get_string, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_start", "name"), &RegExMatch::get_start, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_end", "name"), &RegExMatch::get_end, DEFVAL(0)); +} - return next ? next->test(s, pos) : pos; - } -}; +void RegEx::_pattern_info(uint32_t what, void *where) const { -struct RegExNodeQuantifier : public RegExNode { + if (sizeof(CharType) == 2) { - int min; - int max; - bool greedy; - RegExNode *child; + pcre2_pattern_info_16((pcre2_code_16 *)code, what, where); - RegExNodeQuantifier(int p_min, int p_max) { + } else { - min = p_min; - max = p_max; - greedy = true; - child = NULL; + pcre2_pattern_info_32((pcre2_code_32 *)code, what, where); } +} - ~RegExNodeQuantifier() { - - if (child) - memdelete(child); - } +void RegEx::clear() { - virtual int test(RegExSearch &s, int pos) const { + if (sizeof(CharType) == 2) { - return test_step(s, pos, 0, pos); - } + if (code) + pcre2_code_free_16((pcre2_code_16 *)code); - virtual int test_parent(RegExSearch &s, int pos) const { + } else { - s.complete = false; - return pos; + if (code) + pcre2_code_free_32((pcre2_code_32 *)code); } +} - int test_step(RegExSearch &s, int pos, int level, int start) const { - - if (pos > s.end) - return -1; - - if (!greedy && level > min) { - int res = next ? next->test(s, pos) : pos; - if (s.complete) - return res; - - if (res >= 0 && parent->test_parent(s, res) >= 0) - return res; - } - - if (max >= 0 && level > max) - return -1; +Error RegEx::compile(const String &p_pattern) { - int res = pos; - if (level >= 1) { - if (level > min + 1 && pos == start) - return -1; + pattern = p_pattern; + clear(); - res = child->test(s, pos); - if (s.complete) - return res; - } + int err; + PCRE2_SIZE offset; + uint32_t flags = PCRE2_DUPNAMES; - if (res >= 0) { + if (sizeof(CharType) == 2) { - int res_step = test_step(s, res, level + 1, start); - if (res_step >= 0) - return res_step; + pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx; + pcre2_compile_context_16 *cctx = pcre2_compile_context_create_16(gctx); + PCRE2_SPTR16 p = (PCRE2_SPTR16)pattern.c_str(); - if (greedy && level >= min) { - if (next) - res = next->test(s, res); - if (s.complete) - return res; + code = pcre2_compile_16(p, pattern.length(), flags, &err, &offset, cctx); - if (res >= 0 && parent->test_parent(s, res) >= 0) - return res; - } + if (!code) { + PCRE2_UCHAR16 buf[256]; + pcre2_get_error_message_16(err, buf, 256); + String message = String::num(offset) + ": " + String((const CharType *)buf); + ERR_PRINT(message.utf8()); + return FAILED; } - return -1; - } -}; - -struct RegExNodeBackReference : public RegExNode { - int id; + } else { - RegExNodeBackReference(int p_id) { - - length = -1; - quantifiable = true; - id = p_id; - } + pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx; + pcre2_compile_context_32 *cctx = pcre2_compile_context_create_32(gctx); + PCRE2_SPTR32 p = (PCRE2_SPTR32)pattern.c_str(); - virtual int test(RegExSearch &s, int pos) const { + code = pcre2_compile_32(p, pattern.length(), flags, &err, &offset, cctx); - RegExMatch::Group &ref = s.match->captures[id]; - for (int i = 0; i < ref.length; ++i) { - - if (pos + i >= s.end) - return -1; - - if (s.at(ref.start + i) != s.at(pos + i)) - return -1; + if (!code) { + PCRE2_UCHAR32 buf[256]; + pcre2_get_error_message_32(err, buf, 256); + String message = String::num(offset) + ": " + String((const CharType *)buf); + ERR_PRINT(message.utf8()); + return FAILED; } - return next ? next->test(s, pos + ref.length) : pos + ref.length; } -}; - -struct RegExNodeGroup : public RegExNode { - - bool inverse; - bool reset_pos; - Vector<RegExNode *> childset; - RegExNode *back; - - RegExNodeGroup() { - - length = 0; - quantifiable = true; - inverse = false; - reset_pos = false; - back = NULL; - } - - virtual ~RegExNodeGroup() { - - for (int i = 0; i < childset.size(); ++i) - memdelete(childset[i]); - } - - virtual void test_success(RegExSearch &s, int pos) const { + return OK; +} - return; - } +Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) const { - virtual int test(RegExSearch &s, int pos) const { + ERR_FAIL_COND_V(!is_valid(), NULL); - for (int i = 0; i < childset.size(); ++i) { + Ref<RegExMatch> result = memnew(RegExMatch); - s.complete = false; + int length = p_subject.length(); + if (p_end >= 0 && p_end < length) + length = p_end; - int res = childset[i]->test(s, pos); + if (sizeof(CharType) == 2) { - if (inverse) { - s.complete = false; - if (res < 0) - res = pos + 1; - else - return -1; + pcre2_code_16 *c = (pcre2_code_16 *)code; + pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx; + pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx); + PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str(); - if (i + 1 < childset.size()) - continue; - } + pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx); - if (s.complete) - return res; + int res = pcre2_match_16(c, s, length, p_offset, 0, match, mctx); - if (res >= 0) { - if (reset_pos) - res = pos; - this->test_success(s, res); - return next ? next->test(s, res) : res; - } + if (res < 0) { + pcre2_match_data_free_16(match); + return NULL; } - return -1; - } - - void add_child(RegExNode *node) { - node->parent = this; - node->previous = back; + uint32_t size = pcre2_get_ovector_count_16(match); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_16(match); - if (back) - back->next = node; - else - childset.push_back(node); + result->data.resize(size); - increment_length(node->length); + for (uint32_t i = 0; i < size; i++) { - back = node; - } - - void add_childset() { - - if (childset.size() > 0) - length = -1; - back = NULL; - } - - RegExNode *swap_back(RegExNode *node) { - - RegExNode *old = back; - - if (old) { - if (!old->previous) - childset.remove(childset.size() - 1); - back = old->previous; - increment_length(old->length, true); + result->data[i].start = ovector[i * 2]; + result->data[i].end = ovector[i * 2 + 1]; } - add_child(node); + pcre2_match_data_free_16(match); + pcre2_match_context_free_16(mctx); - return old; - } -}; + } else { -struct RegExNodeCapturing : public RegExNodeGroup { + pcre2_code_32 *c = (pcre2_code_32 *)code; + pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx; + pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx); + PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str(); - int id; + pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx); - RegExNodeCapturing(int p_id = 0) { + int res = pcre2_match_32(c, s, length, p_offset, 0, match, mctx); - id = p_id; - } - - virtual void test_success(RegExSearch &s, int pos) const { - - RegExMatch::Group &ref = s.match->captures[id]; - ref.length = pos - ref.start; - } - - virtual int test(RegExSearch &s, int pos) const { - - RegExMatch::Group &ref = s.match->captures[id]; - int old_start = ref.start; - ref.start = pos; - - int res = RegExNodeGroup::test(s, pos); - - if (res < 0) - ref.start = old_start; - return res; - } - - virtual int test_parent(RegExSearch &s, int pos) const { - - RegExMatch::Group &ref = s.match->captures[id]; - ref.length = pos - ref.start; - return RegExNode::test_parent(s, pos); - } - - static Variant parse_name(const CharType *&c, bool p_allow_numeric) { - - if (c[1] == '0') { - return -1; - } else if ('1' <= c[1] && c[1] <= '9') { - if (!p_allow_numeric) - return -1; - int res = (++c)[0] - '0'; - while ('0' <= c[1] && c[1] <= '9') - res = res * 10 + int((++c)[0] - '0'); - if ((++c)[0] != '>') - return -1; - return res; - } else if (iswalnum(c[1])) { - String res(++c, 1); - while (iswalnum(c[1])) - res += String(++c, 1); - if ((++c)[0] != '>') - return -1; - return res; + if (res < 0) { + pcre2_match_data_free_32(match); + return NULL; } - return -1; - } -}; - -struct RegExNodeLookAhead : public RegExNodeGroup { - - int id; - RegExNodeLookAhead(bool p_inverse, int p_id = 0) { + uint32_t size = pcre2_get_ovector_count_32(match); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_32(match); - quantifiable = false; - inverse = p_inverse; - reset_pos = true; - id = p_id; - } - - virtual int test(RegExSearch &s, int pos) const { + result->data.resize(size); - s.lookahead_pos[id] = pos; - return RegExNodeGroup::test(s, pos); - } + for (uint32_t i = 0; i < size; i++) { - virtual int test_parent(RegExSearch &s, int pos) const { + result->data[i].start = ovector[i * 2]; + result->data[i].end = ovector[i * 2 + 1]; + } - return RegExNode::test_parent(s, s.lookahead_pos[id]); + pcre2_match_data_free_32(match); + pcre2_match_context_free_32(mctx); } -}; -struct RegExNodeLookBehind : public RegExNodeGroup { + result->subject = p_subject; - RegExNodeLookBehind(bool p_inverse, int p_id = 0) { + uint32_t count; + const CharType *table; + uint32_t entry_size; - quantifiable = false; - inverse = p_inverse; - reset_pos = true; - } + _pattern_info(PCRE2_INFO_NAMECOUNT, &count); + _pattern_info(PCRE2_INFO_NAMETABLE, &table); + _pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size); - virtual bool is_look_behind() { return true; } + for (uint32_t i = 0; i < count; i++) { - virtual int test(RegExSearch &s, int pos) const { + CharType id = table[i * entry_size]; + if (result->data[id].start == -1) + continue; + String name = &table[i * entry_size + 1]; + if (result->names.has(name)) + continue; - if (pos < length) - return -1; - return RegExNodeGroup::test(s, pos - length); + result->names.insert(name, id); } -}; -struct RegExNodeBracket : public RegExNode { + return result; +} - bool inverse; - Vector<RegExNode *> children; +String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_all, int p_offset, int p_end) const { - RegExNodeBracket() { + ERR_FAIL_COND_V(!is_valid(), String()); - length = 1; - quantifiable = true; - inverse = false; - } + String output; + output.resize(p_subject.length()); - virtual ~RegExNodeBracket() { + uint32_t flags = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH; + if (p_all) + flags |= PCRE2_SUBSTITUTE_GLOBAL; - for (int i = 0; i < children.size(); ++i) - memdelete(children[i]); - } + PCRE2_SIZE olength = output.length(); - virtual int test(RegExSearch &s, int pos) const { + PCRE2_SIZE length = p_subject.length(); + if (p_end >= 0 && (uint32_t)p_end < length) + length = p_end; - for (int i = 0; i < children.size(); ++i) { + if (sizeof(CharType) == 2) { - int res = children[i]->test(s, pos); + pcre2_code_16 *c = (pcre2_code_16 *)code; + pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx; + pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx); + PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str(); + PCRE2_SPTR16 r = (PCRE2_SPTR16)p_replacement.c_str(); + PCRE2_UCHAR16 *o = (PCRE2_UCHAR16 *)output.c_str(); - if (inverse) { - if (res < 0) - res = pos + 1; - else - return -1; + pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx); - if (i + 1 < children.size()) - continue; - } + int res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); - if (res >= 0) - return next ? next->test(s, res) : res; + if (res == PCRE2_ERROR_NOMEMORY) { + output.resize(olength); + o = (PCRE2_UCHAR16 *)output.c_str(); + res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); } - return -1; - } - void add_child(RegExNode *node) { - - node->parent = this; - children.push_back(node); - } + pcre2_match_data_free_16(match); + pcre2_match_context_free_16(mctx); - void pop_back() { - - memdelete(children[children.size() - 1]); - children.remove(children.size() - 1); - } -}; - -#define REGEX_EXPAND_FAIL(MSG) \ - { \ - ERR_PRINT(MSG); \ - return String(); \ - } - -String RegExMatch::expand(const String &p_template) const { - - String res; - for (const CharType *c = p_template.c_str(); *c != '\0'; ++c) { - if (c[0] == '\\') { - if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{')) { - - int ref = 0; - bool unclosed = false; - - if (c[1] == 'g') { - unclosed = true; - c = &c[2]; - } - - while ('0' <= c[1] && c[1] <= '9') { - ref = ref * 10 + int(c[1] - '0'); - ++c; - } - - if (unclosed) { - if (c[1] != '}') - REGEX_EXPAND_FAIL("unclosed backreference '{'"); - ++c; - } - - res += get_string(ref); - - } else if (c[1] == 'g' && c[2] == '<') { - - const CharType *d = &c[2]; + if (res < 0) + return String(); - Variant name = RegExNodeCapturing::parse_name(d, true); - if (name == Variant(-1)) - REGEX_EXPAND_FAIL("unrecognised character for group name"); + } else { - c = d; + pcre2_code_32 *c = (pcre2_code_32 *)code; + pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx; + pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx); + PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str(); + PCRE2_SPTR32 r = (PCRE2_SPTR32)p_replacement.c_str(); + PCRE2_UCHAR32 *o = (PCRE2_UCHAR32 *)output.c_str(); - res += get_string(name); + pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx); - } else { + int res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); - const CharType *d = c; - CharType ch = RegExNodeChar::parse_escape(d); - if (c == d) - REGEX_EXPAND_FAIL("invalid escape token"); - res += String(&ch, 1); - c = d; - } - } else { - res += String(c, 1); + if (res == PCRE2_ERROR_NOMEMORY) { + output.resize(olength); + o = (PCRE2_UCHAR32 *)output.c_str(); + res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); } - } - return res; -} -int RegExMatch::get_group_count() const { + pcre2_match_data_free_32(match); + pcre2_match_context_free_32(mctx); - int count = 0; - for (int i = 1; i < captures.size(); ++i) - if (captures[i].name.get_type() == Variant::INT) - ++count; - return count; -} - -Array RegExMatch::get_group_array() const { - - Array res; - for (int i = 1; i < captures.size(); ++i) { - const RegExMatch::Group &capture = captures[i]; - if (capture.name.get_type() != Variant::INT) - continue; - - if (capture.start >= 0) - res.push_back(string.substr(capture.start, capture.length)); - else - res.push_back(String()); - } - return res; -} - -Array RegExMatch::get_names() const { - - Array res; - for (int i = 1; i < captures.size(); ++i) - if (captures[i].name.get_type() == Variant::STRING) - res.push_back(captures[i].name); - return res; -} - -Dictionary RegExMatch::get_name_dict() const { - - Dictionary res; - for (int i = 1; i < captures.size(); ++i) { - const RegExMatch::Group &capture = captures[i]; - if (capture.name.get_type() != Variant::STRING) - continue; - - if (capture.start >= 0) - res[capture.name] = string.substr(capture.start, capture.length); - else - res[capture.name] = String(); - } - return res; -} - -String RegExMatch::get_string(const Variant &p_name) const { - - for (int i = 0; i < captures.size(); ++i) { - - const RegExMatch::Group &capture = captures[i]; - - if (capture.name != p_name) - continue; - - if (capture.start == -1) + if (res < 0) return String(); - - return string.substr(capture.start, capture.length); } - return String(); -} - -int RegExMatch::get_start(const Variant &p_name) const { - for (int i = 0; i < captures.size(); ++i) - if (captures[i].name == p_name) - return captures[i].start; - return -1; + return output; } -int RegExMatch::get_end(const Variant &p_name) const { +bool RegEx::is_valid() const { - for (int i = 0; i < captures.size(); ++i) - if (captures[i].name == p_name) - return captures[i].start + captures[i].length; - return -1; + return (code != NULL); } -RegExMatch::RegExMatch() { -} +String RegEx::get_pattern() const { -static bool RegEx_is_shorthand(CharType ch) { - - switch (ch) { - case 'w': - case 'W': - case 'd': - case 'D': - case 's': - case 'S': - return true; - default: - break; - } - return false; + return pattern; } -#define REGEX_COMPILE_FAIL(MSG) \ - { \ - ERR_PRINT(MSG); \ - clear(); \ - return FAILED; \ - } +int RegEx::get_group_count() const { -Error RegEx::compile(const String &p_pattern) { + ERR_FAIL_COND_V(!is_valid(), 0); - ERR_FAIL_COND_V(p_pattern.length() == 0, FAILED); + uint32_t count; - if (pattern == p_pattern && root) - return OK; + _pattern_info(PCRE2_INFO_CAPTURECOUNT, &count); - clear(); - pattern = p_pattern; - group_names.push_back(0); - RegExNodeGroup *root_group = memnew(RegExNodeCapturing(0)); - root = root_group; - Vector<RegExNodeGroup *> stack; - stack.push_back(root_group); - int lookahead_level = 0; - int numeric_groups = 0; - const int numeric_max = 9; - - for (const CharType *c = p_pattern.c_str(); *c != '\0'; ++c) { - - switch (c[0]) { - case '(': - if (c[1] == '?') { - - RegExNodeGroup *group = NULL; - switch (c[2]) { - case ':': - c = &c[2]; - group = memnew(RegExNodeGroup()); - break; - case '!': - case '=': - group = memnew(RegExNodeLookAhead((c[2] == '!'), lookahead_level++)); - if (lookahead_depth < lookahead_level) - lookahead_depth = lookahead_level; - c = &c[2]; - break; - case '<': - if (c[3] == '!' || c[3] == '=') { - group = memnew(RegExNodeLookBehind((c[3] == '!'), lookahead_level++)); - c = &c[3]; - } - break; - case 'P': - if (c[3] == '<') { - const CharType *d = &c[3]; - Variant name = RegExNodeCapturing::parse_name(d, false); - if (name == Variant(-1)) - REGEX_COMPILE_FAIL("unrecognised character for group name"); - group = memnew(RegExNodeCapturing(group_names.size())); - group_names.push_back(name); - c = d; - } - default: - break; - } - if (!group) - REGEX_COMPILE_FAIL("unrecognised qualifier for group"); - stack[0]->add_child(group); - stack.insert(0, group); - - } else if (numeric_groups < numeric_max) { - - RegExNodeCapturing *group = memnew(RegExNodeCapturing(group_names.size())); - group_names.push_back(++numeric_groups); - stack[0]->add_child(group); - stack.insert(0, group); - - } else { - - RegExNodeGroup *group = memnew(RegExNodeGroup()); - stack[0]->add_child(group); - stack.insert(0, group); - } - break; - case ')': - if (stack.size() == 1) - REGEX_COMPILE_FAIL("unexpected ')'"); - stack.remove(0); - break; - case '\\': - if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{')) { - - int ref = 0; - bool unclosed = false; - - if (c[1] == 'g') { - unclosed = true; - c = &c[2]; - } - - while ('0' <= c[1] && c[1] <= '9') { - ref = ref * 10 + int(c[1] - '0'); - ++c; - } - - if (unclosed) { - if (c[1] != '}') - REGEX_COMPILE_FAIL("unclosed backreference '{'"); - ++c; - } - - if (ref > numeric_groups || ref <= 0) - REGEX_COMPILE_FAIL("backreference not found"); - - for (int i = 0; i < stack.size(); ++i) - if (stack[i]->is_look_behind()) - REGEX_COMPILE_FAIL("backreferences inside lookbehind not supported"); - - for (int i = 0; i < group_names.size(); ++i) { - if (group_names[i].get_type() == Variant::INT && int(group_names[i]) == ref) { - ref = group_names[i]; - break; - } - } - - stack[0]->add_child(memnew(RegExNodeBackReference(ref))); - } - if (c[1] == 'g' && c[2] == '<') { - - const CharType *d = &c[2]; - - Variant name = RegExNodeCapturing::parse_name(d, true); - if (name == Variant(-1)) - REGEX_COMPILE_FAIL("unrecognised character for group name"); - - c = d; - - for (int i = 0; i < stack.size(); ++i) - if (stack[i]->is_look_behind()) - REGEX_COMPILE_FAIL("backreferences inside lookbehind not supported"); - - int ref = -1; - - for (int i = 0; i < group_names.size(); ++i) { - if (group_names[i].get_type() == Variant::INT && int(group_names[i]) == ref) { - ref = group_names[i]; - break; - } - } - - if (ref == -1) - REGEX_COMPILE_FAIL("backreference not found"); - - stack[0]->add_child(memnew(RegExNodeBackReference(ref))); - - } else if (c[1] == 'b' || c[1] == 'B') { - - stack[0]->add_child(memnew(RegExNodeWordBoundary(*(++c) == 'B'))); - - } else if (RegEx_is_shorthand(c[1])) { - - stack[0]->add_child(memnew(RegExNodeShorthand(*(++c)))); - - } else { - - const CharType *d = c; - CharType ch = RegExNodeChar::parse_escape(d); - if (c == d) - REGEX_COMPILE_FAIL("invalid escape token"); - stack[0]->add_child(memnew(RegExNodeChar(ch))); - c = d; - } - break; - case '[': { - RegExNodeBracket *bracket = memnew(RegExNodeBracket()); - stack[0]->add_child(bracket); - if (c[1] == '^') { - bracket->inverse = true; - ++c; - } - bool first_child = true; - CharType previous_child; - bool previous_child_single = false; - while (true) { - ++c; - if (!first_child && c[0] == ']') { - - break; - - } else if (c[0] == '\0') { - - REGEX_COMPILE_FAIL("unclosed bracket expression '['"); - - } else if (c[0] == '\\') { - - if (RegEx_is_shorthand(c[1])) { - bracket->add_child(memnew(RegExNodeShorthand(*(++c)))); - } else { - const CharType *d = c; - CharType ch = RegExNodeChar::parse_escape(d); - if (c == d) - REGEX_COMPILE_FAIL("invalid escape token"); - bracket->add_child(memnew(RegExNodeChar(ch))); - c = d; - previous_child = ch; - previous_child_single = true; - } - - } else if (c[0] == ']' && c[1] == ':') { - - const CharType *d = &c[2]; - RegExNodeClass::Type type = RegExNodeClass::parse_type(d); - if (type != RegExNodeClass::Type_none) { - - c = d; - previous_child_single = false; - - } else { - - bracket->add_child(memnew(RegExNodeChar('['))); - previous_child = '['; - previous_child_single = true; - } - } else if (previous_child_single && c[0] == '-') { - - if (c[1] != '\0' && c[1] != ']') { - - CharType next; - - if (c[1] == '\\') { - const CharType *d = ++c; - next = RegExNodeChar::parse_escape(d); - if (c == d) - REGEX_COMPILE_FAIL("invalid escape token"); - } else { - next = *(++c); - } - - if (next < previous_child) - REGEX_COMPILE_FAIL("text range out of order"); - - bracket->pop_back(); - bracket->add_child(memnew(RegExNodeRange(previous_child, next))); - previous_child_single = false; - } else { - - bracket->add_child(memnew(RegExNodeChar('-'))); - previous_child = '-'; - previous_child_single = true; - } - } else { - - bracket->add_child(memnew(RegExNodeChar(c[0]))); - previous_child = c[0]; - previous_child_single = true; - } - first_child = false; - } - } break; - case '|': - for (int i = 0; i < stack.size(); ++i) - if (stack[i]->is_look_behind()) - REGEX_COMPILE_FAIL("alternations inside lookbehind not supported"); - stack[0]->add_childset(); - break; - case '^': - stack[0]->add_child(memnew(RegExNodeAnchorStart())); - break; - case '$': - stack[0]->add_child(memnew(RegExNodeAnchorEnd())); - break; - case '.': - stack[0]->add_child(memnew(RegExNodeShorthand('.'))); - break; - case '?': - case '*': - case '+': - case '{': { - int min_val = 0; - int max_val = -1; - bool valid = true; - const CharType *d = c; - bool max_set = true; - switch (c[0]) { - case '?': - min_val = 0; - max_val = 1; - break; - case '*': - min_val = 0; - max_val = -1; - break; - case '+': - min_val = 1; - max_val = -1; - break; - case '{': - max_set = false; - while (valid) { - ++d; - if (d[0] == '}') { - break; - } else if (d[0] == ',') { - max_set = true; - } else if ('0' <= d[0] && d[0] <= '9') { - if (max_set) { - if (max_val < 0) - max_val = int(d[0] - '0'); - else - max_val = max_val * 10 + int(d[0] - '0'); - } else { - min_val = min_val * 10 + int(d[0] - '0'); - } - } else { - valid = false; - } - } - break; - default: - break; - } - - if (!max_set) - max_val = min_val; - - if (valid) { - - c = d; - - if (stack[0]->back == NULL || !stack[0]->back->quantifiable) - REGEX_COMPILE_FAIL("element not quantifiable"); - - if (min_val != max_val) - for (int i = 0; i < stack.size(); ++i) - if (stack[i]->is_look_behind()) - REGEX_COMPILE_FAIL("variable length quantifiers inside lookbehind not supported"); - - RegExNodeQuantifier *quant = memnew(RegExNodeQuantifier(min_val, max_val)); - quant->child = stack[0]->swap_back(quant); - quant->child->previous = NULL; - quant->child->parent = quant; - - if (min_val == max_val && quant->child->length >= 0) - quant->length = max_val * quant->child->length; - - if (c[1] == '?') { - quant->greedy = false; - ++c; - } - break; - } - } - default: - stack[0]->add_child(memnew(RegExNodeChar(c[0]))); - break; - } - } - if (stack.size() > 1) - REGEX_COMPILE_FAIL("unclosed group '('"); - return OK; + return count; } -Ref<RegExMatch> RegEx::search(const String &p_text, int p_start, int p_end) const { - - ERR_FAIL_COND_V(!is_valid(), NULL); - ERR_FAIL_COND_V(p_start < 0, NULL); - ERR_FAIL_COND_V(p_start >= p_text.length(), NULL); - ERR_FAIL_COND_V(p_end > p_text.length(), NULL); - ERR_FAIL_COND_V(p_end != -1 && p_end < p_start, NULL); +Array RegEx::get_names() const { - Ref<RegExMatch> res = memnew(RegExMatch()); + Array result; - for (int i = 0; i < group_names.size(); ++i) { - RegExMatch::Group group; - group.name = group_names[i]; - res->captures.push_back(group); - } + ERR_FAIL_COND_V(!is_valid(), result); - res->string = p_text; + uint32_t count; + const CharType *table; + uint32_t entry_size; - if (p_end == -1) - p_end = p_text.length(); + _pattern_info(PCRE2_INFO_NAMECOUNT, &count); + _pattern_info(PCRE2_INFO_NAMETABLE, &table); + _pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size); - RegExSearch s(res, p_end, lookahead_depth); + for (uint32_t i = 0; i < count; i++) { - for (int i = p_start; i <= s.end; ++i) { - for (int c = 0; c < group_names.size(); ++c) { - res->captures[c].start = -1; - res->captures[c].length = 0; + String name = &table[i * entry_size + 1]; + if (result.find(name) < 0) { + result.append(name); } - if (root->test(s, i) >= 0) - break; } - if (res->captures[0].start >= 0) - return res; - return NULL; + return result; } -String RegEx::sub(const String &p_text, const String &p_replacement, bool p_all, int p_start, int p_end) const { - - ERR_FAIL_COND_V(!is_valid(), p_text); - ERR_FAIL_COND_V(p_start < 0, p_text); - ERR_FAIL_COND_V(p_start >= p_text.length(), p_text); - ERR_FAIL_COND_V(p_end > p_text.length(), p_text); - ERR_FAIL_COND_V(p_end != -1 && p_end < p_start, p_text); - - String text = p_text; - int start = p_start; - - if (p_end == -1) - p_end = p_text.length(); - - while (start < text.length() && (p_all || start == p_start)) { - - Ref<RegExMatch> m = search(text, start, p_end); - - RegExMatch::Group &s = m->captures[0]; - - if (s.start < 0) - break; - - String res = text.substr(0, s.start) + m->expand(p_replacement); - - start = res.length(); +RegEx::RegEx() { - if (s.length == 0) - ++start; + if (sizeof(CharType) == 2) { - int sub_end = s.start + s.length; - if (sub_end < text.length()) - res += text.substr(sub_end, text.length() - sub_end); + general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, NULL); - p_end += res.length() - text.length(); + } else { - text = res; + general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, NULL); } - return text; + code = NULL; } -void RegEx::clear() { - - if (root) - memdelete(root); - - root = NULL; - group_names.clear(); - lookahead_depth = 0; -} - -bool RegEx::is_valid() const { - - return (root != NULL); -} - -String RegEx::get_pattern() const { - - return pattern; -} - -int RegEx::get_group_count() const { - - int count = 0; - for (int i = 1; i < group_names.size(); ++i) - if (group_names[i].get_type() == Variant::INT) - ++count; - return count; -} - -Array RegEx::get_names() const { +RegEx::RegEx(const String &p_pattern) { - Array res; - for (int i = 1; i < group_names.size(); ++i) - if (group_names[i].get_type() == Variant::STRING) - res.push_back(group_names[i]); - return res; -} + if (sizeof(CharType) == 2) { -RegEx::RegEx() { + general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, NULL); - root = NULL; - lookahead_depth = 0; -} + } else { -RegEx::RegEx(const String &p_pattern) { - - root = NULL; + general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, NULL); + } + code = NULL; compile(p_pattern); } RegEx::~RegEx() { - if (root) - memdelete(root); -} + if (sizeof(CharType) == 2) { -void RegExMatch::_bind_methods() { + if (code) + pcre2_code_free_16((pcre2_code_16 *)code); + pcre2_general_context_free_16((pcre2_general_context_16 *)general_ctx); - ClassDB::bind_method(D_METHOD("expand", "template"), &RegExMatch::expand); - ClassDB::bind_method(D_METHOD("get_group_count"), &RegExMatch::get_group_count); - ClassDB::bind_method(D_METHOD("get_group_array"), &RegExMatch::get_group_array); - ClassDB::bind_method(D_METHOD("get_names"), &RegExMatch::get_names); - ClassDB::bind_method(D_METHOD("get_name_dict"), &RegExMatch::get_name_dict); - ClassDB::bind_method(D_METHOD("get_string", "name"), &RegExMatch::get_string, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_start", "name"), &RegExMatch::get_start, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_end", "name"), &RegExMatch::get_end, DEFVAL(0)); + } else { + + if (code) + pcre2_code_free_32((pcre2_code_32 *)code); + pcre2_general_context_free_32((pcre2_general_context_32 *)general_ctx); + } } void RegEx::_bind_methods() { ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear); ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile); - ClassDB::bind_method(D_METHOD("search", "text", "start", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("sub", "text", "replacement", "all", "start", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("search", "subject", "offset", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("sub", "subject", "replacement", "all", "offset", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("is_valid"), &RegEx::is_valid); ClassDB::bind_method(D_METHOD("get_pattern"), &RegEx::get_pattern); ClassDB::bind_method(D_METHOD("get_group_count"), &RegEx::get_group_count); ClassDB::bind_method(D_METHOD("get_names"), &RegEx::get_names); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "pattern"), "compile", "get_pattern"); } diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 8c76035b82..0d97bcce54 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -31,59 +31,53 @@ #ifndef REGEX_H #define REGEX_H +#include "core/array.h" #include "core/dictionary.h" +#include "core/map.h" #include "core/reference.h" -#include "core/resource.h" #include "core/ustring.h" #include "core/vector.h" -class RegExNode; - class RegExMatch : public Reference { GDCLASS(RegExMatch, Reference); - struct Group { - Variant name; + struct Range { int start; - int length; + int end; }; - Vector<Group> captures; - String string; + String subject; + Vector<Range> data; + Map<String, int> names; friend class RegEx; - friend class RegExSearch; - friend class RegExNodeCapturing; - friend class RegExNodeBackReference; protected: static void _bind_methods(); -public: - String expand(const String &p_template) const; + int _find(const Variant &p_name) const; +public: + String get_subject() const; int get_group_count() const; - Array get_group_array() const; - - Array get_names() const; - Dictionary get_name_dict() const; + Dictionary get_names() const; + Array get_strings() const; String get_string(const Variant &p_name) const; int get_start(const Variant &p_name) const; int get_end(const Variant &p_name) const; - - RegExMatch(); }; -class RegEx : public Resource { +class RegEx : public Reference { - GDCLASS(RegEx, Resource); + GDCLASS(RegEx, Reference); - RegExNode *root; - Vector<Variant> group_names; + void *general_ctx; + void *code; String pattern; - int lookahead_depth; + + void _pattern_info(uint32_t what, void *where) const; protected: static void _bind_methods(); @@ -91,9 +85,10 @@ protected: public: void clear(); Error compile(const String &p_pattern); + void _init(const String &p_pattern = ""); - Ref<RegExMatch> search(const String &p_text, int p_start = 0, int p_end = -1) const; - String sub(const String &p_text, const String &p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const; + Ref<RegExMatch> search(const String &p_subject, int offset = 0, int end = -1) const; + String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const; bool is_valid() const; String get_pattern() const; diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp index 29073a8499..072f18b990 100644 --- a/modules/squish/image_compress_squish.cpp +++ b/modules/squish/image_compress_squish.cpp @@ -91,7 +91,7 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) { if (p_image->get_format() <= Image::FORMAT_RGBA8) { int squish_comp = squish::kColourRangeFit; - Image::Format target_format; + Image::Format target_format = Image::FORMAT_RGBA8; Image::DetectChannels dc = p_image->get_detected_channels(); @@ -140,6 +140,10 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) { squish_comp |= squish::kDxt5; } break; + default: { + ERR_PRINT("Unknown image format, defaulting to RGBA8"); + break; + } } PoolVector<uint8_t> data; diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index 49d959203c..df427907f8 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -31,7 +31,10 @@ #include "os/file_access.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #include "thirdparty/misc/stb_vorbis.c" +#pragma GCC diagnostic pop void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) { @@ -112,8 +115,8 @@ float AudioStreamPlaybackOGGVorbis::get_length() const { AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { if (ogg_alloc.alloc_buffer) { - AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer); stb_vorbis_close(ogg_stream); + AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer); } } diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h index a459e6f31d..bcd829a56a 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h @@ -34,7 +34,10 @@ #include "servers/audio/audio_stream.h" #define STB_VORBIS_HEADER_ONLY +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #include "thirdparty/misc/stb_vorbis.c" +#pragma GCC diagnostic pop #undef STB_VORBIS_HEADER_ONLY class AudioStreamOGGVorbis; diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 086cc202f9..f5c379d32e 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -47,7 +47,49 @@ SVGRasterizer::~SVGRasterizer() { SVGRasterizer ImageLoaderSVG::rasterizer; -Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample) { +inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, const uint32_t p_new) { + + if (p_paint->type == NSVG_PAINT_COLOR) { + if (p_paint->color << 8 == p_old << 8) { + p_paint->color = p_new; + } + } + + if (p_paint->type == NSVG_PAINT_LINEAR_GRADIENT || p_paint->type == NSVG_PAINT_RADIAL_GRADIENT) { + for (int stop_index = 0; stop_index < p_paint->gradient->nstops; stop_index++) { + if (p_paint->gradient->stops[stop_index].color << 8 == p_old << 8) { + p_paint->gradient->stops[stop_index].color = p_new; + } + } + } +} +void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image, const Dictionary p_colors) { + List<uint32_t> replace_colors_i; + List<uint32_t> new_colors_i; + List<Color> replace_colors; + List<Color> new_colors; + + for (int i = 0; i < p_colors.keys().size(); i++) { + Variant r_c = p_colors.keys()[i]; + Variant n_c = p_colors[p_colors.keys()[i]]; + if (r_c.get_type() == Variant::COLOR && n_c.get_type() == Variant::COLOR) { + Color replace_color = r_c; + Color new_color = n_c; + replace_colors_i.push_back(replace_color.to_ABGR32()); + new_colors_i.push_back(new_color.to_ABGR32()); + } + } + + for (NSVGshape *shape = p_svg_image->shapes; shape != NULL; shape = shape->next) { + + for (int i = 0; i < replace_colors_i.size(); i++) { + change_nsvg_paint_color(&(shape->stroke), replace_colors_i[i], new_colors_i[i]); + change_nsvg_paint_color(&(shape->fill), replace_colors_i[i], new_colors_i[i]); + } + } +} + +Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, const Dictionary *p_replace_colors) { NSVGimage *svg_image; PoolVector<uint8_t>::Read src_r = p_data->read(); svg_image = nsvgParse((char *)src_r.ptr(), "px", 96); @@ -56,6 +98,9 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t return ERR_FILE_CORRUPT; } + if (p_replace_colors != NULL) { + _convert_colors(svg_image, *p_replace_colors); + } float upscale = upsample ? 2.0 : 1.0; int w = (int)(svg_image->width * p_scale * upscale); @@ -78,7 +123,7 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t return OK; } -Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample) { +Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample, const Dictionary *p_replace_colors) { size_t str_len = strlen(svg_str); PoolVector<uint8_t> src_data; @@ -86,7 +131,7 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *s PoolVector<uint8_t>::Write src_w = src_data.write(); memcpy(src_w.ptr(), svg_str, str_len + 1); - return _create_image(p_image, &src_data, p_scale, upsample); + return _create_image(p_image, &src_data, p_scale, upsample, p_replace_colors); } Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index 1f2ec3c1c2..f692b1b28c 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -54,14 +54,15 @@ public: class ImageLoaderSVG : public ImageFormatLoader { static SVGRasterizer rasterizer; - static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample); + static void _convert_colors(NSVGimage *p_svg_imge, const Dictionary p_colors); + static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, const Dictionary *p_replace_color = NULL); public: - static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample); + static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, const Dictionary *p_replace_color = NULL); virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderSVG(); }; -#endif
\ No newline at end of file +#endif diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 379c894550..7c7cf5bcbe 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.cpp */ +/* image_loader_tga.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -53,19 +53,19 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t count = (c & 0x7f) + 1; if (c & 0x80) { - for (int i = 0; i < p_pixel_size; i++) { + for (size_t i = 0; i < p_pixel_size; i++) { pixels_w.ptr()[i] = p_compressed_buffer[compressed_pos]; compressed_pos += 1; } - for (int i = 0; i < count; i++) { - for (int j = 0; j < p_pixel_size; j++) { + for (size_t i = 0; i < count; i++) { + for (size_t j = 0; j < p_pixel_size; j++) { p_uncompressed_buffer[output_pos + j] = pixels_w.ptr()[j]; } output_pos += p_pixel_size; } } else { count *= p_pixel_size; - for (int i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { p_uncompressed_buffer[output_pos] = p_compressed_buffer[compressed_pos]; compressed_pos += 1; output_pos += 1; @@ -208,7 +208,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force PoolVector<uint8_t> src_image; int src_image_len = f->get_len(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); - ERR_FAIL_COND_V(src_image_len < sizeof(tga_header_s), ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(src_image_len < (int)sizeof(tga_header_s), ERR_FILE_CORRUPT); src_image.resize(src_image_len); Error err = OK; diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index 8689a1773b..7905ab37a7 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.h */ +/* image_loader_tga.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 57826d69fb..49a4db237a 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.cpp */ +/* image_loader_tinyexr.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h index adecba5d9d..53a81597af 100644 --- a/modules/tinyexr/image_loader_tinyexr.h +++ b/modules/tinyexr/image_loader_tinyexr.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.h */ +/* image_loader_tinyexr.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index b2e7a6aa27..297e9e510f 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -571,7 +571,6 @@ public: virtual bool has_named_classes() const; virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const; virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 7ab2a93b55..37bd730d08 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* visual_script_editor.h */ +/* visual_script_editor.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -523,7 +523,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { if (Object::cast_to<VisualScriptExpression>(*node)) { Ref<VisualScriptComment> vsc = node; gnode->set_comment(true); - gnode->set_resizeable(true); + gnode->set_resizable(true); gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); gnode->connect("resize_request", this, "_comment_node_resized", varray(E->get())); } @@ -886,8 +886,8 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "script_changed"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); // _update_graph(); @@ -903,8 +903,8 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "script_changed"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); return; //or crash because it will become invalid @@ -918,8 +918,8 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(script.ptr(), "rename_custom_signal", new_name, name); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "script_changed"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); return; //or crash because it will become invalid @@ -1057,8 +1057,8 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt undo_redo->add_undo_method(this, "_update_members"); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "script_changed"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); _update_graph(); @@ -1077,8 +1077,8 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt undo_redo->add_undo_method(script.ptr(), "remove_variable", name); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "script_changed"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); return; //or crash because it will become invalid } @@ -1093,8 +1093,8 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt undo_redo->add_undo_method(script.ptr(), "remove_custom_signal", name); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "script_changed"); + undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); + undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); return; //or crash because it will become invalid } diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 6bd052fe26..d0e9b5bb86 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -1179,7 +1179,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { if (expression[next_op + 1].is_op) { // this is not invalid and can really appear // but it becomes invalid anyway because no binary op - // can be followed by an unary op in a valid combination, + // can be followed by a unary op in a valid combination, // due to how precedence works, unaries will always disappear first _set_error("Unexpected two consecutive operators."); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index af7b334e46..1decc004ab 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -2702,7 +2702,10 @@ void VisualScriptCustomNode::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category")); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_working_memory_size")); - BIND_VMETHOD(MethodInfo(Variant::NIL, "_step:Variant", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem"))); + + MethodInfo stepmi(Variant::NIL, "_step", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem")); + stepmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_VMETHOD(stepmi); ClassDB::bind_method(D_METHOD("_script_changed"), &VisualScriptCustomNode::_script_changed); @@ -2839,7 +2842,9 @@ VisualScriptNodeInstance *VisualScriptSubCall::instance(VisualScriptInstance *p_ void VisualScriptSubCall::_bind_methods() { - BIND_VMETHOD(MethodInfo(Variant::NIL, "_subcall:Variant", PropertyInfo(Variant::NIL, "arguments:Variant"))); + MethodInfo scmi(Variant::NIL, "_subcall", PropertyInfo(Variant::NIL, "arguments")); + scmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + BIND_VMETHOD(scmi); } VisualScriptSubCall::VisualScriptSubCall() { diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index 694fb96cfa..421409b265 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* visual_script_nodes.h */ +/* visual_script_nodes.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index 4b8e17421b..b6d4021ca3 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -516,7 +516,7 @@ public: } else { //yield - Object *object; + Object *object = NULL; switch (call_mode) { diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 26344877de..0178ebab84 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* av_stream_webm.cpp.cpp */ +/* video_stream_webm.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index a48a6c6b9a..9a331849be 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* av_stream_webm.cpp.cpp */ +/* video_stream_webm.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ |