summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub110
-rw-r--r--core/allocators.h194
-rw-r--r--core/array.cpp12
-rw-r--r--core/array.h7
-rw-r--r--core/bind/SCsub2
-rw-r--r--core/bind/core_bind.cpp90
-rw-r--r--core/bind/core_bind.h46
-rw-r--r--core/class_db.cpp59
-rw-r--r--core/class_db.h16
-rw-r--r--core/color.cpp14
-rw-r--r--core/color.h10
-rw-r--r--core/color_names.inc2
-rw-r--r--core/command_queue_mt.cpp10
-rw-r--r--core/command_queue_mt.h33
-rw-r--r--core/compressed_translation.cpp8
-rw-r--r--core/compressed_translation.h6
-rw-r--r--core/core_builders.py35
-rw-r--r--core/core_string_names.cpp51
-rw-r--r--core/core_string_names.h6
-rw-r--r--core/cowdata.h74
-rw-r--r--core/dictionary.cpp24
-rw-r--r--core/dictionary.h13
-rw-r--r--core/engine.cpp15
-rw-r--r--core/engine.h13
-rw-r--r--core/error_list.h4
-rw-r--r--core/error_macros.cpp6
-rw-r--r--core/error_macros.h40
-rw-r--r--core/func_ref.cpp9
-rw-r--r--core/func_ref.h6
-rw-r--r--core/global_constants.cpp17
-rw-r--r--core/global_constants.h6
-rw-r--r--core/hash_map.h20
-rw-r--r--core/hashfuncs.h16
-rw-r--r--core/helper/SCsub7
-rw-r--r--core/image.cpp96
-rw-r--r--core/image.h19
-rw-r--r--core/input_map.cpp12
-rw-r--r--core/input_map.h8
-rw-r--r--core/int_types.h4
-rw-r--r--core/io/SCsub3
-rw-r--r--core/io/compression.cpp19
-rw-r--r--core/io/compression.h6
-rw-r--r--core/io/config_file.cpp11
-rw-r--r--core/io/config_file.h6
-rw-r--r--core/io/file_access_buffered.cpp8
-rw-r--r--core/io/file_access_buffered.h11
-rw-r--r--core/io/file_access_buffered_fa.h6
-rw-r--r--core/io/file_access_compressed.cpp44
-rw-r--r--core/io/file_access_compressed.h8
-rw-r--r--core/io/file_access_encrypted.cpp8
-rw-r--r--core/io/file_access_encrypted.h6
-rw-r--r--core/io/file_access_memory.cpp12
-rw-r--r--core/io/file_access_memory.h6
-rw-r--r--core/io/file_access_network.cpp19
-rw-r--r--core/io/file_access_network.h15
-rw-r--r--core/io/file_access_pack.cpp17
-rw-r--r--core/io/file_access_pack.h16
-rw-r--r--core/io/file_access_zip.cpp99
-rw-r--r--core/io/file_access_zip.h8
-rw-r--r--core/io/http_client.cpp158
-rw-r--r--core/io/http_client.h13
-rw-r--r--core/io/image_loader.cpp45
-rw-r--r--core/io/image_loader.h28
-rw-r--r--core/io/ip.cpp11
-rw-r--r--core/io/ip.h8
-rw-r--r--core/io/ip_address.cpp6
-rw-r--r--core/io/ip_address.h6
-rw-r--r--core/io/json.cpp7
-rw-r--r--core/io/json.h6
-rw-r--r--core/io/logger.cpp27
-rw-r--r--core/io/logger.h25
-rw-r--r--core/io/marshalls.cpp37
-rw-r--r--core/io/marshalls.h10
-rw-r--r--core/io/multiplayer_api.cpp200
-rw-r--r--core/io/multiplayer_api.h13
-rw-r--r--core/io/net_socket.cpp (renamed from core/os/shell.cpp)24
-rw-r--r--core/io/net_socket.h79
-rw-r--r--core/io/networked_multiplayer_peer.cpp4
-rw-r--r--core/io/networked_multiplayer_peer.h6
-rw-r--r--core/io/packet_peer.cpp18
-rw-r--r--core/io/packet_peer.h11
-rw-r--r--core/io/packet_peer_udp.cpp202
-rw-r--r--core/io/packet_peer_udp.h46
-rw-r--r--core/io/pck_packer.cpp9
-rw-r--r--core/io/pck_packer.h4
-rw-r--r--core/io/resource_format_binary.cpp79
-rw-r--r--core/io/resource_format_binary.h23
-rw-r--r--core/io/resource_importer.cpp (renamed from core/io/resource_import.cpp)69
-rw-r--r--core/io/resource_importer.h (renamed from core/io/resource_import.h)37
-rw-r--r--core/io/resource_loader.cpp435
-rw-r--r--core/io/resource_loader.h75
-rw-r--r--core/io/resource_saver.cpp163
-rw-r--r--core/io/resource_saver.h35
-rw-r--r--core/io/stream_peer.cpp22
-rw-r--r--core/io/stream_peer.h11
-rw-r--r--core/io/stream_peer_ssl.cpp67
-rw-r--r--core/io/stream_peer_ssl.h11
-rw-r--r--core/io/stream_peer_tcp.cpp316
-rw-r--r--core/io/stream_peer_tcp.h49
-rw-r--r--core/io/tcp_server.cpp102
-rw-r--r--core/io/tcp_server.h29
-rw-r--r--core/io/translation_loader_po.cpp9
-rw-r--r--core/io/translation_loader_po.h12
-rw-r--r--core/io/xml_parser.cpp8
-rw-r--r--core/io/xml_parser.h12
-rw-r--r--core/io/zip_io.cpp137
-rw-r--r--core/io/zip_io.h118
-rw-r--r--core/list.h8
-rw-r--r--core/map.h6
-rw-r--r--core/math/SCsub2
-rw-r--r--core/math/a_star.cpp58
-rw-r--r--core/math/a_star.h9
-rw-r--r--core/math/aabb.cpp6
-rw-r--r--core/math/aabb.h10
-rw-r--r--core/math/audio_frame.cpp4
-rw-r--r--core/math/audio_frame.h6
-rw-r--r--core/math/basis.cpp (renamed from core/math/matrix3.cpp)98
-rw-r--r--core/math/basis.h (renamed from core/math/matrix3.h)18
-rw-r--r--core/math/bsp_tree.cpp14
-rw-r--r--core/math/bsp_tree.h18
-rw-r--r--core/math/camera_matrix.cpp9
-rw-r--r--core/math/camera_matrix.h9
-rw-r--r--core/math/delaunay.cpp1
-rw-r--r--core/math/delaunay.h32
-rw-r--r--core/math/expression.cpp159
-rw-r--r--core/math/expression.h34
-rw-r--r--core/math/face3.cpp16
-rw-r--r--core/math/face3.h22
-rw-r--r--core/math/geometry.cpp44
-rw-r--r--core/math/geometry.h70
-rw-r--r--core/math/math_defs.h17
-rw-r--r--core/math/math_fieldwise.cpp (renamed from core/helper/math_fieldwise.cpp)6
-rw-r--r--core/math/math_fieldwise.h (renamed from core/helper/math_fieldwise.h)4
-rw-r--r--core/math/math_funcs.cpp41
-rw-r--r--core/math/math_funcs.h53
-rw-r--r--core/math/octree.h38
-rw-r--r--core/math/plane.cpp6
-rw-r--r--core/math/plane.h11
-rw-r--r--core/math/quat.cpp29
-rw-r--r--core/math/quat.h44
-rw-r--r--core/math/quick_hull.cpp21
-rw-r--r--core/math/quick_hull.h14
-rw-r--r--core/math/random_number_generator.cpp (renamed from core/helper/value_evaluator.h)32
-rw-r--r--core/math/random_number_generator.h66
-rw-r--r--core/math/random_pcg.cpp (renamed from core/os/shell.h)43
-rw-r--r--core/math/random_pcg.h69
-rw-r--r--core/math/rect2.cpp6
-rw-r--r--core/math/rect2.h6
-rw-r--r--core/math/transform.cpp11
-rw-r--r--core/math/transform.h12
-rw-r--r--core/math/transform_2d.cpp16
-rw-r--r--core/math/transform_2d.h7
-rw-r--r--core/math/triangle_mesh.cpp7
-rw-r--r--core/math/triangle_mesh.h9
-rw-r--r--core/math/triangulate.cpp6
-rw-r--r--core/math/triangulate.h6
-rw-r--r--core/math/vector2.cpp10
-rw-r--r--core/math/vector2.h10
-rw-r--r--core/math/vector3.cpp7
-rw-r--r--core/math/vector3.h31
-rw-r--r--core/message_queue.cpp21
-rw-r--r--core/message_queue.h15
-rw-r--r--core/method_bind.cpp6
-rw-r--r--core/method_bind.h15
-rw-r--r--core/method_ptrcall.h10
-rw-r--r--core/node_path.cpp8
-rw-r--r--core/node_path.h9
-rw-r--r--core/oa_hash_map.h20
-rw-r--r--core/object.cpp194
-rw-r--r--core/object.h60
-rw-r--r--core/ordered_hash_map.h10
-rw-r--r--core/os/SCsub2
-rw-r--r--core/os/copymem.h6
-rw-r--r--core/os/dir_access.cpp26
-rw-r--r--core/os/dir_access.h11
-rw-r--r--core/os/file_access.cpp58
-rw-r--r--core/os/file_access.h17
-rw-r--r--core/os/input.cpp17
-rw-r--r--core/os/input.h15
-rw-r--r--core/os/input_event.cpp78
-rw-r--r--core/os/input_event.h21
-rw-r--r--core/os/keyboard.cpp7
-rw-r--r--core/os/keyboard.h11
-rw-r--r--core/os/main_loop.cpp12
-rw-r--r--core/os/main_loop.h13
-rw-r--r--core/os/memory.cpp12
-rw-r--r--core/os/memory.h35
-rw-r--r--core/os/midi_driver.cpp6
-rw-r--r--core/os/midi_driver.h7
-rw-r--r--core/os/mutex.cpp8
-rw-r--r--core/os/mutex.h6
-rw-r--r--core/os/os.cpp45
-rw-r--r--core/os/os.h57
-rw-r--r--core/os/rw_lock.cpp6
-rw-r--r--core/os/rw_lock.h10
-rw-r--r--core/os/semaphore.cpp7
-rw-r--r--core/os/semaphore.h7
-rw-r--r--core/os/thread.cpp4
-rw-r--r--core/os/thread.h10
-rw-r--r--core/os/thread_dummy.cpp6
-rw-r--r--core/os/thread_dummy.h12
-rw-r--r--core/os/thread_safe.cpp9
-rw-r--r--core/os/thread_safe.h6
-rw-r--r--core/os/threaded_array_processor.h14
-rw-r--r--core/packed_data_container.cpp8
-rw-r--r--core/packed_data_container.h6
-rw-r--r--core/pair.h10
-rw-r--r--core/path_remap.cpp4
-rw-r--r--core/path_remap.h4
-rw-r--r--core/pool_allocator.cpp12
-rw-r--r--core/pool_allocator.h6
-rw-r--r--core/pool_vector.cpp (renamed from core/dvector.cpp)10
-rw-r--r--core/pool_vector.h (renamed from core/dvector.h)56
-rw-r--r--core/print_string.cpp6
-rw-r--r--core/print_string.h6
-rw-r--r--core/project_settings.cpp160
-rw-r--r--core/project_settings.h19
-rw-r--r--core/ref_ptr.cpp8
-rw-r--r--core/ref_ptr.h6
-rw-r--r--core/reference.cpp10
-rw-r--r--core/reference.h12
-rw-r--r--core/register_core_types.cpp130
-rw-r--r--core/register_core_types.h4
-rw-r--r--core/resource.cpp19
-rw-r--r--core/resource.h16
-rw-r--r--core/rid.cpp4
-rw-r--r--core/rid.h15
-rw-r--r--core/ring_buffer.h12
-rw-r--r--core/safe_refcount.cpp4
-rw-r--r--core/safe_refcount.h10
-rw-r--r--core/script_debugger_local.cpp8
-rw-r--r--core/script_debugger_local.h8
-rw-r--r--core/script_debugger_remote.cpp103
-rw-r--r--core/script_debugger_remote.h18
-rw-r--r--core/script_language.cpp51
-rw-r--r--core/script_language.h29
-rw-r--r--core/self_list.h6
-rw-r--r--core/set.h9
-rw-r--r--core/simple_type.h4
-rw-r--r--core/sort_array.h (renamed from core/sort.h)17
-rw-r--r--core/string_buffer.h7
-rw-r--r--core/string_builder.cpp4
-rw-r--r--core/string_builder.h4
-rw-r--r--core/string_name.cpp (renamed from core/string_db.cpp)12
-rw-r--r--core/string_name.h (renamed from core/string_db.h)18
-rw-r--r--core/translation.cpp23
-rw-r--r--core/translation.h6
-rw-r--r--core/type_info.h4
-rw-r--r--core/typedefs.h48
-rw-r--r--core/ucaps.h4
-rw-r--r--core/undo_redo.cpp54
-rw-r--r--core/undo_redo.h13
-rw-r--r--core/ustring.cpp95
-rw-r--r--core/ustring.h86
-rw-r--r--core/variant.cpp115
-rw-r--r--core/variant.h50
-rw-r--r--core/variant_call.cpp58
-rw-r--r--core/variant_construct_string.cpp438
-rw-r--r--core/variant_op.cpp122
-rw-r--r--core/variant_parser.cpp48
-rw-r--r--core/variant_parser.h13
-rw-r--r--core/vector.h86
-rw-r--r--core/version.h11
-rw-r--r--core/vmap.h29
-rw-r--r--core/vset.h8
265 files changed, 5339 insertions, 3317 deletions
diff --git a/core/SCsub b/core/SCsub
index c8e2e10b9f..00d0bcac24 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -9,23 +9,6 @@ from platform_methods import run_in_subprocess
env.core_sources = []
-# Generate global defaults
-gd_call = ""
-gd_inc = ""
-
-for x in env.global_defaults:
- env.core_sources.append("#platform/" + x + "/globals/global_defaults.cpp")
- gd_inc += '#include "platform/' + x + '/globals/global_defaults.h"\n'
- gd_call += "\tregister_" + x + "_global_defaults();\n"
-
-gd_cpp = '#include "project_settings.h"\n'
-gd_cpp += gd_inc
-gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n"
-
-with open("global_defaults.gen.cpp", "w") as f:
- f.write(gd_cpp)
-
-
# Generate AES256 script encryption key
import os
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
@@ -52,13 +35,17 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
# NOTE: It is safe to generate this file here, since this is still executed serially
with open("script_encryption_key.gen.cpp", "w") as f:
- f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
+ f.write("#include \"core/project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
+
+# Add required thirdparty code.
+env_thirdparty = env.Clone()
+env_thirdparty.disable_warnings()
-# Add required thirdparty code. Header paths are hardcoded, we don't need to append
+# Misc thirdparty code: header paths are hardcoded, we don't need to append
# to the include path (saves a few chars on the compiler invocation for touchy MSVC...)
-thirdparty_dir = "#thirdparty/misc/"
-thirdparty_sources = [
+thirdparty_misc_dir = "#thirdparty/misc/"
+thirdparty_misc_sources = [
# C sources
"base64.c",
"fastlz.c",
@@ -72,10 +59,34 @@ thirdparty_sources = [
"pcg.cpp",
"triangulator.cpp",
]
-thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
-env.add_source_files(env.core_sources, thirdparty_sources)
-
-# Minizip library, can be unbundled in theory
+thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
+env_thirdparty.add_source_files(env.core_sources, thirdparty_misc_sources)
+
+# Zlib library, can be unbundled
+if env['builtin_zlib']:
+ thirdparty_zlib_dir = "#thirdparty/zlib/"
+ thirdparty_zlib_sources = [
+ "adler32.c",
+ "compress.c",
+ "crc32.c",
+ "deflate.c",
+ "infback.c",
+ "inffast.c",
+ "inflate.c",
+ "inftrees.c",
+ "trees.c",
+ "uncompr.c",
+ "zutil.c",
+ ]
+ thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
+
+ env_thirdparty.Append(CPPPATH=[thirdparty_zlib_dir])
+ # Needs to be available in main env too
+ env.Append(CPPPATH=[thirdparty_zlib_dir])
+
+ env_thirdparty.add_source_files(env.core_sources, thirdparty_zlib_sources)
+
+# Minizip library, could be unbundled in theory
# However, our version has some custom modifications, so it won't compile with the system one
thirdparty_minizip_dir = "#thirdparty/minizip/"
thirdparty_minizip_sources = [
@@ -84,15 +95,54 @@ thirdparty_minizip_sources = [
"zip.c",
]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
-env.add_source_files(env.core_sources, thirdparty_minizip_sources)
-
-if 'builtin_zstd' in env and env['builtin_zstd']:
- SConscript("#thirdparty/zstd/SCsub")
+env_thirdparty.add_source_files(env.core_sources, thirdparty_minizip_sources)
+
+# Zstd library, can be unbundled in theory
+# though we currently use some private symbols
+# https://github.com/godotengine/godot/issues/17374
+if env['builtin_zstd']:
+ thirdparty_zstd_dir = "#thirdparty/zstd/"
+ thirdparty_zstd_sources = [
+ "common/debug.c",
+ "common/entropy_common.c",
+ "common/error_private.c",
+ "common/fse_decompress.c",
+ "common/pool.c",
+ "common/threading.c",
+ "common/xxhash.c",
+ "common/zstd_common.c",
+ "compress/fse_compress.c",
+ "compress/hist.c",
+ "compress/huf_compress.c",
+ "compress/zstd_compress.c",
+ "compress/zstd_double_fast.c",
+ "compress/zstd_fast.c",
+ "compress/zstd_lazy.c",
+ "compress/zstd_ldm.c",
+ "compress/zstd_opt.c",
+ "compress/zstdmt_compress.c",
+ "decompress/huf_decompress.c",
+ "decompress/zstd_ddict.c",
+ "decompress/zstd_decompress_block.c",
+ "decompress/zstd_decompress.c",
+ ]
+ thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
+
+ env_thirdparty.Append(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
+ env_thirdparty.Append(CCFLAGS="-DZSTD_STATIC_LINKING_ONLY")
+ env.Append(CPPPATH=thirdparty_zstd_dir)
+ # Also needed in main env includes will trigger warnings
+ env.Append(CCFLAGS="-DZSTD_STATIC_LINKING_ONLY")
+
+ env_thirdparty.add_source_files(env.core_sources, thirdparty_zstd_sources)
# Godot's own sources
env.add_source_files(env.core_sources, "*.cpp")
+# Certificates
+env.Depends("#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificates.crt", env.Value(env['builtin_certs']), env.Value(env['system_certs_path'])])
+env.CommandNoCache("#core/io/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(core_builders.make_certs_header))
# Make binders
env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run))
@@ -114,10 +164,8 @@ SConscript('os/SCsub')
SConscript('math/SCsub')
SConscript('io/SCsub')
SConscript('bind/SCsub')
-SConscript('helper/SCsub')
# Build it all as a library
lib = env.add_library("core", env.core_sources)
env.Prepend(LIBS=[lib])
-Export('env')
diff --git a/core/allocators.h b/core/allocators.h
deleted file mode 100644
index e17ab298d6..0000000000
--- a/core/allocators.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*************************************************************************/
-/* allocators.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef ALLOCATORS_H
-#define ALLOCATORS_H
-
-#include "os/memory.h"
-template <int PREALLOC_COUNT = 64, int MAX_HANDS = 8>
-class BalloonAllocator {
-
- enum {
-
- USED_FLAG = (1 << 30),
- USED_MASK = USED_FLAG - 1
- };
-
- struct Balloon {
-
- Balloon *next;
- Balloon *prev;
- uint32_t hand;
- };
-
- struct Hand {
-
- int used;
- int allocated;
- Balloon *first;
- Balloon *last;
- };
-
- Hand hands[MAX_HANDS];
-
-public:
- void *alloc(size_t p_size) {
-
- size_t max = (1 << MAX_HANDS);
- ERR_FAIL_COND_V(p_size > max, NULL);
-
- unsigned int hand = 0;
-
- while (p_size > (size_t)(1 << hand))
- ++hand;
-
- Hand &h = hands[hand];
-
- if (h.used == h.allocated) {
-
- for (int i = 0; i < PREALLOC_COUNT; i++) {
-
- Balloon *b = (Balloon *)memalloc(sizeof(Balloon) + (1 << hand));
- b->hand = hand;
- if (h.last) {
-
- b->prev = h.last;
- h.last->next = b;
- h.last = b;
- } else {
-
- b->prev = NULL;
- h.last = b;
- h.first = b;
- }
- }
-
- h.last->next = NULL;
- h.allocated += PREALLOC_COUNT;
- }
-
- Balloon *pick = h.last;
-
- ERR_FAIL_COND_V((pick->hand & USED_FLAG), NULL);
-
- // remove last
- h.last = h.last->prev;
- h.last->next = NULL;
-
- pick->next = h.first;
- h.first->prev = pick;
- pick->prev = NULL;
- h.first = pick;
- h.used++;
- pick->hand |= USED_FLAG;
-
- return (void *)(pick + 1);
- }
-
- void free(void *p_ptr) {
-
- Balloon *b = (Balloon *)p_ptr;
- b -= 1;
-
- ERR_FAIL_COND(!(b->hand & USED_FLAG));
-
- b->hand = b->hand & USED_MASK; // not used
- int hand = b->hand;
-
- Hand &h = hands[hand];
-
- if (b == h.first)
- h.first = b->next;
-
- if (b->prev)
- b->prev->next = b->next;
- if (b->next)
- b->next->prev = b->prev;
-
- if (h.last != b) {
- h.last->next = b;
- b->prev = h.last;
- b->next = NULL;
- h.last = b;
- }
-
- h.used--;
-
- if (h.used <= (h.allocated - (PREALLOC_COUNT * 2))) { // this is done to ensure no alloc/free is done constantly
-
- for (int i = 0; i < PREALLOC_COUNT; i++) {
- ERR_CONTINUE(h.last->hand & USED_FLAG);
-
- Balloon *new_last = h.last->prev;
- if (new_last)
- new_last->next = NULL;
- memfree(h.last);
- h.last = new_last;
- }
- h.allocated -= PREALLOC_COUNT;
- }
- }
-
- BalloonAllocator() {
-
- for (int i = 0; i < MAX_HANDS; i++) {
-
- hands[i].allocated = 0;
- hands[i].used = 0;
- hands[i].first = NULL;
- hands[i].last = NULL;
- }
- }
-
- void clear() {
-
- for (int i = 0; i < MAX_HANDS; i++) {
-
- while (hands[i].first) {
-
- Balloon *b = hands[i].first;
- hands[i].first = b->next;
- memfree(b);
- }
-
- hands[i].allocated = 0;
- hands[i].used = 0;
- hands[i].first = NULL;
- hands[i].last = NULL;
- }
- }
-
- ~BalloonAllocator() {
-
- clear();
- }
-};
-
-#endif // ALLOCATORS_H
diff --git a/core/array.cpp b/core/array.cpp
index ebad0df126..649e610a69 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,10 +30,10 @@
#include "array.h"
-#include "hashfuncs.h"
-#include "object.h"
-#include "variant.h"
-#include "vector.h"
+#include "core/hashfuncs.h"
+#include "core/object.h"
+#include "core/variant.h"
+#include "core/vector.h"
class ArrayPrivate {
public:
diff --git a/core/array.h b/core/array.h
index c824c9b4f7..6158db4065 100644
--- a/core/array.h
+++ b/core/array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,8 @@
#ifndef ARRAY_H
#define ARRAY_H
-#include "typedefs.h"
+#include "core/typedefs.h"
+
class Variant;
class ArrayPrivate;
class Object;
diff --git a/core/bind/SCsub b/core/bind/SCsub
index 4efc902717..1c5f954470 100644
--- a/core/bind/SCsub
+++ b/core/bind/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
-
-Export('env')
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 2bd271205a..f6828ea76a 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,14 +30,14 @@
#include "core_bind.h"
+#include "core/io/file_access_compressed.h"
+#include "core/io/file_access_encrypted.h"
+#include "core/io/json.h"
+#include "core/io/marshalls.h"
+#include "core/math/geometry.h"
+#include "core/os/keyboard.h"
+#include "core/os/os.h"
#include "core/project_settings.h"
-#include "geometry.h"
-#include "io/file_access_compressed.h"
-#include "io/file_access_encrypted.h"
-#include "io/json.h"
-#include "io/marshalls.h"
-#include "os/keyboard.h"
-#include "os/os.h"
#include "thirdparty/misc/base64.h"
@@ -132,7 +132,7 @@ bool _ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
void _ResourceLoader::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_interactive", "path", "type_hint"), &_ResourceLoader::load_interactive, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "p_no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type);
ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources);
ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies);
@@ -180,6 +180,7 @@ void _ResourceSaver::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_OMIT_EDITOR_PROPERTIES);
BIND_ENUM_CONSTANT(FLAG_SAVE_BIG_ENDIAN);
BIND_ENUM_CONSTANT(FLAG_COMPRESS);
+ BIND_ENUM_CONSTANT(FLAG_REPLACE_SUBRESOURCE_PATHS);
}
_ResourceSaver::_ResourceSaver() {
@@ -224,8 +225,12 @@ int _OS::get_video_driver_count() const {
return OS::get_singleton()->get_video_driver_count();
}
-String _OS::get_video_driver_name(int p_driver) const {
- return OS::get_singleton()->get_video_driver_name(p_driver);
+String _OS::get_video_driver_name(VideoDriver p_driver) const {
+ return OS::get_singleton()->get_video_driver_name((int)p_driver);
+}
+
+_OS::VideoDriver _OS::get_current_video_driver() const {
+ return (VideoDriver)OS::get_singleton()->get_current_video_driver();
}
int _OS::get_audio_driver_count() const {
@@ -377,12 +382,20 @@ bool _OS::get_borderless_window() const {
void _OS::set_ime_active(const bool p_active) {
- return OS::get_singleton()->set_ime_active(p_active);
+ OS::get_singleton()->set_ime_active(p_active);
}
void _OS::set_ime_position(const Point2 &p_pos) {
- return OS::get_singleton()->set_ime_position(p_pos);
+ OS::get_singleton()->set_ime_position(p_pos);
+}
+
+Point2 _OS::get_ime_selection() const {
+ return OS::get_singleton()->get_ime_selection();
+}
+
+String _OS::get_ime_text() const {
+ return OS::get_singleton()->get_ime_text();
}
void _OS::set_use_file_access_save_and_swap(bool p_enable) {
@@ -583,17 +596,17 @@ struct Time {
};
*/
-int _OS::get_static_memory_usage() const {
+uint64_t _OS::get_static_memory_usage() const {
return OS::get_singleton()->get_static_memory_usage();
}
-int _OS::get_static_memory_peak_usage() const {
+uint64_t _OS::get_static_memory_peak_usage() const {
return OS::get_singleton()->get_static_memory_peak_usage();
}
-int _OS::get_dynamic_memory_usage() const {
+uint64_t _OS::get_dynamic_memory_usage() const {
return OS::get_singleton()->get_dynamic_memory_usage();
}
@@ -818,6 +831,10 @@ uint64_t _OS::get_system_time_secs() const {
return OS::get_singleton()->get_system_time_secs();
}
+uint64_t _OS::get_system_time_msecs() const {
+ return OS::get_singleton()->get_system_time_msecs();
+}
+
void _OS::delay_usec(uint32_t p_usec) const {
OS::get_singleton()->delay_usec(p_usec);
@@ -1019,6 +1036,11 @@ void _OS::center_window() {
OS::get_singleton()->center_window();
}
+void _OS::move_window_to_foreground() {
+
+ OS::get_singleton()->move_window_to_foreground();
+}
+
bool _OS::is_debug_build() const {
#ifdef DEBUG_ENABLED
@@ -1090,6 +1112,8 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_video_driver_count"), &_OS::get_video_driver_count);
ClassDB::bind_method(D_METHOD("get_video_driver_name", "driver"), &_OS::get_video_driver_name);
+ ClassDB::bind_method(D_METHOD("get_current_video_driver"), &_OS::get_current_video_driver);
+
ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count);
ClassDB::bind_method(D_METHOD("get_audio_driver_name", "driver"), &_OS::get_audio_driver_name);
ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs);
@@ -1120,6 +1144,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_attention"), &_OS::request_attention);
ClassDB::bind_method(D_METHOD("get_real_window_size"), &_OS::get_real_window_size);
ClassDB::bind_method(D_METHOD("center_window"), &_OS::center_window);
+ ClassDB::bind_method(D_METHOD("move_window_to_foreground"), &_OS::move_window_to_foreground);
ClassDB::bind_method(D_METHOD("set_borderless_window", "borderless"), &_OS::set_borderless_window);
ClassDB::bind_method(D_METHOD("get_borderless_window"), &_OS::get_borderless_window);
@@ -1127,7 +1152,10 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_window_per_pixel_transparency_enabled"), &_OS::get_window_per_pixel_transparency_enabled);
ClassDB::bind_method(D_METHOD("set_window_per_pixel_transparency_enabled", "enabled"), &_OS::set_window_per_pixel_transparency_enabled);
+ ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &_OS::set_ime_active);
ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &_OS::set_ime_position);
+ ClassDB::bind_method(D_METHOD("get_ime_selection"), &_OS::get_ime_selection);
+ ClassDB::bind_method(D_METHOD("get_ime_text"), &_OS::get_ime_text);
ClassDB::bind_method(D_METHOD("set_screen_orientation", "orientation"), &_OS::set_screen_orientation);
ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation);
@@ -1164,6 +1192,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_datetime_from_unix_time", "unix_time_val"), &_OS::get_datetime_from_unix_time);
ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime", "datetime"), &_OS::get_unix_time_from_datetime);
ClassDB::bind_method(D_METHOD("get_system_time_secs"), &_OS::get_system_time_secs);
+ ClassDB::bind_method(D_METHOD("get_system_time_msecs"), &_OS::get_system_time_msecs);
ClassDB::bind_method(D_METHOD("set_icon", "icon"), &_OS::set_icon);
@@ -1253,6 +1282,9 @@ void _OS::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_position"), "set_window_position", "get_window_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_size"), "set_window_size", "get_window_size");
+ BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES2);
+ BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES3);
+
BIND_ENUM_CONSTANT(DAY_SUNDAY);
BIND_ENUM_CONSTANT(DAY_MONDAY);
BIND_ENUM_CONSTANT(DAY_TUESDAY);
@@ -1747,9 +1779,9 @@ String _File::get_line() const {
return f->get_line();
}
-Vector<String> _File::get_csv_line(String delim) const {
+Vector<String> _File::get_csv_line(const String &p_delim) const {
ERR_FAIL_COND_V(!f, Vector<String>());
- return f->get_csv_line(delim);
+ return f->get_csv_line(p_delim);
}
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
@@ -1846,6 +1878,11 @@ void _File::store_line(const String &p_string) {
f->store_line(p_string);
}
+void _File::store_csv_line(const Vector<String> &p_values, const String &p_delim) {
+ ERR_FAIL_COND(!f);
+ f->store_csv_line(p_values, p_delim);
+}
+
void _File::store_buffer(const PoolVector<uint8_t> &p_buffer) {
ERR_FAIL_COND(!f);
@@ -1929,6 +1966,7 @@ void _File::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_real"), &_File::get_real);
ClassDB::bind_method(D_METHOD("get_buffer", "len"), &_File::get_buffer);
ClassDB::bind_method(D_METHOD("get_line"), &_File::get_line);
+ ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(","));
ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text);
ClassDB::bind_method(D_METHOD("get_md5", "path"), &_File::get_md5);
ClassDB::bind_method(D_METHOD("get_sha256", "path"), &_File::get_sha256);
@@ -1936,7 +1974,6 @@ void _File::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_endian_swap", "enable"), &_File::set_endian_swap);
ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error);
ClassDB::bind_method(D_METHOD("get_var"), &_File::get_var);
- ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(","));
ClassDB::bind_method(D_METHOD("store_8", "value"), &_File::store_8);
ClassDB::bind_method(D_METHOD("store_16", "value"), &_File::store_16);
@@ -1947,6 +1984,7 @@ void _File::_bind_methods() {
ClassDB::bind_method(D_METHOD("store_real", "value"), &_File::store_real);
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &_File::store_buffer);
ClassDB::bind_method(D_METHOD("store_line", "line"), &_File::store_line);
+ ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &_File::store_csv_line, DEFVAL(","));
ClassDB::bind_method(D_METHOD("store_string", "string"), &_File::store_string);
ClassDB::bind_method(D_METHOD("store_var", "value"), &_File::store_var);
@@ -2394,7 +2432,7 @@ void _Thread::_start_func(void *ud) {
} break;
case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
- reason = "Too Many Arguments";
+ reason = "Too Few Arguments";
} break;
case Variant::CallError::CALL_ERROR_INVALID_METHOD: {
@@ -2487,7 +2525,7 @@ _Thread::~_Thread() {
if (active) {
ERR_EXPLAIN("Reference to a Thread object object was lost while the thread is still running...");
}
- ERR_FAIL_COND(active == true);
+ ERR_FAIL_COND(active);
}
/////////////////////////////////////
@@ -2859,10 +2897,10 @@ void JSONParseResult::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_error_line", "error_line"), &JSONParseResult::set_error_line);
ClassDB::bind_method(D_METHOD("set_result", "result"), &JSONParseResult::set_result);
- ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "error", PROPERTY_HINT_NONE, "Error", PROPERTY_USAGE_CLASS_IS_ENUM), "set_error", "get_error");
- ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "error_string"), "set_error_string", "get_error_string");
- ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "error_line"), "set_error_line", "get_error_line");
- ADD_PROPERTYNZ(PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_result", "get_result");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "error", PROPERTY_HINT_NONE, "Error", PROPERTY_USAGE_CLASS_IS_ENUM), "set_error", "get_error");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "error_string"), "set_error_string", "get_error_string");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "error_line"), "set_error_line", "get_error_line");
+ ADD_PROPERTY(PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_result", "get_result");
}
void JSONParseResult::set_error(Error p_error) {
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 21aea12b23..f3bc4644d8 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,15 +31,15 @@
#ifndef CORE_BIND_H
#define CORE_BIND_H
-#include "image.h"
-#include "io/compression.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "os/dir_access.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "os/semaphore.h"
-#include "os/thread.h"
+#include "core/image.h"
+#include "core/io/compression.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
class _ResourceLoader : public Object {
GDCLASS(_ResourceLoader, Object);
@@ -80,6 +80,7 @@ public:
FLAG_OMIT_EDITOR_PROPERTIES = 8,
FLAG_SAVE_BIG_ENDIAN = 16,
FLAG_COMPRESS = 32,
+ FLAG_REPLACE_SUBRESOURCE_PATHS = 64,
};
static _ResourceSaver *get_singleton() { return singleton; }
@@ -102,6 +103,11 @@ protected:
static _OS *singleton;
public:
+ enum VideoDriver {
+ VIDEO_DRIVER_GLES3,
+ VIDEO_DRIVER_GLES2,
+ };
+
enum PowerState {
POWERSTATE_UNKNOWN, /**< cannot determine power status */
POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */
@@ -151,7 +157,8 @@ public:
Array get_fullscreen_mode_list(int p_screen = 0) const;
virtual int get_video_driver_count() const;
- virtual String get_video_driver_name(int p_driver) const;
+ virtual String get_video_driver_name(VideoDriver p_driver) const;
+ virtual VideoDriver get_current_video_driver() const;
virtual int get_audio_driver_count() const;
virtual String get_audio_driver_name(int p_driver) const;
@@ -184,6 +191,7 @@ public:
virtual bool is_window_always_on_top() const;
virtual void request_attention();
virtual void center_window();
+ virtual void move_window_to_foreground();
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window() const;
@@ -193,6 +201,8 @@ public:
virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
+ virtual Point2 get_ime_selection() const;
+ virtual String get_ime_text() const;
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing();
@@ -277,10 +287,11 @@ public:
Dictionary get_time_zone_info() const;
uint64_t get_unix_time() const;
uint64_t get_system_time_secs() const;
+ uint64_t get_system_time_msecs() const;
- int get_static_memory_usage() const;
- int get_static_memory_peak_usage() const;
- int get_dynamic_memory_usage() const;
+ uint64_t get_static_memory_usage() const;
+ uint64_t get_static_memory_peak_usage() const;
+ uint64_t get_dynamic_memory_usage() const;
void delay_usec(uint32_t p_usec) const;
void delay_msec(uint32_t p_msec) const;
@@ -350,6 +361,7 @@ public:
_OS();
};
+VARIANT_ENUM_CAST(_OS::VideoDriver);
VARIANT_ENUM_CAST(_OS::PowerState);
VARIANT_ENUM_CAST(_OS::Weekday);
VARIANT_ENUM_CAST(_OS::Month);
@@ -453,6 +465,7 @@ public:
PoolVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
String get_line() const;
+ Vector<String> get_csv_line(const String &p_delim = ",") const;
String get_as_text() const;
String get_md5(const String &p_path) const;
String get_sha256(const String &p_path) const;
@@ -478,12 +491,11 @@ public:
void store_string(const String &p_string);
void store_line(const String &p_string);
+ void store_csv_line(const Vector<String> &p_values, const String &p_delim = ",");
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
- Vector<String> get_csv_line(String delim = ",") const;
-
void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
void store_var(const Variant &p_var);
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 03b214aa41..219bdbddd8 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,9 @@
#include "class_db.h"
-#include "os/mutex.h"
-#include "version.h"
+#include "core/engine.h"
+#include "core/os/mutex.h"
+#include "core/version.h"
#define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock);
#define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock);
@@ -512,7 +513,12 @@ Object *ClassDB::instance(const StringName &p_class) {
ERR_FAIL_COND_V(ti->disabled, NULL);
ERR_FAIL_COND_V(!ti->creation_func, NULL);
}
-
+#ifdef TOOLS_ENABLED
+ if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
+ ERR_PRINTS("Class '" + String(p_class) + "' can only be instantiated by editor.");
+ return NULL;
+ }
+#endif
return ti->creation_func();
}
bool ClassDB::can_instance(const StringName &p_class) {
@@ -803,10 +809,10 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
- ClassInfo *check = type;
StringName sname = p_signal.name;
-#ifdef DEBUG_METHODS_ENABLED
+#ifdef DEBUG_METHODS_ENABLED
+ ClassInfo *check = type;
while (check) {
if (check->signal_map.has(sname)) {
ERR_EXPLAIN("Type " + String(p_class) + " already has signal: " + String(sname));
@@ -930,9 +936,8 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
}
#ifdef DEBUG_METHODS_ENABLED
-
if (type->property_setget.has(p_pinfo.name)) {
- ERR_EXPLAIN("Object already has property: " + p_class);
+ ERR_EXPLAIN("Object " + p_class + " already has property: " + p_pinfo.name);
ERR_FAIL();
}
#endif
@@ -1361,6 +1366,41 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p
}
}
+HashMap<StringName, HashMap<StringName, Variant> > ClassDB::default_values;
+
+Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property) {
+
+ if (!default_values.has(p_class)) {
+
+ default_values[p_class] = HashMap<StringName, Variant>();
+
+ if (ClassDB::can_instance(p_class)) {
+
+ Object *c = ClassDB::instance(p_class);
+ List<PropertyInfo> plist;
+ c->get_property_list(&plist);
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) {
+
+ Variant v = c->get(E->get().name);
+ default_values[p_class][E->get().name] = v;
+ }
+ }
+ memdelete(c);
+ }
+ }
+
+ if (!default_values.has(p_class)) {
+ return Variant();
+ }
+
+ if (!default_values[p_class].has(p_property)) {
+ return Variant();
+ }
+
+ return default_values[p_class][p_property];
+}
+
RWLock *ClassDB::lock = NULL;
void ClassDB::init() {
@@ -1387,6 +1427,7 @@ void ClassDB::cleanup() {
classes.clear();
resource_base_extensions.clear();
compat_classes.clear();
+ default_values.clear();
memdelete(lock);
}
diff --git a/core/class_db.h b/core/class_db.h
index 66a67f6c9f..321682d76b 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,16 +31,16 @@
#ifndef CLASS_DB_H
#define CLASS_DB_H
-#include "method_bind.h"
-#include "object.h"
-#include "print_string.h"
+#include "core/method_bind.h"
+#include "core/object.h"
+#include "core/print_string.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
/** To bind more then 6 parameters include this:
- * #include "method_bind_ext.gen.inc"
+ * #include "core/method_bind_ext.gen.inc"
*/
#define DEFVAL(m_defval) (m_defval)
@@ -161,6 +161,8 @@ public:
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
+ static HashMap<StringName, HashMap<StringName, Variant> > default_values;
+
public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template <class T>
@@ -352,6 +354,8 @@ public:
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
+ static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property);
+
static StringName get_category(const StringName &p_node);
static void set_class_enabled(StringName p_class, bool p_enable);
diff --git a/core/color.cpp b/core/color.cpp
index 17c9e2daeb..efd2941b47 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,10 +30,10 @@
#include "color.h"
-#include "color_names.inc"
-#include "map.h"
-#include "math_funcs.h"
-#include "print_string.h"
+#include "core/color_names.inc"
+#include "core/map.h"
+#include "core/math/math_funcs.h"
+#include "core/print_string.h"
uint32_t Color::to_argb32() const {
@@ -468,7 +468,7 @@ String Color::to_html(bool p_alpha) const {
return txt;
}
-Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) {
+Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
p_h = Math::fmod(p_h * 360.0f, 360.0f);
if (p_h < 0.0)
diff --git a/core/color.h b/core/color.h
index 00f4c9e9e8..b2148e1357 100644
--- a/core/color.h
+++ b/core/color.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef COLOR_H
#define COLOR_H
-#include "math_funcs.h"
-#include "ustring.h"
+#include "core/math/math_funcs.h"
+#include "core/ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -194,7 +194,7 @@ struct Color {
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
- Color from_hsv(float p_h, float p_s, float p_v, float p_a);
+ Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
static Color from_rgbe9995(uint32_t p_color);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
diff --git a/core/color_names.inc b/core/color_names.inc
index 3ae42648d0..e126bfe0f8 100644
--- a/core/color_names.inc
+++ b/core/color_names.inc
@@ -1,5 +1,5 @@
// Names from https://en.wikipedia.org/wiki/List_of_colors (through https://raw.githubusercontent.com/SuperUserNameMan/color_to_name/616a7cddafefda91478b7bc26167de97fb5badb1/godot_version.gd), slightly edited and normalized
-#include "map.h"
+#include "core/map.h"
static Map<String, Color> _named_colors;
static void _populate_named_colors() {
diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp
index a39c920dfa..2bdf02295c 100644
--- a/core/command_queue_mt.cpp
+++ b/core/command_queue_mt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "command_queue_mt.h"
-#include "os/os.h"
+#include "core/os/os.h"
void CommandQueueMT::lock() {
@@ -97,7 +97,7 @@ tryagain:
return false;
}
- dealloc_ptr += (size >> 1) + sizeof(uint32_t);
+ dealloc_ptr += (size >> 1) + 8;
return true;
}
@@ -107,6 +107,7 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
write_ptr = 0;
dealloc_ptr = 0;
mutex = Mutex::create();
+ command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
@@ -128,4 +129,5 @@ CommandQueueMT::~CommandQueueMT() {
memdelete(sync_sems[i].sem);
}
+ memfree(command_mem);
}
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 7978eaa7bf..59eabd8786 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,12 @@
#ifndef COMMAND_QUEUE_MT_H
#define COMMAND_QUEUE_MT_H
-#include "os/memory.h"
-#include "os/mutex.h"
-#include "os/semaphore.h"
-#include "simple_type.h"
-#include "typedefs.h"
+#include "core/os/memory.h"
+#include "core/os/mutex.h"
+#include "core/os/semaphore.h"
+#include "core/simple_type.h"
+#include "core/typedefs.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -254,6 +255,7 @@
unlock(); \
if (sync) sync->post(); \
ss->sem->wait(); \
+ ss->in_use = false; \
}
#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
@@ -270,6 +272,7 @@
unlock(); \
if (sync) sync->post(); \
ss->sem->wait(); \
+ ss->in_use = false; \
}
#define MAX_CMD_PARAMS 13
@@ -295,7 +298,6 @@ class CommandQueueMT {
virtual void post() {
sync_sem->sem->post();
- sync_sem->in_use = false;
}
};
@@ -318,7 +320,7 @@ class CommandQueueMT {
SYNC_SEMAPHORES = 8
};
- uint8_t command_mem[COMMAND_MEM_SIZE];
+ uint8_t *command_mem;
uint32_t read_ptr;
uint32_t write_ptr;
uint32_t dealloc_ptr;
@@ -330,7 +332,7 @@ class CommandQueueMT {
T *allocate() {
// alloc size is size+T+safeguard
- uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
+ uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8;
tryagain:
@@ -360,7 +362,7 @@ class CommandQueueMT {
}
// if this happens, it's a bug
- ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < sizeof(uint32_t), NULL);
+ ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < 8, NULL);
// zero means, wrap to beginning
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
@@ -372,12 +374,13 @@ class CommandQueueMT {
// Allocate the size and the 'in use' bit.
// First bit used to mark if command is still in use (1)
// or if it has been destroyed and can be deallocated (0).
+ uint32_t size = (sizeof(T) + 8 - 1) & ~(8 - 1);
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
- *p = (sizeof(T) << 1) | 1;
- write_ptr += sizeof(uint32_t);
+ *p = (size << 1) | 1;
+ write_ptr += 8;
// allocate the command
T *cmd = memnew_placement(&command_mem[write_ptr], T);
- write_ptr += sizeof(T);
+ write_ptr += size;
return cmd;
}
@@ -415,7 +418,7 @@ class CommandQueueMT {
goto tryagain;
}
- read_ptr += sizeof(uint32_t);
+ read_ptr += 8;
CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp
index 46df63066b..f102721470 100644
--- a/core/compressed_translation.cpp
+++ b/core/compressed_translation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "compressed_translation.h"
-#include "pair.h"
+#include "core/pair.h"
extern "C" {
#include "thirdparty/misc/smaz.h"
@@ -83,7 +83,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
if (ps.orig_len != 0) {
CharString dst_s;
dst_s.resize(src_s.size());
- int ret = smaz_compress(src_s.get_data(), src_s.size(), &dst_s[0], src_s.size());
+ int ret = smaz_compress(src_s.get_data(), src_s.size(), dst_s.ptrw(), src_s.size());
if (ret >= src_s.size()) {
//if compressed is larger than original, just use original
ps.orig_len = src_s.size();
diff --git a/core/compressed_translation.h b/core/compressed_translation.h
index ccc47d0bf6..0b49907a68 100644
--- a/core/compressed_translation.h
+++ b/core/compressed_translation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef COMPRESSED_TRANSLATION_H
#define COMPRESSED_TRANSLATION_H
-#include "translation.h"
+#include "core/translation.h"
class PHashTranslation : public Translation {
diff --git a/core/core_builders.py b/core/core_builders.py
index 90e505aab9..f3a9e3b221 100644
--- a/core/core_builders.py
+++ b/core/core_builders.py
@@ -4,7 +4,40 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
"""
from platform_methods import subprocess_main
-from compat import iteritems, itervalues, open_utf8, escape_string
+from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
+
+
+def make_certs_header(target, source, env):
+
+ src = source[0]
+ dst = target[0]
+ f = open(src, "rb")
+ g = open_utf8(dst, "w")
+ buf = f.read()
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _CERTS_RAW_H\n")
+ g.write("#define _CERTS_RAW_H\n")
+
+ # System certs path. Editor will use them if defined. (for package maintainers)
+ path = env['system_certs_path']
+ g.write("#define _SYSTEM_CERTS_PATH \"%s\"\n" % str(path))
+ if env['builtin_certs']:
+ # Defined here and not in env so changing it does not trigger a full rebuild.
+ g.write("#define BUILTIN_CERTS_ENABLED\n")
+ g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _certs_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+ g.write("};\n")
+ g.write("#endif")
+
+ g.close()
+ f.close()
def make_authors_header(target, source, env):
diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp
index ba596f7f16..1b59508abf 100644
--- a/core/core_string_names.cpp
+++ b/core/core_string_names.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,28 +47,27 @@ CoreStringNames::CoreStringNames() :
#ifdef TOOLS_ENABLED
_sections_unfolded(StaticCString::create("_sections_unfolded")),
#endif
- _custom_features(StaticCString::create("_custom_features")) {
-
- x = StaticCString::create("x");
- y = StaticCString::create("y");
- z = StaticCString::create("z");
- w = StaticCString::create("w");
- r = StaticCString::create("r");
- g = StaticCString::create("g");
- b = StaticCString::create("b");
- a = StaticCString::create("a");
- position = StaticCString::create("position");
- size = StaticCString::create("size");
- end = StaticCString::create("end");
- basis = StaticCString::create("basis");
- origin = StaticCString::create("origin");
- normal = StaticCString::create("normal");
- d = StaticCString::create("d");
- h = StaticCString::create("h");
- s = StaticCString::create("s");
- v = StaticCString::create("v");
- r8 = StaticCString::create("r8");
- g8 = StaticCString::create("g8");
- b8 = StaticCString::create("b8");
- a8 = StaticCString::create("a8");
+ _custom_features(StaticCString::create("_custom_features")),
+ x(StaticCString::create("x")),
+ y(StaticCString::create("y")),
+ z(StaticCString::create("z")),
+ w(StaticCString::create("w")),
+ r(StaticCString::create("r")),
+ g(StaticCString::create("g")),
+ b(StaticCString::create("b")),
+ a(StaticCString::create("a")),
+ position(StaticCString::create("position")),
+ size(StaticCString::create("size")),
+ end(StaticCString::create("end")),
+ basis(StaticCString::create("basis")),
+ origin(StaticCString::create("origin")),
+ normal(StaticCString::create("normal")),
+ d(StaticCString::create("d")),
+ h(StaticCString::create("h")),
+ s(StaticCString::create("s")),
+ v(StaticCString::create("v")),
+ r8(StaticCString::create("r8")),
+ g8(StaticCString::create("g8")),
+ b8(StaticCString::create("b8")),
+ a8(StaticCString::create("a8")) {
}
diff --git a/core/core_string_names.h b/core/core_string_names.h
index dcbce14aac..6fea40e1b2 100644
--- a/core/core_string_names.h
+++ b/core/core_string_names.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef CORE_STRING_NAMES_H
#define CORE_STRING_NAMES_H
-#include "string_db.h"
+#include "core/string_name.h"
class CoreStringNames {
diff --git a/core/cowdata.h b/core/cowdata.h
index 6a8f644d53..3e40ad0f4b 100644
--- a/core/cowdata.h
+++ b/core/cowdata.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,10 @@
#ifndef COWDATA_H_
#define COWDATA_H_
-#include "os/memory.h"
-#include "safe_refcount.h"
+#include <string.h>
+
+#include "core/os/memory.h"
+#include "core/safe_refcount.h"
template <class T>
class Vector;
@@ -87,7 +89,10 @@ private:
#if defined(_add_overflow) && defined(_mul_overflow)
size_t o;
size_t p;
- if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
+ if (_mul_overflow(p_elements, sizeof(T), &o)) {
+ *out = 0;
+ return false;
+ }
*out = next_power_of_2(o);
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
return true;
@@ -174,6 +179,8 @@ public:
return OK;
};
+ int find(const T &p_val, int p_from = 0) const;
+
_FORCE_INLINE_ CowData();
_FORCE_INLINE_ ~CowData();
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
@@ -191,12 +198,14 @@ void CowData<T>::_unref(void *p_data) {
return; // still in use
// clean up
- uint32_t *count = _get_size();
- T *data = (T *)(count + 1);
+ if (!__has_trivial_destructor(T)) {
+ uint32_t *count = _get_size();
+ T *data = (T *)(count + 1);
- for (uint32_t i = 0; i < *count; ++i) {
- // call destructors
- data[i].~T();
+ for (uint32_t i = 0; i < *count; ++i) {
+ // call destructors
+ data[i].~T();
+ }
}
// free mem
@@ -223,9 +232,13 @@ void CowData<T>::_copy_on_write() {
T *_data = (T *)(mem_new);
// initialize new elements
- for (uint32_t i = 0; i < current_size; i++) {
+ if (__has_trivial_copy(T)) {
+ memcpy(mem_new, _ptr, current_size * sizeof(T));
- memnew_placement(&_data[i], T(_get_data()[i]));
+ } else {
+ for (uint32_t i = 0; i < current_size; i++) {
+ memnew_placement(&_data[i], T(_get_data()[i]));
+ }
}
_unref(_ptr);
@@ -272,22 +285,25 @@ Error CowData<T>::resize(int p_size) {
}
// construct the newly created elements
- T *elems = _get_data();
- for (int i = *_get_size(); i < p_size; i++) {
+ if (!__has_trivial_constructor(T)) {
+ T *elems = _get_data();
- memnew_placement(&elems[i], T);
+ for (int i = *_get_size(); i < p_size; i++) {
+ memnew_placement(&elems[i], T);
+ }
}
*_get_size() = p_size;
} else if (p_size < size()) {
- // deinitialize no longer needed elements
- for (uint32_t i = p_size; i < *_get_size(); i++) {
-
- T *t = &_get_data()[i];
- t->~T();
+ if (!__has_trivial_destructor(T)) {
+ // deinitialize no longer needed elements
+ for (uint32_t i = p_size; i < *_get_size(); i++) {
+ T *t = &_get_data()[i];
+ t->~T();
+ }
}
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
@@ -302,6 +318,24 @@ Error CowData<T>::resize(int p_size) {
}
template <class T>
+int CowData<T>::find(const T &p_val, int p_from) const {
+ int ret = -1;
+
+ if (p_from < 0 || size() == 0) {
+ return ret;
+ }
+
+ for (int i = p_from; i < size(); i++) {
+ if (get(i) == p_val) {
+ ret = i;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+template <class T>
void CowData<T>::_ref(const CowData *p_from) {
_ref(*p_from);
}
diff --git a/core/dictionary.cpp b/core/dictionary.cpp
index 9cc913fa0d..bea0997cc9 100644
--- a/core/dictionary.cpp
+++ b/core/dictionary.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,9 @@
#include "dictionary.h"
-#include "ordered_hash_map.h"
-#include "safe_refcount.h"
-#include "variant.h"
+#include "core/ordered_hash_map.h"
+#include "core/safe_refcount.h"
+#include "core/variant.h"
struct DictionaryPrivate {
@@ -112,6 +112,15 @@ Variant Dictionary::get_valid(const Variant &p_key) const {
return E.get();
}
+Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
+ const Variant *result = getptr(p_key);
+ if (!result) {
+ return p_default;
+ }
+
+ return *result;
+}
+
int Dictionary::size() const {
return _p->variant_map.size();
@@ -145,6 +154,11 @@ bool Dictionary::operator==(const Dictionary &p_dictionary) const {
return _p == p_dictionary._p;
}
+bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
+
+ return _p != p_dictionary._p;
+}
+
void Dictionary::_ref(const Dictionary &p_from) const {
//make a copy first (thread safe)
diff --git a/core/dictionary.h b/core/dictionary.h
index dbf2233819..eab7354cef 100644
--- a/core/dictionary.h
+++ b/core/dictionary.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,10 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H
-#include "array.h"
-#include "list.h"
-#include "ustring.h"
+#include "core/array.h"
+#include "core/list.h"
+#include "core/ustring.h"
+
class Variant;
struct DictionaryPrivate;
@@ -57,6 +58,7 @@ public:
Variant *getptr(const Variant &p_key);
Variant get_valid(const Variant &p_key) const;
+ Variant get(const Variant &p_key, const Variant &p_default) const;
int size() const;
bool empty() const;
@@ -68,6 +70,7 @@ public:
bool erase(const Variant &p_key);
bool operator==(const Dictionary &p_dictionary) const;
+ bool operator!=(const Dictionary &p_dictionary) const;
uint32_t hash() const;
void operator=(const Dictionary &p_dictionary);
diff --git a/core/engine.cpp b/core/engine.cpp
index 7c8024b946..9607dedb3c 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,11 +30,11 @@
#include "engine.h"
-#include "authors.gen.h"
-#include "donors.gen.h"
-#include "license.gen.h"
-#include "version.h"
-#include "version_hash.gen.h"
+#include "core/authors.gen.h"
+#include "core/donors.gen.h"
+#include "core/license.gen.h"
+#include "core/version.h"
+#include "core/version_hash.gen.h"
void Engine::set_iterations_per_second(int p_ips) {
@@ -98,6 +98,7 @@ Dictionary Engine::get_version_info() const {
#else
dict["patch"] = 0;
#endif
+ dict["hex"] = VERSION_HEX;
dict["status"] = VERSION_STATUS;
dict["build"] = VERSION_BUILD;
dict["year"] = VERSION_YEAR;
diff --git a/core/engine.h b/core/engine.h
index 031ba29cd6..15665fee29 100644
--- a/core/engine.h
+++ b/core/engine.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef ENGINE_H
#define ENGINE_H
-#include "list.h"
-#include "os/main_loop.h"
-#include "ustring.h"
-#include "vector.h"
+#include "core/list.h"
+#include "core/os/main_loop.h"
+#include "core/ustring.h"
+#include "core/vector.h"
class Engine {
@@ -125,6 +125,7 @@ public:
String get_license_text() const;
Engine();
+ virtual ~Engine() {}
};
#endif // ENGINE_H
diff --git a/core/error_list.h b/core/error_list.h
index 6b9cd0016b..304861da4e 100644
--- a/core/error_list.h
+++ b/core/error_list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/error_macros.cpp b/core/error_macros.cpp
index 5786802930..0e8e4a9bb4 100644
--- a/core/error_macros.cpp
+++ b/core/error_macros.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "error_macros.h"
-#include "io/logger.h"
+#include "core/io/logger.h"
#include "os/os.h"
bool _err_error_exists = false;
diff --git a/core/error_macros.h b/core/error_macros.h
index bee738ceea..ca5ccd24cf 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef ERROR_MACROS_H
#define ERROR_MACROS_H
-#include "typedefs.h"
+#include "core/typedefs.h"
/**
* Error macros. Unlike exceptions and asserts, these macros try to maintain consistency and stability
* inside the code. It is recommended to always return processable data, so in case of an error, the
@@ -154,6 +154,20 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
+/** An index has failed if m_index >=m_size, the function exists.
+* This function returns an error value, if returning Error, please select the most
+* appropriate error condition from error_macros.h
+*/
+
+#define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \
+ do { \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
+ return m_retval; \
+ } else \
+ _err_error_exists = false; \
+ } while (0); // (*)
+
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
* We'll return a null reference and try to keep running.
*/
@@ -296,6 +310,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_PRINT_ONCE(m_string) \
+ { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
+ _err_error_exists = false; \
+ first_print = false; \
+ } \
+ }
+
/** Print a warning string.
*/
@@ -311,6 +335,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define WARN_PRINT_ONCE(m_string) \
+ { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
+ _err_error_exists = false; \
+ first_print = false; \
+ } \
+ }
+
#define WARN_DEPRECATED \
{ \
static volatile bool warning_shown = false; \
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index c707f1c4cb..4a965473d9 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,7 +69,6 @@ void FuncRef::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function);
}
-FuncRef::FuncRef() {
-
- id = 0;
+FuncRef::FuncRef() :
+ id(0) {
}
diff --git a/core/func_ref.h b/core/func_ref.h
index 681fe747d6..339279fdba 100644
--- a/core/func_ref.h
+++ b/core/func_ref.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef FUNC_REF_H
#define FUNC_REF_H
-#include "reference.h"
+#include "core/reference.h"
class FuncRef : public Reference {
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index 962881e720..fb90403226 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,10 +30,10 @@
#include "global_constants.h"
-#include "object.h"
-#include "os/input_event.h"
-#include "os/keyboard.h"
-#include "variant.h"
+#include "core/object.h"
+#include "core/os/input_event.h"
+#include "core/os/keyboard.h"
+#include "core/variant.h"
struct _GlobalConstant {
@@ -547,8 +547,9 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY);
- BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO);
- BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE);
+ //deprecated, replaced by ClassDB function to check default value
+ //BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO);
+ //BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE);
diff --git a/core/global_constants.h b/core/global_constants.h
index 76f618989c..c798a3b9bc 100644
--- a/core/global_constants.h
+++ b/core/global_constants.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef GLOBAL_CONSTANTS_H
#define GLOBAL_CONSTANTS_H
-#include "string_db.h"
+#include "core/string_name.h"
class GlobalConstants {
public:
diff --git a/core/hash_map.h b/core/hash_map.h
index 2df743ba7d..44459a3080 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,12 @@
#ifndef HASH_MAP_H
#define HASH_MAP_H
-#include "error_macros.h"
-#include "hashfuncs.h"
-#include "list.h"
-#include "math_funcs.h"
-#include "os/memory.h"
-#include "ustring.h"
+#include "core/error_macros.h"
+#include "core/hashfuncs.h"
+#include "core/list.h"
+#include "core/math/math_funcs.h"
+#include "core/os/memory.h"
+#include "core/ustring.h"
/**
* @class HashMap
@@ -150,7 +150,7 @@ private:
if (new_hash_table_power == -1)
return;
- Element **new_hash_table = memnew_arr(Element *, (1 << new_hash_table_power));
+ Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
if (!new_hash_table) {
ERR_PRINT("Out of Memory");
@@ -230,7 +230,7 @@ private:
if (!p_t.hash_table || p_t.hash_table_power == 0)
return; /* not copying from empty table */
- hash_table = memnew_arr(Element *, 1 << p_t.hash_table_power);
+ hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power;
elements = p_t.elements;
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index 735e679d1e..07d78dcbde 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,12 @@
#ifndef HASHFUNCS_H
#define HASHFUNCS_H
-#include "math_defs.h"
-#include "math_funcs.h"
-#include "node_path.h"
-#include "string_db.h"
-#include "typedefs.h"
-#include "ustring.h"
+#include "core/math/math_defs.h"
+#include "core/math/math_funcs.h"
+#include "core/node_path.h"
+#include "core/string_name.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
/**
* Hashing functions
diff --git a/core/helper/SCsub b/core/helper/SCsub
deleted file mode 100644
index 4efc902717..0000000000
--- a/core/helper/SCsub
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-
-env.add_source_files(env.core_sources, "*.cpp")
-
-Export('env')
diff --git a/core/image.cpp b/core/image.cpp
index 08bb9a35c3..5a287ca50e 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,15 +30,15 @@
#include "image.h"
+#include "core/hash_map.h"
#include "core/io/image_loader.h"
+#include "core/io/resource_loader.h"
+#include "core/math/math_funcs.h"
#include "core/os/copymem.h"
-#include "hash_map.h"
-#include "math_funcs.h"
-#include "print_string.h"
+#include "core/print_string.h"
-#include "io/resource_loader.h"
-#include "math_funcs.h"
#include "thirdparty/misc/hq2x.h"
+
#include <stdio.h>
const char *Image::format_names[Image::FORMAT_MAX] = {
@@ -307,6 +307,7 @@ void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_widt
r_width = w;
r_height = h;
}
+
int Image::get_mipmap_offset(int p_mipmap) const {
ERR_FAIL_INDEX_V(p_mipmap, get_mipmap_count() + 1, -1);
@@ -499,8 +500,6 @@ void Image::convert(Format p_new_format) {
bool gen_mipmaps = mipmaps;
- //mipmaps=false;
-
_copy_internals_from(new_img);
if (gen_mipmaps)
@@ -781,9 +780,9 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
// Setup mipmap-aware scaling
Image dst2;
- int mip1;
- int mip2;
- float mip1_weight;
+ int mip1 = 0;
+ int mip2 = 0;
+ float mip1_weight = 0;
if (mipmap_aware) {
float avg_scale = ((float)p_width / width + (float)p_height / height) * 0.5f;
if (avg_scale >= 1.0f) {
@@ -799,6 +798,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (interpolate_mipmaps) {
dst2.create(p_width, p_height, 0, format);
}
+
bool had_mipmaps = mipmaps;
if (interpolate_mipmaps && !had_mipmaps) {
generate_mipmaps();
@@ -951,6 +951,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
}
void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
+
if (!_can_modify(format)) {
ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats.");
ERR_FAIL();
@@ -996,7 +997,7 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
}
}
- if (mipmaps > 0)
+ if (has_mipmaps())
dst.generate_mipmaps();
_copy_internals_from(dst);
}
@@ -1013,10 +1014,10 @@ void Image::flip_y() {
ERR_FAIL();
}
- bool gm = mipmaps;
-
- if (gm)
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
clear_mipmaps();
+ }
{
PoolVector<uint8_t>::Write w = data.write();
@@ -1037,8 +1038,9 @@ void Image::flip_y() {
}
}
- if (gm)
+ if (used_mipmaps) {
generate_mipmaps();
+ }
}
void Image::flip_x() {
@@ -1048,9 +1050,10 @@ void Image::flip_x() {
ERR_FAIL();
}
- bool gm = mipmaps;
- if (gm)
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
clear_mipmaps();
+ }
{
PoolVector<uint8_t>::Write w = data.write();
@@ -1071,8 +1074,9 @@ void Image::flip_x() {
}
}
- if (gm)
+ if (used_mipmaps) {
generate_mipmaps();
+ }
}
int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps) {
@@ -1167,12 +1171,13 @@ void Image::expand_x2_hq2x() {
ERR_FAIL_COND(!_can_modify(format));
- Format current = format;
- bool mm = has_mipmaps();
- if (mm) {
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
clear_mipmaps();
}
+ Format current = format;
+
if (current != FORMAT_RGBA8)
convert(FORMAT_RGBA8);
@@ -1193,6 +1198,8 @@ void Image::expand_x2_hq2x() {
if (current != FORMAT_RGBA8)
convert(current);
+ // FIXME: This is likely meant to use "used_mipmaps" as defined above, but if we do,
+ // we end up with a regression: GH-22747
if (mipmaps) {
generate_mipmaps();
}
@@ -1466,7 +1473,8 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
void Image::create(const char **p_xpm) {
- int size_width, size_height;
+ int size_width = 0;
+ int size_height = 0;
int pixelchars = 0;
mipmaps = false;
bool has_alpha = false;
@@ -1482,8 +1490,8 @@ void Image::create(const char **p_xpm) {
int line = 0;
HashMap<String, Color> colormap;
- int colormap_size;
- uint32_t pixel_size;
+ int colormap_size = 0;
+ uint32_t pixel_size = 0;
PoolVector<uint8_t>::Write w;
while (status != DONE) {
@@ -1758,6 +1766,15 @@ int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format
return mm;
}
+int Image::get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap) {
+
+ if (p_mipmap <= 0) {
+ return 0;
+ }
+ int mm;
+ return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmap - 1);
+}
+
bool Image::is_compressed() const {
return format > FORMAT_RGBE9995;
}
@@ -1772,7 +1789,7 @@ Error Image::decompress() {
_image_decompress_pvrtc(this);
else if (format == FORMAT_ETC && _image_decompress_etc1)
_image_decompress_etc1(this);
- else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc1)
+ else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc2)
_image_decompress_etc2(this);
else
return ERR_UNAVAILABLE;
@@ -1914,7 +1931,8 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
return;
- Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+ Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
PoolVector<uint8_t>::Write wp = data.write();
uint8_t *dst_data_ptr = wp.ptr();
@@ -1968,7 +1986,8 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
return;
- Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+ Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
PoolVector<uint8_t>::Write wp = data.write();
uint8_t *dst_data_ptr = wp.ptr();
@@ -2025,7 +2044,8 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
return;
- Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+ Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
lock();
Ref<Image> img = p_src;
@@ -2079,7 +2099,8 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
return;
- Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+ Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
lock();
Ref<Image> img = p_src;
@@ -2611,6 +2632,9 @@ void Image::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
+ BIND_CONSTANT(MAX_WIDTH);
+ BIND_CONSTANT(MAX_HEIGHT);
+
BIND_ENUM_CONSTANT(FORMAT_L8); //luminance
BIND_ENUM_CONSTANT(FORMAT_LA8); //luminance-alpha
BIND_ENUM_CONSTANT(FORMAT_R8);
@@ -2877,15 +2901,15 @@ void Image::fix_alpha_edges() {
if (dist >= closest_dist)
continue;
- const uint8_t *rp = &srcptr[(k * width + l) << 2];
+ const uint8_t *rp2 = &srcptr[(k * width + l) << 2];
- if (rp[3] < alpha_threshold)
+ if (rp2[3] < alpha_threshold)
continue;
closest_dist = dist;
- closest_color[0] = rp[0];
- closest_color[1] = rp[1];
- closest_color[2] = rp[2];
+ closest_color[0] = rp2[0];
+ closest_color[1] = rp2[1];
+ closest_color[2] = rp2[2];
}
}
diff --git a/core/image.h b/core/image.h
index 6af55ca8d9..872b84d565 100644
--- a/core/image.h
+++ b/core/image.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef IMAGE_H
#define IMAGE_H
-#include "color.h"
-#include "dvector.h"
-#include "rect2.h"
-#include "resource.h"
+#include "core/color.h"
+#include "core/math/rect2.h"
+#include "core/pool_vector.h"
+#include "core/resource.h"
/**
* @author Juan Linietsky <reduzio@gmail.com>
@@ -52,14 +52,14 @@ typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
class Image : public Resource {
GDCLASS(Image, Resource);
+public:
+ static SavePNGFunc save_png_func;
+
enum {
MAX_WIDTH = 16384, // force a limit somehow
MAX_HEIGHT = 16384 // force a limit somehow
};
-public:
- static SavePNGFunc save_png_func;
-
enum Format {
FORMAT_L8, //luminance
@@ -286,6 +286,7 @@ public:
static int get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps = false);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
+ static int get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap);
enum CompressMode {
COMPRESS_S3TC,
diff --git a/core/input_map.cpp b/core/input_map.cpp
index ffc8a39da5..15f68f9c2a 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,8 @@
#include "input_map.h"
-#include "os/keyboard.h"
-#include "project_settings.h"
+#include "core/os/keyboard.h"
+#include "core/project_settings.h"
InputMap *InputMap::singleton = NULL;
@@ -199,6 +199,10 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
+ if (p_pressed != NULL)
+ *p_pressed = input_event_action->is_pressed();
+ if (p_strength != NULL)
+ *p_strength = (*p_pressed) ? 1.0f : 0.0f;
return input_event_action->get_action() == p_action;
}
diff --git a/core/input_map.h b/core/input_map.h
index bdec75c65b..895fd26928 100644
--- a/core/input_map.h
+++ b/core/input_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef INPUT_MAP_H
#define INPUT_MAP_H
-#include "object.h"
-#include "os/input_event.h"
+#include "core/object.h"
+#include "core/os/input_event.h"
class InputMap : public Object {
diff --git a/core/int_types.h b/core/int_types.h
index e2b70d58fc..891b6172fa 100644
--- a/core/int_types.h
+++ b/core/int_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/SCsub b/core/io/SCsub
index 79b56cb716..1c5f954470 100644
--- a/core/io/SCsub
+++ b/core/io/SCsub
@@ -3,6 +3,3 @@
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
-
-Export('env')
-
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index bc3bfcf356..a113f3b61b 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "compression.h"
-#include "os/copymem.h"
-#include "project_settings.h"
-#include "zip_io.h"
+
+#include "core/io/zip_io.h"
+#include "core/os/copymem.h"
+#include "core/project_settings.h"
#include "thirdparty/misc/fastlz.h"
@@ -80,10 +81,10 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
} break;
case MODE_ZSTD: {
ZSTD_CCtx *cctx = ZSTD_createCCtx();
- ZSTD_CCtx_setParameter(cctx, ZSTD_p_compressionLevel, zstd_level);
+ ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd_level);
if (zstd_long_distance_matching) {
- ZSTD_CCtx_setParameter(cctx, ZSTD_p_enableLongDistanceMatching, 1);
- ZSTD_CCtx_setParameter(cctx, ZSTD_p_windowLog, zstd_window_log_size);
+ ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, 1);
+ ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, zstd_window_log_size);
}
int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD);
int ret = ZSTD_compressCCtx(cctx, p_dst, max_dst_size, p_src, p_src_size, zstd_level);
@@ -174,7 +175,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
} break;
case MODE_ZSTD: {
ZSTD_DCtx *dctx = ZSTD_createDCtx();
- if (zstd_long_distance_matching) ZSTD_DCtx_setMaxWindowSize(dctx, 1 << zstd_window_log_size);
+ if (zstd_long_distance_matching) ZSTD_DCtx_setMaxWindowSize(dctx, (size_t)1 << zstd_window_log_size);
int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size);
ZSTD_freeDCtx(dctx);
return ret;
diff --git a/core/io/compression.h b/core/io/compression.h
index a0ccd539cb..883dbf3a99 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef COMPRESSION_H
#define COMPRESSION_H
-#include "typedefs.h"
+#include "core/typedefs.h"
class Compression {
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index aa06ae5cc0..414742deeb 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "config_file.h"
-#include "os/file_access.h"
-#include "os/keyboard.h"
-#include "variant_parser.h"
+
+#include "core/os/file_access.h"
+#include "core/os/keyboard.h"
+#include "core/variant_parser.h"
PoolStringArray ConfigFile::_get_sections() const {
diff --git a/core/io/config_file.h b/core/io/config_file.h
index ac749bed76..36e5c0ca7d 100644
--- a/core/io/config_file.h
+++ b/core/io/config_file.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,7 +32,7 @@
#define CONFIG_FILE_H
#include "core/ordered_hash_map.h"
-#include "reference.h"
+#include "core/reference.h"
class ConfigFile : public Reference {
diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp
index dcaf99e24a..83ff532aa4 100644
--- a/core/io/file_access_buffered.cpp
+++ b/core/io/file_access_buffered.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,7 @@
#include "file_access_buffered.h"
-#include <string.h>
-
-#include "error_macros.h"
+#include "core/error_macros.h"
Error FileAccessBuffered::set_error(Error p_error) const {
diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h
index f4ed47d6bc..4065d77c58 100644
--- a/core/io/file_access_buffered.h
+++ b/core/io/file_access_buffered.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,9 @@
#ifndef FILE_ACCESS_BUFFERED_H
#define FILE_ACCESS_BUFFERED_H
-#include "os/file_access.h"
-
-#include "dvector.h"
-#include "ustring.h"
+#include "core/os/file_access.h"
+#include "core/pool_vector.h"
+#include "core/ustring.h"
class FileAccessBuffered : public FileAccess {
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h
index 493fa1c243..be960fbc25 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,7 +54,7 @@ class FileAccessBufferedFA : public FileAccessBuffered {
cache.offset = p_offset;
cache.buffer.resize(p_size);
- // on dvector
+ // on PoolVector
//PoolVector<uint8_t>::Write write = cache.buffer.write();
//f.get_buffer(write.ptrw(), p_size);
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index d6547ba19f..b268d5c710 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "file_access_compressed.h"
-#include "print_string.h"
+
+#include "core/print_string.h"
+
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
magic = p_magic.ascii().get_data();
@@ -291,7 +293,6 @@ uint8_t FileAccessCompressed::get_8() const {
} else {
read_block--;
at_end = true;
- ret = 0;
}
}
@@ -372,24 +373,23 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
return 0;
}
-FileAccessCompressed::FileAccessCompressed() {
-
- f = NULL;
- magic = "GCMP";
- cmode = Compression::MODE_ZSTD;
- writing = false;
- write_ptr = 0;
- write_buffer_size = 0;
- write_max = 0;
- block_size = 0;
- read_eof = false;
- at_end = false;
- read_total = 0;
- read_ptr = NULL;
- read_block = 0;
- read_block_count = 0;
- read_block_size = 0;
- read_pos = 0;
+FileAccessCompressed::FileAccessCompressed() :
+ cmode(Compression::MODE_ZSTD),
+ writing(false),
+ write_ptr(0),
+ write_buffer_size(0),
+ write_max(0),
+ block_size(0),
+ read_eof(false),
+ at_end(false),
+ read_ptr(NULL),
+ read_block(0),
+ read_block_count(0),
+ read_block_size(0),
+ read_pos(0),
+ read_total(0),
+ magic("GCMP"),
+ f(NULL) {
}
FileAccessCompressed::~FileAccessCompressed() {
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 587f58a7c6..f408b1bc29 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef FILE_ACCESS_COMPRESSED_H
#define FILE_ACCESS_COMPRESSED_H
-#include "io/compression.h"
-#include "os/file_access.h"
+#include "core/io/compression.h"
+#include "core/os/file_access.h"
class FileAccessCompressed : public FileAccess {
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 812e881114..6ad68dd74d 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,9 @@
#include "file_access_encrypted.h"
+#include "core/os/copymem.h"
+#include "core/print_string.h"
#include "core/variant.h"
-#include "os/copymem.h"
-#include "print_string.h"
#include "thirdparty/misc/aes256.h"
#include "thirdparty/misc/md5.h"
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index b9365a9fd0..e77d62a9f4 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef FILE_ACCESS_ENCRYPTED_H
#define FILE_ACCESS_ENCRYPTED_H
-#include "os/file_access.h"
+#include "core/os/file_access.h"
class FileAccessEncrypted : public FileAccess {
public:
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index c4eb2848b1..fbcf5b8021 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,10 +30,10 @@
#include "file_access_memory.h"
-#include "map.h"
-#include "os/copymem.h"
-#include "os/dir_access.h"
-#include "project_settings.h"
+#include "core/map.h"
+#include "core/os/copymem.h"
+#include "core/os/dir_access.h"
+#include "core/project_settings.h"
static Map<String, Vector<uint8_t> > *files = NULL;
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 2136f4cc0c..73952133c1 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef FILE_ACCESS_MEMORY_H
#define FILE_ACCESS_MEMORY_H
-#include "os/file_access.h"
+#include "core/os/file_access.h"
class FileAccessMemory : public FileAccess {
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index d72d3ca9f1..501a21a50d 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,10 +29,11 @@
/*************************************************************************/
#include "file_access_network.h"
-#include "io/ip.h"
-#include "marshalls.h"
-#include "os/os.h"
-#include "project_settings.h"
+
+#include "core/io/ip.h"
+#include "core/io/marshalls.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
//#define DEBUG_PRINT(m_p) print_line(m_p)
//#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n",m_what,OS::get_singleton()->get_ticks_usec());
@@ -226,7 +227,7 @@ FileAccessNetworkClient::FileAccessNetworkClient() {
quit = false;
singleton = this;
last_id = 0;
- client = Ref<StreamPeerTCP>(StreamPeerTCP::create_ref());
+ client.instance();
sem = Semaphore::create();
lockcount = 0;
}
@@ -499,8 +500,9 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
void FileAccessNetwork::configure() {
GLOBAL_DEF("network/remote_fs/page_size", 65536);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/remote_fs/page_size", PropertyInfo(Variant::INT, "network/remote_fs/page_size", PROPERTY_HINT_RANGE, "1,65536,1,or_greater")); //is used as denominator and can't be zero
GLOBAL_DEF("network/remote_fs/page_read_ahead", 4);
- GLOBAL_DEF("network/remote_fs/max_pages", 20);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/remote_fs/page_read_ahead", PropertyInfo(Variant::INT, "network/remote_fs/page_read_ahead", PROPERTY_HINT_RANGE, "0,8,1,or_greater"));
}
FileAccessNetwork::FileAccessNetwork() {
@@ -518,7 +520,6 @@ FileAccessNetwork::FileAccessNetwork() {
nc->unlock_mutex();
page_size = GLOBAL_GET("network/remote_fs/page_size");
read_ahead = GLOBAL_GET("network/remote_fs/page_read_ahead");
- max_pages = GLOBAL_GET("network/remote_fs/max_pages");
last_activity_val = 0;
waiting_on_page = -1;
last_page = -1;
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index be9bdb1af6..5bbf7588c7 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef FILE_ACCESS_NETWORK_H
#define FILE_ACCESS_NETWORK_H
-#include "io/stream_peer_tcp.h"
-#include "os/file_access.h"
-#include "os/semaphore.h"
-#include "os/thread.h"
+#include "core/io/stream_peer_tcp.h"
+#include "core/os/file_access.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
class FileAccessNetwork;
@@ -47,8 +47,6 @@ class FileAccessNetworkClient {
int size;
};
- int ml;
-
List<BlockRequest> block_requests;
Semaphore *sem;
@@ -100,7 +98,6 @@ class FileAccessNetwork : public FileAccess {
int page_size;
int read_ahead;
- int max_pages;
mutable int waiting_on_page;
mutable int last_activity_val;
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index efb4c7a073..c97b8cafac 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "file_access_pack.h"
-#include "version.h"
+
+#include "core/version.h"
#include <stdio.h>
@@ -168,11 +169,11 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) {
uint32_t version = f->get_32();
uint32_t ver_major = f->get_32();
uint32_t ver_minor = f->get_32();
- uint32_t ver_rev = f->get_32();
+ f->get_32(); // ver_rev
ERR_EXPLAIN("Pack version unsupported: " + itos(version));
ERR_FAIL_COND_V(version != PACK_VERSION, false);
- ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev));
+ ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor));
ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false);
for (int i = 0; i < 16; i++) {
@@ -454,7 +455,7 @@ String DirAccessPack::get_current_dir() {
while (pd->parent) {
pd = pd->parent;
- p = pd->name + "/" + p;
+ p = pd->name.plus_file(p);
}
return "res://" + p;
@@ -489,6 +490,10 @@ size_t DirAccessPack::get_space_left() {
return 0;
}
+String DirAccessPack::get_filesystem_type() const {
+ return "PCK";
+}
+
DirAccessPack::DirAccessPack() {
current = PackedData::get_singleton()->root;
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index f29e431d9a..a90672ce26 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,11 @@
#ifndef FILE_ACCESS_PACK_H
#define FILE_ACCESS_PACK_H
-#include "list.h"
-#include "map.h"
-#include "os/dir_access.h"
-#include "os/file_access.h"
-#include "print_string.h"
+#include "core/list.h"
+#include "core/map.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/print_string.h"
class PackSource;
@@ -221,6 +221,8 @@ public:
size_t get_space_left();
+ virtual String get_filesystem_type() const;
+
DirAccessPack();
~DirAccessPack();
};
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 7b6385c3ff..be28c9a877 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,31 +43,31 @@ static void *godot_open(void *data, const char *p_fname, int mode) {
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
return NULL;
- };
+ }
FileAccess *f = (FileAccess *)data;
f->open(p_fname, FileAccess::READ);
return f->is_open() ? data : NULL;
-};
+}
static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
FileAccess *f = (FileAccess *)data;
f->get_buffer((uint8_t *)buf, size);
return size;
-};
+}
static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
return 0;
-};
+}
static long godot_tell(voidpf opaque, voidpf stream) {
FileAccess *f = (FileAccess *)opaque;
return f->get_position();
-};
+}
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
@@ -84,36 +84,36 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
break;
default:
break;
- };
+ }
f->seek(pos);
return 0;
-};
+}
static int godot_close(voidpf opaque, voidpf stream) {
FileAccess *f = (FileAccess *)opaque;
f->close();
return 0;
-};
+}
static int godot_testerror(voidpf opaque, voidpf stream) {
FileAccess *f = (FileAccess *)opaque;
return f->get_error() != OK ? 1 : 0;
-};
+}
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
return memalloc(items * size);
-};
+}
static void godot_free(voidpf opaque, voidpf address) {
memfree(address);
-};
+}
-}; // extern "C"
+} // extern "C"
void ZipArchive::close_handle(unzFile p_file) const {
@@ -122,7 +122,7 @@ void ZipArchive::close_handle(unzFile p_file) const {
unzCloseCurrentFile(p_file);
unzClose(p_file);
memdelete(f);
-};
+}
unzFile ZipArchive::get_file_handle(String p_file) const {
@@ -155,10 +155,10 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
unzClose(pkg);
ERR_FAIL_V(NULL);
- };
+ }
return pkg;
-};
+}
bool ZipArchive::try_open_pack(const String &p_path) {
@@ -168,10 +168,10 @@ bool ZipArchive::try_open_pack(const String &p_path) {
zlib_filefunc_def io;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f)
+ FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
+ if (!fa)
return false;
- io.opaque = f;
+ io.opaque = fa;
io.zopen_file = godot_open;
io.zread_file = godot_read;
io.zwrite_file = godot_write;
@@ -215,36 +215,36 @@ bool ZipArchive::try_open_pack(const String &p_path) {
if ((i + 1) < gi.number_entry) {
unzGoToNextFile(zfile);
- };
- };
+ }
+ }
return true;
-};
+}
bool ZipArchive::file_exists(String p_name) const {
return files.has(p_name);
-};
+}
FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew(FileAccessZip(p_path, *p_file));
-};
+}
ZipArchive *ZipArchive::get_singleton() {
if (instance == NULL) {
instance = memnew(ZipArchive);
- };
+ }
return instance;
-};
+}
ZipArchive::ZipArchive() {
instance = this;
//fa_create_func = FileAccess::get_create_func();
-};
+}
ZipArchive::~ZipArchive() {
@@ -253,10 +253,10 @@ ZipArchive::~ZipArchive() {
FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile);
unzClose(packages[i].zfile);
memdelete(f);
- };
+ }
packages.clear();
-};
+}
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
@@ -272,7 +272,7 @@ Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(err != UNZ_OK, FAILED);
return OK;
-};
+}
void FileAccessZip::close() {
@@ -283,50 +283,50 @@ void FileAccessZip::close() {
ERR_FAIL_COND(!arch);
arch->close_handle(zfile);
zfile = NULL;
-};
+}
bool FileAccessZip::is_open() const {
return zfile != NULL;
-};
+}
void FileAccessZip::seek(size_t p_position) {
ERR_FAIL_COND(!zfile);
unzSeekCurrentFile(zfile, p_position);
-};
+}
void FileAccessZip::seek_end(int64_t p_position) {
ERR_FAIL_COND(!zfile);
unzSeekCurrentFile(zfile, get_len() + p_position);
-};
+}
size_t FileAccessZip::get_position() const {
ERR_FAIL_COND_V(!zfile, 0);
return unztell(zfile);
-};
+}
size_t FileAccessZip::get_len() const {
ERR_FAIL_COND_V(!zfile, 0);
return file_info.uncompressed_size;
-};
+}
bool FileAccessZip::eof_reached() const {
ERR_FAIL_COND_V(!zfile, true);
return at_eof;
-};
+}
uint8_t FileAccessZip::get_8() const {
uint8_t ret = 0;
get_buffer(&ret, 1);
return ret;
-};
+}
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
@@ -339,20 +339,20 @@ int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
if (read < p_length)
at_eof = true;
return read;
-};
+}
Error FileAccessZip::get_error() const {
if (!zfile) {
return ERR_UNCONFIGURED;
- };
+ }
if (eof_reached()) {
return ERR_FILE_EOF;
- };
+ }
return OK;
-};
+}
void FileAccessZip::flush() {
@@ -362,22 +362,21 @@ void FileAccessZip::flush() {
void FileAccessZip::store_8(uint8_t p_dest) {
ERR_FAIL();
-};
+}
bool FileAccessZip::file_exists(const String &p_name) {
return false;
-};
-
-FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) {
+}
- zfile = NULL;
+FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) :
+ zfile(NULL) {
_open(p_path, FileAccess::READ);
-};
+}
FileAccessZip::~FileAccessZip() {
close();
-};
+}
#endif
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index df83575f6a..fc8f85c07b 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,7 @@
#define FILE_ACCESS_ZIP_H
#include "core/io/file_access_pack.h"
-#include "map.h"
+#include "core/map.h"
#include "thirdparty/minizip/unzip.h"
@@ -90,8 +90,6 @@ class FileAccessZip : public FileAccess {
mutable bool at_eof;
- ZipArchive *archive;
-
public:
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 2425bb6d69..e5c6d2a4f2 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "http_client.h"
-#include "io/stream_peer_ssl.h"
-#include "version.h"
+
+#include "core/io/stream_peer_ssl.h"
+#include "core/version.h"
const char *HTTPClient::_methods[METHOD_MAX] = {
"GET",
@@ -274,9 +275,10 @@ void HTTPClient::close() {
response_headers.clear();
response_str.clear();
- body_size = 0;
+ body_size = -1;
body_left = 0;
chunk_left = 0;
+ chunk_trailer_part = 0;
read_until_eof = false;
response_num = 0;
handshaking = false;
@@ -348,7 +350,7 @@ Error HTTPClient::poll() {
}
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
- // Handshake has been successfull
+ // Handshake has been successful
handshaking = false;
status = STATUS_CONNECTED;
return OK;
@@ -373,7 +375,20 @@ Error HTTPClient::poll() {
} break;
}
} break;
+ case STATUS_BODY:
case STATUS_CONNECTED: {
+ // Check if we are still connected
+ if (ssl) {
+ Ref<StreamPeerSSL> tmp = connection;
+ tmp->poll();
+ if (tmp->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
+ status = STATUS_CONNECTION_ERROR;
+ return ERR_CONNECTION_ERROR;
+ }
+ } else if (tcp_connection->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
+ status = STATUS_CONNECTION_ERROR;
+ return ERR_CONNECTION_ERROR;
+ }
// Connection established, requests can now be made
return OK;
} break;
@@ -403,20 +418,20 @@ Error HTTPClient::poll() {
String response;
response.parse_utf8((const char *)response_str.ptr());
Vector<String> responses = response.split("\n");
- body_size = 0;
+ body_size = -1;
chunked = false;
body_left = 0;
chunk_left = 0;
+ chunk_trailer_part = false;
read_until_eof = false;
response_str.clear();
response_headers.clear();
response_num = RESPONSE_OK;
- // Per the HTTP 1.1 spec, keep-alive is the default, but in practice
- // it's safe to assume it only if the explicit header is found, allowing
- // to handle body-up-to-EOF responses on naive servers; that's what Curl
- // and browsers do
- bool keep_alive = false;
+ // Per the HTTP 1.1 spec, keep-alive is the default.
+ // Not following that specification breaks standard implemetations.
+ // Broken web servers should be fixed.
+ bool keep_alive = true;
for (int i = 0; i < responses.size(); i++) {
@@ -433,8 +448,8 @@ Error HTTPClient::poll() {
if (encoding == "chunked") {
chunked = true;
}
- } else if (s.begins_with("connection: keep-alive")) {
- keep_alive = true;
+ } else if (s.begins_with("connection: close")) {
+ keep_alive = false;
}
if (i == 0 && responses[i].begins_with("HTTP")) {
@@ -447,7 +462,7 @@ Error HTTPClient::poll() {
}
}
- if (body_size || chunked) {
+ if (body_size != -1 || chunked) {
status = STATUS_BODY;
} else if (!keep_alive) {
@@ -467,7 +482,8 @@ Error HTTPClient::poll() {
case STATUS_DISCONNECTED: {
return ERR_UNCONFIGURED;
} break;
- case STATUS_CONNECTION_ERROR: {
+ case STATUS_CONNECTION_ERROR:
+ case STATUS_SSL_HANDSHAKE_ERROR: {
return ERR_CONNECTION_ERROR;
} break;
case STATUS_CANT_CONNECT: {
@@ -490,13 +506,37 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
ERR_FAIL_COND_V(status != STATUS_BODY, PoolByteArray());
+ PoolByteArray ret;
Error err = OK;
if (chunked) {
while (true) {
- if (chunk_left == 0) {
+ if (chunk_trailer_part) {
+ // We need to consume the trailer part too or keep-alive will break
+ uint8_t b;
+ int rec = 0;
+ err = _get_http_data(&b, 1, rec);
+
+ if (rec == 0)
+ break;
+
+ chunk.push_back(b);
+ int cs = chunk.size();
+ if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) {
+ if (cs == 2) {
+ // Finally over
+ chunk_trailer_part = false;
+ status = STATUS_CONNECTED;
+ chunk.clear();
+ break;
+ } else {
+ // We do not process nor return the trailer data
+ chunk.clear();
+ }
+ }
+ } else if (chunk_left == 0) {
// Reading length
uint8_t b;
int rec = 0;
@@ -510,7 +550,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
if (chunk.size() > 32) {
ERR_PRINT("HTTP Invalid chunk hex len");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
if (chunk.size() > 2 && chunk[chunk.size() - 2] == '\r' && chunk[chunk.size() - 1] == '\n') {
@@ -528,22 +568,22 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
else {
ERR_PRINT("HTTP Chunk len not in hex!!");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
len <<= 4;
len |= v;
if (len > (1 << 24)) {
ERR_PRINT("HTTP Chunk too big!! >16mb");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
}
if (len == 0) {
// End reached!
- status = STATUS_CONNECTED;
+ chunk_trailer_part = true;
chunk.clear();
- return PoolByteArray();
+ break;
}
chunk_left = len + 2;
@@ -563,18 +603,13 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') {
ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
- PoolByteArray ret;
ret.resize(chunk.size() - 2);
- {
- PoolByteArray::Write w = ret.write();
- copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
- }
+ PoolByteArray::Write w = ret.write();
+ copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
chunk.clear();
-
- return ret;
}
break;
@@ -584,45 +619,26 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
} else {
int to_read = !read_until_eof ? MIN(body_left, read_chunk_size) : read_chunk_size;
- PoolByteArray ret;
ret.resize(to_read);
int _offset = 0;
- while (read_until_eof || to_read > 0) {
+ while (to_read > 0) {
int rec = 0;
{
PoolByteArray::Write w = ret.write();
err = _get_http_data(w.ptr() + _offset, to_read, rec);
}
- if (rec < 0) {
- if (to_read > 0) // Ended up reading less
- ret.resize(_offset);
+ if (rec <= 0) { // Ended up reading less
+ ret.resize(_offset);
break;
} else {
_offset += rec;
+ to_read -= rec;
if (!read_until_eof) {
body_left -= rec;
- to_read -= rec;
- } else {
- if (rec < to_read) {
- ret.resize(_offset);
- err = ERR_FILE_EOF;
- break;
- }
- ret.resize(_offset + to_read);
}
}
- }
- if (!read_until_eof) {
- if (body_left == 0) {
- status = STATUS_CONNECTED;
- }
- return ret;
- } else {
- if (err == ERR_FILE_EOF) {
- err = OK; // EOF is expected here
- close();
- return ret;
- }
+ if (err != OK)
+ break;
}
}
@@ -637,12 +653,12 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
status = STATUS_CONNECTION_ERROR;
}
- } else if (body_left == 0 && !chunked) {
+ } else if (body_left == 0 && !chunked && !read_until_eof) {
status = STATUS_CONNECTED;
}
- return PoolByteArray();
+ return ret;
}
HTTPClient::Status HTTPClient::get_status() const {
@@ -664,11 +680,24 @@ Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received
if (blocking) {
- Error err = connection->get_data(p_buffer, p_bytes);
- if (err == OK)
- r_received = p_bytes;
- else
- r_received = 0;
+ // We can't use StreamPeer.get_data, since when reaching EOF we will get an
+ // error without knowing how many bytes we received.
+ Error err = ERR_FILE_EOF;
+ int read = 0;
+ int left = p_bytes;
+ r_received = 0;
+ while (left > 0) {
+ err = connection->get_partial_data(p_buffer + r_received, left, read);
+ if (err == OK) {
+ r_received += read;
+ } else if (err == ERR_FILE_EOF) {
+ r_received += read;
+ return err;
+ } else {
+ return err;
+ }
+ left -= read;
+ }
return err;
} else {
return connection->get_partial_data(p_buffer, p_bytes, r_received);
@@ -682,15 +711,16 @@ void HTTPClient::set_read_chunk_size(int p_size) {
HTTPClient::HTTPClient() {
- tcp_connection = StreamPeerTCP::create_ref();
+ tcp_connection.instance();
resolving = IP::RESOLVER_INVALID_ID;
status = STATUS_DISCONNECTED;
conn_port = -1;
- body_size = 0;
+ body_size = -1;
chunked = false;
body_left = 0;
read_until_eof = false;
chunk_left = 0;
+ chunk_trailer_part = false;
response_num = 0;
ssl = false;
blocking = false;
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 82b56b01db..85ee1959a2 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
-#include "io/ip.h"
-#include "io/stream_peer.h"
-#include "io/stream_peer_tcp.h"
-#include "reference.h"
+#include "core/io/ip.h"
+#include "core/io/stream_peer.h"
+#include "core/io/stream_peer_tcp.h"
+#include "core/reference.h"
class HTTPClient : public Reference {
@@ -172,6 +172,7 @@ private:
bool chunked;
Vector<uint8_t> chunk;
int chunk_left;
+ bool chunk_trailer_part;
int body_size;
int body_left;
bool read_until_eof;
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index b8fd13d67c..a5a0738140 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,8 @@
#include "image_loader.h"
-#include "print_string.h"
+#include "core/print_string.h"
+
bool ImageFormatLoader::recognize(const String &p_extension) const {
List<String> extensions;
@@ -59,7 +60,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
String extension = p_file.get_extension();
- for (int i = 0; i < loader_count; i++) {
+ for (int i = 0; i < loader.size(); i++) {
if (!loader[i]->recognize(extension))
continue;
@@ -82,30 +83,45 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
- for (int i = 0; i < loader_count; i++) {
+ for (int i = 0; i < loader.size(); i++) {
loader[i]->get_recognized_extensions(p_extensions);
}
}
-bool ImageLoader::recognize(const String &p_extension) {
+ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
- for (int i = 0; i < loader_count; i++) {
+ for (int i = 0; i < loader.size(); i++) {
if (loader[i]->recognize(p_extension))
- return true;
+ return loader[i];
}
- return false;
+ return NULL;
}
-ImageFormatLoader *ImageLoader::loader[MAX_LOADERS];
-int ImageLoader::loader_count = 0;
+Vector<ImageFormatLoader *> ImageLoader::loader;
void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
- ERR_FAIL_COND(loader_count >= MAX_LOADERS);
- loader[loader_count++] = p_loader;
+ loader.push_back(p_loader);
+}
+
+void ImageLoader::remove_image_format_loader(ImageFormatLoader *p_loader) {
+
+ loader.erase(p_loader);
+}
+
+const Vector<ImageFormatLoader *> &ImageLoader::get_image_format_loaders() {
+
+ return loader;
+}
+
+void ImageLoader::cleanup() {
+
+ while (loader.size()) {
+ remove_image_format_loader(loader[0]);
+ }
}
/////////////////
@@ -117,7 +133,6 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
- memdelete(f);
return RES();
}
@@ -137,7 +152,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
int idx = -1;
- for (int i = 0; i < ImageLoader::loader_count; i++) {
+ for (int i = 0; i < ImageLoader::loader.size(); i++) {
if (ImageLoader::loader[i]->recognize(extension)) {
idx = i;
break;
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index fbb654c326..95c562b7a9 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,11 @@
#ifndef IMAGE_LOADER_H
#define IMAGE_LOADER_H
-#include "image.h"
-#include "io/resource_loader.h"
-#include "list.h"
-#include "os/file_access.h"
-#include "ustring.h"
+#include "core/image.h"
+#include "core/io/resource_loader.h"
+#include "core/list.h"
+#include "core/os/file_access.h"
+#include "core/ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -70,23 +70,25 @@ public:
class ImageLoader {
- enum {
- MAX_LOADERS = 8
- };
+ static Vector<ImageFormatLoader *> loader;
friend class ResourceFormatLoaderImage;
- static ImageFormatLoader *loader[MAX_LOADERS];
- static int loader_count;
protected:
public:
static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false, float p_scale = 1.0);
static void get_recognized_extensions(List<String> *p_extensions);
- static bool recognize(const String &p_extension);
+ static ImageFormatLoader *recognize(const String &p_extension);
static void add_image_format_loader(ImageFormatLoader *p_loader);
+ static void remove_image_format_loader(ImageFormatLoader *p_loader);
+
+ static const Vector<ImageFormatLoader *> &get_image_format_loaders();
+
+ static void cleanup();
};
class ResourceFormatLoaderImage : public ResourceFormatLoader {
+ GDCLASS(ResourceFormatLoaderImage, ResourceFormatLoader)
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 82c94ca0b2..420e48f839 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "ip.h"
-#include "hash_map.h"
-#include "os/semaphore.h"
-#include "os/thread.h"
+
+#include "core/hash_map.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
VARIANT_ENUM_CAST(IP::ResolverStatus);
diff --git a/core/io/ip.h b/core/io/ip.h
index d55b05b6fe..ead71ebb54 100644
--- a/core/io/ip.h
+++ b/core/io/ip.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef IP_H
#define IP_H
-#include "io/ip_address.h"
-#include "os/os.h"
+#include "core/io/ip_address.h"
+#include "core/os/os.h"
struct _IP_ResolverPrivate;
diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp
index 6d979d10eb..763a5fbb9a 100644
--- a/core/io/ip_address.cpp
+++ b/core/io/ip_address.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -184,7 +184,7 @@ bool IP_Address::is_ipv4() const {
}
const uint8_t *IP_Address::get_ipv4() const {
- ERR_FAIL_COND_V(!is_ipv4(), 0);
+ ERR_FAIL_COND_V(!is_ipv4(), &(field8[12])); // Not the correct IPv4 (it's an IPv6), but we don't want to return a null pointer risking an engine crash.
return &(field8[12]);
}
diff --git a/core/io/ip_address.h b/core/io/ip_address.h
index d7b031b960..3a5f87b617 100644
--- a/core/io/ip_address.h
+++ b/core/io/ip_address.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef IP_ADDRESS_H
#define IP_ADDRESS_H
-#include "ustring.h"
+#include "core/ustring.h"
struct IP_Address {
diff --git a/core/io/json.cpp b/core/io/json.cpp
index 7b2c5a62df..c211ca2ed4 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "json.h"
-#include "print_string.h"
+
+#include "core/print_string.h"
const char *JSON::tk_name[TK_MAX] = {
"'{'",
diff --git a/core/io/json.h b/core/io/json.h
index 9c12423798..7c6877c2cc 100644
--- a/core/io/json.h
+++ b/core/io/json.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef JSON_H
#define JSON_H
-#include "variant.h"
+#include "core/variant.h"
class JSON {
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index 786bec461b..eeb82bfce4 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,9 @@
#include "logger.h"
-#include "os/dir_access.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/dir_access.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
// va_copy was defined in the C99, but not in C++ standards before C++11.
// When you compile C++ without --std=c++<XX> option, compilers still define
@@ -45,6 +45,10 @@
#endif
#endif
+#if defined(MINGW_ENABLED) || defined(_MSC_VER)
+#define sprintf sprintf_s
+#endif
+
bool Logger::should_log(bool p_err) {
return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled);
}
@@ -175,11 +179,10 @@ void RotatedFileLogger::rotate_file() {
file = FileAccess::open(base_path, FileAccess::WRITE);
}
-RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) {
- file = NULL;
- base_path = p_base_path.simplify_path();
- max_files = p_max_files > 0 ? p_max_files : 1;
-
+RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) :
+ base_path(p_base_path.simplify_path()),
+ max_files(p_max_files > 0 ? p_max_files : 1),
+ file(NULL) {
rotate_file();
}
@@ -236,8 +239,8 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
StdLogger::~StdLogger() {}
-CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) {
- loggers = p_loggers;
+CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) :
+ loggers(p_loggers) {
}
void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) {
diff --git a/core/io/logger.h b/core/io/logger.h
index 631e7a0589..ff5b8ce489 100644
--- a/core/io/logger.h
+++ b/core/io/logger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,10 @@
#ifndef LOGGER_H
#define LOGGER_H
-#include "os/file_access.h"
-#include "ustring.h"
-#include "vector.h"
+#include "core/os/file_access.h"
+#include "core/ustring.h"
+#include "core/vector.h"
+
#include <stdarg.h>
class Logger {
@@ -48,11 +49,11 @@ public:
ERR_SHADER
};
- virtual void logv(const char *p_format, va_list p_list, bool p_err) = 0;
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0;
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
- void logf(const char *p_format, ...);
- void logf_error(const char *p_format, ...);
+ void logf(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
+ void logf_error(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
virtual ~Logger();
};
@@ -63,7 +64,7 @@ public:
class StdLogger : public Logger {
public:
- virtual void logv(const char *p_format, va_list p_list, bool p_err);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
virtual ~StdLogger();
};
@@ -87,7 +88,7 @@ class RotatedFileLogger : public Logger {
public:
RotatedFileLogger(const String &p_base_path, int p_max_files = 10);
- virtual void logv(const char *p_format, va_list p_list, bool p_err);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
virtual ~RotatedFileLogger();
};
@@ -98,7 +99,7 @@ class CompositeLogger : public Logger {
public:
CompositeLogger(Vector<Logger *> p_loggers);
- virtual void logv(const char *p_format, va_list p_list, bool p_err);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
void add_logger(Logger *p_logger);
@@ -106,4 +107,4 @@ public:
virtual ~CompositeLogger();
};
-#endif \ No newline at end of file
+#endif
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index e97df0c261..5087a63b68 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "marshalls.h"
-#include "os/keyboard.h"
-#include "print_string.h"
-#include "reference.h"
+
+#include "core/os/keyboard.h"
+#include "core/print_string.h"
+#include "core/reference.h"
+
#include <limits.h>
#include <stdio.h>
@@ -53,9 +55,8 @@ ObjectID EncodedObjectAsID::get_object_id() const {
return id;
}
-EncodedObjectAsID::EncodedObjectAsID() {
-
- id = 0;
+EncodedObjectAsID::EncodedObjectAsID() :
+ id(0) {
}
#define ENCODE_MASK 0xFF
@@ -805,7 +806,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
case Variant::INT: {
int64_t val = p_variant;
- if (val > 0x7FFFFFFF || val < -0x80000000) {
+ if (val > (int64_t)INT_MAX || val < (int64_t)INT_MIN) {
flags |= ENCODE_FLAG_64;
}
} break;
@@ -822,6 +823,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
flags |= ENCODE_FLAG_OBJECT_AS_ID;
}
} break;
+ default: {} // nothing to do at this stage
}
if (buf) {
@@ -847,17 +849,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::INT: {
- int64_t val = p_variant;
- if (val > 0x7FFFFFFF || val < -0x80000000) {
+ if (flags & ENCODE_FLAG_64) {
//64 bits
if (buf) {
- encode_uint64(val, buf);
+ encode_uint64(p_variant.operator int64_t(), buf);
}
r_len += 8;
} else {
if (buf) {
- encode_uint32(int32_t(val), buf);
+ encode_uint32(p_variant.operator int32_t(), buf);
}
r_len += 4;
@@ -865,9 +866,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::REAL: {
- double d = p_variant;
- float f = d;
- if (double(f) != d) {
+ if (flags & ENCODE_FLAG_64) {
if (buf) {
encode_double(p_variant.operator double(), buf);
}
@@ -890,11 +889,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
if (buf) {
encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format
encode_uint32(np.get_subname_count(), buf + 4);
- uint32_t flags = 0;
+ uint32_t np_flags = 0;
if (np.is_absolute())
- flags |= 1;
+ np_flags |= 1;
- encode_uint32(flags, buf + 8);
+ encode_uint32(np_flags, buf + 8);
buf += 12;
}
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index 381e4e3d20..11c4b2c98e 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef MARSHALLS_H
#define MARSHALLS_H
-#include "typedefs.h"
+#include "core/reference.h"
+#include "core/typedefs.h"
+#include "core/variant.h"
-#include "reference.h"
-#include "variant.h"
/**
* Miscellaneous helpers for marshalling data types, and encoding
* in an endian independent way
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 8e67f1c97a..7680d47620 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,7 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/io/multiplayer_api.h"
+#include "multiplayer_api.h"
+
#include "core/io/marshalls.h"
#include "scene/main/node.h"
@@ -37,24 +38,26 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
switch (mode) {
case MultiplayerAPI::RPC_MODE_DISABLED: {
- //do nothing
+ // Do nothing.
} break;
case MultiplayerAPI::RPC_MODE_REMOTE: {
- //do nothing also, no need to call local
+ // Do nothing also. Remote cannot produce a local call.
} break;
+ case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
+ if (is_master)
+ r_skip_rpc = true; // I am the master, so skip remote call.
+ } // Do not break, fall over to other sync.
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
- case MultiplayerAPI::RPC_MODE_MASTERSYNC:
- case MultiplayerAPI::RPC_MODE_SLAVESYNC:
- case MultiplayerAPI::RPC_MODE_SYNC: {
- //call it, sync always results in call
+ case MultiplayerAPI::RPC_MODE_PUPPETSYNC: {
+ // Call it, sync always results in a local call.
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTER: {
if (is_master)
- r_skip_rpc = true; //no other master so..
+ r_skip_rpc = true; // I am the master, so skip remote call.
return is_master;
} break;
- case MultiplayerAPI::RPC_MODE_SLAVE: {
+ case MultiplayerAPI::RPC_MODE_PUPPET: {
return !is_master;
} break;
}
@@ -67,19 +70,16 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
case MultiplayerAPI::RPC_MODE_DISABLED: {
return false;
} break;
- case MultiplayerAPI::RPC_MODE_REMOTE: {
- return true;
- } break;
- case MultiplayerAPI::RPC_MODE_REMOTESYNC:
- case MultiplayerAPI::RPC_MODE_SYNC: {
+ case MultiplayerAPI::RPC_MODE_REMOTE:
+ case MultiplayerAPI::RPC_MODE_REMOTESYNC: {
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
case MultiplayerAPI::RPC_MODE_MASTER: {
return p_node->is_network_master();
} break;
- case MultiplayerAPI::RPC_MODE_SLAVESYNC:
- case MultiplayerAPI::RPC_MODE_SLAVE: {
+ case MultiplayerAPI::RPC_MODE_PUPPETSYNC:
+ case MultiplayerAPI::RPC_MODE_PUPPET: {
return !p_node->is_network_master() && p_remote_id == p_node->get_network_master();
} break;
}
@@ -94,7 +94,7 @@ void MultiplayerAPI::poll() {
network_peer->poll();
- if (!network_peer.is_valid()) //it's possible that polling might have resulted in a disconnection, so check here
+ if (!network_peer.is_valid()) // It's possible that polling might have resulted in a disconnection, so check here.
return;
while (network_peer->get_available_packet_count()) {
@@ -113,7 +113,7 @@ void MultiplayerAPI::poll() {
rpc_sender_id = 0;
if (!network_peer.is_valid()) {
- break; //it's also possible that a packet or RPC caused a disconnection, so also check here
+ break; // It's also possible that a packet or RPC caused a disconnection, so also check here.
}
}
}
@@ -122,6 +122,7 @@ void MultiplayerAPI::clear() {
connected_peers.clear();
path_get_cache.clear();
path_send_cache.clear();
+ packet_cache.clear();
last_send_cache_id = 1;
}
@@ -131,6 +132,8 @@ void MultiplayerAPI::set_root_node(Node *p_node) {
void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
+ if (p_peer == network_peer) return; // Nothing to do
+
if (network_peer.is_valid()) {
network_peer->disconnect("peer_connected", this, "_add_peer");
network_peer->disconnect("peer_disconnected", this, "_del_peer");
@@ -160,7 +163,9 @@ Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const {
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it");
ERR_FAIL_COND(root_node == NULL);
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 1);
uint8_t packet_type = p_packet[0];
@@ -180,13 +185,15 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
case NETWORK_COMMAND_REMOTE_CALL:
case NETWORK_COMMAND_REMOTE_SET: {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 6);
Node *node = _process_get_node(p_from, p_packet, p_packet_len);
+ ERR_EXPLAIN("Invalid packet received. Requested node was not found.");
ERR_FAIL_COND(node == NULL);
- //detect cstring end
+ // Detect cstring end.
int len_end = 5;
for (; len_end < p_packet_len; len_end++) {
if (p_packet[len_end] == 0) {
@@ -194,6 +201,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
}
}
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(len_end >= p_packet_len);
StringName name = String::utf8((const char *)&p_packet[5]);
@@ -222,9 +230,11 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
Node *node = NULL;
if (target & 0x80000000) {
- //use full path (not cached yet)
+ // Use full path (not cached yet).
int ofs = target & 0x7FFFFFFF;
+
+ ERR_EXPLAIN("Invalid packet received. Size smaller than declared.");
ERR_FAIL_COND_V(ofs >= p_packet_len, NULL);
String paths;
@@ -237,17 +247,19 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
if (!node)
ERR_PRINTS("Failed to get path from RPC: " + String(np));
} else {
- //use cached path
+ // Use cached path.
int id = target;
Map<int, PathGetCache>::Element *E = path_get_cache.find(p_from);
+ ERR_EXPLAIN("Invalid packet received. Requests invalid peer cache.");
ERR_FAIL_COND_V(!E, NULL);
Map<int, PathGetCache::NodeInfo>::Element *F = E->get().nodes.find(id);
+ ERR_EXPLAIN("Invalid packet received. Unabled to find requested cached node.");
ERR_FAIL_COND_V(!F, NULL);
PathGetCache::NodeInfo *ni = &F->get();
- //do proper caching later
+ // Do proper caching later.
node = root_node->get_node(ni->path);
if (!node)
@@ -258,9 +270,10 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_offset >= p_packet_len);
- // Check that remote can call the RPC on this node
+ // Check that remote can call the RPC on this node.
RPCMode rpc_mode = RPC_MODE_DISABLED;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_name);
if (E) {
@@ -268,6 +281,8 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
} else if (p_node->get_script_instance()) {
rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name);
}
+
+ ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
ERR_FAIL_COND(!_can_call_mode(p_node, rpc_mode, p_from));
int argc = p_packet[p_offset];
@@ -280,11 +295,14 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
for (int i = 0; i < argc; i++) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_offset >= p_packet_len);
+
int vlen;
Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
+ ERR_EXPLAIN("Invalid packet received. Unable to decode RPC argument.");
ERR_FAIL_COND(err != OK);
- //args[i]=p_packet[3+i];
+
argp.write[i] = &args[i];
p_offset += vlen;
}
@@ -301,9 +319,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_offset >= p_packet_len);
- // Check that remote can call the RSET on this node
+ // Check that remote can call the RSET on this node.
RPCMode rset_mode = RPC_MODE_DISABLED;
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_name);
if (E) {
@@ -311,10 +330,15 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
} else if (p_node->get_script_instance()) {
rset_mode = p_node->get_script_instance()->get_rset_mode(p_name);
}
+
+ ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from));
Variant value;
- decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset);
+ Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset);
+
+ ERR_EXPLAIN("Invalid packet received. Unable to decode RSET value.");
+ ERR_FAIL_COND(err != OK);
bool valid;
@@ -327,6 +351,7 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 5);
int id = decode_uint32(&p_packet[1]);
@@ -345,9 +370,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
path_get_cache[p_from].nodes[id] = ni;
- //send ack
-
- //encode path
+ // Encode path to send ack.
CharString pname = String(path).utf8();
int len = encode_cstring(pname.get_data(), NULL);
@@ -364,6 +387,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 2);
String paths;
@@ -372,31 +396,33 @@ void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet,
NodePath path = paths;
PathSentCache *psc = path_send_cache.getptr(path);
+ ERR_EXPLAIN("Invalid packet received. Tries to confirm a path which was not found in cache.");
ERR_FAIL_COND(!psc);
Map<int, bool>::Element *E = psc->confirmed_peers.find(p_from);
+ ERR_EXPLAIN("Invalid packet received. Source peer was not found in cache for the given path.");
ERR_FAIL_COND(!E);
E->get() = true;
}
bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int p_target) {
bool has_all_peers = true;
- List<int> peers_to_add; //if one is missing, take note to add it
+ List<int> peers_to_add; // If one is missing, take note to add it.
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
if (p_target < 0 && E->get() == -p_target)
- continue; //continue, excluded
+ continue; // Continue, excluded.
if (p_target > 0 && E->get() != p_target)
- continue; //continue, not for this peer
+ continue; // Continue, not for this peer.
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
- if (!F || F->get() == false) {
- //path was not cached, or was cached but is unconfirmed
+ if (!F || !F->get()) {
+ // Path was not cached, or was cached but is unconfirmed.
if (!F) {
- //not cached at all, take note
+ // Not cached at all, take note.
peers_to_add.push_back(E->get());
}
@@ -404,11 +430,11 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
}
}
- //those that need to be added, send a message for this
+ // Those that need to be added, send a message for this.
for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
- //encode function name
+ // Encode function name.
CharString pname = String(p_path).utf8();
int len = encode_cstring(pname.get_data(), NULL);
@@ -419,11 +445,11 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
encode_uint32(psc->id, &packet.write[1]);
encode_cstring(pname.get_data(), &packet.write[5]);
- network_peer->set_target_peer(E->get()); //to all of you
+ network_peer->set_target_peer(E->get()); // To all of you.
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->put_packet(packet.ptr(), packet.size());
- psc->confirmed_peers.insert(E->get(), false); //insert into confirmed, but as false since it was not confirmed
+ psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
}
return has_all_peers;
@@ -462,35 +488,36 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
NodePath from_path = (root_node->get_path()).rel_path_to(p_from->get_path());
+ ERR_EXPLAIN("Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
ERR_FAIL_COND(from_path.is_empty());
- //see if the path is cached
+ // See if the path is cached.
PathSentCache *psc = path_send_cache.getptr(from_path);
if (!psc) {
- //path is not cached, create
+ // Path is not cached, create.
path_send_cache[from_path] = PathSentCache();
psc = path_send_cache.getptr(from_path);
psc->id = last_send_cache_id++;
}
- //create base packet, lots of hardcode because it must be tight
+ // Create base packet, lots of hardcode because it must be tight.
int ofs = 0;
#define MAKE_ROOM(m_amount) \
if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);
- //encode type
+ // Encode type.
MAKE_ROOM(1);
packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
ofs += 1;
- //encode ID
+ // Encode ID.
MAKE_ROOM(ofs + 4);
encode_uint32(psc->id, &(packet_cache.write[ofs]));
ofs += 4;
- //encode function name
+ // Encode function name.
CharString name = String(p_name).utf8();
int len = encode_cstring(name.get_data(), NULL);
MAKE_ROOM(ofs + len);
@@ -498,20 +525,22 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
ofs += len;
if (p_set) {
- //set argument
+ // Set argument.
Error err = encode_variant(*p_arg[0], NULL, len);
+ ERR_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len);
ofs += len;
} else {
- //call arguments
+ // Call arguments.
MAKE_ROOM(ofs + 1);
packet_cache.write[ofs] = p_argcount;
ofs += 1;
for (int i = 0; i < p_argcount; i++) {
Error err = encode_variant(*p_arg[i], NULL, len);
+ ERR_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
ERR_FAIL_COND(err != OK);
MAKE_ROOM(ofs + len);
encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
@@ -519,21 +548,21 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
}
- //see if all peers have cached path (is so, call can be fast)
+ // See if all peers have cached path (is so, call can be fast).
bool has_all_peers = _send_confirm_path(from_path, psc, p_to);
- //take chance and set transfer mode, since all send methods will use it
+ // Take chance and set transfer mode, since all send methods will use it.
network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
if (has_all_peers) {
- //they all have verified paths, so send fast
- network_peer->set_target_peer(p_to); //to all of you
- network_peer->put_packet(packet_cache.ptr(), ofs); //a message with love
+ // They all have verified paths, so send fast.
+ network_peer->set_target_peer(p_to); // To all of you.
+ network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
} else {
- //not all verified path, so send one by one
+ // Not all verified path, so send one by one.
- //apend path at the end, since we will need it for some packets
+ // Append path at the end, since we will need it for some packets.
CharString pname = String(from_path).utf8();
int path_len = encode_cstring(pname.get_data(), NULL);
MAKE_ROOM(ofs + path_len);
@@ -542,23 +571,23 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
if (p_to < 0 && E->get() == -p_to)
- continue; //continue, excluded
+ continue; // Continue, excluded.
if (p_to > 0 && E->get() != p_to)
- continue; //continue, not for this peer
+ continue; // Continue, not for this peer.
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
- ERR_CONTINUE(!F); //should never happen
+ ERR_CONTINUE(!F); // Should never happen.
- network_peer->set_target_peer(E->get()); //to this one specifically
+ network_peer->set_target_peer(E->get()); // To this one specifically.
- if (F->get() == true) {
- //this one confirmed path, so use id
+ if (F->get()) {
+ // This one confirmed path, so use id.
encode_uint32(psc->id, &(packet_cache.write[1]));
network_peer->put_packet(packet_cache.ptr(), ofs);
} else {
- //this one did not confirm path yet, so use entire path (sorry!)
- encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); //offset to path and flag
+ // This one did not confirm path yet, so use entire path (sorry!).
+ encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); // Offset to path and flag.
network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
}
}
@@ -573,7 +602,7 @@ void MultiplayerAPI::_add_peer(int p_id) {
void MultiplayerAPI::_del_peer(int p_id) {
connected_peers.erase(p_id);
- path_get_cache.erase(p_id); //I no longer need your cache, sorry
+ path_get_cache.erase(p_id); // I no longer need your cache, sorry.
emit_signal("network_peer_disconnected", p_id);
}
@@ -594,8 +623,12 @@ void MultiplayerAPI::_server_disconnected() {
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
- ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to call an RPC while no network peer is active.");
ERR_FAIL_COND(!network_peer.is_valid());
+ ERR_EXPLAIN("Trying to call an RPC on a node which is not inside SceneTree.");
+ ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to call an RPC via a network peer which is not connected.");
+ ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
int node_id = network_peer->get_unique_id();
bool skip_rpc = false;
@@ -604,7 +637,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
bool is_master = p_node->is_network_master();
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
- //check that send mode can use local call
+ // Check that send mode can use local call.
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
if (E) {
@@ -612,9 +645,9 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
if (call_local_native) {
- // done below
+ // Done below.
} else if (p_node->get_script_instance()) {
- //attempt with script
+ // Attempt with script.
RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
}
@@ -650,15 +683,19 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
- ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to RSET while no network peer is active.");
ERR_FAIL_COND(!network_peer.is_valid());
+ ERR_EXPLAIN("Trying to RSET on a node which is not inside SceneTree.");
+ ERR_FAIL_COND(!p_node->is_inside_tree());
+ ERR_EXPLAIN("Trying to send an RSET via a network peer which is not connected.");
+ ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
int node_id = network_peer->get_unique_id();
bool is_master = p_node->is_network_master();
bool skip_rset = false;
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
- //check that send mode can use local call
+ // Check that send mode can use local call.
bool set_local = false;
@@ -678,7 +715,7 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
return;
}
} else if (p_node->get_script_instance()) {
- //attempt with script
+ // Attempt with script.
RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
set_local = _should_call_local(rpc_mode, is_master, skip_rset);
@@ -706,8 +743,11 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
+ ERR_EXPLAIN("Trying to send an empty raw packet.");
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
+ ERR_EXPLAIN("Trying to send a raw packet while no network peer is active.");
ERR_FAIL_COND_V(!network_peer.is_valid(), ERR_UNCONFIGURED);
+ ERR_EXPLAIN("Trying to send a raw packet via a network peer which is not connected.");
ERR_FAIL_COND_V(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED);
MAKE_ROOM(p_data.size() + 1);
@@ -723,6 +763,7 @@ Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, Networked
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) {
+ ERR_EXPLAIN("Invalid packet received. Size too small.");
ERR_FAIL_COND(p_packet_len < 2);
PoolVector<uint8_t> out;
@@ -737,30 +778,36 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac
int MultiplayerAPI::get_network_unique_id() const {
+ ERR_EXPLAIN("No network peer is assigned. Unable to get unique network ID.");
ERR_FAIL_COND_V(!network_peer.is_valid(), 0);
return network_peer->get_unique_id();
}
bool MultiplayerAPI::is_network_server() const {
+ // XXX Maybe fail silently? Maybe should actually return true to make development of both local and online multiplayer easier?
+ ERR_EXPLAIN("No network peer is assigned. I can't be a server.");
ERR_FAIL_COND_V(!network_peer.is_valid(), false);
return network_peer->is_server();
}
void MultiplayerAPI::set_refuse_new_network_connections(bool p_refuse) {
+ ERR_EXPLAIN("No network peer is assigned. Unable to set 'refuse_new_connections'.");
ERR_FAIL_COND(!network_peer.is_valid());
network_peer->set_refuse_new_connections(p_refuse);
}
bool MultiplayerAPI::is_refusing_new_network_connections() const {
+ ERR_EXPLAIN("No network peer is assigned. Unable to get 'refuse_new_connections'.");
ERR_FAIL_COND_V(!network_peer.is_valid(), false);
return network_peer->is_refusing_new_connections();
}
Vector<int> MultiplayerAPI::get_network_connected_peers() const {
+ ERR_EXPLAIN("No network peer is assigned. Assume no peers are connected.");
ERR_FAIL_COND_V(!network_peer.is_valid(), Vector<int>());
Vector<int> ret;
@@ -803,15 +850,18 @@ void MultiplayerAPI::_bind_methods() {
BIND_ENUM_CONSTANT(RPC_MODE_DISABLED);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
- BIND_ENUM_CONSTANT(RPC_MODE_SYNC);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
- BIND_ENUM_CONSTANT(RPC_MODE_SLAVE);
+ BIND_ENUM_CONSTANT(RPC_MODE_PUPPET);
+ BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); // Deprecated.
BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC);
+ BIND_ENUM_CONSTANT(RPC_MODE_SYNC); // Deprecated.
BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC);
- BIND_ENUM_CONSTANT(RPC_MODE_SLAVESYNC);
+ BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
}
MultiplayerAPI::MultiplayerAPI() {
+ rpc_sender_id = 0;
+ root_node = NULL;
clear();
}
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index e47b1830e8..a9cf77aaba 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -91,12 +91,13 @@ public:
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers
- RPC_MODE_SYNC, // Using rpc() on it will call method / set property in all remote peers and locally
RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote
- RPC_MODE_SLAVE, // Using rpc() on it will call method for all slaves
- RPC_MODE_REMOTESYNC, // Same as RPC_MODE_SYNC, compatibility
+ RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets
+ RPC_MODE_SLAVE = RPC_MODE_PUPPET, // Deprecated, same as puppet
+ RPC_MODE_REMOTESYNC, // Using rpc() on it will call method / set property in all remote peers and locally
+ RPC_MODE_SYNC = RPC_MODE_REMOTESYNC, // Deprecated. Same as RPC_MODE_REMOTESYNC
RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally
- RPC_MODE_SLAVESYNC, // Using rpc() on it will call method / set property in all slave peers and locally
+ RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method / set property in all puppets peers and locally
};
void poll();
diff --git a/core/os/shell.cpp b/core/io/net_socket.cpp
index 32649a0667..08580356a7 100644
--- a/core/os/shell.cpp
+++ b/core/io/net_socket.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* shell.cpp */
+/* net_socket.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,19 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "shell.h"
+#include "net_socket.h"
-Shell *Shell::singleton = NULL;
+NetSocket *(*NetSocket::_create)() = NULL;
-Shell *Shell::get_singleton() {
+NetSocket *NetSocket::create() {
- return singleton;
-}
-
-Shell::~Shell() {
-}
-
-Shell::Shell() {
+ if (_create)
+ return _create();
- singleton = this;
+ ERR_PRINT("Unable to create network socket, platform not supported");
+ return NULL;
}
diff --git a/core/io/net_socket.h b/core/io/net_socket.h
new file mode 100644
index 0000000000..94e7ef6f75
--- /dev/null
+++ b/core/io/net_socket.h
@@ -0,0 +1,79 @@
+/*************************************************************************/
+/* net_socket.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NET_SOCKET_H
+#define NET_SOCKET_H
+
+#include "core/io/ip.h"
+#include "core/reference.h"
+
+class NetSocket : public Reference {
+
+protected:
+ static NetSocket *(*_create)();
+
+public:
+ static NetSocket *create();
+
+ enum PollType {
+ POLL_TYPE_IN,
+ POLL_TYPE_OUT,
+ POLL_TYPE_IN_OUT
+ };
+
+ enum Type {
+ TYPE_NONE,
+ TYPE_TCP,
+ TYPE_UDP,
+ };
+
+ virtual Error open(Type p_type, IP::Type &ip_type) = 0;
+ virtual void close() = 0;
+ virtual Error bind(IP_Address p_addr, uint16_t p_port) = 0;
+ virtual Error listen(int p_max_pending) = 0;
+ virtual Error connect_to_host(IP_Address p_addr, uint16_t p_port) = 0;
+ virtual Error poll(PollType p_type, int timeout) const = 0;
+ virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read) = 0;
+ virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) = 0;
+ virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) = 0;
+ virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
+ virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port) = 0;
+
+ virtual bool is_open() const = 0;
+ virtual int get_available_bytes() const = 0;
+
+ virtual void set_broadcasting_enabled(bool p_enabled) = 0;
+ virtual void set_blocking_enabled(bool p_enabled) = 0;
+ virtual void set_ipv6_only_enabled(bool p_enabled) = 0;
+ virtual void set_tcp_no_delay_enabled(bool p_enabled) = 0;
+ virtual void set_reuse_address_enabled(bool p_enabled) = 0;
+};
+
+#endif // NET_SOCKET_H
diff --git a/core/io/networked_multiplayer_peer.cpp b/core/io/networked_multiplayer_peer.cpp
index 6354eef8b5..b5469e6e88 100644
--- a/core/io/networked_multiplayer_peer.cpp
+++ b/core/io/networked_multiplayer_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/networked_multiplayer_peer.h b/core/io/networked_multiplayer_peer.h
index 66089c27b9..91752fdc7e 100644
--- a/core/io/networked_multiplayer_peer.h
+++ b/core/io/networked_multiplayer_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef NETWORKED_MULTIPLAYER_PEER_H
#define NETWORKED_MULTIPLAYER_PEER_H
-#include "io/packet_peer.h"
+#include "core/io/packet_peer.h"
class NetworkedMultiplayerPeer : public PacketPeer {
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index dc4997dfc2..d7bfdbbb37 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,14 +30,14 @@
#include "packet_peer.h"
-#include "io/marshalls.h"
-#include "project_settings.h"
-/* helpers / binders */
+#include "core/io/marshalls.h"
+#include "core/project_settings.h"
-PacketPeer::PacketPeer() {
+/* helpers / binders */
- allow_object_decoding = false;
- last_get_error = OK;
+PacketPeer::PacketPeer() :
+ last_get_error(OK),
+ allow_object_decoding(false) {
}
void PacketPeer::set_allow_object_decoding(bool p_enable) {
@@ -224,7 +224,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size)
uint32_t len = decode_uint32(lbuf);
ERR_FAIL_COND_V(remaining < (int)len, ERR_UNAVAILABLE);
- ERR_FAIL_COND_V(input_buffer.size() < len, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(input_buffer.size() < (int)len, ERR_UNAVAILABLE);
ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
ring_buffer.read(input_buffer.ptrw(), len); // read packet
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index b10152e96b..48c50eb76b 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,10 @@
#ifndef PACKET_PEER_H
#define PACKET_PEER_H
-#include "io/stream_peer.h"
-#include "object.h"
-#include "ring_buffer.h"
+#include "core/io/stream_peer.h"
+#include "core/object.h"
+#include "core/ring_buffer.h"
+
class PacketPeer : public Reference {
GDCLASS(PacketPeer, Reference);
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index bfbea15582..5912b8df94 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,8 @@
/*************************************************************************/
#include "packet_peer_udp.h"
-#include "io/ip.h"
-PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL;
+#include "core/io/ip.h"
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
@@ -58,6 +57,177 @@ Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {
return OK;
}
+int PacketPeerUDP::get_available_packet_count() const {
+
+ // TODO we should deprecate this, and expose poll instead!
+ Error err = const_cast<PacketPeerUDP *>(this)->_poll();
+ if (err != OK)
+ return -1;
+
+ return queue_count;
+}
+
+Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
+
+ Error err = _poll();
+ if (err != OK)
+ return err;
+ if (queue_count == 0)
+ return ERR_UNAVAILABLE;
+
+ uint32_t size = 0;
+ uint8_t ipv6[16];
+ rb.read(ipv6, 16, true);
+ packet_ip.set_ipv6(ipv6);
+ rb.read((uint8_t *)&packet_port, 4, true);
+ rb.read((uint8_t *)&size, 4, true);
+ rb.read(packet_buffer, size, true);
+ --queue_count;
+ *r_buffer = packet_buffer;
+ r_buffer_size = size;
+ return OK;
+}
+
+Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED);
+
+ Error err;
+ int sent = -1;
+
+ if (!_sock->is_open()) {
+ IP::Type ip_type = peer_addr.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+ err = _sock->open(NetSocket::TYPE_UDP, ip_type);
+ ERR_FAIL_COND_V(err != OK, err);
+ _sock->set_blocking_enabled(false);
+ }
+
+ do {
+ err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
+ if (err != OK) {
+ if (err != ERR_BUSY)
+ return FAILED;
+ else if (!blocking)
+ return ERR_BUSY;
+ // Keep trying to send full packet
+ continue;
+ }
+ return OK;
+
+ } while (sent != p_buffer_size);
+
+ return OK;
+}
+
+int PacketPeerUDP::get_max_packet_size() const {
+
+ return 512; // uhm maybe not
+}
+
+Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_recv_buffer_size) {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
+
+ Error err;
+ IP::Type ip_type = IP::TYPE_ANY;
+
+ if (p_bind_address.is_valid())
+ ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+
+ err = _sock->open(NetSocket::TYPE_UDP, ip_type);
+
+ if (err != OK)
+ return ERR_CANT_CREATE;
+
+ _sock->set_blocking_enabled(false);
+ _sock->set_reuse_address_enabled(true);
+ err = _sock->bind(p_bind_address, p_port);
+
+ if (err != OK) {
+ _sock->close();
+ return err;
+ }
+ rb.resize(nearest_shift(p_recv_buffer_size));
+ return OK;
+}
+
+void PacketPeerUDP::close() {
+
+ if (_sock.is_valid())
+ _sock->close();
+ rb.resize(16);
+ queue_count = 0;
+}
+
+Error PacketPeerUDP::wait() {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ return _sock->poll(NetSocket::POLL_TYPE_IN, -1);
+}
+
+Error PacketPeerUDP::_poll() {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+
+ if (!_sock->is_open()) {
+ return FAILED;
+ }
+
+ Error err;
+ int read;
+ IP_Address ip;
+ uint16_t port;
+
+ while (true) {
+ err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port);
+
+ if (err != OK) {
+ if (err == ERR_BUSY)
+ break;
+ return FAILED;
+ }
+
+ if (rb.space_left() < read + 24) {
+#ifdef TOOLS_ENABLED
+ WARN_PRINTS("Buffer full, dropping packets!");
+#endif
+ continue;
+ }
+
+ uint32_t port32 = port;
+ rb.write(ip.get_ipv6(), 16);
+ rb.write((uint8_t *)&port32, 4);
+ rb.write((uint8_t *)&read, 4);
+ rb.write(recv_buffer, read);
+ ++queue_count;
+ }
+
+ return OK;
+}
+bool PacketPeerUDP::is_listening() const {
+
+ return _sock.is_valid() && _sock->is_open();
+}
+
+IP_Address PacketPeerUDP::get_packet_address() const {
+
+ return packet_ip;
+}
+
+int PacketPeerUDP::get_packet_port() const {
+
+ return packet_port;
+}
+
+void PacketPeerUDP::set_dest_address(const IP_Address &p_address, int p_port) {
+
+ peer_addr = p_address;
+ peer_port = p_port;
+}
+
void PacketPeerUDP::_bind_methods() {
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), DEFVAL(65536));
@@ -65,26 +235,20 @@ void PacketPeerUDP::_bind_methods() {
ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait);
ClassDB::bind_method(D_METHOD("is_listening"), &PacketPeerUDP::is_listening);
ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
- //ClassDB::bind_method(D_METHOD("get_packet_address"),&PacketPeerUDP::_get_packet_address);
ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port);
ClassDB::bind_method(D_METHOD("set_dest_address", "host", "port"), &PacketPeerUDP::_set_dest_address);
}
-Ref<PacketPeerUDP> PacketPeerUDP::create_ref() {
-
- if (!_create)
- return Ref<PacketPeerUDP>();
- return Ref<PacketPeerUDP>(_create());
-}
-
-PacketPeerUDP *PacketPeerUDP::create() {
-
- if (!_create)
- return NULL;
- return _create();
+PacketPeerUDP::PacketPeerUDP() :
+ packet_port(0),
+ queue_count(0),
+ peer_port(0),
+ blocking(true),
+ _sock(Ref<NetSocket>(NetSocket::create())) {
+ rb.resize(16);
}
-PacketPeerUDP::PacketPeerUDP() {
+PacketPeerUDP::~PacketPeerUDP() {
- blocking = true;
+ close();
}
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index 035f4ad1c9..0593137604 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,37 +31,55 @@
#ifndef PACKET_PEER_UDP_H
#define PACKET_PEER_UDP_H
-#include "io/ip.h"
-#include "io/packet_peer.h"
+#include "core/io/ip.h"
+#include "core/io/net_socket.h"
+#include "core/io/packet_peer.h"
class PacketPeerUDP : public PacketPeer {
GDCLASS(PacketPeerUDP, PacketPeer);
protected:
+ enum {
+ PACKET_BUFFER_SIZE = 65536
+ };
+
+ RingBuffer<uint8_t> rb;
+ uint8_t recv_buffer[PACKET_BUFFER_SIZE];
+ uint8_t packet_buffer[PACKET_BUFFER_SIZE];
+ IP_Address packet_ip;
+ int packet_port;
+ int queue_count;
+
+ IP_Address peer_addr;
+ int peer_port;
bool blocking;
+ Ref<NetSocket> _sock;
- static PacketPeerUDP *(*_create)();
static void _bind_methods();
String _get_packet_ip() const;
Error _set_dest_address(const String &p_address, int p_port);
+ Error _poll();
public:
void set_blocking_mode(bool p_enable);
- virtual Error listen(int p_port, const IP_Address &p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0;
- virtual void close() = 0;
- virtual Error wait() = 0;
- virtual bool is_listening() const = 0;
- virtual IP_Address get_packet_address() const = 0;
- virtual int get_packet_port() const = 0;
- virtual void set_dest_address(const IP_Address &p_address, int p_port) = 0;
+ Error listen(int p_port, const IP_Address &p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536);
+ void close();
+ Error wait();
+ bool is_listening() const;
+ IP_Address get_packet_address() const;
+ int get_packet_port() const;
+ void set_dest_address(const IP_Address &p_address, int p_port);
- static Ref<PacketPeerUDP> create_ref();
- static PacketPeerUDP *create();
+ Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
+ Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
+ int get_available_packet_count() const;
+ int get_max_packet_size() const;
PacketPeerUDP();
+ ~PacketPeerUDP();
};
#endif // PACKET_PEER_UDP_H
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 2fd73db27d..8920bbfb81 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "pck_packer.h"
+
#include "core/os/file_access.h"
-#include "version.h"
+#include "core/version.h"
static uint64_t _align(uint64_t p_n, int p_alignment) {
@@ -174,7 +175,7 @@ Error PCKPacker::flush(bool p_verbose) {
printf("\n");
file->close();
- memdelete(buf);
+ memdelete_arr(buf);
return OK;
};
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 4fcf9a8822..4df495b11f 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 02c2c6ce1a..42070cd132 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -106,7 +106,7 @@ StringName ResourceInteractiveLoaderBinary::_get_string() {
uint32_t id = f->get_32();
if (id & 0x80000000) {
uint32_t len = id & 0x7FFFFFFF;
- if (len > str_buf.size()) {
+ if ((int)len > str_buf.size()) {
str_buf.resize(len);
}
if (len == 0)
@@ -296,9 +296,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_OBJECT: {
- uint32_t type = f->get_32();
+ uint32_t objtype = f->get_32();
- switch (type) {
+ switch (objtype) {
case OBJECT_EMPTY: {
//do none
@@ -317,7 +317,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
case OBJECT_EXTERNAL_RESOURCE: {
//old file format, still around for compatibility
- String type = get_unicode_string();
+ String exttype = get_unicode_string();
String path = get_unicode_string();
if (path.find("://") == -1 && path.is_rel_path()) {
@@ -329,7 +329,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
path = remaps[path];
}
- RES res = ResourceLoader::load(path, type);
+ RES res = ResourceLoader::load(path, exttype);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
@@ -342,11 +342,11 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
int erindex = f->get_32();
if (erindex < 0 || erindex >= external_resources.size()) {
- WARN_PRINT("Broken external resource! (index out of size");
+ WARN_PRINT("Broken external resource! (index out of size)");
r_v = Variant();
} else {
- String type = external_resources[erindex].type;
+ String exttype = external_resources[erindex].type;
String path = external_resources[erindex].path;
if (path.find("://") == -1 && path.is_rel_path()) {
@@ -354,7 +354,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
}
- RES res = ResourceLoader::load(path, type);
+ RES res = ResourceLoader::load(path, exttype);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
@@ -970,12 +970,11 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
return type;
}
-ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() {
-
- f = NULL;
- stage = 0;
- error = OK;
- translation_remapped = false;
+ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() :
+ translation_remapped(false),
+ f(NULL),
+ error(OK),
+ stage(0) {
}
ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
@@ -1309,14 +1308,13 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
case Variant::INT: {
int64_t val = p_property;
- if (val > 0x7FFFFFFF || val < -0x80000000) {
+ if (val > 0x7FFFFFFF || val < -(int64_t)0x80000000) {
f->store_32(VARIANT_INT64);
f->store_64(val);
} else {
f->store_32(VARIANT_INT);
- int val = p_property;
- f->store_32(int32_t(val));
+ f->store_32(int32_t(p_property));
}
} break;
@@ -1503,7 +1501,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
if (!resource_set.has(res)) {
f->store_32(OBJECT_EMPTY);
- ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
+ ERR_EXPLAIN("Resource was not pre cached for the resource section, most likely due to circular refedence.");
ERR_FAIL();
}
@@ -1652,6 +1650,10 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
return;
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
+ if (res->get_path() == path) {
+ ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
+ return;
+ }
int idx = external_resources.size();
external_resources[res] = idx;
return;
@@ -1668,7 +1670,20 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
- _find_resources(res->get(E->get().name));
+ Variant value = res->get(E->get().name);
+ if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
+ RES sres = value;
+ if (sres.is_valid()) {
+ NonPersistentKey npk;
+ npk.base = res;
+ npk.property = E->get().name;
+ non_persistent_map[npk] = sres;
+ resource_set.insert(sres);
+ saved_resources.push_back(sres);
+ }
+ } else {
+ _find_resources(value);
+ }
}
}
@@ -1718,7 +1733,7 @@ void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
- f->store_32(utf8.length() + 1 | 0x80000000);
+ f->store_32((utf8.length() + 1) | 0x80000000);
} else {
f->store_32(utf8.length() + 1);
}
@@ -1763,6 +1778,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
takeover_paths = false;
local_path = p_path.get_base_dir();
+ path = ProjectSettings::get_singleton()->localize_path(p_path);
_find_resources(p_resource, true);
@@ -1812,9 +1828,24 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
Property p;
p.name_idx = get_string_index(F->get().name);
- p.value = E->get()->get(F->get().name);
- if (((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && p.value.is_zero()) || ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && p.value.is_one()))
+
+ if (F->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
+ NonPersistentKey npk;
+ npk.base = E->get();
+ npk.property = F->get().name;
+ if (non_persistent_map.has(npk)) {
+ p.value = non_persistent_map[npk];
+ }
+ } else {
+ p.value = E->get()->get(F->get().name);
+ }
+
+ Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name);
+
+ if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, p.value, default_value))) {
continue;
+ }
+
p.pi = F->get();
rd.properties.push_back(p);
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 021f7f6a2f..a4894e4033 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,9 @@
#ifndef RESOURCE_FORMAT_BINARY_H
#define RESOURCE_FORMAT_BINARY_H
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "os/file_access.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/file_access.h"
class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
@@ -100,6 +100,7 @@ public:
};
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
+ GDCLASS(ResourceFormatLoaderBinary, ResourceFormatLoader)
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
@@ -113,16 +114,24 @@ public:
class ResourceFormatSaverBinaryInstance {
String local_path;
+ String path;
bool relative_paths;
bool bundle_resources;
bool skip_editor;
bool big_endian;
bool takeover_paths;
- int bin_meta_idx;
FileAccess *f;
String magic;
Set<RES> resource_set;
+
+ struct NonPersistentKey { //for resource properties generated on the fly
+ RES base;
+ StringName property;
+ bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; }
+ };
+
+ Map<NonPersistentKey, RES> non_persistent_map;
Map<StringName, int> string_map;
Vector<StringName> strings;
@@ -153,7 +162,7 @@ public:
};
class ResourceFormatSaverBinary : public ResourceFormatSaver {
-
+ GDCLASS(ResourceFormatSaverBinary, ResourceFormatSaver)
public:
static ResourceFormatSaverBinary *singleton;
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
diff --git a/core/io/resource_import.cpp b/core/io/resource_importer.cpp
index cfe6655504..b5fa412576 100644
--- a/core/io/resource_import.cpp
+++ b/core/io/resource_importer.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* resource_import.cpp */
+/* resource_importer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,10 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "resource_import.h"
+#include "resource_importer.h"
-#include "os/os.h"
-#include "variant_parser.h"
+#include "core/os/os.h"
+#include "core/variant_parser.h"
+
+bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const {
+ return p_a->get_importer_name() < p_b->get_importer_name();
+}
Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const {
@@ -90,6 +94,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
r_path_and_type.type = value;
} else if (assign == "importer") {
r_path_and_type.importer = value;
+ } else if (assign == "metadata") {
+ r_path_and_type.metadata = value;
} else if (assign == "valid") {
if (r_valid) {
*r_valid = value;
@@ -177,6 +183,11 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
}
}
+bool ResourceFormatImporter::exists(const String &p_path) const {
+
+ return FileAccess::exists(p_path + ".import");
+}
+
bool ResourceFormatImporter::recognize_path(const String &p_path, const String &p_for_type) const {
return FileAccess::exists(p_path + ".import");
@@ -304,6 +315,18 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const {
return pat.type;
}
+Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const {
+ PathAndType pat;
+ Error err = _get_path_and_type(p_path, pat);
+
+ if (err != OK) {
+
+ return Variant();
+ }
+
+ return pat.metadata;
+}
+
void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
PathAndType pat;
@@ -366,6 +389,40 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co
return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text();
}
+bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const {
+
+ bool valid = true;
+ PathAndType pat;
+ _get_path_and_type(p_path, pat, &valid);
+
+ if (!valid) {
+ return false;
+ }
+
+ for (int i = 0; i < importers.size(); i++) {
+ if (importers[i]->get_importer_name() == pat.importer) {
+ if (!importers[i]->are_import_settings_valid(p_path)) { //importer thinks this is not valid
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+String ResourceFormatImporter::get_import_settings_hash() const {
+
+ Vector<Ref<ResourceImporter> > sorted_importers = importers;
+
+ sorted_importers.sort_custom<SortImporterByName>();
+
+ String hash;
+ for (int i = 0; i < sorted_importers.size(); i++) {
+ hash += ":" + sorted_importers[i]->get_importer_name() + ":" + sorted_importers[i]->get_import_settings_string();
+ }
+ return hash.md5_text();
+}
+
ResourceFormatImporter *ResourceFormatImporter::singleton = NULL;
ResourceFormatImporter::ResourceFormatImporter() {
diff --git a/core/io/resource_import.h b/core/io/resource_importer.h
index 80e0743eda..1c146c33d7 100644
--- a/core/io/resource_import.h
+++ b/core/io/resource_importer.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* resource_import.h */
+/* resource_importer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,24 +28,33 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RESOURCE_IMPORT_H
-#define RESOURCE_IMPORT_H
+#ifndef RESOURCE_IMPORTER_H
+#define RESOURCE_IMPORTER_H
+
+#include "core/io/resource_loader.h"
-#include "io/resource_loader.h"
class ResourceImporter;
class ResourceFormatImporter : public ResourceFormatLoader {
+ GDCLASS(ResourceFormatImporter, ResourceFormatLoader)
+
struct PathAndType {
String path;
String type;
String importer;
+ Variant metadata;
};
Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const;
static ResourceFormatImporter *singleton;
+ //need them to stay in order to compute the settings hash
+ struct SortImporterByName {
+ bool operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const;
+ };
+
Vector<Ref<ResourceImporter> > importers;
public:
@@ -56,8 +65,11 @@ public:
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
+ virtual Variant get_resource_metadata(const String &p_path) const;
virtual bool is_import_valid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
+ virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); }
+ virtual bool exists(const String &p_path) const;
virtual bool can_be_imported(const String &p_path) const;
virtual int get_import_order(const String &p_path) const;
@@ -65,12 +77,17 @@ public:
String get_internal_resource_path(const String &p_path) const;
void get_internal_resource_path_list(const String &p_path, List<String> *r_paths);
- void add_importer(const Ref<ResourceImporter> &p_importer) { importers.push_back(p_importer); }
+ void add_importer(const Ref<ResourceImporter> &p_importer) {
+ importers.push_back(p_importer);
+ }
void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); }
Ref<ResourceImporter> get_importer_by_name(const String &p_name) const;
Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const;
void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers);
+ bool are_import_settings_valid(const String &p_path) const;
+ String get_import_settings_hash() const;
+
String get_import_base_path(const String &p_for_file) const;
ResourceFormatImporter();
};
@@ -104,7 +121,9 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL) = 0;
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL) = 0;
+ virtual bool are_import_settings_valid(const String &p_path) const { return true; }
+ virtual String get_import_settings_string() const { return String(); }
};
-#endif // RESOURCE_IMPORT_H
+#endif // RESOURCE_IMPORTER_H
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index c01aff9144..c917b9ba28 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,15 +29,17 @@
/*************************************************************************/
#include "resource_loader.h"
-#include "io/resource_import.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "path_remap.h"
-#include "print_string.h"
-#include "project_settings.h"
-#include "translation.h"
-#include "variant_parser.h"
-ResourceFormatLoader *ResourceLoader::loader[MAX_LOADERS];
+
+#include "core/io/resource_importer.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/path_remap.h"
+#include "core/print_string.h"
+#include "core/project_settings.h"
+#include "core/translation.h"
+#include "core/variant_parser.h"
+
+Ref<ResourceFormatLoader> ResourceLoader::loader[ResourceLoader::MAX_LOADERS];
int ResourceLoader::loader_count = 0;
@@ -51,6 +53,12 @@ Error ResourceInteractiveLoader::wait() {
return err;
}
+ResourceInteractiveLoader::~ResourceInteractiveLoader() {
+ if (path_loading != String()) {
+ ResourceLoader::_remove_from_loading_map_and_thread(path_loading, path_loading_thread);
+ }
+}
+
bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_for_type) const {
String extension = p_path.get_extension();
@@ -71,6 +79,25 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
return false;
}
+bool ResourceFormatLoader::handles_type(const String &p_type) const {
+
+ if (get_script_instance() && get_script_instance()->has_method("handles_type")) {
+ // I guess custom loaders for custom resources should use "Resource"
+ return get_script_instance()->call("handles_type", p_type);
+ }
+
+ return false;
+}
+
+String ResourceFormatLoader::get_resource_type(const String &p_path) const {
+
+ if (get_script_instance() && get_script_instance()->has_method("get_resource_type")) {
+ return get_script_instance()->call("get_resource_type", p_path);
+ }
+
+ return "";
+}
+
void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
if (p_type == "" || handles_type(p_type))
@@ -127,9 +154,37 @@ bool ResourceFormatLoader::exists(const String &p_path) const {
return FileAccess::exists(p_path); //by default just check file
}
+void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) const {
+
+ if (get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")) {
+ PoolStringArray exts = get_script_instance()->call("get_recognized_extensions");
+
+ {
+ PoolStringArray::Read r = exts.read();
+ for (int i = 0; i < exts.size(); ++i) {
+ p_extensions->push_back(r[i]);
+ }
+ }
+ }
+}
+
RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error) {
- String path = p_path;
+ if (get_script_instance() && get_script_instance()->has_method("load")) {
+ Variant res = get_script_instance()->call("load", p_path, p_original_path);
+
+ if (res.get_type() == Variant::INT) {
+
+ if (r_error)
+ *r_error = (Error)res.operator int64_t();
+
+ } else {
+
+ if (r_error)
+ *r_error = OK;
+ return res;
+ }
+ }
//or this must be implemented
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error);
@@ -158,7 +213,47 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
- //do nothing by default
+ if (get_script_instance() && get_script_instance()->has_method("get_dependencies")) {
+ PoolStringArray deps = get_script_instance()->call("get_dependencies", p_path, p_add_types);
+
+ {
+ PoolStringArray::Read r = deps.read();
+ for (int i = 0; i < deps.size(); ++i) {
+ p_dependencies->push_back(r[i]);
+ }
+ }
+ }
+}
+
+Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
+
+ if (get_script_instance() && get_script_instance()->has_method("rename_dependencies")) {
+
+ Dictionary deps_dict;
+ for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
+ deps_dict[E->key()] = E->value();
+ }
+
+ int64_t res = get_script_instance()->call("rename_dependencies", deps_dict);
+ return (Error)res;
+ }
+
+ return OK;
+}
+
+void ResourceFormatLoader::_bind_methods() {
+
+ {
+ MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"));
+ info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ ClassDB::add_virtual_method(get_class_static(), info);
+ }
+
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::POOL_STRING_ARRAY, "get_recognized_extensions"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles_type", PropertyInfo(Variant::STRING, "typename")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_resource_type", PropertyInfo(Variant::STRING, "path")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo("get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames")));
}
///////////////////////////////////
@@ -191,6 +286,63 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
return RES();
}
+bool ResourceLoader::_add_to_loading_map(const String &p_path) {
+
+ bool success;
+ if (loading_map_mutex) {
+ loading_map_mutex->lock();
+ }
+
+ LoadingMapKey key;
+ key.path = p_path;
+ key.thread = Thread::get_caller_id();
+
+ if (loading_map.has(key)) {
+ success = false;
+ } else {
+ loading_map[key] = true;
+ success = true;
+ }
+
+ if (loading_map_mutex) {
+ loading_map_mutex->unlock();
+ }
+
+ return success;
+}
+
+void ResourceLoader::_remove_from_loading_map(const String &p_path) {
+ if (loading_map_mutex) {
+ loading_map_mutex->lock();
+ }
+
+ LoadingMapKey key;
+ key.path = p_path;
+ key.thread = Thread::get_caller_id();
+
+ loading_map.erase(key);
+
+ if (loading_map_mutex) {
+ loading_map_mutex->unlock();
+ }
+}
+
+void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) {
+ if (loading_map_mutex) {
+ loading_map_mutex->lock();
+ }
+
+ LoadingMapKey key;
+ key.path = p_path;
+ key.thread = p_thread;
+
+ loading_map.erase(key);
+
+ if (loading_map_mutex) {
+ loading_map_mutex->unlock();
+ }
+}
+
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error)
@@ -202,23 +354,61 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
else
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- if (!p_no_cache && ResourceCache::has(local_path)) {
+ if (!p_no_cache) {
- print_verbose("Loading resource: " + local_path + " (cached)");
- if (r_error)
- *r_error = OK;
- return RES(ResourceCache::get(local_path));
+ {
+ bool success = _add_to_loading_map(local_path);
+ if (!success) {
+ ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
+ ERR_FAIL_V(RES());
+ }
+ }
+
+ //lock first if possible
+ if (ResourceCache::lock) {
+ ResourceCache::lock->read_lock();
+ }
+
+ //get ptr
+ Resource **rptr = ResourceCache::resources.getptr(local_path);
+
+ if (rptr) {
+ RES res(*rptr);
+ //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
+ if (res.is_valid()) {
+ //referencing is fine
+ if (r_error)
+ *r_error = OK;
+ if (ResourceCache::lock) {
+ ResourceCache::lock->read_unlock();
+ }
+ _remove_from_loading_map(local_path);
+ return res;
+ }
+ }
+ if (ResourceCache::lock) {
+ ResourceCache::lock->read_unlock();
+ }
}
bool xl_remapped = false;
String path = _path_remap(local_path, &xl_remapped);
- ERR_FAIL_COND_V(path == "", RES());
+ if (path == "") {
+ if (!p_no_cache) {
+ _remove_from_loading_map(local_path);
+ }
+ ERR_EXPLAIN("Remapping '" + local_path + "'failed.");
+ ERR_FAIL_V(RES());
+ }
print_verbose("Loading resource: " + path);
RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error);
if (res.is_null()) {
+ if (!p_no_cache) {
+ _remove_from_loading_map(local_path);
+ }
return RES();
}
if (!p_no_cache)
@@ -237,6 +427,14 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
}
#endif
+ if (!p_no_cache) {
+ _remove_from_loading_map(local_path);
+ }
+
+ if (_loaded_callback) {
+ _loaded_callback(res, p_path);
+ }
+
return res;
}
@@ -281,19 +479,37 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
else
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- if (!p_no_cache && ResourceCache::has(local_path)) {
+ if (!p_no_cache) {
+
+ bool success = _add_to_loading_map(local_path);
+ if (!success) {
+ ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
+ ERR_FAIL_V(RES());
+ }
- print_verbose("Loading resource: " + local_path + " (cached)");
- Ref<Resource> res_cached = ResourceCache::get(local_path);
- Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
+ if (ResourceCache::has(local_path)) {
- ril->resource = res_cached;
- return ril;
+ print_verbose("Loading resource: " + local_path + " (cached)");
+ Ref<Resource> res_cached = ResourceCache::get(local_path);
+ Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
+
+ ril->resource = res_cached;
+ ril->path_loading = local_path;
+ ril->path_loading_thread = Thread::get_caller_id();
+ return ril;
+ }
}
bool xl_remapped = false;
String path = _path_remap(local_path, &xl_remapped);
- ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>());
+ if (path == "") {
+ if (!p_no_cache) {
+ _remove_from_loading_map(local_path);
+ }
+ ERR_EXPLAIN("Remapping '" + local_path + "'failed.");
+ ERR_FAIL_V(RES());
+ }
+
print_verbose("Loading resource: " + path);
bool found = false;
@@ -305,14 +521,22 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error);
if (ril.is_null())
continue;
- if (!p_no_cache)
+ if (!p_no_cache) {
ril->set_local_path(local_path);
+ ril->path_loading = local_path;
+ ril->path_loading_thread = Thread::get_caller_id();
+ }
+
if (xl_remapped)
ril->set_translation_remapped(true);
return ril;
}
+ if (!p_no_cache) {
+ _remove_from_loading_map(local_path);
+ }
+
if (found) {
ERR_EXPLAIN("Failed loading resource: " + path);
} else {
@@ -322,9 +546,11 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
return Ref<ResourceInteractiveLoader>();
}
-void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader, bool p_at_front) {
+void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) {
+ ERR_FAIL_COND(p_format_loader.is_null());
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
+
if (p_at_front) {
for (int i = loader_count; i > 0; i--) {
loader[i] = loader[i - 1];
@@ -336,6 +562,27 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l
}
}
+void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader) {
+
+ ERR_FAIL_COND(p_format_loader.is_null());
+
+ // Find loader
+ int i = 0;
+ for (; i < loader_count; ++i) {
+ if (loader[i] == p_format_loader)
+ break;
+ }
+
+ ERR_FAIL_COND(i >= loader_count); // Not found
+
+ // Shift next loaders up
+ for (; i < loader_count - 1; ++i) {
+ loader[i] = loader[i + 1];
+ }
+ loader[loader_count - 1].unref();
+ --loader_count;
+}
+
int ResourceLoader::get_import_order(const String &p_path) {
String path = _path_remap(p_path);
@@ -386,6 +633,31 @@ bool ResourceLoader::is_import_valid(const String &p_path) {
return false; //not found
}
+bool ResourceLoader::is_imported(const String &p_path) {
+
+ String path = _path_remap(p_path);
+
+ String local_path;
+ if (path.is_rel_path())
+ local_path = "res://" + path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(path);
+
+ for (int i = 0; i < loader_count; i++) {
+
+ if (!loader[i]->recognize_path(local_path))
+ continue;
+ /*
+ if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
+ continue;
+ */
+
+ return loader[i]->is_imported(p_path);
+ }
+
+ return false; //not found
+}
+
void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
String path = _path_remap(p_path);
@@ -613,6 +885,111 @@ void ResourceLoader::clear_path_remaps() {
path_remaps.clear();
}
+void ResourceLoader::set_load_callback(ResourceLoadedCallback p_callback) {
+ _loaded_callback = p_callback;
+}
+
+ResourceLoadedCallback ResourceLoader::_loaded_callback = NULL;
+
+Ref<ResourceFormatLoader> ResourceLoader::_find_custom_resource_format_loader(String path) {
+ for (int i = 0; i < loader_count; ++i) {
+ if (loader[i]->get_script_instance() && loader[i]->get_script_instance()->get_script()->get_path() == path) {
+ return loader[i];
+ }
+ }
+ return Ref<ResourceFormatLoader>();
+}
+
+bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
+
+ if (_find_custom_resource_format_loader(script_path).is_valid())
+ return false;
+
+ Ref<Resource> res = ResourceLoader::load(script_path);
+ ERR_FAIL_COND_V(res.is_null(), false);
+ ERR_FAIL_COND_V(!res->is_class("Script"), false);
+
+ Ref<Script> s = res;
+ StringName ibt = s->get_instance_base_type();
+ bool valid_type = ClassDB::is_parent_class(ibt, "ResourceFormatLoader");
+ ERR_EXPLAIN("Script does not inherit a CustomResourceLoader: " + script_path);
+ ERR_FAIL_COND_V(!valid_type, false);
+
+ Object *obj = ClassDB::instance(ibt);
+
+ ERR_EXPLAIN("Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt));
+ ERR_FAIL_COND_V(obj == NULL, false);
+
+ ResourceFormatLoader *crl = NULL;
+ crl = Object::cast_to<ResourceFormatLoader>(obj);
+ crl->set_script(s.get_ref_ptr());
+ ResourceLoader::add_resource_format_loader(crl);
+
+ return true;
+}
+
+void ResourceLoader::remove_custom_resource_format_loader(String script_path) {
+
+ Ref<ResourceFormatLoader> custom_loader = _find_custom_resource_format_loader(script_path);
+ if (custom_loader.is_valid())
+ remove_resource_format_loader(custom_loader);
+}
+
+void ResourceLoader::add_custom_loaders() {
+ // Custom loaders registration exploits global class names
+
+ String custom_loader_base_class = ResourceFormatLoader::get_class_static();
+
+ List<StringName> global_classes;
+ ScriptServer::get_global_class_list(&global_classes);
+
+ for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
+
+ StringName class_name = E->get();
+ StringName base_class = ScriptServer::get_global_class_base(class_name);
+
+ if (base_class == custom_loader_base_class) {
+ String path = ScriptServer::get_global_class_path(class_name);
+ add_custom_resource_format_loader(path);
+ }
+ }
+}
+
+void ResourceLoader::remove_custom_loaders() {
+
+ Vector<Ref<ResourceFormatLoader> > custom_loaders;
+ for (int i = 0; i < loader_count; ++i) {
+ if (loader[i]->get_script_instance()) {
+ custom_loaders.push_back(loader[i]);
+ }
+ }
+
+ for (int i = 0; i < custom_loaders.size(); ++i) {
+ remove_resource_format_loader(custom_loaders[i]);
+ }
+}
+
+Mutex *ResourceLoader::loading_map_mutex = NULL;
+HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map;
+
+void ResourceLoader::initialize() {
+#ifndef NO_THREADS
+ loading_map_mutex = Mutex::create();
+#endif
+}
+
+void ResourceLoader::finalize() {
+#ifndef NO_THREADS
+ const LoadingMapKey *K = NULL;
+ while ((K = loading_map.next(K))) {
+ ERR_PRINTS("Exited while resource is being loaded: " + K->path);
+ }
+ loading_map.clear();
+ memdelete(loading_map_mutex);
+ loading_map_mutex = NULL;
+#endif
+}
+
ResourceLoadErrorNotify ResourceLoader::err_notify = NULL;
void *ResourceLoader::err_notify_ud = NULL;
@@ -625,3 +1002,5 @@ bool ResourceLoader::timestamp_on_load = false;
SelfList<Resource>::List ResourceLoader::remapped_list;
HashMap<String, Vector<String> > ResourceLoader::translation_remaps;
HashMap<String, String> ResourceLoader::path_remaps;
+
+ResourceLoaderImport ResourceLoader::import = NULL;
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index f78464ef0c..ca7610a0d2 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef RESOURCE_LOADER_H
#define RESOURCE_LOADER_H
-#include "resource.h"
-
+#include "core/os/thread.h"
+#include "core/resource.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -40,6 +40,9 @@
class ResourceInteractiveLoader : public Reference {
GDCLASS(ResourceInteractiveLoader, Reference);
+ friend class ResourceLoader;
+ String path_loading;
+ Thread::ID path_loading_thread;
protected:
static void _bind_methods();
@@ -54,21 +57,29 @@ public:
virtual Error wait();
ResourceInteractiveLoader() {}
+ ~ResourceInteractiveLoader();
};
-class ResourceFormatLoader {
+class ResourceFormatLoader : public Reference {
+
+ GDCLASS(ResourceFormatLoader, Reference)
+
+protected:
+ static void _bind_methods();
+
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual bool exists(const String &p_path) const;
- virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
- virtual bool handles_type(const String &p_type) const = 0;
- virtual String get_resource_type(const String &p_path) const = 0;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
- virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map) { return OK; }
+ virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
virtual bool is_import_valid(const String &p_path) const { return true; }
+ virtual bool is_imported(const String &p_path) const { return false; }
virtual int get_import_order(const String &p_path) const { return 0; }
virtual ~ResourceFormatLoader() {}
@@ -77,13 +88,16 @@ public:
typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text);
typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type);
+typedef Error (*ResourceLoaderImport)(const String &p_path);
+typedef void (*ResourceLoadedCallback)(RES p_resource, const String &p_path);
+
class ResourceLoader {
enum {
MAX_LOADERS = 64
};
- static ResourceFormatLoader *loader[MAX_LOADERS];
+ static Ref<ResourceFormatLoader> loader[MAX_LOADERS];
static int loader_count;
static bool timestamp_on_load;
@@ -101,23 +115,51 @@ class ResourceLoader {
static SelfList<Resource>::List remapped_list;
friend class ResourceFormatImporter;
+ friend class ResourceInteractiveLoader;
//internal load function
static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error);
+ static ResourceLoadedCallback _loaded_callback;
+
+ static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
+ static Mutex *loading_map_mutex;
+
+ //used to track paths being loaded in a thread, avoids cyclic recursion
+ struct LoadingMapKey {
+ String path;
+ Thread::ID thread;
+ bool operator==(const LoadingMapKey &p_key) const {
+ return (thread == p_key.thread && path == p_key.path);
+ }
+ };
+ struct LoadingMapKeyHasher {
+
+ static _FORCE_INLINE_ uint32_t hash(const LoadingMapKey &p_key) { return p_key.path.hash() + HashMapHasherDefault::hash(p_key.thread); }
+ };
+
+ static HashMap<LoadingMapKey, int, LoadingMapKeyHasher> loading_map;
+
+ static bool _add_to_loading_map(const String &p_path);
+ static void _remove_from_loading_map(const String &p_path);
+ static void _remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread);
+
public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static bool exists(const String &p_path, const String &p_type_hint = "");
static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions);
- static void add_resource_format_loader(ResourceFormatLoader *p_format_loader, bool p_at_front = false);
+ static void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front = false);
+ static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader);
static String get_resource_type(const String &p_path);
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
static bool is_import_valid(const String &p_path);
+ static bool is_imported(const String &p_path);
static int get_import_order(const String &p_path);
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
+ static bool get_timestamp_on_load() { return timestamp_on_load; }
static void notify_load_error(const String &p_err) {
if (err_notify) err_notify(err_notify_ud, p_err);
@@ -147,6 +189,17 @@ public:
static void reload_translation_remaps();
static void load_translation_remaps();
static void clear_translation_remaps();
+
+ static void set_load_callback(ResourceLoadedCallback p_callback);
+ static ResourceLoaderImport import;
+
+ static bool add_custom_resource_format_loader(String script_path);
+ static void remove_custom_resource_format_loader(String script_path);
+ static void add_custom_loaders();
+ static void remove_custom_loaders();
+
+ static void initialize();
+ static void finalize();
};
#endif
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 3dcd94880a..c992e2bf94 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,17 +29,62 @@
/*************************************************************************/
#include "resource_saver.h"
-#include "os/file_access.h"
-#include "project_settings.h"
-#include "resource_loader.h"
-#include "script_language.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
+#include "core/project_settings.h"
+#include "core/script_language.h"
-ResourceFormatSaver *ResourceSaver::saver[MAX_SAVERS];
+Ref<ResourceFormatSaver> ResourceSaver::saver[MAX_SAVERS];
int ResourceSaver::saver_count = 0;
bool ResourceSaver::timestamp_on_save = false;
ResourceSavedCallback ResourceSaver::save_callback = 0;
+Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+
+ if (get_script_instance() && get_script_instance()->has_method("save")) {
+ return (Error)get_script_instance()->call("save", p_path, p_resource, p_flags).operator int64_t();
+ }
+
+ return ERR_METHOD_NOT_FOUND;
+}
+
+bool ResourceFormatSaver::recognize(const RES &p_resource) const {
+
+ if (get_script_instance() && get_script_instance()->has_method("recognize")) {
+ return get_script_instance()->call("recognize", p_resource);
+ }
+
+ return false;
+}
+
+void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+
+ if (get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")) {
+ PoolStringArray exts = get_script_instance()->call("get_recognized_extensions", p_resource);
+
+ {
+ PoolStringArray::Read r = exts.read();
+ for (int i = 0; i < exts.size(); ++i) {
+ p_extensions->push_back(r[i]);
+ }
+ }
+ }
+}
+
+void ResourceFormatSaver::_bind_methods() {
+
+ {
+ PropertyInfo arg0 = PropertyInfo(Variant::STRING, "path");
+ PropertyInfo arg1 = PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
+ PropertyInfo arg2 = PropertyInfo(Variant::INT, "flags");
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "save", arg0, arg1, arg2));
+ }
+
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::POOL_STRING_ARRAY, "get_recognized_extensions", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "recognize", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+}
+
Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
String extension = p_path.get_extension();
@@ -89,7 +134,7 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
rwcopy->set_path(old_path);
if (save_callback && p_path.begins_with("res://"))
- save_callback(p_path);
+ save_callback(p_resource, p_path);
return OK;
} else {
@@ -112,8 +157,9 @@ void ResourceSaver::get_recognized_extensions(const RES &p_resource, List<String
}
}
-void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver, bool p_at_front) {
+void ResourceSaver::add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front) {
+ ERR_FAIL_COND(p_format_saver.is_null());
ERR_FAIL_COND(saver_count >= MAX_SAVERS);
if (p_at_front) {
@@ -126,3 +172,102 @@ void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_save
saver[saver_count++] = p_format_saver;
}
}
+
+void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver) {
+
+ ERR_FAIL_COND(p_format_saver.is_null());
+
+ // Find saver
+ int i = 0;
+ for (; i < saver_count; ++i) {
+ if (saver[i] == p_format_saver)
+ break;
+ }
+
+ ERR_FAIL_COND(i >= saver_count); // Not found
+
+ // Shift next savers up
+ for (; i < saver_count - 1; ++i) {
+ saver[i] = saver[i + 1];
+ }
+ saver[saver_count - 1].unref();
+ --saver_count;
+}
+
+Ref<ResourceFormatSaver> ResourceSaver::_find_custom_resource_format_saver(String path) {
+ for (int i = 0; i < saver_count; ++i) {
+ if (saver[i]->get_script_instance() && saver[i]->get_script_instance()->get_script()->get_path() == path) {
+ return saver[i];
+ }
+ }
+ return Ref<ResourceFormatSaver>();
+}
+
+bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
+
+ if (_find_custom_resource_format_saver(script_path).is_valid())
+ return false;
+
+ Ref<Resource> res = ResourceLoader::load(script_path);
+ ERR_FAIL_COND_V(res.is_null(), false);
+ ERR_FAIL_COND_V(!res->is_class("Script"), false);
+
+ Ref<Script> s = res;
+ StringName ibt = s->get_instance_base_type();
+ bool valid_type = ClassDB::is_parent_class(ibt, "ResourceFormatSaver");
+ ERR_EXPLAIN("Script does not inherit a CustomResourceSaver: " + script_path);
+ ERR_FAIL_COND_V(!valid_type, false);
+
+ Object *obj = ClassDB::instance(ibt);
+
+ ERR_EXPLAIN("Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt));
+ ERR_FAIL_COND_V(obj == NULL, false);
+
+ ResourceFormatSaver *crl = NULL;
+ crl = Object::cast_to<ResourceFormatSaver>(obj);
+ crl->set_script(s.get_ref_ptr());
+ ResourceSaver::add_resource_format_saver(crl);
+
+ return true;
+}
+
+void ResourceSaver::remove_custom_resource_format_saver(String script_path) {
+
+ Ref<ResourceFormatSaver> custom_saver = _find_custom_resource_format_saver(script_path);
+ if (custom_saver.is_valid())
+ remove_resource_format_saver(custom_saver);
+}
+
+void ResourceSaver::add_custom_savers() {
+ // Custom resource savers exploits global class names
+
+ String custom_saver_base_class = ResourceFormatSaver::get_class_static();
+
+ List<StringName> global_classes;
+ ScriptServer::get_global_class_list(&global_classes);
+
+ for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
+
+ StringName class_name = E->get();
+ StringName base_class = ScriptServer::get_global_class_base(class_name);
+
+ if (base_class == custom_saver_base_class) {
+ String path = ScriptServer::get_global_class_path(class_name);
+ add_custom_resource_format_saver(path);
+ }
+ }
+}
+
+void ResourceSaver::remove_custom_savers() {
+
+ Vector<Ref<ResourceFormatSaver> > custom_savers;
+ for (int i = 0; i < saver_count; ++i) {
+ if (saver[i]->get_script_instance()) {
+ custom_savers.push_back(saver[i]);
+ }
+ }
+
+ for (int i = 0; i < custom_savers.size(); ++i) {
+ remove_resource_format_saver(custom_savers[i]);
+ }
+}
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 396f37d414..7df3bfb1f8 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,22 +31,27 @@
#ifndef RESOURCE_SAVER_H
#define RESOURCE_SAVER_H
-#include "resource.h"
+#include "core/resource.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-class ResourceFormatSaver {
+class ResourceFormatSaver : public Reference {
+ GDCLASS(ResourceFormatSaver, Reference)
+
+protected:
+ static void _bind_methods();
+
public:
- virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) = 0;
- virtual bool recognize(const RES &p_resource) const = 0;
- virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const = 0;
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual bool recognize(const RES &p_resource) const;
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
virtual ~ResourceFormatSaver() {}
};
-typedef void (*ResourceSavedCallback)(const String &p_path);
+typedef void (*ResourceSavedCallback)(Ref<Resource> p_resource, const String &p_path);
class ResourceSaver {
@@ -54,11 +59,13 @@ class ResourceSaver {
MAX_SAVERS = 64
};
- static ResourceFormatSaver *saver[MAX_SAVERS];
+ static Ref<ResourceFormatSaver> saver[MAX_SAVERS];
static int saver_count;
static bool timestamp_on_save;
static ResourceSavedCallback save_callback;
+ static Ref<ResourceFormatSaver> _find_custom_resource_format_saver(String path);
+
public:
enum SaverFlags {
@@ -73,10 +80,18 @@ public:
static Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
static void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions);
- static void add_resource_format_saver(ResourceFormatSaver *p_format_saver, bool p_at_front = false);
+ static void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front = false);
+ static void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
static void set_timestamp_on_save(bool p_timestamp) { timestamp_on_save = p_timestamp; }
+ static bool get_timestamp_on_save() { return timestamp_on_save; }
+
static void set_save_callback(ResourceSavedCallback p_callback);
+
+ static bool add_custom_resource_format_saver(String script_path);
+ static void remove_custom_resource_format_saver(String script_path);
+ static void add_custom_savers();
+ static void remove_custom_savers();
};
#endif
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 3e0ee088c2..3042c0f60a 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "stream_peer.h"
-#include "io/marshalls.h"
+
+#include "core/io/marshalls.h"
Error StreamPeer::_put_data(const PoolVector<uint8_t> &p_data) {
@@ -208,6 +209,12 @@ void StreamPeer::put_double(double p_val) {
}
put_data(buf, 8);
}
+void StreamPeer::put_string(const String &p_string) {
+
+ CharString cs = p_string.ascii();
+ put_u32(cs.length());
+ put_data((const uint8_t *)cs.get_data(), cs.length());
+}
void StreamPeer::put_utf8_string(const String &p_string) {
CharString cs = p_string.utf8();
@@ -324,6 +331,8 @@ double StreamPeer::get_double() {
}
String StreamPeer::get_string(int p_bytes) {
+ if (p_bytes < 0)
+ p_bytes = get_u32();
ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<char> buf;
@@ -336,6 +345,8 @@ String StreamPeer::get_string(int p_bytes) {
}
String StreamPeer::get_utf8_string(int p_bytes) {
+ if (p_bytes < 0)
+ p_bytes = get_u32();
ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<uint8_t> buf;
@@ -385,6 +396,7 @@ void StreamPeer::_bind_methods() {
ClassDB::bind_method(D_METHOD("put_u64", "value"), &StreamPeer::put_u64);
ClassDB::bind_method(D_METHOD("put_float", "value"), &StreamPeer::put_float);
ClassDB::bind_method(D_METHOD("put_double", "value"), &StreamPeer::put_double);
+ ClassDB::bind_method(D_METHOD("put_string", "value"), &StreamPeer::put_string);
ClassDB::bind_method(D_METHOD("put_utf8_string", "value"), &StreamPeer::put_utf8_string);
ClassDB::bind_method(D_METHOD("put_var", "value"), &StreamPeer::put_var);
@@ -398,8 +410,8 @@ void StreamPeer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_u64"), &StreamPeer::get_u64);
ClassDB::bind_method(D_METHOD("get_float"), &StreamPeer::get_float);
ClassDB::bind_method(D_METHOD("get_double"), &StreamPeer::get_double);
- ClassDB::bind_method(D_METHOD("get_string", "bytes"), &StreamPeer::get_string);
- ClassDB::bind_method(D_METHOD("get_utf8_string", "bytes"), &StreamPeer::get_utf8_string);
+ ClassDB::bind_method(D_METHOD("get_string", "bytes"), &StreamPeer::get_string, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("get_utf8_string", "bytes"), &StreamPeer::get_utf8_string, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_var"), &StreamPeer::get_var);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian_enabled");
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index 605b0a7980..059ccd016c 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef STREAM_PEER_H
#define STREAM_PEER_H
-#include "reference.h"
+#include "core/reference.h"
class StreamPeer : public Reference {
GDCLASS(StreamPeer, Reference);
@@ -71,6 +71,7 @@ public:
void put_u64(uint64_t p_val);
void put_float(float p_val);
void put_double(double p_val);
+ void put_string(const String &p_string);
void put_utf8_string(const String &p_string);
void put_var(const Variant &p_variant);
@@ -84,8 +85,8 @@ public:
int64_t get_64();
float get_float();
double get_double();
- String get_string(int p_bytes);
- String get_utf8_string(int p_bytes);
+ String get_string(int p_bytes = -1);
+ String get_utf8_string(int p_bytes = -1);
Variant get_var();
StreamPeer() { big_endian = false; }
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index 25adb6a6ee..254ae84bf5 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,11 @@
/*************************************************************************/
#include "stream_peer_ssl.h"
-#include "os/file_access.h"
-#include "project_settings.h"
+
+#include "core/io/certs_compressed.gen.h"
+#include "core/io/compression.h"
+#include "core/os/file_access.h"
+#include "core/project_settings.h"
StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL;
@@ -41,13 +44,20 @@ StreamPeerSSL *StreamPeerSSL::create() {
StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false;
-bool StreamPeerSSL::initialize_certs = true;
void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
if (load_certs_func)
load_certs_func(p_memory);
}
+void StreamPeerSSL::load_certs_from_file(String p_path) {
+ if (p_path != "") {
+ PoolByteArray certs = get_cert_file_as_array(p_path);
+ if (certs.size() > 0)
+ load_certs_func(certs);
+ }
+}
+
bool StreamPeerSSL::is_available() {
return available;
}
@@ -60,6 +70,25 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
return blocking_handshake;
}
+PoolByteArray StreamPeerSSL::get_cert_file_as_array(String p_path) {
+
+ PoolByteArray out;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ if (f) {
+ int flen = f->get_len();
+ out.resize(flen + 1);
+ PoolByteArray::Write w = out.write();
+ f->get_buffer(w.ptr(), flen);
+ w[flen] = 0; // Make sure it ends with string terminator
+ memdelete(f);
+#ifdef DEBUG_ENABLED
+ print_verbose(vformat("Loaded certs from '%s'.", p_path));
+#endif
+ }
+
+ return out;
+}
+
PoolByteArray StreamPeerSSL::get_project_cert_array() {
PoolByteArray out;
@@ -67,24 +96,21 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
if (certs_path != "") {
-
- FileAccess *f = FileAccess::open(certs_path, FileAccess::READ);
- if (f) {
- int flen = f->get_len();
- out.resize(flen + 1);
- {
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
- w[flen] = 0; //end f string
- }
-
- memdelete(f);
-
+ // Use certs defined in project settings.
+ return get_cert_file_as_array(certs_path);
+ }
+#ifdef BUILTIN_CERTS_ENABLED
+ else {
+ // Use builtin certs only if user did not override it in project settings.
+ out.resize(_certs_uncompressed_size + 1);
+ PoolByteArray::Write w = out.write();
+ Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
+ w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
#ifdef DEBUG_ENABLED
- print_verbose(vformat("Loaded certs from '%s'.", certs_path));
+ print_verbose("Loaded builtin certs");
#endif
- }
}
+#endif
return out;
}
@@ -102,6 +128,7 @@ void StreamPeerSSL::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_handshake"), "set_blocking_handshake_enabled", "is_blocking_handshake_enabled");
BIND_ENUM_CONSTANT(STATUS_DISCONNECTED);
+ BIND_ENUM_CONSTANT(STATUS_HANDSHAKING);
BIND_ENUM_CONSTANT(STATUS_CONNECTED);
BIND_ENUM_CONSTANT(STATUS_ERROR);
BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 870704e875..482576c4c6 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef STREAM_PEER_SSL_H
#define STREAM_PEER_SSL_H
-#include "io/stream_peer.h"
+#include "core/io/stream_peer.h"
class StreamPeerSSL : public StreamPeer {
GDCLASS(StreamPeerSSL, StreamPeer);
@@ -46,9 +46,6 @@ protected:
static LoadCertsFromMemory load_certs_func;
static bool available;
- friend class Main;
- static bool initialize_certs;
-
bool blocking_handshake;
public:
@@ -72,7 +69,9 @@ public:
static StreamPeerSSL *create();
+ static PoolByteArray get_cert_file_as_array(String p_path);
static PoolByteArray get_project_cert_array();
+ static void load_certs_from_file(String p_path);
static void load_certs_from_memory(const PoolByteArray &p_memory);
static bool is_available();
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index 54ebb3ae0d..45f3e46e35 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,294 @@
#include "stream_peer_tcp.h"
-StreamPeerTCP *(*StreamPeerTCP::_create)() = NULL;
+Error StreamPeerTCP::_poll_connection() {
+
+ ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED);
+
+ Error err = _sock->connect_to_host(peer_host, peer_port);
+
+ if (err == OK) {
+ status = STATUS_CONNECTED;
+ return OK;
+ } else if (err == ERR_BUSY) {
+ // Still trying to connect
+ return OK;
+ }
+
+ disconnect_from_host();
+ status = STATUS_ERROR;
+ return ERR_CONNECTION_ERROR;
+}
+
+void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint16_t p_port) {
+
+ _sock = p_sock;
+ _sock->set_blocking_enabled(false);
+
+ status = STATUS_CONNECTING;
+
+ peer_host = p_host;
+ peer_port = p_port;
+}
+
+Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port) {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
+
+ Error err;
+ IP::Type ip_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+
+ err = _sock->open(NetSocket::TYPE_TCP, ip_type);
+ ERR_FAIL_COND_V(err != OK, FAILED);
+
+ _sock->set_blocking_enabled(false);
+
+ err = _sock->connect_to_host(p_host, p_port);
+
+ if (err == OK) {
+ status = STATUS_CONNECTED;
+ } else if (err == ERR_BUSY) {
+ status = STATUS_CONNECTING;
+ } else {
+ ERR_PRINT("Connection to remote host failed!");
+ disconnect_from_host();
+ return FAILED;
+ }
+
+ peer_host = p_host;
+ peer_port = p_port;
+
+ return OK;
+}
+
+Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+
+ if (status == STATUS_NONE || status == STATUS_ERROR) {
+
+ return FAILED;
+ }
+
+ if (status != STATUS_CONNECTED) {
+
+ if (_poll_connection() != OK) {
+
+ return FAILED;
+ }
+
+ if (status != STATUS_CONNECTED) {
+ r_sent = 0;
+ return OK;
+ }
+ }
+
+ if (!_sock->is_open())
+ return FAILED;
+
+ Error err;
+ int data_to_send = p_bytes;
+ const uint8_t *offset = p_data;
+ int total_sent = 0;
+
+ while (data_to_send) {
+
+ int sent_amount = 0;
+ err = _sock->send(offset, data_to_send, sent_amount);
+
+ if (err != OK) {
+
+ if (err != ERR_BUSY) {
+ disconnect_from_host();
+ return FAILED;
+ }
+
+ if (!p_block) {
+ r_sent = total_sent;
+ return OK;
+ }
+
+ // Block and wait for the socket to accept more data
+ err = _sock->poll(NetSocket::POLL_TYPE_OUT, -1);
+ if (err != OK) {
+ disconnect_from_host();
+ return FAILED;
+ }
+ } else {
+
+ data_to_send -= sent_amount;
+ offset += sent_amount;
+ total_sent += sent_amount;
+ }
+ }
+
+ r_sent = total_sent;
+
+ return OK;
+}
+
+Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) {
+
+ if (!is_connected_to_host()) {
+
+ return FAILED;
+ }
+
+ if (status == STATUS_CONNECTING) {
+
+ if (_poll_connection() != OK) {
+
+ return FAILED;
+ }
+
+ if (status != STATUS_CONNECTED) {
+ r_received = 0;
+ return OK;
+ }
+ }
+
+ Error err;
+ int to_read = p_bytes;
+ int total_read = 0;
+ r_received = 0;
+
+ while (to_read) {
+
+ int read = 0;
+ err = _sock->recv(p_buffer + total_read, to_read, read);
+
+ if (err != OK) {
+
+ if (err != ERR_BUSY) {
+ disconnect_from_host();
+ return FAILED;
+ }
+
+ if (!p_block) {
+ r_received = total_read;
+ return OK;
+ }
+
+ err = _sock->poll(NetSocket::POLL_TYPE_IN, -1);
+
+ if (err != OK) {
+ disconnect_from_host();
+ return FAILED;
+ }
+
+ } else if (read == 0) {
+
+ disconnect_from_host();
+ r_received = total_read;
+ return ERR_FILE_EOF;
+
+ } else {
+
+ to_read -= read;
+ total_read += read;
+ }
+ }
+
+ r_received = total_read;
+
+ return OK;
+}
+
+void StreamPeerTCP::set_no_delay(bool p_enabled) {
+
+ ERR_FAIL_COND(!is_connected_to_host());
+ _sock->set_tcp_no_delay_enabled(p_enabled);
+}
+
+bool StreamPeerTCP::is_connected_to_host() const {
+
+ if (status == STATUS_NONE || status == STATUS_ERROR) {
+
+ return false;
+ }
+
+ if (status != STATUS_CONNECTED) {
+ return true;
+ }
+
+ return _sock.is_valid() && _sock->is_open();
+}
+
+StreamPeerTCP::Status StreamPeerTCP::get_status() {
+
+ if (status == STATUS_CONNECTING) {
+ _poll_connection();
+ } else if (status == STATUS_CONNECTED) {
+ Error err;
+ err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
+ if (err == OK) {
+ // FIN received
+ if (_sock->get_available_bytes() == 0) {
+ disconnect_from_host();
+ return status;
+ }
+ }
+ // Also poll write
+ err = _sock->poll(NetSocket::POLL_TYPE_IN_OUT, 0);
+ if (err != OK && err != ERR_BUSY) {
+ // Got an error
+ disconnect_from_host();
+ status = STATUS_ERROR;
+ }
+ }
+
+ return status;
+}
+
+void StreamPeerTCP::disconnect_from_host() {
+
+ if (_sock.is_valid() && _sock->is_open())
+ _sock->close();
+
+ status = STATUS_NONE;
+ peer_host = IP_Address();
+ peer_port = 0;
+}
+
+Error StreamPeerTCP::put_data(const uint8_t *p_data, int p_bytes) {
+
+ int total;
+ return write(p_data, p_bytes, total, true);
+}
+
+Error StreamPeerTCP::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
+
+ return write(p_data, p_bytes, r_sent, false);
+}
+
+Error StreamPeerTCP::get_data(uint8_t *p_buffer, int p_bytes) {
+
+ int total;
+ return read(p_buffer, p_bytes, total, true);
+}
+
+Error StreamPeerTCP::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
+
+ return read(p_buffer, p_bytes, r_received, false);
+}
+
+int StreamPeerTCP::get_available_bytes() const {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), -1);
+ return _sock->get_available_bytes();
+}
+
+IP_Address StreamPeerTCP::get_connected_host() const {
+
+ return peer_host;
+}
+
+uint16_t StreamPeerTCP::get_connected_port() const {
+
+ return peer_port;
+}
Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
@@ -62,23 +349,14 @@ void StreamPeerTCP::_bind_methods() {
BIND_ENUM_CONSTANT(STATUS_ERROR);
}
-Ref<StreamPeerTCP> StreamPeerTCP::create_ref() {
-
- if (!_create)
- return Ref<StreamPeerTCP>();
- return Ref<StreamPeerTCP>(_create());
+StreamPeerTCP::StreamPeerTCP() :
+ _sock(Ref<NetSocket>(NetSocket::create())),
+ status(STATUS_NONE),
+ peer_host(IP_Address()),
+ peer_port(0) {
}
-StreamPeerTCP *StreamPeerTCP::create() {
+StreamPeerTCP::~StreamPeerTCP() {
- if (!_create)
- return NULL;
- return _create();
+ disconnect_from_host();
}
-
-StreamPeerTCP::StreamPeerTCP() {
-}
-
-StreamPeerTCP::~StreamPeerTCP(){
-
-};
diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h
index 8a16d820f2..1ca39375aa 100644
--- a/core/io/stream_peer_tcp.h
+++ b/core/io/stream_peer_tcp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef STREAM_PEER_TCP_H
#define STREAM_PEER_TCP_H
-#include "stream_peer.h"
-
-#include "io/ip.h"
-#include "ip_address.h"
+#include "core/io/ip.h"
+#include "core/io/ip_address.h"
+#include "core/io/net_socket.h"
+#include "core/io/stream_peer.h"
class StreamPeerTCP : public StreamPeer {
@@ -51,24 +51,37 @@ public:
};
protected:
- virtual Error _connect(const String &p_address, int p_port);
- static StreamPeerTCP *(*_create)();
+ Ref<NetSocket> _sock;
+ Status status;
+ IP_Address peer_host;
+ uint16_t peer_port;
+
+ Error _connect(const String &p_address, int p_port);
+ Error _poll_connection();
+ Error write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block);
+ Error read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block);
+
static void _bind_methods();
public:
- virtual Error connect_to_host(const IP_Address &p_host, uint16_t p_port) = 0;
+ void accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint16_t p_port);
+
+ Error connect_to_host(const IP_Address &p_host, uint16_t p_port);
+ bool is_connected_to_host() const;
+ IP_Address get_connected_host() const;
+ uint16_t get_connected_port() const;
+ void disconnect_from_host();
- //read/write from streampeer
+ int get_available_bytes() const;
+ Status get_status();
- virtual bool is_connected_to_host() const = 0;
- virtual Status get_status() const = 0;
- virtual void disconnect_from_host() = 0;
- virtual IP_Address get_connected_host() const = 0;
- virtual uint16_t get_connected_port() const = 0;
- virtual void set_no_delay(bool p_enabled) = 0;
+ void set_no_delay(bool p_enabled);
- static Ref<StreamPeerTCP> create_ref();
- static StreamPeerTCP *create();
+ // Read/Write from StreamPeer
+ Error put_data(const uint8_t *p_data, int p_bytes);
+ Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent);
+ Error get_data(uint8_t *p_buffer, int p_bytes);
+ Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received);
StreamPeerTCP();
~StreamPeerTCP();
diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp
index 5916d58390..6599c4eb5b 100644
--- a/core/io/tcp_server.cpp
+++ b/core/io/tcp_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,29 +30,97 @@
#include "tcp_server.h"
-TCP_Server *(*TCP_Server::_create)() = NULL;
+void TCP_Server::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*"));
+ ClassDB::bind_method(D_METHOD("is_connection_available"), &TCP_Server::is_connection_available);
+ ClassDB::bind_method(D_METHOD("take_connection"), &TCP_Server::take_connection);
+ ClassDB::bind_method(D_METHOD("stop"), &TCP_Server::stop);
+}
+
+Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
+
+ Error err;
+ IP::Type ip_type = IP::TYPE_ANY;
+
+ // If the bind address is valid use its type as the socket type
+ if (p_bind_address.is_valid())
+ ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+
+ err = _sock->open(NetSocket::TYPE_TCP, ip_type);
+
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
+
+ _sock->set_blocking_enabled(false);
+ _sock->set_reuse_address_enabled(true);
+
+ err = _sock->bind(p_bind_address, p_port);
+
+ if (err != OK) {
+
+ _sock->close();
+ return ERR_ALREADY_IN_USE;
+ }
-Ref<TCP_Server> TCP_Server::create_ref() {
+ err = _sock->listen(MAX_PENDING_CONNECTIONS);
- if (!_create)
- return NULL;
- return Ref<TCP_Server>(_create());
+ if (err != OK) {
+ _sock->close();
+ return FAILED;
+ }
+ return OK;
}
-TCP_Server *TCP_Server::create() {
+bool TCP_Server::is_connection_available() const {
- if (!_create)
- return NULL;
- return _create();
+ ERR_FAIL_COND_V(!_sock.is_valid(), false);
+
+ if (!_sock->is_open())
+ return false;
+
+ Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
+ if (err != OK) {
+ return false;
+ }
+
+ return true;
}
-void TCP_Server::_bind_methods() {
+Ref<StreamPeerTCP> TCP_Server::take_connection() {
- ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*"));
- ClassDB::bind_method(D_METHOD("is_connection_available"), &TCP_Server::is_connection_available);
- ClassDB::bind_method(D_METHOD("take_connection"), &TCP_Server::take_connection);
- ClassDB::bind_method(D_METHOD("stop"), &TCP_Server::stop);
+ Ref<StreamPeerTCP> conn;
+ if (!is_connection_available()) {
+ return conn;
+ }
+
+ Ref<NetSocket> ns;
+ IP_Address ip;
+ uint16_t port = 0;
+ ns = _sock->accept(ip, port);
+ if (!ns.is_valid())
+ return conn;
+
+ conn = Ref<StreamPeerTCP>(memnew(StreamPeerTCP));
+ conn->accept_socket(ns, ip, port);
+ return conn;
+}
+
+void TCP_Server::stop() {
+
+ if (_sock.is_valid()) {
+ _sock->close();
+ }
+}
+
+TCP_Server::TCP_Server() :
+ _sock(Ref<NetSocket>(NetSocket::create())) {
}
-TCP_Server::TCP_Server() {
+TCP_Server::~TCP_Server() {
+
+ stop();
}
diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h
index a250e8b249..538db175ad 100644
--- a/core/io/tcp_server.h
+++ b/core/io/tcp_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,31 +31,32 @@
#ifndef TCP_SERVER_H
#define TCP_SERVER_H
-#include "io/ip.h"
-#include "io/stream_peer.h"
-#include "stream_peer_tcp.h"
+#include "core/io/ip.h"
+#include "core/io/net_socket.h"
+#include "core/io/stream_peer.h"
+#include "core/io/stream_peer_tcp.h"
class TCP_Server : public Reference {
GDCLASS(TCP_Server, Reference);
protected:
- static TCP_Server *(*_create)();
+ enum {
+ MAX_PENDING_CONNECTIONS = 8
+ };
- //bind helper
+ Ref<NetSocket> _sock;
static void _bind_methods();
public:
- virtual Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*")) = 0;
- virtual bool is_connection_available() const = 0;
- virtual Ref<StreamPeerTCP> take_connection() = 0;
+ Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*"));
+ bool is_connection_available() const;
+ Ref<StreamPeerTCP> take_connection();
- virtual void stop() = 0; //stop listening
-
- static Ref<TCP_Server> create_ref();
- static TCP_Server *create();
+ void stop(); // Stop listening
TCP_Server();
+ ~TCP_Server();
};
#endif // TCP_SERVER_H
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 85c1fc5ddf..67a0a905bd 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "translation_loader_po.h"
-#include "os/file_access.h"
-#include "translation.h"
+
+#include "core/os/file_access.h"
+#include "core/translation.h"
RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const String &p_path) {
diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h
index 33cf9bd8b4..d5fd264385 100644
--- a/core/io/translation_loader_po.h
+++ b/core/io/translation_loader_po.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,12 @@
#ifndef TRANSLATION_LOADER_PO_H
#define TRANSLATION_LOADER_PO_H
-#include "io/resource_loader.h"
-#include "os/file_access.h"
-#include "translation.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
+#include "core/translation.h"
+
class TranslationLoaderPO : public ResourceFormatLoader {
+ GDCLASS(TranslationLoaderPO, ResourceFormatLoader)
public:
static RES load_translation(FileAccess *f, Error *r_error, const String &p_path = String());
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 33c9b56d5a..4638ddcc09 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "xml_parser.h"
-#include "print_string.h"
+
+#include "core/print_string.h"
+
//#define DEBUG_XML
VARIANT_ENUM_CAST(XMLParser::NodeType);
diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h
index 297b57ffdc..0df2d74ab4 100644
--- a/core/io/xml_parser.h
+++ b/core/io/xml_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef XML_PARSER_H
#define XML_PARSER_H
-#include "os/file_access.h"
-#include "reference.h"
-#include "ustring.h"
-#include "vector.h"
+#include "core/os/file_access.h"
+#include "core/reference.h"
+#include "core/ustring.h"
+#include "core/vector.h"
/*
Based on irrXML (see their zlib license). Added mainly for compatibility with their Collada loader.
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp
new file mode 100644
index 0000000000..8f3e0b49ec
--- /dev/null
+++ b/core/io/zip_io.cpp
@@ -0,0 +1,137 @@
+/*************************************************************************/
+/* zip_io.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "zip_io.h"
+
+#include "core/os/copymem.h"
+
+void *zipio_open(void *data, const char *p_fname, int mode) {
+
+ FileAccess *&f = *(FileAccess **)data;
+
+ String fname;
+ fname.parse_utf8(p_fname);
+
+ if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
+ f = FileAccess::open(fname, FileAccess::WRITE);
+ } else {
+
+ f = FileAccess::open(fname, FileAccess::READ);
+ }
+
+ if (!f)
+ return NULL;
+
+ return data;
+}
+
+uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
+
+ FileAccess *f = *(FileAccess **)data;
+ return f->get_buffer((uint8_t *)buf, size);
+}
+
+uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+ f->store_buffer((uint8_t *)buf, size);
+ return size;
+}
+
+long zipio_tell(voidpf opaque, voidpf stream) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+ return f->get_position();
+}
+
+long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+
+ int pos = offset;
+ switch (origin) {
+
+ case ZLIB_FILEFUNC_SEEK_CUR:
+ pos = f->get_position() + offset;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END:
+ pos = f->get_len() + offset;
+ break;
+ default:
+ break;
+ };
+
+ f->seek(pos);
+ return 0;
+}
+
+int zipio_close(voidpf opaque, voidpf stream) {
+
+ FileAccess *&f = *(FileAccess **)opaque;
+ if (f) {
+ f->close();
+ f = NULL;
+ }
+ return 0;
+}
+
+int zipio_testerror(voidpf opaque, voidpf stream) {
+
+ FileAccess *f = *(FileAccess **)opaque;
+ return (f && f->get_error() != OK) ? 1 : 0;
+}
+
+voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
+
+ voidpf ptr = memalloc(items * size);
+ zeromem(ptr, items * size);
+ return ptr;
+}
+
+void zipio_free(voidpf opaque, voidpf address) {
+
+ memfree(address);
+}
+
+zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
+
+ zlib_filefunc_def io;
+ io.opaque = p_file;
+ io.zopen_file = zipio_open;
+ io.zread_file = zipio_read;
+ io.zwrite_file = zipio_write;
+ io.ztell_file = zipio_tell;
+ io.zseek_file = zipio_seek;
+ io.zclose_file = zipio_close;
+ io.zerror_file = zipio_testerror;
+ io.alloc_mem = zipio_alloc;
+ io.free_mem = zipio_free;
+ return io;
+}
diff --git a/core/io/zip_io.h b/core/io/zip_io.h
index 3a7fdb0302..fb63878a4c 100644
--- a/core/io/zip_io.h
+++ b/core/io/zip_io.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,114 +31,28 @@
#ifndef ZIP_IO_H
#define ZIP_IO_H
-#include "os/copymem.h"
-#include "os/file_access.h"
+#include "core/os/file_access.h"
+// Not direclty used in this header, but assumed available in downstream users
+// like platform/*/export/export.cpp. Could be fixed, but probably better to have
+// thirdparty includes in as little headers as possible.
#include "thirdparty/minizip/unzip.h"
#include "thirdparty/minizip/zip.h"
-static void *zipio_open(void *data, const char *p_fname, int mode) {
+void *zipio_open(void *data, const char *p_fname, int mode);
+uLong zipio_read(void *data, void *fdata, void *buf, uLong size);
+uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size);
- FileAccess *&f = *(FileAccess **)data;
+long zipio_tell(voidpf opaque, voidpf stream);
+long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin);
- String fname;
- fname.parse_utf8(p_fname);
+int zipio_close(voidpf opaque, voidpf stream);
- if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
- f = FileAccess::open(fname, FileAccess::WRITE);
- } else {
+int zipio_testerror(voidpf opaque, voidpf stream);
- f = FileAccess::open(fname, FileAccess::READ);
- }
+voidpf zipio_alloc(voidpf opaque, uInt items, uInt size);
+void zipio_free(voidpf opaque, voidpf address);
- if (!f)
- return NULL;
-
- return data;
-};
-
-static uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
-
- FileAccess *f = *(FileAccess **)data;
- return f->get_buffer((uint8_t *)buf, size);
-};
-
-static uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
-
- FileAccess *f = *(FileAccess **)opaque;
- f->store_buffer((uint8_t *)buf, size);
- return size;
-};
-
-static long zipio_tell(voidpf opaque, voidpf stream) {
-
- FileAccess *f = *(FileAccess **)opaque;
- return f->get_position();
-};
-
-static long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
-
- FileAccess *f = *(FileAccess **)opaque;
-
- int pos = offset;
- switch (origin) {
-
- case ZLIB_FILEFUNC_SEEK_CUR:
- pos = f->get_position() + offset;
- break;
- case ZLIB_FILEFUNC_SEEK_END:
- pos = f->get_len() + offset;
- break;
- default:
- break;
- };
-
- f->seek(pos);
- return 0;
-};
-
-static int zipio_close(voidpf opaque, voidpf stream) {
-
- FileAccess *&f = *(FileAccess **)opaque;
- if (f) {
- f->close();
- f = NULL;
- }
- return 0;
-};
-
-static int zipio_testerror(voidpf opaque, voidpf stream) {
-
- FileAccess *f = *(FileAccess **)opaque;
- return (f && f->get_error() != OK) ? 1 : 0;
-};
-
-static voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
-
- voidpf ptr = memalloc(items * size);
- zeromem(ptr, items * size);
- return ptr;
-}
-
-static void zipio_free(voidpf opaque, voidpf address) {
-
- memfree(address);
-}
-
-static zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
-
- zlib_filefunc_def io;
- io.opaque = p_file;
- io.zopen_file = zipio_open;
- io.zread_file = zipio_read;
- io.zwrite_file = zipio_write;
- io.ztell_file = zipio_tell;
- io.zseek_file = zipio_seek;
- io.zclose_file = zipio_close;
- io.zerror_file = zipio_testerror;
- io.alloc_mem = zipio_alloc;
- io.free_mem = zipio_free;
- return io;
-}
+zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file);
#endif // ZIP_IO_H
diff --git a/core/list.h b/core/list.h
index f977df4634..c26aad6463 100644
--- a/core/list.h
+++ b/core/list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef GLOBALS_LIST_H
#define GLOBALS_LIST_H
-#include "os/memory.h"
-#include "sort.h"
+#include "core/os/memory.h"
+#include "core/sort_array.h"
/**
* Generic Templatized Linked List Implementation.
diff --git a/core/map.h b/core/map.h
index 700d4b8693..a701ba36f7 100644
--- a/core/map.h
+++ b/core/map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef MAP_H
#define MAP_H
-#include "set.h"
+#include "core/set.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/core/math/SCsub b/core/math/SCsub
index 4efc902717..1c5f954470 100644
--- a/core/math/SCsub
+++ b/core/math/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
-
-Export('env')
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 021391da83..6c3b84d49a 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "a_star.h"
-#include "geometry.h"
+
+#include "core/math/geometry.h"
+#include "core/script_language.h"
#include "scene/scene_string_names.h"
-#include "script_language.h"
int AStar::get_available_point_id() const {
@@ -96,11 +97,14 @@ void AStar::remove_point(int p_id) {
Point *p = points[p_id];
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
-
- Segment s(p_id, E->get()->id);
- segments.erase(s);
- E->get()->neighbours.erase(p);
+ Map<int, Point *>::Element *PE = points.front();
+ while (PE) {
+ for (Set<Point *>::Element *E = PE->get()->neighbours.front(); E; E = E->next()) {
+ Segment s(p_id, E->get()->id);
+ segments.erase(s);
+ E->get()->neighbours.erase(p);
+ }
+ PE = PE->next();
}
memdelete(p);
@@ -249,14 +253,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
n->distance = _compute_cost(begin_point->id, n->id) * n->weight_scale;
n->last_pass = pass;
open_list.add(&n->list);
-
- if (end_point == n) {
- found_route = true;
- break;
- }
}
- while (!found_route) {
+ while (true) {
if (open_list.first() == NULL) {
// No path found
@@ -264,8 +263,8 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
}
// Check open list
- SelfList<Point> *least_cost_point = NULL;
- real_t least_cost = 1e30;
+ SelfList<Point> *least_cost_point = open_list.first();
+ real_t least_cost = Math_INF;
// TODO: Cache previous results
for (SelfList<Point> *E = open_list.first(); E; E = E->next()) {
@@ -276,13 +275,16 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
cost += _estimate_cost(p->id, end_point->id);
if (cost < least_cost) {
-
least_cost_point = E;
least_cost = cost;
}
}
Point *p = least_cost_point->self();
+ if (p == end_point) {
+ found_route = true;
+ break;
+ }
for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
@@ -294,7 +296,6 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
// Already visited, is this cheaper?
if (e->distance > distance) {
-
e->prev_point = p;
e->distance = distance;
}
@@ -305,18 +306,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
e->distance = distance;
e->last_pass = pass; // Mark as used
open_list.add(&e->list);
-
- if (e == end_point) {
- // End reached; stop algorithm
- found_route = true;
- break;
- }
}
}
- if (found_route)
- break;
-
open_list.remove(least_cost_point);
}
@@ -382,14 +374,14 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
{
PoolVector<Vector3>::Write w = path.write();
- Point *p = end_point;
+ Point *p2 = end_point;
int idx = pc - 1;
- while (p != begin_point) {
- w[idx--] = p->pos;
- p = p->prev_point;
+ while (p2 != begin_point) {
+ w[idx--] = p2->pos;
+ p2 = p2->prev_point;
}
- w[0] = p->pos; // Assign first
+ w[0] = p2->pos; // Assign first
}
return path;
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 8c1b5f64cb..d094bc4863 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,9 @@
#ifndef ASTAR_H
#define ASTAR_H
-#include "reference.h"
-#include "self_list.h"
+#include "core/reference.h"
+#include "core/self_list.h"
+
/**
A* pathfinding algorithm
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index e2e71dda92..a4eb1fe2a5 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "aabb.h"
-#include "print_string.h"
+#include "core/print_string.h"
real_t AABB::get_area() const {
diff --git a/core/math/aabb.h b/core/math/aabb.h
index cdb8eb48a3..52e5ed3626 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,9 @@
#ifndef AABB_H
#define AABB_H
-#include "math_defs.h"
-#include "plane.h"
-#include "vector3.h"
+#include "core/math/math_defs.h"
+#include "core/math/plane.h"
+#include "core/math/vector3.h"
/**
* AABB / AABB (Axis Aligned Bounding Box)
diff --git a/core/math/audio_frame.cpp b/core/math/audio_frame.cpp
index eff817bbaa..2496a70890 100644
--- a/core/math/audio_frame.cpp
+++ b/core/math/audio_frame.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 67ba025e1c..f970c510e0 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef AUDIOFRAME_H
#define AUDIOFRAME_H
-#include "typedefs.h"
+#include "core/typedefs.h"
static inline float undenormalise(volatile float f) {
union {
diff --git a/core/math/matrix3.cpp b/core/math/basis.cpp
index 7db41756ed..8816e3639a 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/basis.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* matrix3.cpp */
+/* basis.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,10 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "matrix3.h"
-#include "math_funcs.h"
-#include "os/copymem.h"
-#include "print_string.h"
+#include "basis.h"
+
+#include "core/math/math_funcs.h"
+#include "core/os/copymem.h"
+#include "core/print_string.h"
+
#define cofac(row1, col1, row2, col2) \
(elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1])
@@ -74,9 +76,11 @@ void Basis::invert() {
}
void Basis::orthonormalize() {
+
#ifdef MATH_CHECKS
ERR_FAIL_COND(determinant() == 0);
#endif
+
// Gram-Schmidt Process
Vector3 x = get_axis(0);
@@ -116,16 +120,16 @@ bool Basis::is_diagonal() const {
}
bool Basis::is_rotation() const {
- return Math::is_equal_approx(determinant(), 1) && is_orthogonal();
+ return Math::is_equal_approx(determinant(), 1, UNIT_EPSILON) && is_orthogonal();
}
bool Basis::is_symmetric() const {
- if (!Math::is_equal_approx(elements[0][1], elements[1][0]))
+ if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON))
return false;
- if (!Math::is_equal_approx(elements[0][2], elements[2][0]))
+ if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON))
return false;
- if (!Math::is_equal_approx(elements[1][2], elements[2][1]))
+ if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON))
return false;
return true;
@@ -256,7 +260,7 @@ Vector3 Basis::get_scale_abs() const {
}
Vector3 Basis::get_scale_local() const {
- real_t det_sign = determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(determinant());
return det_sign * Vector3(elements[0].length(), elements[1].length(), elements[2].length());
}
@@ -282,7 +286,7 @@ Vector3 Basis::get_scale() const {
// matrix elements.
//
// The rotation part of this decomposition is returned by get_rotation* functions.
- real_t det_sign = determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(determinant());
return det_sign * Vector3(
Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
@@ -297,14 +301,14 @@ Vector3 Basis::rotref_posscale_decomposition(Basis &rotref) const {
ERR_FAIL_COND_V(determinant() == 0, Vector3());
Basis m = transposed() * (*this);
- ERR_FAIL_COND_V(m.is_diagonal() == false, Vector3());
+ ERR_FAIL_COND_V(!m.is_diagonal(), Vector3());
#endif
Vector3 scale = get_scale();
Basis inv_scale = Basis().scaled(scale.inverse()); // this will also absorb the sign of scale
rotref = (*this) * inv_scale;
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(rotref.is_orthogonal() == false, Vector3());
+ ERR_FAIL_COND_V(!rotref.is_orthogonal(), Vector3());
#endif
return scale.abs();
}
@@ -428,7 +432,7 @@ Vector3 Basis::get_euler_xyz() const {
Vector3 euler;
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, euler);
+ ERR_FAIL_COND_V(!is_rotation(), euler);
#endif
real_t sy = elements[0][2];
if (sy < 1.0) {
@@ -486,6 +490,11 @@ void Basis::set_euler_xyz(const Vector3 &p_euler) {
// as the x, y, and z components of a Vector3 respectively.
Vector3 Basis::get_euler_yxz() const {
+ /* checking this is a bad idea, because obtaining from scaled transform is a valid use case
+#ifdef MATH_CHECKS
+ ERR_FAIL_COND(!is_rotation());
+#endif
+*/
// Euler angles in YXZ convention.
// See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
//
@@ -494,9 +503,7 @@ Vector3 Basis::get_euler_yxz() const {
// cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx
Vector3 euler;
-#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, euler);
-#endif
+
real_t m12 = elements[1][2];
if (m12 < 1) {
@@ -554,7 +561,7 @@ bool Basis::is_equal_approx(const Basis &a, const Basis &b) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
- if (Math::is_equal_approx(a.elements[i][j], b.elements[i][j]) == false)
+ if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], UNIT_EPSILON))
return false;
}
}
@@ -597,10 +604,14 @@ Basis::operator String() const {
}
Quat Basis::get_quat() const {
-#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, Quat());
-#endif
- real_t trace = elements[0][0] + elements[1][1] + elements[2][2];
+
+ /* Allow getting a quaternion from an unnormalized transform */
+ Basis m = *this;
+ m.elements[0].normalize();
+ m.elements[1].normalize();
+ m.elements[2].normalize();
+
+ real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2];
real_t temp[4];
if (trace > 0.0) {
@@ -608,23 +619,23 @@ Quat Basis::get_quat() const {
temp[3] = (s * 0.5);
s = 0.5 / s;
- temp[0] = ((elements[2][1] - elements[1][2]) * s);
- temp[1] = ((elements[0][2] - elements[2][0]) * s);
- temp[2] = ((elements[1][0] - elements[0][1]) * s);
+ temp[0] = ((m.elements[2][1] - m.elements[1][2]) * s);
+ temp[1] = ((m.elements[0][2] - m.elements[2][0]) * s);
+ temp[2] = ((m.elements[1][0] - m.elements[0][1]) * s);
} else {
- int i = elements[0][0] < elements[1][1] ?
- (elements[1][1] < elements[2][2] ? 2 : 1) :
- (elements[0][0] < elements[2][2] ? 2 : 0);
+ int i = m.elements[0][0] < m.elements[1][1] ?
+ (m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
+ (m.elements[0][0] < m.elements[2][2] ? 2 : 0);
int j = (i + 1) % 3;
int k = (i + 2) % 3;
- real_t s = Math::sqrt(elements[i][i] - elements[j][j] - elements[k][k] + 1.0);
+ real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
temp[i] = s * 0.5;
s = 0.5 / s;
- temp[3] = (elements[k][j] - elements[j][k]) * s;
- temp[j] = (elements[j][i] + elements[i][j]) * s;
- temp[k] = (elements[k][i] + elements[i][k]) * s;
+ temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
+ temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
+ temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
}
return Quat(temp[0], temp[1], temp[2], temp[3]);
@@ -694,9 +705,11 @@ void Basis::set_orthogonal_index(int p_index) {
}
void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
+ /* checking this is a bad idea, because obtaining from scaled transform is a valid use case
#ifdef MATH_CHECKS
- ERR_FAIL_COND(is_rotation() == false);
+ ERR_FAIL_COND(!is_rotation());
#endif
+*/
real_t angle, x, y, z; // variables for result
real_t epsilon = 0.01; // margin to allow for rounding errors
real_t epsilon2 = 0.1; // margin to distinguish between 0 and 180 degrees
@@ -783,7 +796,7 @@ void Basis::set_quat(const Quat &p_quat) {
void Basis::set_axis_angle(const Vector3 &p_axis, real_t p_phi) {
// Rotation matrix from axis and angle, see https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_angle
#ifdef MATH_CHECKS
- ERR_FAIL_COND(p_axis.is_normalized() == false);
+ ERR_FAIL_COND(!p_axis.is_normalized());
#endif
Vector3 axis_sq(p_axis.x * p_axis.x, p_axis.y * p_axis.y, p_axis.z * p_axis.z);
@@ -833,14 +846,15 @@ void Basis::set_diagonal(const Vector3 p_diag) {
}
Basis Basis::slerp(const Basis &target, const real_t &t) const {
-// TODO: implement this directly without using quaternions to make it more efficient
-#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, Basis());
- ERR_FAIL_COND_V(target.is_rotation() == false, Basis());
-#endif
+ //consider scale
Quat from(*this);
Quat to(target);
- return Basis(from.slerp(to, t));
+ Basis b(from.slerp(to, t));
+ b.elements[0] *= Math::lerp(elements[0].length(), target.elements[0].length(), t);
+ b.elements[1] *= Math::lerp(elements[1].length(), target.elements[1].length(), t);
+ b.elements[2] *= Math::lerp(elements[2].length(), target.elements[2].length(), t);
+
+ return b;
}
diff --git a/core/math/matrix3.h b/core/math/basis.h
index 9ff1a97dc9..128e56b494 100644
--- a/core/math/matrix3.h
+++ b/core/math/basis.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* matrix3.h */
+/* basis.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,16 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vector3.h"
+// Circular dependency between Vector3 and Basis :/
+#include "core/math/vector3.h"
-#ifndef MATRIX3_H
-#define MATRIX3_H
+#ifndef BASIS_H
+#define BASIS_H
-#include "quat.h"
+#include "core/math/quat.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
class Basis {
public:
Vector3 elements[3];
@@ -339,4 +341,4 @@ real_t Basis::determinant() const {
elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
}
-#endif
+#endif // BASIS_H
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index 24096de551..d7e6e82cd9 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "bsp_tree.h"
-#include "error_macros.h"
-#include "print_string.h"
+
+#include "core/error_macros.h"
+#include "core/print_string.h"
void BSP_Tree::from_aabb(const AABB &p_aabb) {
@@ -164,7 +165,6 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
int pass_count = 0;
const Node *nodesptr = &nodes[0];
const Plane *planesptr = &planes[0];
- int plane_count = planes.size();
int node_count = nodes.size();
if (node_count == 0) // no nodes!
@@ -191,9 +191,9 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
break;
}
- uint16_t plane = nodesptr[idx].plane;
#ifdef DEBUG_ENABLED
-
+ int plane_count = planes.size();
+ uint16_t plane = nodesptr[idx].plane;
ERR_FAIL_INDEX_V(plane, plane_count, false);
#endif
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
index fb16818ae7..a7a3697990 100644
--- a/core/math/bsp_tree.h
+++ b/core/math/bsp_tree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,13 +31,13 @@
#ifndef BSP_TREE_H
#define BSP_TREE_H
-#include "aabb.h"
-#include "dvector.h"
-#include "face3.h"
-#include "method_ptrcall.h"
-#include "plane.h"
-#include "variant.h"
-#include "vector.h"
+#include "core/math/aabb.h"
+#include "core/math/face3.h"
+#include "core/math/plane.h"
+#include "core/method_ptrcall.h"
+#include "core/pool_vector.h"
+#include "core/variant.h"
+#include "core/vector.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 1ab9b3532e..caf08c7379 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "camera_matrix.h"
-#include "math_funcs.h"
-#include "print_string.h"
+
+#include "core/math/math_funcs.h"
+#include "core/print_string.h"
void CameraMatrix::set_identity() {
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index a689c7238a..015588a8cb 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,9 @@
#ifndef CAMERA_MATRIX_H
#define CAMERA_MATRIX_H
-#include "rect2.h"
-#include "transform.h"
+#include "core/math/rect2.h"
+#include "core/math/transform.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
diff --git a/core/math/delaunay.cpp b/core/math/delaunay.cpp
deleted file mode 100644
index 8cae92b7c0..0000000000
--- a/core/math/delaunay.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "delaunay.h"
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index 46535d5ce9..bd0cf97937 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -1,7 +1,37 @@
+/*************************************************************************/
+/* delaunay.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef DELAUNAY_H
#define DELAUNAY_H
-#include "rect2.h"
+#include "core/math/rect2.h"
class Delaunay2D {
public:
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index ba40cb4586..99251d80e3 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -1,12 +1,42 @@
+/*************************************************************************/
+/* expression.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "expression.h"
-#include "class_db.h"
-#include "func_ref.h"
-#include "io/marshalls.h"
-#include "math_funcs.h"
-#include "os/os.h"
-#include "reference.h"
-#include "variant_parser.h"
+#include "core/class_db.h"
+#include "core/func_ref.h"
+#include "core/io/marshalls.h"
+#include "core/math/math_funcs.h"
+#include "core/os/os.h"
+#include "core/reference.h"
+#include "core/variant_parser.h"
const char *Expression::func_name[Expression::FUNC_MAX] = {
"sin",
@@ -726,6 +756,10 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
////////
+static bool _is_number(CharType c) {
+ return (c >= '0' && c <= '9');
+}
+
Error Expression::_get_token(Token &r_token) {
while (true) {
@@ -783,17 +817,12 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_COLON;
return OK;
};
- case '.': {
-
- r_token.type = TK_PERIOD;
- return OK;
- };
case '$': {
r_token.type = TK_INPUT;
int index = 0;
do {
- if (expression[str_ofs] < '0' || expression[str_ofs] > '9') {
+ if (!_is_number(expression[str_ofs])) {
_set_error("Expected number after '$'");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
@@ -802,7 +831,7 @@ Error Expression::_get_token(Token &r_token) {
index += expression[str_ofs] - '0';
str_ofs++;
- } while (expression[str_ofs] >= '0' && expression[str_ofs] <= '9');
+ } while (_is_number(expression[str_ofs]));
r_token.value = index;
return OK;
@@ -949,14 +978,14 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
+ if (!(_is_number(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
_set_error("Malformed hex constant in string");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
CharType v;
- if (c >= '0' && c <= '9') {
+ if (_is_number(c)) {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
v = c - 'a';
@@ -1002,7 +1031,8 @@ Error Expression::_get_token(Token &r_token) {
break;
}
- if (cchar >= '0' && cchar <= '9') {
+ CharType next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
+ if (_is_number(cchar) || (cchar == '.' && _is_number(next_char))) {
//a number
String num;
@@ -1023,7 +1053,7 @@ Error Expression::_get_token(Token &r_token) {
switch (reading) {
case READING_INT: {
- if (c >= '0' && c <= '9') {
+ if (_is_number(c)) {
//pass
} else if (c == '.') {
reading = READING_DEC;
@@ -1037,7 +1067,7 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_DEC: {
- if (c >= '0' && c <= '9') {
+ if (_is_number(c)) {
} else if (c == 'e') {
reading = READING_EXP;
@@ -1049,7 +1079,7 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_EXP: {
- if (c >= '0' && c <= '9') {
+ if (_is_number(c)) {
exp_beg = true;
} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
@@ -1084,7 +1114,7 @@ Error Expression::_get_token(Token &r_token) {
String id;
bool first = true;
- while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) {
+ while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && _is_number(cchar))) {
id += String::chr(cchar);
cchar = GET_CHAR();
@@ -1146,6 +1176,12 @@ Error Expression::_get_token(Token &r_token) {
}
return OK;
+
+ } else if (cchar == '.') {
+ // Handled down there as we support '.[0-9]' as numbers above
+ r_token.type = TK_PERIOD;
+ return OK;
+
} else {
_set_error("Unexpected character.");
r_token.type = TK_ERROR;
@@ -1153,6 +1189,7 @@ Error Expression::_get_token(Token &r_token) {
}
}
}
+#undef GET_CHAR
}
r_token.type = TK_ERROR;
@@ -1227,10 +1264,10 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- dn->dict.push_back(expr);
+ dn->dict.push_back(subexpr);
_get_token(tk);
if (tk.type != TK_COLON) {
@@ -1238,11 +1275,11 @@ Expression::ENode *Expression::_parse_expression() {
return NULL;
}
- expr = _parse_expression();
- if (!expr)
+ subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- dn->dict.push_back(expr);
+ dn->dict.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1271,10 +1308,10 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- an->array.push_back(expr);
+ an->array.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1318,25 +1355,25 @@ Expression::ENode *Expression::_parse_expression() {
while (true) {
- int cofs = str_ofs;
+ int cofs2 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
break;
}
- str_ofs = cofs; //revert
+ str_ofs = cofs2; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- func_call->arguments.push_back(expr);
+ func_call->arguments.push_back(subexpr);
- cofs = str_ofs;
+ cofs2 = str_ofs;
_get_token(tk);
if (tk.type == TK_COMMA) {
//all good
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
- str_ofs = cofs;
+ str_ofs = cofs2;
} else {
_set_error("Expected ',' or ')'");
}
@@ -1407,11 +1444,11 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- constructor->arguments.push_back(expr);
+ constructor->arguments.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1448,11 +1485,11 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- bifunc->arguments.push_back(expr);
+ bifunc->arguments.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1547,25 +1584,25 @@ Expression::ENode *Expression::_parse_expression() {
while (true) {
- int cofs = str_ofs;
+ int cofs3 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
break;
}
- str_ofs = cofs; //revert
+ str_ofs = cofs3; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- func_call->arguments.push_back(expr);
+ func_call->arguments.push_back(subexpr);
- cofs = str_ofs;
+ cofs3 = str_ofs;
_get_token(tk);
if (tk.type == TK_COMMA) {
//all good
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
- str_ofs = cofs;
+ str_ofs = cofs3;
} else {
_set_error("Expected ',' or ')'");
}
@@ -1865,7 +1902,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant b;
if (op->nodes[1]) {
- bool ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str);
+ ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str);
if (ret)
return true;
}
@@ -2033,7 +2070,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
for (int i = 0; i < call->arguments.size(); i++) {
Variant value;
- bool ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str);
+ ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str);
if (ret)
return true;
@@ -2083,6 +2120,10 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu
}
Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) {
+ if (error_set) {
+ ERR_EXPLAIN("There was previously a parse error: " + error_str);
+ ERR_FAIL_V(Variant());
+ }
execution_error = false;
Variant output;
@@ -2116,13 +2157,13 @@ void Expression::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_error_text"), &Expression::get_error_text);
}
-Expression::Expression() {
- output_type = Variant::NIL;
- error_set = true;
- root = NULL;
- nodes = NULL;
- sequenced = false;
- execution_error = false;
+Expression::Expression() :
+ output_type(Variant::NIL),
+ sequenced(false),
+ error_set(true),
+ root(NULL),
+ nodes(NULL),
+ execution_error(false) {
}
Expression::~Expression() {
diff --git a/core/math/expression.h b/core/math/expression.h
index 7a7639cf0b..fa0878c93c 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* expression.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef EXPRESSION_H
#define EXPRESSION_H
@@ -86,7 +116,9 @@ private:
Variant::Type type;
String name;
- Input() { type = Variant::NIL; }
+ Input() :
+ type(Variant::NIL) {
+ }
};
Vector<Input> inputs;
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index 801f2a3b4d..ab09142b2d 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "face3.h"
-#include "geometry.h"
+
+#include "core/math/geometry.h"
int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_over[3]) const {
@@ -201,11 +202,12 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const {
{ \
real_t aabb_min = p_aabb.position.m_ax; \
real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \
- real_t tri_min, tri_max; \
- for (int i = 0; i < 3; i++) { \
- if (i == 0 || vertex[i].m_ax > tri_max) \
+ real_t tri_min = vertex[0].m_ax; \
+ real_t tri_max = vertex[0].m_ax; \
+ for (int i = 1; i < 3; i++) { \
+ if (vertex[i].m_ax > tri_max) \
tri_max = vertex[i].m_ax; \
- if (i == 0 || vertex[i].m_ax < tri_min) \
+ if (vertex[i].m_ax < tri_min) \
tri_min = vertex[i].m_ax; \
} \
\
diff --git a/core/math/face3.h b/core/math/face3.h
index faed0fa8d4..184e80ff77 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef FACE3_H
#define FACE3_H
-#include "aabb.h"
-#include "plane.h"
-#include "transform.h"
-#include "vector3.h"
+#include "core/math/aabb.h"
+#include "core/math/plane.h"
+#include "core/math/transform.h"
+#include "core/math/vector3.h"
class Face3 {
public:
@@ -241,13 +241,13 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
real_t minT = 1e20, maxT = -1e20;
for (int k = 0; k < 3; k++) {
- real_t d = axis.dot(vertex[k]);
+ real_t vert_d = axis.dot(vertex[k]);
- if (d > maxT)
- maxT = d;
+ if (vert_d > maxT)
+ maxT = vert_d;
- if (d < minT)
- minT = d;
+ if (vert_d < minT)
+ minT = vert_d;
}
if (maxB < minT || maxT < minB)
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index d8cb657b5e..194a6f6352 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,11 @@
/*************************************************************************/
#include "geometry.h"
-#include "print_string.h"
+#include "core/print_string.h"
+#include "thirdparty/misc/triangulator.h"
+
+/* this implementation is very inefficient, commenting unless bugs happen. See the other one.
bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
Vector<int> indices = Geometry::triangulate_polygon(p_polygon);
@@ -41,6 +44,7 @@ bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2>
}
return false;
}
+*/
void Geometry::MeshData::optimize_vertices() {
@@ -734,6 +738,40 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
return wrapped_faces;
}
+Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) {
+ Vector<Vector<Vector2> > decomp;
+ List<TriangulatorPoly> in_poly, out_poly;
+
+ TriangulatorPoly inp;
+ inp.Init(polygon.size());
+ for (int i = 0; i < polygon.size(); i++) {
+ inp.GetPoint(i) = polygon[i];
+ }
+ inp.SetOrientation(TRIANGULATOR_CCW);
+ in_poly.push_back(inp);
+ TriangulatorPartition tpart;
+ if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
+ ERR_PRINT("Convex decomposing failed!");
+ return decomp;
+ }
+
+ decomp.resize(out_poly.size());
+ int idx = 0;
+ for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
+ TriangulatorPoly &tp = I->get();
+
+ decomp.write[idx].resize(tp.GetNumPoints());
+
+ for (int i = 0; i < tp.GetNumPoints(); i++) {
+ decomp.write[idx].write[i] = tp.GetPoint(i);
+ }
+
+ idx++;
+ }
+
+ return decomp;
+}
+
Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes) {
MeshData mesh;
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 83b9467a30..4b478b6b16 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,14 +31,15 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
-#include "dvector.h"
-#include "face3.h"
-#include "object.h"
-#include "print_string.h"
-#include "rect2.h"
-#include "triangulate.h"
-#include "vector.h"
-#include "vector3.h"
+#include "core/math/face3.h"
+#include "core/math/rect2.h"
+#include "core/math/triangulate.h"
+#include "core/math/vector3.h"
+#include "core/object.h"
+#include "core/pool_vector.h"
+#include "core/print_string.h"
+#include "core/vector.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -513,7 +514,7 @@ public:
return (cn.cross(an) > 0) == orientation;
}
- static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon);
+ //static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon);
static Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 *p_segment) {
@@ -799,6 +800,51 @@ public:
return Vector<Vector<Vector2> >();
}
+ static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
+ int c = p_polygon.size();
+ if (c < 3)
+ return false;
+ const Vector2 *p = p_polygon.ptr();
+ real_t sum = 0;
+ for (int i = 0; i < c; i++) {
+ const Vector2 &v1 = p[i];
+ const Vector2 &v2 = p[(i + 1) % c];
+ sum += (v2.x - v1.x) * (v2.y + v1.y);
+ }
+
+ return sum > 0.0f;
+ }
+
+ /* alternate implementation that should be faster */
+ static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
+ int c = p_polygon.size();
+ if (c < 3)
+ return false;
+ const Vector2 *p = p_polygon.ptr();
+ Vector2 further_away(-1e20, -1e20);
+ Vector2 further_away_opposite(1e20, 1e20);
+
+ for (int i = 0; i < c; i++) {
+ further_away.x = MAX(p[i].x, further_away.x);
+ further_away.y = MAX(p[i].y, further_away.y);
+ further_away_opposite.x = MIN(p[i].x, further_away_opposite.x);
+ further_away_opposite.y = MIN(p[i].y, further_away_opposite.y);
+ }
+
+ further_away += (further_away - further_away_opposite) * Vector2(1.221313, 1.512312); // make point outside that wont intersect with points in segment from p_point
+
+ int intersections = 0;
+ for (int i = 0; i < c; i++) {
+ const Vector2 &v1 = p[i];
+ const Vector2 &v2 = p[(i + 1) % c];
+ if (segment_intersects_segment_2d(v1, v2, p_point, further_away, NULL)) {
+ intersections++;
+ }
+ }
+
+ return (intersections & 1);
+ }
+
static PoolVector<PoolVector<Face3> > separate_objects(PoolVector<Face3> p_array);
static PoolVector<Face3> wrap_geometry(PoolVector<Face3> p_array, real_t *p_error = NULL); ///< create a "wrap" that encloses the given geometry
@@ -904,6 +950,8 @@ public:
return H;
}
+ static Vector<Vector<Vector2> > decompose_polygon_in_convex(Vector<Point2> polygon);
+
static MeshData build_convex_mesh(const PoolVector<Plane> &p_planes);
static PoolVector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
static PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
diff --git a/core/math/math_defs.h b/core/math/math_defs.h
index a5feee6eb5..c54d3cc96f 100644
--- a/core/math/math_defs.h
+++ b/core/math/math_defs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,7 @@
#define CMP_EPSILON 0.00001
#define CMP_EPSILON2 (CMP_EPSILON * CMP_EPSILON)
+
#define CMP_NORMALIZE_TOLERANCE 0.000001
#define CMP_POINT_IN_PLANE_EPSILON 0.00001
@@ -49,6 +50,14 @@
#define MATH_CHECKS
#endif
+//this epsilon is for values related to a unit size (scalar or vector len)
+#ifdef PRECISE_MATH_CHECKS
+#define UNIT_EPSILON 0.00001
+#else
+//tolerate some more floating point error normally
+#define UNIT_EPSILON 0.001
+#endif
+
#define USEC_TO_SEC(m_usec) ((m_usec) / 1000000.0)
enum ClockDirection {
@@ -93,9 +102,9 @@ enum Corner {
};
/**
- * The "Real" type is an abstract type used for real numbers, such as 1.5,
+ * The "Real" type is an abstract type used for real numbers, such as 1.5,
* in contrast to integer numbers. Precision can be controlled with the
- * presence or absence of the REAL_T_IS_DOUBLE define.
+ * presence or absence of the REAL_T_IS_DOUBLE define.
*/
#ifdef REAL_T_IS_DOUBLE
typedef double real_t;
diff --git a/core/helper/math_fieldwise.cpp b/core/math/math_fieldwise.cpp
index ff3f8b3520..f65f504f4c 100644
--- a/core/helper/math_fieldwise.cpp
+++ b/core/math/math_fieldwise.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#ifdef TOOLS_ENABLED
-#include "core/helper/math_fieldwise.h"
+#include "math_fieldwise.h"
#define SETUP_TYPE(m_type) \
m_type source = p_source; \
diff --git a/core/helper/math_fieldwise.h b/core/math/math_fieldwise.h
index 0e7cc3ea4a..c245928f56 100644
--- a/core/helper/math_fieldwise.h
+++ b/core/math/math_fieldwise.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 5c8512d8bd..5b5fd8e283 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,34 +30,31 @@
#include "math_funcs.h"
-#include "core/os/os.h"
-
-pcg32_random_t Math::default_pcg = { 12047754176567800795ULL, PCG_DEFAULT_INC_64 };
+RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC);
#define PHI 0x9e3779b9
-// TODO: we should eventually expose pcg.inc too
uint32_t Math::rand_from_seed(uint64_t *seed) {
- pcg32_random_t pcg = { *seed, PCG_DEFAULT_INC_64 };
- uint32_t r = pcg32_random_r(&pcg);
- *seed = pcg.state;
+ RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC);
+ uint32_t r = rng.rand();
+ *seed = rng.get_seed();
return r;
}
void Math::seed(uint64_t x) {
- default_pcg.state = x;
+ default_rand.seed(x);
}
void Math::randomize() {
- seed(OS::get_singleton()->get_ticks_usec() * default_pcg.state + PCG_DEFAULT_INC_64);
+ default_rand.randomize();
}
uint32_t Math::rand() {
- return pcg32_random_r(&default_pcg);
+ return default_rand.rand();
}
int Math::step_decimals(double p_step) {
- static const int maxn = 9;
+ static const int maxn = 10;
static const double sd[maxn] = {
0.9999, // somehow compensate for floating point error
0.09999,
@@ -67,17 +64,19 @@ int Math::step_decimals(double p_step) {
0.000009999,
0.0000009999,
0.00000009999,
- 0.000000009999
+ 0.000000009999,
+ 0.0000000009999
};
- double as = Math::abs(p_step);
+ double abs = Math::abs(p_step);
+ double decs = abs - (int)abs; // Strip away integer part
for (int i = 0; i < maxn; i++) {
- if (as >= sd[i]) {
+ if (decs >= sd[i]) {
return i;
}
}
- return maxn;
+ return 0;
}
double Math::dectime(double p_value, double p_amount, double p_step) {
@@ -167,13 +166,9 @@ uint32_t Math::larger_prime(uint32_t p_val) {
}
double Math::random(double from, double to) {
- unsigned int r = Math::rand();
- double ret = (double)r / (double)RANDOM_MAX;
- return (ret) * (to - from) + from;
+ return default_rand.random(from, to);
}
float Math::random(float from, float to) {
- unsigned int r = Math::rand();
- float ret = (float)r / (float)RANDOM_MAX;
- return (ret) * (to - from) + from;
+ return default_rand.random(from, to);
}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 992084a653..17112d8940 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,9 @@
#ifndef MATH_FUNCS_H
#define MATH_FUNCS_H
-#include "math_defs.h"
-#include "typedefs.h"
+#include "core/math/math_defs.h"
+#include "core/math/random_pcg.h"
+#include "core/typedefs.h"
#include "thirdparty/misc/pcg.h"
@@ -41,12 +42,12 @@
class Math {
- static pcg32_random_t default_pcg;
+ static RandomPCG default_rand;
public:
Math() {} // useless to instance
- static const uint64_t RANDOM_MAX = 4294967295;
+ static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); }
static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); }
@@ -216,17 +217,17 @@ public:
static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
- static _ALWAYS_INLINE_ int wrapi(int value, int min, int max) {
- int rng = max - min;
- return min + ((((value - min) % rng) + rng) % rng);
+ static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
+ int64_t rng = max - min;
+ return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min;
}
static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) {
double rng = max - min;
- return value - (rng * Math::floor((value - min) / rng));
+ return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min;
}
static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) {
float rng = max - min;
- return value - (rng * Math::floor((value - min) / rng));
+ return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min;
}
// double only, as these functions are mainly used by the editor and not performance-critical,
@@ -241,20 +242,32 @@ public:
static void randomize();
static uint32_t rand_from_seed(uint64_t *seed);
static uint32_t rand();
- static _ALWAYS_INLINE_ double randf() { return (double)rand() / (double)Math::RANDOM_MAX; }
- static _ALWAYS_INLINE_ float randd() { return (float)rand() / (float)Math::RANDOM_MAX; }
+ static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_MAX; }
+ static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_MAX; }
static double random(double from, double to);
static float random(float from, float to);
static real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); }
- static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) {
+ static _ALWAYS_INLINE_ bool is_equal_approx_ratio(real_t a, real_t b, real_t epsilon = CMP_EPSILON) {
+ // this is an approximate way to check that numbers are close, as a ratio of their average size
+ // helps compare approximate numbers that may be very big or very small
+ real_t diff = abs(a - b);
+ if (diff == 0.0) {
+ return true;
+ }
+ real_t avg_size = (abs(a) + abs(b)) / 2.0;
+ diff /= avg_size;
+ return diff < epsilon;
+ }
+
+ static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b, real_t epsilon = CMP_EPSILON) {
// TODO: Comparing floats for approximate-equality is non-trivial.
// Using epsilon should cover the typical cases in Godot (where a == b is used to compare two reals), such as matrix and vector comparison operators.
// A proper implementation in terms of ULPs should eventually replace the contents of this function.
// See https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ for details.
- return abs(a - b) < CMP_EPSILON;
+ return abs(a - b) < epsilon;
}
static _ALWAYS_INLINE_ float absf(float g) {
@@ -305,16 +318,6 @@ public:
return b;
}
-#if defined(__GNUC__)
-
- static _ALWAYS_INLINE_ int64_t dtoll(double p_double) { return (int64_t)p_double; } ///@TODO OPTIMIZE
- static _ALWAYS_INLINE_ int64_t dtoll(float p_float) { return (int64_t)p_float; } ///@TODO OPTIMIZE and rename
-#else
-
- static _ALWAYS_INLINE_ int64_t dtoll(double p_double) { return (int64_t)p_double; } ///@TODO OPTIMIZE
- static _ALWAYS_INLINE_ int64_t dtoll(float p_float) { return (int64_t)p_float; } ///@TODO OPTIMIZE and rename
-#endif
-
static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) {
uint16_t h_exp, h_sig;
uint32_t f_sgn, f_exp, f_sig;
diff --git a/core/math/octree.h b/core/math/octree.h
index 4e3d6257f0..d6fc9776bc 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,12 @@
#ifndef OCTREE_H
#define OCTREE_H
-#include "aabb.h"
-#include "list.h"
-#include "map.h"
-#include "print_string.h"
-#include "variant.h"
-#include "vector3.h"
+#include "core/list.h"
+#include "core/map.h"
+#include "core/math/aabb.h"
+#include "core/math/vector3.h"
+#include "core/print_string.h"
+#include "core/variant.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -478,7 +478,7 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
splits++;
}
} else {
- /* check againt AABB where child should be */
+ /* check against AABB where child should be */
AABB aabb = p_octant->aabb;
aabb.size *= 0.5;
@@ -916,34 +916,34 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
pass++;
- for (typename List<typename Element::OctantOwner, AL>::Element *E = owners.front(); E;) {
+ for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F;) {
- Octant *o = E->get().octant;
- typename List<typename Element::OctantOwner, AL>::Element *N = E->next();
+ Octant *o = F->get().octant;
+ typename List<typename Element::OctantOwner, AL>::Element *N = F->next();
/*
if (!use_pairs)
- o->elements.erase( E->get().E );
+ o->elements.erase( F->get().E );
*/
if (use_pairs && e.pairable)
- o->pairable_elements.erase(E->get().E);
+ o->pairable_elements.erase(F->get().E);
else
- o->elements.erase(E->get().E);
+ o->elements.erase(F->get().E);
if (_remove_element_from_octant(&e, o, common_parent->parent)) {
- owners.erase(E);
+ owners.erase(F);
}
- E = N;
+ F = N;
}
if (use_pairs) {
//unpair child elements in anything that survived
- for (typename List<typename Element::OctantOwner, AL>::Element *E = owners.front(); E; E = E->next()) {
+ for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F; F = F->next()) {
- Octant *o = E->get().octant;
+ Octant *o = F->get().octant;
// erase children pairs, unref ONCE
pass++;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index 78bb1771a4..cd3cbce300 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "plane.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#define _PLANE_EQ_DOT_EPSILON 0.999
#define _PLANE_EQ_D_EPSILON 0.0001
diff --git a/core/math/plane.h b/core/math/plane.h
index e567422dd0..1c6e4b816b 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef PLANE_H
#define PLANE_H
-#include "vector3.h"
+#include "core/math/vector3.h"
class Plane {
public:
@@ -74,10 +74,11 @@ public:
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
operator String() const;
- _FORCE_INLINE_ Plane() { d = 0; }
+ _FORCE_INLINE_ Plane() :
+ d(0) {}
_FORCE_INLINE_ Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) :
normal(p_a, p_b, p_c),
- d(p_d){};
+ d(p_d) {}
_FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d);
_FORCE_INLINE_ Plane(const Vector3 &p_point, const Vector3 &p_normal);
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 2251571146..1a67be7384 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "quat.h"
-#include "matrix3.h"
-#include "print_string.h"
+
+#include "core/math/basis.h"
+#include "core/print_string.h"
// set_euler_xyz expects a vector containing the Euler angles in the format
// (ax,ay,az), where ax is the angle of rotation around x axis,
@@ -99,7 +100,7 @@ void Quat::set_euler_yxz(const Vector3 &p_euler) {
// This implementation uses YXZ convention (Z is the first rotation).
Vector3 Quat::get_euler_yxz() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Vector3(0, 0, 0));
+ ERR_FAIL_COND_V(!is_normalized(), Vector3(0, 0, 0));
#endif
Basis m(*this);
return m.get_euler_yxz();
@@ -134,20 +135,20 @@ Quat Quat::normalized() const {
}
bool Quat::is_normalized() const {
- return Math::is_equal_approx(length_squared(), 1.0);
+ return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON); //use less epsilon
}
Quat Quat::inverse() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
#endif
return Quat(-x, -y, -z, w);
}
Quat Quat::slerp(const Quat &q, const real_t &t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
- ERR_FAIL_COND_V(q.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
+ ERR_FAIL_COND_V(!q.is_normalized(), Quat());
#endif
Quat to1;
real_t omega, cosom, sinom, scale0, scale1;
@@ -193,8 +194,8 @@ Quat Quat::slerp(const Quat &q, const real_t &t) const {
Quat Quat::slerpni(const Quat &q, const real_t &t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
- ERR_FAIL_COND_V(q.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
+ ERR_FAIL_COND_V(!q.is_normalized(), Quat());
#endif
const Quat &from = *this;
@@ -215,8 +216,8 @@ Quat Quat::slerpni(const Quat &q, const real_t &t) const {
Quat Quat::cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const real_t &t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
- ERR_FAIL_COND_V(q.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
+ ERR_FAIL_COND_V(!q.is_normalized(), Quat());
#endif
//the only way to do slerp :|
real_t t2 = (1.0 - t) * t * 2;
@@ -232,7 +233,7 @@ Quat::operator String() const {
void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) {
#ifdef MATH_CHECKS
- ERR_FAIL_COND(axis.is_normalized() == false);
+ ERR_FAIL_COND(!axis.is_normalized());
#endif
real_t d = axis.length();
if (d == 0)
diff --git a/core/math/quat.h b/core/math/quat.h
index 6dc8d66f60..7d71ec03e8 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,18 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vector3.h"
+// Circular dependency between Vector3 and Basis :/
+#include "core/math/vector3.h"
#ifndef QUAT_H
#define QUAT_H
-#include "math_defs.h"
-#include "math_funcs.h"
-#include "ustring.h"
+#include "core/math/math_defs.h"
+#include "core/math/math_funcs.h"
+#include "core/ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
class Quat {
public:
real_t x, y, z, w;
@@ -85,7 +87,7 @@ public:
_FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, v);
+ ERR_FAIL_COND_V(!is_normalized(), v);
#endif
Vector3 u(x, y, z);
Vector3 uv = u.cross(v);
@@ -113,20 +115,20 @@ public:
z = p_z;
w = p_w;
}
- inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
- x = p_x;
- y = p_y;
- z = p_z;
- w = p_w;
+ inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) :
+ x(p_x),
+ y(p_y),
+ z(p_z),
+ w(p_w) {
}
Quat(const Vector3 &axis, const real_t &angle) { set_axis_angle(axis, angle); }
Quat(const Vector3 &euler) { set_euler(euler); }
- Quat(const Quat &q) {
- x = q.x;
- y = q.y;
- z = q.z;
- w = q.w;
+ Quat(const Quat &q) :
+ x(q.x),
+ y(q.y),
+ z(q.z),
+ w(q.w) {
}
Quat(const Vector3 &v0, const Vector3 &v1) // shortest arc
@@ -151,9 +153,11 @@ public:
}
}
- inline Quat() {
- x = y = z = 0;
- w = 1;
+ inline Quat() :
+ x(0),
+ y(0),
+ z(0),
+ w(1) {
}
};
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 9d4f4f66b7..fc2eb1454d 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,14 +29,13 @@
/*************************************************************************/
#include "quick_hull.h"
-#include "map.h"
+
+#include "core/map.h"
uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF;
Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
- static const real_t over_tolerance = 0.0001;
-
/* CREATE AABB VOLUME */
AABB aabb;
@@ -179,6 +178,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
faces.push_back(f);
}
+ real_t over_tolerance = 3 * UNIT_EPSILON * (aabb.size.x + aabb.size.y + aabb.size.z);
+
/* COMPUTE AVAILABLE VERTICES */
for (int i = 0; i < p_points.size(); i++) {
@@ -437,12 +438,12 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
}
// remove all edge connections to this face
- for (Map<Edge, RetFaceConnect>::Element *E = ret_edges.front(); E; E = E->next()) {
- if (E->get().left == O)
- E->get().left = NULL;
+ for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) {
+ if (G->get().left == O)
+ G->get().left = NULL;
- if (E->get().right == O)
- E->get().right = NULL;
+ if (G->get().right == O)
+ G->get().right = NULL;
}
ret_edges.erase(F); //remove the edge
diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h
index eef4a9adff..a445a47cbe 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef QUICK_HULL_H
#define QUICK_HULL_H
-#include "aabb.h"
-#include "geometry.h"
-#include "list.h"
-#include "set.h"
+#include "core/list.h"
+#include "core/math/aabb.h"
+#include "core/math/geometry.h"
+#include "core/set.h"
class QuickHull {
@@ -64,7 +64,7 @@ public:
struct Face {
Plane plane;
- int vertices[3];
+ uint32_t vertices[3];
Vector<int> points_over;
bool operator<(const Face &p_face) const {
diff --git a/core/helper/value_evaluator.h b/core/math/random_number_generator.cpp
index 39177a7820..fccc0f72fe 100644
--- a/core/helper/value_evaluator.h
+++ b/core/math/random_number_generator.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* value_evaluator.h */
+/* random_number_generator.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,19 +28,19 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VALUE_EVALUATOR_H
-#define VALUE_EVALUATOR_H
+#include "random_number_generator.h"
-#include "core/object.h"
+RandomNumberGenerator::RandomNumberGenerator() :
+ randbase() {}
-class ValueEvaluator : public Object {
+void RandomNumberGenerator::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed);
+ ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
- GDCLASS(ValueEvaluator, Object);
-
-public:
- virtual double eval(const String &p_text) {
- return p_text.to_double();
- }
-};
-
-#endif // VALUE_EVALUATOR_H
+ ClassDB::bind_method(D_METHOD("randi"), &RandomNumberGenerator::randi);
+ ClassDB::bind_method(D_METHOD("randf"), &RandomNumberGenerator::randf);
+ ClassDB::bind_method(D_METHOD("randf_range", "from", "to"), &RandomNumberGenerator::randf_range);
+ ClassDB::bind_method(D_METHOD("randi_range", "from", "to"), &RandomNumberGenerator::randi_range);
+ ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize);
+}
diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h
new file mode 100644
index 0000000000..66c77b8ccf
--- /dev/null
+++ b/core/math/random_number_generator.h
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* random_number_generator.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RANDOM_NUMBER_GENERATOR_H
+#define RANDOM_NUMBER_GENERATOR_H
+
+#include "core/math/random_pcg.h"
+#include "core/reference.h"
+
+class RandomNumberGenerator : public Reference {
+ GDCLASS(RandomNumberGenerator, Reference);
+
+ RandomPCG randbase;
+
+protected:
+ static void _bind_methods();
+
+public:
+ _FORCE_INLINE_ void set_seed(uint64_t seed) { randbase.seed(seed); }
+
+ _FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); }
+
+ _FORCE_INLINE_ void randomize() { return randbase.randomize(); }
+
+ _FORCE_INLINE_ uint32_t randi() { return randbase.rand(); }
+
+ _FORCE_INLINE_ real_t randf() { return randbase.randf(); }
+
+ _FORCE_INLINE_ real_t randf_range(real_t from, real_t to) { return randbase.random(from, to); }
+
+ _FORCE_INLINE_ int randi_range(int from, int to) {
+ unsigned int ret = randbase.rand();
+ return ret % (to - from + 1) + from;
+ }
+
+ RandomNumberGenerator();
+};
+
+#endif // RANDOM_NUMBER_GENERATOR_H
diff --git a/core/os/shell.h b/core/math/random_pcg.cpp
index d3d92028ea..8c324414e6 100644
--- a/core/os/shell.h
+++ b/core/math/random_pcg.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* shell.h */
+/* random_pcg.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,25 +28,28 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SHELL_H
-#define SHELL_H
+#include "random_pcg.h"
-#include "typedefs.h"
-#include "ustring.h"
+#include "core/os/os.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class Shell {
+RandomPCG::RandomPCG(uint64_t p_seed, uint64_t p_inc) :
+ pcg() {
+ pcg.inc = p_inc;
+ seed(p_seed);
+}
- static Shell *singleton;
+void RandomPCG::randomize() {
+ seed(OS::get_singleton()->get_ticks_usec() * pcg.state + PCG_DEFAULT_INC_64);
+}
-public:
- static Shell *get_singleton();
- virtual void execute(String p_path) = 0;
+double RandomPCG::random(double p_from, double p_to) {
+ unsigned int r = rand();
+ double ret = (double)r / (double)RANDOM_MAX;
+ return (ret) * (p_to - p_from) + p_from;
+}
- Shell();
- virtual ~Shell();
-};
-
-#endif
+float RandomPCG::random(float p_from, float p_to) {
+ unsigned int r = rand();
+ float ret = (float)r / (float)RANDOM_MAX;
+ return (ret) * (p_to - p_from) + p_from;
+}
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
new file mode 100644
index 0000000000..f6cc3db595
--- /dev/null
+++ b/core/math/random_pcg.h
@@ -0,0 +1,69 @@
+/*************************************************************************/
+/* random_pcg.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RANDOM_PCG_H
+#define RANDOM_PCG_H
+
+#include "core/math/math_defs.h"
+
+#include "thirdparty/misc/pcg.h"
+
+class RandomPCG {
+ pcg32_random_t pcg;
+ uint64_t current_seed = DEFAULT_SEED; // seed with this to get the same state
+
+public:
+ static const uint64_t DEFAULT_SEED = 12047754176567800795U;
+ static const uint64_t DEFAULT_INC = PCG_DEFAULT_INC_64;
+ static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
+
+ RandomPCG(uint64_t p_seed = DEFAULT_SEED, uint64_t p_inc = PCG_DEFAULT_INC_64);
+
+ _FORCE_INLINE_ void seed(uint64_t p_seed) {
+ current_seed = p_seed;
+ pcg.state = p_seed;
+ pcg32_random_r(&pcg); // Force changing internal state to avoid initial 0
+ }
+ _FORCE_INLINE_ uint64_t get_seed() { return current_seed; }
+
+ void randomize();
+ _FORCE_INLINE_ uint32_t rand() {
+ current_seed = pcg.state;
+ return pcg32_random_r(&pcg);
+ }
+ _FORCE_INLINE_ double randd() { return (double)rand() / (double)RANDOM_MAX; }
+ _FORCE_INLINE_ float randf() { return (float)rand() / (float)RANDOM_MAX; }
+
+ double random(double p_from, double p_to);
+ float random(float p_from, float p_to);
+ real_t random(int p_from, int p_to) { return (real_t)random((real_t)p_from, (real_t)p_to); }
+};
+
+#endif // RANDOM_PCG_H
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index 480bccdff1..fea128afbd 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
+#include "core/math/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 20329bee0d..901d372132 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef RECT2_H
#define RECT2_H
-#include "vector2.h" // also includes math_funcs and ustring
+#include "core/math/vector2.h" // also includes math_funcs and ustring
struct Transform2D;
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 976e0f174e..7ff7cac914 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "transform.h"
-#include "math_funcs.h"
-#include "os/copymem.h"
-#include "print_string.h"
+
+#include "core/math/math_funcs.h"
+#include "core/os/copymem.h"
+#include "core/print_string.h"
void Transform::affine_invert() {
diff --git a/core/math/transform.h b/core/math/transform.h
index c06eaec604..2f43f6b035 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,14 @@
#ifndef TRANSFORM_H
#define TRANSFORM_H
-#include "aabb.h"
-#include "matrix3.h"
-#include "plane.h"
+#include "core/math/aabb.h"
+#include "core/math/basis.h"
+#include "core/math/plane.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
class Transform {
public:
Basis basis;
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 4bb763c879..7d00158f3d 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,13 +80,14 @@ real_t Transform2D::get_rotation() const {
}
void Transform2D::set_rotation(real_t p_rot) {
-
+ Size2 scale = get_scale();
real_t cr = Math::cos(p_rot);
real_t sr = Math::sin(p_rot);
elements[0][0] = cr;
elements[0][1] = sr;
elements[1][0] = -sr;
elements[1][1] = cr;
+ set_scale(scale);
}
Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
@@ -101,10 +102,17 @@ Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
}
Size2 Transform2D::get_scale() const {
- real_t det_sign = basis_determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(basis_determinant());
return Size2(elements[0].length(), det_sign * elements[1].length());
}
+void Transform2D::set_scale(Size2 &p_scale) {
+ elements[0].normalize();
+ elements[1].normalize();
+ elements[0] *= p_scale.x;
+ elements[1] *= p_scale.y;
+}
+
void Transform2D::scale(const Size2 &p_scale) {
scale_basis(p_scale);
elements[2] *= p_scale;
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index bf73755f0d..b9e7a36fb3 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef TRANSFORM_2D_H
#define TRANSFORM_2D_H
-#include "rect2.h" // also includes vector2, math_funcs, and ustring
+#include "core/math/rect2.h" // also includes vector2, math_funcs, and ustring
struct Transform2D {
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper":
@@ -81,6 +81,7 @@ struct Transform2D {
real_t basis_determinant() const;
Size2 get_scale() const;
+ void set_scale(Size2 &p_scale);
_FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; }
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; }
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 5475f733c3..83784a1fa7 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "triangle_mesh.h"
-#include "sort.h"
+
+#include "core/sort_array.h"
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index bf793fc50f..ee7bf0f6b5 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,9 @@
#ifndef TRIANGLE_MESH_H
#define TRIANGLE_MESH_H
-#include "face3.h"
-#include "reference.h"
+#include "core/math/face3.h"
+#include "core/reference.h"
+
class TriangleMesh : public Reference {
GDCLASS(TriangleMesh, Reference);
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index 0edc0ea039..be409e62a7 100644
--- a/core/math/triangulate.cpp
+++ b/core/math/triangulate.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -186,7 +186,7 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
nv--;
- /* resest error detection counter */
+ /* reset error detection counter */
count = 2 * nv;
}
}
diff --git a/core/math/triangulate.h b/core/math/triangulate.h
index a0f56f5f27..2437e2b0f0 100644
--- a/core/math/triangulate.h
+++ b/core/math/triangulate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef TRIANGULATE_H
#define TRIANGULATE_H
-#include "vector2.h"
+#include "core/math/vector2.h"
/*
http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 84c9f0fca6..5c1ea5943d 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,7 +65,7 @@ Vector2 Vector2::normalized() const {
bool Vector2::is_normalized() const {
// use length_squared() instead of length() to avoid sqrt(), makes it more stringent.
- return Math::is_equal_approx(length_squared(), 1.0);
+ return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON);
}
real_t Vector2::distance_to(const Vector2 &p_vector2) const {
@@ -167,7 +167,7 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
// slide returns the component of the vector along the given plane, specified by its normal vector.
Vector2 Vector2::slide(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector2());
#endif
return *this - p_normal * this->dot(p_normal);
}
@@ -178,7 +178,7 @@ Vector2 Vector2::bounce(const Vector2 &p_normal) const {
Vector2 Vector2::reflect(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector2());
#endif
return 2.0 * p_normal * this->dot(p_normal) - *this;
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index fbcdc80b60..a20326f667 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef VECTOR2_H
#define VECTOR2_H
-#include "math_funcs.h"
-#include "ustring.h"
+#include "core/math/math_funcs.h"
+#include "core/ustring.h"
struct Vector2i;
@@ -230,7 +230,7 @@ Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const {
Vector2 Vector2::slerp(const Vector2 &p_b, real_t p_t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(!is_normalized(), Vector2());
#endif
real_t theta = angle_to(p_b);
return rotated(theta * p_t);
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 78d52d5cd1..1c28934422 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "vector3.h"
-#include "matrix3.h"
+
+#include "core/math/basis.h"
void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) {
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 5f0e8919ff..b11838d16e 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef VECTOR3_H
#define VECTOR3_H
-#include "math_defs.h"
-#include "math_funcs.h"
-#include "typedefs.h"
-#include "ustring.h"
+#include "core/math/math_defs.h"
+#include "core/math/math_funcs.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
class Basis;
@@ -150,13 +150,8 @@ struct Vector3 {
}
};
-#ifdef VECTOR3_IMPL_OVERRIDE
-
-#include "vector3_inline.h"
-
-#else
-
-#include "matrix3.h"
+// Should be included after class definition, otherwise we get circular refs
+#include "core/math/basis.h"
Vector3 Vector3::cross(const Vector3 &p_b) const {
@@ -223,7 +218,7 @@ Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const {
Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(!is_normalized(), Vector3());
#endif
real_t theta = angle_to(p_b);
@@ -419,7 +414,7 @@ Vector3 Vector3::normalized() const {
bool Vector3::is_normalized() const {
// use length_squared() instead of length() to avoid sqrt(), makes it more stringent.
- return Math::is_equal_approx(length_squared(), 1.0);
+ return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON);
}
Vector3 Vector3::inverse() const {
@@ -435,7 +430,7 @@ void Vector3::zero() {
// slide returns the component of the vector along the given plane, specified by its normal vector.
Vector3 Vector3::slide(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector3());
#endif
return *this - p_normal * this->dot(p_normal);
}
@@ -446,11 +441,9 @@ Vector3 Vector3::bounce(const Vector3 &p_normal) const {
Vector3 Vector3::reflect(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector3());
#endif
return 2.0 * p_normal * this->dot(p_normal) - *this;
}
-#endif
-
#endif // VECTOR3_H
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index 97ee236a46..c57bd4081c 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,8 @@
#include "message_queue.h"
-#include "project_settings.h"
-#include "script_language.h"
+#include "core/project_settings.h"
+#include "core/script_language.h"
MessageQueue *MessageQueue::singleton = NULL;
@@ -209,9 +209,9 @@ void MessageQueue::statistics() {
} break;
}
+ } else {
//object was deleted
print_line("Object was deleted while awaiting a callback");
- } else {
null_count++;
}
@@ -271,6 +271,9 @@ void MessageQueue::flush() {
//using reverse locking strategy
_THREAD_SAFE_LOCK_
+ ERR_FAIL_COND(flushing); //already flushing, you did something odd
+ flushing = true;
+
while (read_pos < buffer_end) {
//lock on each iteration, so a call can re-add itself to the message queue
@@ -327,17 +330,25 @@ void MessageQueue::flush() {
}
buffer_end = 0; // reset buffer
+ flushing = false;
_THREAD_SAFE_UNLOCK_
}
+bool MessageQueue::is_flushing() const {
+
+ return flushing;
+}
+
MessageQueue::MessageQueue() {
ERR_FAIL_COND(singleton != NULL);
singleton = this;
+ flushing = false;
buffer_end = 0;
buffer_max_used = 0;
buffer_size = GLOBAL_DEF_RST("memory/limits/message_queue/max_size_kb", DEFAULT_QUEUE_SIZE_KB);
+ ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/message_queue/max_size_kb", PropertyInfo(Variant::INT, "memory/limits/message_queue/max_size_kb", PROPERTY_HINT_RANGE, "0,2048,1,or_greater"));
buffer_size *= 1024;
buffer = memnew_arr(uint8_t, buffer_size);
}
diff --git a/core/message_queue.h b/core/message_queue.h
index be5ffe4fae..2515eb4a98 100644
--- a/core/message_queue.h
+++ b/core/message_queue.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,8 @@
#ifndef MESSAGE_QUEUE_H
#define MESSAGE_QUEUE_H
-#include "object.h"
-#include "os/mutex.h"
-#include "os/thread_safe.h"
+#include "core/object.h"
+#include "core/os/thread_safe.h"
class MessageQueue {
@@ -44,8 +43,6 @@ class MessageQueue {
DEFAULT_QUEUE_SIZE_KB = 1024
};
- Mutex *mutex;
-
enum {
TYPE_CALL,
TYPE_NOTIFICATION,
@@ -75,6 +72,8 @@ class MessageQueue {
static MessageQueue *singleton;
+ bool flushing;
+
public:
static MessageQueue *get_singleton();
@@ -90,6 +89,8 @@ public:
void statistics();
void flush();
+ bool is_flushing() const;
+
int get_max_buffer_usage() const;
MessageQueue();
diff --git a/core/method_bind.cpp b/core/method_bind.cpp
index 52ee9e0848..72b0030ce8 100644
--- a/core/method_bind.cpp
+++ b/core/method_bind.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
// object.h needs to be the first include *before* method_bind.h
// FIXME: Find out why and fix potential cyclical dependencies.
-#include "object.h"
+#include "core/object.h"
#include "method_bind.h"
diff --git a/core/method_bind.h b/core/method_bind.h
index 7ee687ee40..5ea8adb7e0 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,11 @@
#ifndef METHOD_BIND_H
#define METHOD_BIND_H
-#include "list.h"
-#include "method_ptrcall.h"
-#include "object.h"
-#include "variant.h"
+#include "core/list.h"
+#include "core/method_ptrcall.h"
+#include "core/object.h"
+#include "core/variant.h"
+
#include <stdio.h>
/**
@@ -45,7 +46,7 @@
#define DEBUG_METHODS_ENABLED
#endif
-#include "type_info.h"
+#include "core/type_info.h"
enum MethodFlags {
diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h
index 6a33cf4d70..e06081d24a 100644
--- a/core/method_ptrcall.h
+++ b/core/method_ptrcall.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,9 @@
#ifndef METHOD_PTRCALL_H
#define METHOD_PTRCALL_H
-#include "transform_2d.h"
-#include "typedefs.h"
-#include "variant.h"
+#include "core/math/transform_2d.h"
+#include "core/typedefs.h"
+#include "core/variant.h"
#ifdef PTRCALL_ENABLED
diff --git a/core/node_path.cpp b/core/node_path.cpp
index 7d4116fa1e..07ff765516 100644
--- a/core/node_path.cpp
+++ b/core/node_path.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "node_path.h"
-#include "print_string.h"
+#include "core/print_string.h"
void NodePath::_update_hash_cache() const {
@@ -276,7 +276,7 @@ NodePath NodePath::get_as_property_path() const {
String initial_subname = data->path[0];
- for (size_t i = 1; i < data->path.size(); i++) {
+ for (int i = 1; i < data->path.size(); i++) {
initial_subname += "/" + data->path[i];
}
new_path.insert(0, initial_subname);
diff --git a/core/node_path.h b/core/node_path.h
index 71235029af..24725123d6 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,9 @@
#ifndef NODE_PATH_H
#define NODE_PATH_H
-#include "string_db.h"
-#include "ustring.h"
+#include "core/string_name.h"
+#include "core/ustring.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
diff --git a/core/oa_hash_map.h b/core/oa_hash_map.h
index 3a17fc21f3..e52d36a859 100644
--- a/core/oa_hash_map.h
+++ b/core/oa_hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef OA_HASH_MAP_H
#define OA_HASH_MAP_H
-#include "hashfuncs.h"
-#include "math_funcs.h"
-#include "os/copymem.h"
-#include "os/memory.h"
+#include "core/hashfuncs.h"
+#include "core/math/math_funcs.h"
+#include "core/os/copymem.h"
+#include "core/os/memory.h"
/**
* A HashMap implementation that uses open addressing with robinhood hashing.
@@ -125,7 +125,7 @@ private:
while (42) {
if (hashes[pos] == EMPTY_HASH) {
- _construct(pos, hash, p_key, p_value);
+ _construct(pos, hash, key, value);
return;
}
@@ -136,7 +136,7 @@ private:
if (hashes[pos] & DELETED_HASH_BIT) {
// we found a place where we can fit in!
- _construct(pos, hash, p_key, p_value);
+ _construct(pos, hash, key, value);
return;
}
@@ -166,7 +166,7 @@ private:
values = memnew_arr(TValue, capacity);
hashes = memnew_arr(uint32_t, capacity);
- for (int i = 0; i < capacity; i++) {
+ for (uint32_t i = 0; i < capacity; i++) {
hashes[i] = 0;
}
@@ -311,7 +311,7 @@ public:
values = memnew_arr(TValue, p_initial_capacity);
hashes = memnew_arr(uint32_t, p_initial_capacity);
- for (int i = 0; i < p_initial_capacity; i++) {
+ for (uint32_t i = 0; i < p_initial_capacity; i++) {
hashes[i] = 0;
}
}
diff --git a/core/object.cpp b/core/object.cpp
index 24a31930a0..8b693f039c 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,14 +30,14 @@
#include "object.h"
-#include "class_db.h"
-#include "core_string_names.h"
-#include "message_queue.h"
-#include "os/os.h"
-#include "print_string.h"
-#include "resource.h"
-#include "script_language.h"
-#include "translation.h"
+#include "core/class_db.h"
+#include "core/core_string_names.h"
+#include "core/message_queue.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
+#include "core/resource.h"
+#include "core/script_language.h"
+#include "core/translation.h"
#ifdef DEBUG_ENABLED
@@ -277,8 +277,8 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
return_val(p_ret),
+ flags(METHOD_FLAG_NORMAL),
id(0) {
}
@@ -440,16 +440,6 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
if (r_valid)
*r_valid = true;
return;
-#ifdef TOOLS_ENABLED
- } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) {
- Array arr = p_value;
- for (int i = 0; i < arr.size(); i++) {
- editor_section_folding.insert(arr[i]);
- }
- if (r_valid)
- *r_valid = true;
- return;
-#endif
}
//something inside the object... :|
@@ -520,16 +510,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
if (r_valid)
*r_valid = true;
return ret;
-#ifdef TOOLS_ENABLED
- } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) {
- Array array;
- for (Set<String>::Element *E = editor_section_folding.front(); E; E = E->next()) {
- array.push_back(E->get());
- }
- if (r_valid)
- *r_valid = true;
- return array;
-#endif
+
} else {
//something inside the object... :|
bool success = _getv(p_name, ret);
@@ -655,15 +636,11 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
#ifdef TOOLS_ENABLED
p_list->push_back(PropertyInfo(Variant::NIL, "Script", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
#endif
- p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NONZERO));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT));
}
-#ifdef TOOLS_ENABLED
- if (editor_section_folding.size()) {
- p_list->push_back(PropertyInfo(Variant::ARRAY, CoreStringNames::get_singleton()->_sections_unfolded, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ if (!metadata.empty()) {
+ p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
-#endif
- if (!metadata.empty())
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_STORE_IF_NONZERO));
if (script_instance && !p_reversed) {
p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
script_instance->get_property_list(p_list);
@@ -726,40 +703,38 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Vari
}
#ifdef DEBUG_ENABLED
-static bool _test_call_error(const StringName &p_func, const Variant::CallError &error) {
+static void _test_call_error(const StringName &p_func, const Variant::CallError &error) {
switch (error.error) {
case Variant::CallError::CALL_OK:
- return true;
case Variant::CallError::CALL_ERROR_INVALID_METHOD:
- return false;
+ break;
case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected));
- ERR_FAIL_V(true);
- } break;
+ ERR_FAIL();
+ break;
+ }
case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument));
- ERR_FAIL_V(true);
-
- } break;
+ ERR_FAIL();
+ break;
+ }
case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument));
- ERR_FAIL_V(true);
-
- } break;
- case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
- } //?
+ ERR_FAIL();
+ break;
+ }
+ case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL:
+ break;
}
-
- return true;
}
#else
-#define _test_call_error(m_str, m_err) ((m_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) ? false : true)
+#define _test_call_error(m_str, m_err)
#endif
@@ -857,23 +832,22 @@ void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid)
}
Variant Object::callv(const StringName &p_method, const Array &p_args) {
+ const Variant **argptrs = NULL;
- if (p_args.size() == 0) {
- return call(p_method);
- }
-
- Vector<Variant> args;
- args.resize(p_args.size());
- Vector<const Variant *> argptrs;
- argptrs.resize(p_args.size());
-
- for (int i = 0; i < p_args.size(); i++) {
- args.write[i] = p_args[i];
- argptrs.write[i] = &args[i];
+ if (p_args.size() > 0) {
+ argptrs = (const Variant **)alloca(sizeof(Variant *) * p_args.size());
+ for (int i = 0; i < p_args.size(); i++) {
+ argptrs[i] = &p_args[i];
+ }
}
Variant::CallError ce;
- return call(p_method, (const Variant **)argptrs.ptr(), p_args.size(), ce);
+ Variant ret = call(p_method, argptrs, p_args.size(), ce);
+ if (ce.error != Variant::CallError::CALL_OK) {
+ ERR_EXPLAIN("Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce));
+ ERR_FAIL_V(Variant());
+ }
+ return ret;
}
Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
@@ -1039,7 +1013,7 @@ void Object::set_script(const RefPtr &p_script) {
}
}
- _change_notify("script");
+ _change_notify(); //scripts may add variables, so refresh is desired
emit_signal(CoreStringNames::get_singleton()->script_changed);
}
@@ -1254,7 +1228,10 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
target->call(c.method, args, argc, ce);
if (ce.error != Variant::CallError::CALL_OK) {
-
+#ifdef DEBUG_ENABLED
+ if (c.flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool()))
+ continue;
+#endif
if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
//most likely object is not initialized yet, do not throw error.
} else {
@@ -1267,7 +1244,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
bool disconnect = c.flags & CONNECT_ONESHOT;
#ifdef TOOLS_ENABLED
if (disconnect && (c.flags & CONNECT_PERSIST) && Engine::get_singleton()->is_editor_hint()) {
- //this signal was connected from the editor, and is being edited. just dont disconnect for now
+ //this signal was connected from the editor, and is being edited. just don't disconnect for now
disconnect = false;
}
#endif
@@ -1463,8 +1440,20 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
//check in script
- if (!signal_is_valid && !script.is_null() && Ref<Script>(script)->has_script_signal(p_signal))
- signal_is_valid = true;
+ if (!signal_is_valid && !script.is_null()) {
+
+ if (Ref<Script>(script)->has_script_signal(p_signal)) {
+ signal_is_valid = true;
+ }
+#ifdef TOOLS_ENABLED
+ else {
+ //allow connecting signals anyway if script is invalid, see issue #17070
+ if (!Ref<Script>(script)->is_valid()) {
+ signal_is_valid = true;
+ }
+ }
+#endif
+ }
if (!signal_is_valid) {
ERR_EXPLAIN("In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'");
@@ -1735,6 +1724,8 @@ void Object::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_deferred", &Object::_call_deferred_bind, mi);
}
+ ClassDB::bind_method(D_METHOD("set_deferred", "property", "value"), &Object::set_deferred);
+
ClassDB::bind_method(D_METHOD("callv", "method", "arg_array"), &Object::callv);
ClassDB::bind_method(D_METHOD("has_method", "method"), &Object::has_method);
@@ -1791,6 +1782,10 @@ void Object::call_deferred(const StringName &p_method, VARIANT_ARG_DECLARE) {
MessageQueue::get_singleton()->push_call(this, p_method, VARIANT_ARG_PASS);
}
+void Object::set_deferred(const StringName &p_property, const Variant &p_value) {
+ MessageQueue::get_singleton()->push_set(this, p_property, p_value);
+}
+
void Object::set_block_signals(bool p_block) {
_block_signals = p_block;
@@ -1926,6 +1921,18 @@ void *Object::get_script_instance_binding(int p_script_language_index) {
return _script_instance_bindings[p_script_language_index];
}
+bool Object::has_script_instance_binding(int p_script_language_index) {
+
+ return _script_instance_bindings[p_script_language_index] != NULL;
+}
+
+void Object::set_script_instance_binding(int p_script_language_index, void *p_data) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(_script_instance_bindings[p_script_language_index] != NULL);
+#endif
+ _script_instance_bindings[p_script_language_index] = p_data;
+}
+
Object::Object() {
_class_ptr = NULL;
@@ -1955,30 +1962,30 @@ Object::~Object() {
memdelete(script_instance);
script_instance = NULL;
- List<Connection> sconnections;
const StringName *S = NULL;
- while ((S = signal_map.next(S))) {
+ while ((S = signal_map.next(NULL))) {
Signal *s = &signal_map[*S];
- ERR_EXPLAIN("Attempt to delete an object in the middle of a signal emission from it");
- ERR_CONTINUE(s->lock > 0);
-
- for (int i = 0; i < s->slot_map.size(); i++) {
-
- sconnections.push_back(s->slot_map.getv(i).conn);
+ if (s->lock) {
+ ERR_EXPLAIN("Attempt to delete an object in the middle of a signal emission from it");
+ ERR_CONTINUE(s->lock > 0);
}
- }
- for (List<Connection>::Element *E = sconnections.front(); E; E = E->next()) {
+ //brute force disconnect for performance
+ int slot_count = s->slot_map.size();
+ const VMap<Signal::Target, Signal::Slot>::Pair *slot_list = s->slot_map.get_array();
- Connection &c = E->get();
- ERR_CONTINUE(c.source != this); //bug?
+ for (int i = 0; i < slot_count; i++) {
- this->_disconnect(c.signal, c.target, c.method, true);
+ slot_list[i].value.conn.target->connections.erase(slot_list[i].value.cE);
+ }
+
+ signal_map.erase(*S);
}
+ //signals from nodes that connect to this node
while (connections.size()) {
Connection c = connections.front()->get();
@@ -1989,9 +1996,11 @@ Object::~Object() {
_instance_ID = 0;
_predelete_ok = 2;
- for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
- if (_script_instance_bindings[i]) {
- ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ if (!ScriptServer::are_languages_finished()) {
+ for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
+ if (_script_instance_bindings[i]) {
+ ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ }
}
}
}
@@ -2014,11 +2023,13 @@ ObjectID ObjectDB::add_instance(Object *p_object) {
ERR_FAIL_COND_V(p_object->get_instance_id() != 0, 0);
rw_lock->write_lock();
- instances[++instance_counter] = p_object;
- instance_checks[p_object] = instance_counter;
+ ObjectID instance_id = ++instance_counter;
+ instances[instance_id] = p_object;
+ instance_checks[p_object] = instance_id;
+
rw_lock->write_unlock();
- return instance_counter;
+ return instance_id;
}
void ObjectDB::remove_instance(Object *p_object) {
@@ -2095,6 +2106,5 @@ void ObjectDB::cleanup() {
instances.clear();
instance_checks.clear();
rw_lock->write_unlock();
-
memdelete(rw_lock);
}
diff --git a/core/object.h b/core/object.h
index 43e1cf4785..e8a6178052 100644
--- a/core/object.h
+++ b/core/object.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,13 +31,13 @@
#ifndef OBJECT_H
#define OBJECT_H
-#include "hash_map.h"
-#include "list.h"
-#include "map.h"
-#include "os/rw_lock.h"
-#include "set.h"
-#include "variant.h"
-#include "vmap.h"
+#include "core/hash_map.h"
+#include "core/list.h"
+#include "core/map.h"
+#include "core/os/rw_lock.h"
+#include "core/set.h"
+#include "core/variant.h"
+#include "core/vmap.h"
#define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()
#define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5
@@ -103,8 +103,9 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
PROPERTY_USAGE_CATEGORY = 256,
- PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
- PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
+ //those below are deprecated thanks to ClassDB's now class value cache
+ //PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
+ //PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
@@ -116,6 +117,9 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 19,
PROPERTY_USAGE_INTERNAL = 1 << 20,
PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated
+ PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
+ PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
+ PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24,
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
@@ -125,10 +129,6 @@ enum PropertyUsageFlags {
#define ADD_SIGNAL(m_signal) ClassDB::add_signal(get_class_static(), m_signal)
#define ADD_PROPERTY(m_property, m_setter, m_getter) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter))
#define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index)
-#define ADD_PROPERTYNZ(m_property, m_setter, m_getter) ClassDB::add_property(get_class_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONZERO), _scs_create(m_setter), _scs_create(m_getter))
-#define ADD_PROPERTYINZ(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONZERO), _scs_create(m_setter), _scs_create(m_getter), m_index)
-#define ADD_PROPERTYNO(m_property, m_setter, m_getter) ClassDB::add_property(get_class_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), _scs_create(m_setter), _scs_create(m_getter))
-#define ADD_PROPERTYINO(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), _scs_create(m_setter), _scs_create(m_getter), m_index)
#define ADD_GROUP(m_name, m_prefix) ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
struct PropertyInfo {
@@ -187,11 +187,11 @@ Array convert_property_list(const List<PropertyInfo> *p_list);
struct MethodInfo {
String name;
- List<PropertyInfo> arguments;
- Vector<Variant> default_arguments;
PropertyInfo return_val;
uint32_t flags;
int id;
+ List<PropertyInfo> arguments;
+ Vector<Variant> default_arguments;
inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; }
inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); }
@@ -317,7 +317,7 @@ protected:
virtual void _initialize_classv() { \
initialize_class(); \
} \
- _FORCE_INLINE_ bool (Object::*(_get_get() const))(const StringName &p_name, Variant &) const { \
+ _FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &) const { \
return (bool (Object::*)(const StringName &, Variant &) const) & m_class::_get; \
} \
virtual bool _getv(const StringName &p_name, Variant &r_ret) const { \
@@ -327,7 +327,7 @@ protected:
} \
return m_inherits::_getv(p_name, r_ret); \
} \
- _FORCE_INLINE_ bool (Object::*(_get_set() const))(const StringName &p_name, const Variant &p_property) { \
+ _FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) { \
return (bool (Object::*)(const StringName &, const Variant &)) & m_class::_set; \
} \
virtual bool _setv(const StringName &p_name, const Variant &p_property) { \
@@ -337,7 +337,7 @@ protected:
} \
return false; \
} \
- _FORCE_INLINE_ void (Object::*(_get_get_property_list() const))(List<PropertyInfo> * p_list) const { \
+ _FORCE_INLINE_ void (Object::*_get_get_property_list() const)(List<PropertyInfo> * p_list) const { \
return (void (Object::*)(List<PropertyInfo> *) const) & m_class::_get_property_list; \
} \
virtual void _get_property_listv(List<PropertyInfo> *p_list, bool p_reversed) const { \
@@ -356,7 +356,7 @@ protected:
m_inherits::_get_property_listv(p_list, p_reversed); \
} \
} \
- _FORCE_INLINE_ void (Object::*(_get_notification() const))(int) { \
+ _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \
return (void (Object::*)(int)) & m_class::_notification; \
} \
virtual void _notificationv(int p_notification, bool p_reversed) { \
@@ -421,7 +421,7 @@ private:
};
#ifdef DEBUG_ENABLED
- friend class _ObjectDebugLock;
+ friend struct _ObjectDebugLock;
#endif
friend bool predelete_handler(Object *);
friend void postinitialize_handler(Object *);
@@ -513,16 +513,16 @@ protected:
_FORCE_INLINE_ static void (*_get_bind_methods())() {
return &Object::_bind_methods;
}
- _FORCE_INLINE_ bool (Object::*(_get_get() const))(const StringName &p_name, Variant &r_ret) const {
+ _FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &r_ret) const {
return &Object::_get;
}
- _FORCE_INLINE_ bool (Object::*(_get_set() const))(const StringName &p_name, const Variant &p_property) {
+ _FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) {
return &Object::_set;
}
- _FORCE_INLINE_ void (Object::*(_get_get_property_list() const))(List<PropertyInfo> *p_list) const {
+ _FORCE_INLINE_ void (Object::*_get_get_property_list() const)(List<PropertyInfo> *p_list) const {
return &Object::_get_property_list;
}
- _FORCE_INLINE_ void (Object::*(_get_notification() const))(int) {
+ _FORCE_INLINE_ void (Object::*_get_notification() const)(int) {
return &Object::_notification;
}
static void get_valid_parents_static(List<String> *p_parents);
@@ -700,6 +700,7 @@ public:
bool is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const;
void call_deferred(const StringName &p_method, VARIANT_ARG_LIST);
+ void set_deferred(const StringName &p_property, const Variant &p_value);
void set_block_signals(bool p_block);
bool is_blocking_signals() const;
@@ -722,10 +723,15 @@ public:
#ifdef TOOLS_ENABLED
void editor_set_section_unfold(const String &p_section, bool p_unfolded);
bool editor_is_section_unfolded(const String &p_section);
+ const Set<String> &editor_get_section_folding() const { return editor_section_folding; }
+ void editor_clear_section_folding() { editor_section_folding.clear(); }
+
#endif
//used by script languages to store binding data
void *get_script_instance_binding(int p_script_language_index);
+ bool has_script_instance_binding(int p_script_language_index);
+ void set_script_instance_binding(int p_script_language_index, void *p_data);
void clear_internal_resource_paths();
@@ -779,6 +785,6 @@ public:
};
//needed by macros
-#include "class_db.h"
+#include "core/class_db.h"
#endif
diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h
index 93ce9a90a7..09d43d6797 100644
--- a/core/ordered_hash_map.h
+++ b/core/ordered_hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,9 @@
#ifndef ORDERED_HASH_MAP_H
#define ORDERED_HASH_MAP_H
-#include "hash_map.h"
-#include "list.h"
-#include "pair.h"
+#include "core/hash_map.h"
+#include "core/list.h"
+#include "core/pair.h"
/**
* A hash map which allows to iterate elements in insertion order.
diff --git a/core/os/SCsub b/core/os/SCsub
index 4efc902717..1c5f954470 100644
--- a/core/os/SCsub
+++ b/core/os/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
-
-Export('env')
diff --git a/core/os/copymem.h b/core/os/copymem.h
index 87d77bd426..cc68983d4d 100644
--- a/core/os/copymem.h
+++ b/core/os/copymem.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef COPYMEM_H
#define COPYMEM_H
-#include "typedefs.h"
+#include "core/typedefs.h"
#ifdef PLATFORM_COPYMEM
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index e631d6e994..2c1c655175 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,10 +29,11 @@
/*************************************************************************/
#include "dir_access.h"
-#include "os/file_access.h"
-#include "os/memory.h"
-#include "os/os.h"
-#include "project_settings.h"
+
+#include "core/os/file_access.h"
+#include "core/os/memory.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
String DirAccess::_get_root_path() const {
@@ -226,6 +227,7 @@ String DirAccess::fix_path(String p_path) const {
return p_path;
} break;
+ case ACCESS_MAX: break; // Can't happen, but silences warning
}
return p_path;
@@ -347,9 +349,9 @@ class DirChanger {
String original_dir;
public:
- DirChanger(DirAccess *p_da, String p_dir) {
- da = p_da;
- original_dir = p_da->get_current_dir();
+ DirChanger(DirAccess *p_da, String p_dir) :
+ da(p_da),
+ original_dir(p_da->get_current_dir()) {
p_da->change_dir(p_dir);
}
@@ -429,8 +431,12 @@ Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) {
ERR_FAIL_COND_V(err, err);
}
+ if (!p_to.ends_with("/")) {
+ p_to = p_to + "/";
+ }
+
DirChanger dir_changer(this, p_from);
- Error err = _copy_dir(target_da, p_to + "/", p_chmod_flags);
+ Error err = _copy_dir(target_da, p_to, p_chmod_flags);
memdelete(target_da);
return err;
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index 4df0618021..bde19bd5ae 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,14 +31,14 @@
#ifndef DIR_ACCESS_H
#define DIR_ACCESS_H
-#include "typedefs.h"
-#include "ustring.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-//@ TOOD, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies
+//@ TODO, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies
class DirAccess {
public:
enum AccessType {
@@ -98,6 +98,7 @@ public:
virtual Error rename(String p_from, String p_to) = 0;
virtual Error remove(String p_name) = 0;
+ virtual String get_filesystem_type() const = 0;
static String get_full_path(const String &p_path, AccessType p_access);
static DirAccess *create_for_path(const String &p_path);
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 59f07c03e7..39d9f45bd7 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,8 +32,8 @@
#include "core/io/file_access_pack.h"
#include "core/io/marshalls.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "thirdparty/misc/md5.h"
#include "thirdparty/misc/sha256.h"
@@ -46,7 +46,6 @@ bool FileAccess::backup_save = false;
FileAccess *FileAccess::create(AccessType p_access) {
- ERR_FAIL_COND_V(!create_func, 0);
ERR_FAIL_INDEX_V(p_access, ACCESS_MAX, 0);
FileAccess *ret = create_func[p_access]();
@@ -166,6 +165,7 @@ String FileAccess::fix_path(const String &p_path) const {
return r_path;
} break;
+ case ACCESS_MAX: break; // Can't happen, but silences warning
}
return r_path;
@@ -346,14 +346,15 @@ String FileAccess::get_line() const {
return String::utf8(line.get_data());
}
-Vector<String> FileAccess::get_csv_line(String delim) const {
+Vector<String> FileAccess::get_csv_line(const String &p_delim) const {
- ERR_FAIL_COND_V(delim.length() != 1, Vector<String>());
+ ERR_FAIL_COND_V(p_delim.length() != 1, Vector<String>());
String l;
int qc = 0;
do {
- ERR_FAIL_COND_V(eof_reached(), Vector<String>());
+ if (eof_reached())
+ break;
l += get_line() + "\n";
qc = 0;
@@ -376,7 +377,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
CharType c = l[i];
CharType s[2] = { 0, 0 };
- if (!in_quote && c == delim[0]) {
+ if (!in_quote && c == p_delim[0]) {
strings.push_back(current);
current = String();
} else if (c == '"') {
@@ -408,6 +409,23 @@ int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const {
return i;
}
+String FileAccess::get_as_utf8_string() const {
+ PoolVector<uint8_t> sourcef;
+ int len = get_len();
+ sourcef.resize(len + 1);
+
+ PoolVector<uint8_t>::Write w = sourcef.write();
+ int r = get_buffer(w.ptr(), len);
+ ERR_FAIL_COND_V(r != len, String());
+ w[len] = 0;
+
+ String s;
+ if (s.parse_utf8((const char *)w.ptr())) {
+ return String();
+ }
+ return s;
+}
+
void FileAccess::store_16(uint16_t p_dest) {
uint8_t a, b;
@@ -525,6 +543,28 @@ void FileAccess::store_line(const String &p_line) {
store_8('\n');
}
+void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_delim) {
+
+ ERR_FAIL_COND(p_delim.length() != 1);
+
+ String line = "";
+ int size = p_values.size();
+ for (int i = 0; i < size; ++i) {
+ String value = p_values[i];
+
+ if (value.find("\"") != -1 || value.find(p_delim) != -1 || value.find("\n") != -1) {
+ value = "\"" + value.replace("\"", "\"\"") + "\"";
+ }
+ if (i < size - 1) {
+ value += p_delim;
+ }
+
+ line += value;
+ }
+
+ store_line(line);
+}
+
void FileAccess::store_buffer(const uint8_t *p_src, int p_length) {
for (int i = 0; i < p_length; i++)
diff --git a/core/os/file_access.h b/core/os/file_access.h
index c4635fdfbb..c65b75369c 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,11 @@
#ifndef FILE_ACCESS_H
#define FILE_ACCESS_H
-#include "math_defs.h"
-#include "os/memory.h"
-#include "typedefs.h"
-#include "ustring.h"
+#include "core/math/math_defs.h"
+#include "core/os/memory.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
+
/**
* Multi-Platform abstraction for accessing to files.
*/
@@ -111,7 +112,8 @@ public:
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
virtual String get_line() const;
virtual String get_token() const;
- virtual Vector<String> get_csv_line(String delim = ",") const;
+ virtual Vector<String> get_csv_line(const String &p_delim = ",") const;
+ virtual String get_as_utf8_string() const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
@@ -135,6 +137,7 @@ public:
virtual void store_string(const String &p_string);
virtual void store_line(const String &p_line);
+ virtual void store_csv_line(const Vector<String> &p_values, const String &p_delim = ",");
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
diff --git a/core/os/input.cpp b/core/os/input.cpp
index a5b0f91e63..caa9fb1493 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "input.h"
-#include "input_map.h"
-#include "os/os.h"
-#include "project_settings.h"
+
+#include "core/input_map.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+
Input *Input::singleton = NULL;
Input *Input::get_singleton() {
@@ -40,7 +42,7 @@ Input *Input::get_singleton() {
}
void Input::set_mouse_mode(MouseMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 4);
+ ERR_FAIL_INDEX((int)p_mode, 4);
OS::get_singleton()->set_mouse_mode((OS::MouseMode)p_mode);
}
@@ -84,11 +86,12 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode);
ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &Input::warp_mouse_position);
- ClassDB::bind_method(D_METHOD("action_press", "action"), &Input::action_press);
+ ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &Input::action_press, DEFVAL(1.f));
ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release);
ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
+ ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
diff --git a/core/os/input.h b/core/os/input.h
index 001871c5dc..c8b80b28d0 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,9 @@
#ifndef INPUT_H
#define INPUT_H
-#include "object.h"
-#include "os/main_loop.h"
-#include "os/thread_safe.h"
+#include "core/object.h"
+#include "core/os/main_loop.h"
+#include "core/os/thread_safe.h"
class Input : public Object {
@@ -113,7 +113,7 @@ public:
virtual Vector3 get_magnetometer() const = 0;
virtual Vector3 get_gyroscope() const = 0;
- virtual void action_press(const StringName &p_action) = 0;
+ virtual void action_press(const StringName &p_action, float p_strength = 1.f) = 0;
virtual void action_release(const StringName &p_action) = 0;
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
@@ -132,6 +132,9 @@ public:
virtual int get_joy_axis_index_from_string(String p_axis) = 0;
virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0;
+ virtual void accumulate_input_event(const Ref<InputEvent> &p_event) = 0;
+ virtual void flush_accumulated_events() = 0;
+ virtual void set_use_accumulated_input(bool p_enable) = 0;
Input();
};
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 12c6ef7d3b..40308f4f7d 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,8 @@
#include "input_event.h"
-#include "input_map.h"
-#include "os/keyboard.h"
+#include "core/input_map.h"
+#include "core/os/keyboard.h"
void InputEvent::set_device(int p_device) {
device = p_device;
@@ -122,6 +122,8 @@ void InputEvent::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
+ ClassDB::bind_method(D_METHOD("accumulate", "with_event"), &InputEvent::accumulate);
+
ClassDB::bind_method(D_METHOD("xformed_by", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2()));
ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device");
@@ -620,6 +622,44 @@ String InputEventMouseMotion::as_text() const {
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
}
+bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventMouseMotion> motion = p_event;
+ if (motion.is_null())
+ return false;
+
+ if (is_pressed() != motion->is_pressed()) {
+ return false;
+ }
+
+ if (get_button_mask() != motion->get_button_mask()) {
+ return false;
+ }
+
+ if (get_shift() != motion->get_shift()) {
+ return false;
+ }
+
+ if (get_control() != motion->get_control()) {
+ return false;
+ }
+
+ if (get_alt() != motion->get_alt()) {
+ return false;
+ }
+
+ if (get_metakey() != motion->get_metakey()) {
+ return false;
+ }
+
+ set_position(motion->get_position());
+ set_global_position(motion->get_global_position());
+ set_speed(motion->get_speed());
+ relative += motion->get_relative();
+
+ return true;
+}
+
void InputEventMouseMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
@@ -749,6 +789,15 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
return match;
}
+bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
+
+ Ref<InputEventJoypadButton> button = p_event;
+ if (button.is_null())
+ return false;
+
+ return button_index == button->button_index;
+}
+
String InputEventJoypadButton::as_text() const {
return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure));
@@ -950,11 +999,10 @@ bool InputEventAction::is_pressed() const {
}
bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
- Ref<InputEventKey> event = p_event;
- if (event.is_null())
+ if (p_event.is_null())
return false;
- return event->is_action(action);
+ return p_event->is_action(action);
}
bool InputEventAction::is_action(const StringName &p_action) const {
@@ -962,6 +1010,22 @@ bool InputEventAction::is_action(const StringName &p_action) const {
return action == p_action;
}
+bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
+
+ Ref<InputEventAction> act = p_event;
+ if (act.is_null())
+ return false;
+
+ bool match = action == act->action;
+ if (match) {
+ if (p_pressed != NULL)
+ *p_pressed = act->pressed;
+ if (p_strength != NULL)
+ *p_strength = (*p_pressed) ? 1.0f : 0.0f;
+ }
+ return match;
+}
+
String InputEventAction::as_text() const {
return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false");
diff --git a/core/os/input_event.h b/core/os/input_event.h
index 8732c7e377..47f9293a7f 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,12 @@
#ifndef INPUT_EVENT_H
#define INPUT_EVENT_H
-#include "os/copymem.h"
-#include "resource.h"
-#include "transform_2d.h"
-#include "typedefs.h"
-#include "ustring.h"
+#include "core/math/transform_2d.h"
+#include "core/os/copymem.h"
+#include "core/resource.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -185,6 +186,7 @@ public:
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const;
+ virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
InputEvent();
};
@@ -350,6 +352,8 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual String as_text() const;
+ virtual bool accumulate(const Ref<InputEvent> &p_event);
+
InputEventMouseMotion();
};
@@ -399,6 +403,7 @@ public:
float get_pressure() const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const;
+ virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
@@ -480,6 +485,8 @@ public:
virtual bool is_action(const StringName &p_action) const;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const;
+
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index 9dfc91e308..311025a5fd 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "keyboard.h"
-#include "os/os.h"
+
+#include "core/os/os.h"
struct _KeyCodeText {
int code;
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index a0e6f8b2ef..58a0807579 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,13 +31,10 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
-#include "ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+#include "core/ustring.h"
/**
-@author Juan Linietsky <reduzio@gmail.com>
+ @author Juan Linietsky <reduzio@gmail.com>
*/
/*
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index c51801e3e2..895ce14ae9 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,18 +29,19 @@
/*************************************************************************/
#include "main_loop.h"
-#include "script_language.h"
+
+#include "core/script_language.h"
void MainLoop::_bind_methods() {
- ClassDB::bind_method(D_METHOD("input_event", "ev"), &MainLoop::input_event);
+ ClassDB::bind_method(D_METHOD("input_event", "event"), &MainLoop::input_event);
ClassDB::bind_method(D_METHOD("input_text", "text"), &MainLoop::input_text);
ClassDB::bind_method(D_METHOD("init"), &MainLoop::init);
ClassDB::bind_method(D_METHOD("iteration", "delta"), &MainLoop::iteration);
ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle);
ClassDB::bind_method(D_METHOD("finish"), &MainLoop::finish);
- BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "ev", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
+ BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo("_input_text", PropertyInfo(Variant::STRING, "text")));
BIND_VMETHOD(MethodInfo("_initialize"));
BIND_VMETHOD(MethodInfo("_iteration", PropertyInfo(Variant::REAL, "delta")));
@@ -59,6 +60,7 @@ void MainLoop::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
BIND_CONSTANT(NOTIFICATION_CRASH);
+ BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
};
void MainLoop::set_init_script(const Ref<Script> &p_init_script) {
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index f96e46141e..bfdf92acfa 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,14 @@
#ifndef MAIN_LOOP_H
#define MAIN_LOOP_H
-#include "os/input_event.h"
-#include "reference.h"
-#include "script_language.h"
+#include "core/os/input_event.h"
+#include "core/reference.h"
+#include "core/script_language.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
class MainLoop : public Object {
GDCLASS(MainLoop, Object);
@@ -63,6 +65,7 @@ public:
NOTIFICATION_TRANSLATION_CHANGED = 90,
NOTIFICATION_WM_ABOUT = 91,
NOTIFICATION_CRASH = 92,
+ NOTIFICATION_OS_IME_UPDATE = 93,
};
virtual void input_event(const Ref<InputEvent> &p_event);
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index 3eab4343a9..d1de51f3db 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "memory.h"
-#include "copymem.h"
+
+#include "core/error_macros.h"
+#include "core/os/copymem.h"
#include "core/safe_refcount.h"
-#include "error_macros.h"
+
#include <stdio.h>
#include <stdlib.h>
@@ -170,9 +172,9 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
if (prepad) {
mem -= PAD_ALIGN;
- uint64_t *s = (uint64_t *)mem;
#ifdef DEBUG_ENABLED
+ uint64_t *s = (uint64_t *)mem;
atomic_sub(&mem_usage, *s);
#endif
diff --git a/core/os/memory.h b/core/os/memory.h
index f5c6c0b38a..f3ca9fc614 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,8 @@
#ifndef MEMORY_H
#define MEMORY_H
-#include "safe_refcount.h"
+#include "core/safe_refcount.h"
+
#include <stddef.h>
/**
@@ -115,7 +116,9 @@ void memdelete(T *p_class) {
if (!predelete_handler(p_class))
return; // doesn't want to be deleted
- p_class->~T();
+ if (!__has_trivial_destructor(T))
+ p_class->~T();
+
Memory::free_static(p_class, false);
}
@@ -124,7 +127,9 @@ void memdelete_allocator(T *p_class) {
if (!predelete_handler(p_class))
return; // doesn't want to be deleted
- p_class->~T();
+ if (!__has_trivial_destructor(T))
+ p_class->~T();
+
A::free(p_class);
}
@@ -149,11 +154,13 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
ERR_FAIL_COND_V(!mem, failptr);
*(mem - 1) = p_elements;
- T *elems = (T *)mem;
+ if (!__has_trivial_constructor(T)) {
+ T *elems = (T *)mem;
- /* call operator new */
- for (size_t i = 0; i < p_elements; i++) {
- new (&elems[i], sizeof(T), p_descr) T;
+ /* call operator new */
+ for (size_t i = 0; i < p_elements; i++) {
+ new (&elems[i], sizeof(T), p_descr) T;
+ }
}
return (T *)mem;
@@ -176,12 +183,14 @@ void memdelete_arr(T *p_class) {
uint64_t *ptr = (uint64_t *)p_class;
- uint64_t elem_count = *(ptr - 1);
+ if (!__has_trivial_destructor(T)) {
+ uint64_t elem_count = *(ptr - 1);
- for (uint64_t i = 0; i < elem_count; i++) {
+ for (uint64_t i = 0; i < elem_count; i++) {
+ p_class[i].~T();
+ }
+ }
- p_class[i].~T();
- };
Memory::free_static(ptr, true);
}
diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp
index 7b4f84473c..0d7ad23d68 100644
--- a/core/os/midi_driver.cpp
+++ b/core/os/midi_driver.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,8 @@
#include "midi_driver.h"
+#include "core/os/os.h"
#include "main/input_default.h"
-#include "os/os.h"
MIDIDriver *MIDIDriver::singleton = NULL;
MIDIDriver *MIDIDriver::get_singleton() {
diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h
index 1a3a67a411..e0e5e2be67 100644
--- a/core/os/midi_driver.h
+++ b/core/os/midi_driver.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,9 @@
#ifndef MIDI_DRIVER_H
#define MIDI_DRIVER_H
+#include "core/typedefs.h"
#include "core/variant.h"
-#include "typedefs.h"
+
/**
* Multi-Platform abstraction for accessing to MIDI.
*/
diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp
index 7c4ea2323c..1ae7e1f877 100644
--- a/core/os/mutex.cpp
+++ b/core/os/mutex.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "mutex.h"
-#include "error_macros.h"
+
+#include "core/error_macros.h"
+
#include <stddef.h>
Mutex *(*Mutex::create_func)(bool) = 0;
diff --git a/core/os/mutex.h b/core/os/mutex.h
index 9debe7f41b..17367f32f2 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef MUTEX_H
#define MUTEX_H
-#include "error_list.h"
+#include "core/error_list.h"
/**
* @class Mutex
diff --git a/core/os/os.cpp b/core/os/os.cpp
index e90d714450..03e63f636e 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,13 +30,13 @@
#include "os.h"
-#include "dir_access.h"
-#include "input.h"
-#include "os/file_access.h"
-#include "os/midi_driver.h"
-#include "project_settings.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/os/input.h"
+#include "core/os/midi_driver.h"
+#include "core/project_settings.h"
+#include "core/version_generated.gen.h"
#include "servers/audio_server.h"
-#include "version_generated.gen.h"
#include <stdarg.h>
@@ -61,6 +61,9 @@ uint64_t OS::get_unix_time() const {
uint64_t OS::get_system_time_secs() const {
return 0;
}
+uint64_t OS::get_system_time_msecs() const {
+ return 0;
+}
void OS::debug_break(){
// something
@@ -390,16 +393,16 @@ Error OS::dialog_input_text(String p_title, String p_description, String p_parti
return OK;
};
-int OS::get_static_memory_usage() const {
+uint64_t OS::get_static_memory_usage() const {
return Memory::get_mem_usage();
}
-int OS::get_dynamic_memory_usage() const {
+uint64_t OS::get_dynamic_memory_usage() const {
return MemoryPool::total_memory;
}
-int OS::get_static_memory_peak_usage() const {
+uint64_t OS::get_static_memory_peak_usage() const {
return Memory::get_mem_max_usage();
}
@@ -415,7 +418,7 @@ bool OS::has_touchscreen_ui_hint() const {
return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse();
}
-int OS::get_free_static_memory() const {
+uint64_t OS::get_free_static_memory() const {
return Memory::get_mem_available();
}
@@ -566,6 +569,11 @@ int OS::get_power_percent_left() {
return -1;
}
+void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) {
+
+ has_server_feature_callback = p_callback;
+}
+
bool OS::has_feature(const String &p_feature) {
if (p_feature == get_name())
@@ -622,6 +630,10 @@ bool OS::has_feature(const String &p_feature) {
if (_check_internal_feature_support(p_feature))
return true;
+ if (has_server_feature_callback && has_server_feature_callback(p_feature)) {
+ return true;
+ }
+
if (ProjectSettings::get_singleton()->has_custom_feature(p_feature))
return true;
@@ -632,10 +644,13 @@ void OS::center_window() {
if (is_window_fullscreen()) return;
+ Point2 sp = get_screen_position(get_current_screen());
Size2 scr = get_screen_size(get_current_screen());
Size2 wnd = get_real_window_size();
- int x = scr.width / 2 - wnd.width / 2;
- int y = scr.height / 2 - wnd.height / 2;
+
+ int x = sp.width + (scr.width - wnd.width) / 2;
+ int y = sp.height + (scr.height - wnd.height) / 2;
+
set_window_position(Vector2(x, y));
}
@@ -723,6 +738,8 @@ OS::OS() {
_logger = NULL;
+ has_server_feature_callback = NULL;
+
Vector<Logger *> loggers;
loggers.push_back(memnew(StdLogger));
_set_logger(memnew(CompositeLogger(loggers)));
diff --git a/core/os/os.h b/core/os/os.h
index 100af95ef1..ebfe7d20dc 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,25 +31,20 @@
#ifndef OS_H
#define OS_H
-#include "engine.h"
-#include "image.h"
-#include "io/logger.h"
-#include "list.h"
-#include "os/main_loop.h"
-#include "ustring.h"
-#include "vector.h"
+#include "core/engine.h"
+#include "core/image.h"
+#include "core/io/logger.h"
+#include "core/list.h"
+#include "core/os/main_loop.h"
+#include "core/ustring.h"
+#include "core/vector.h"
+
#include <stdarg.h>
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-enum VideoDriver {
- VIDEO_DRIVER_GLES3,
- VIDEO_DRIVER_GLES2,
- VIDEO_DRIVER_MAX,
-};
-
class OS {
static OS *singleton;
@@ -82,6 +77,7 @@ protected:
public:
typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection);
+ typedef bool (*HasServerFeatureCallback)(const String &p_feature);
enum PowerState {
POWERSTATE_UNKNOWN, /**< cannot determine power status */
@@ -126,9 +122,10 @@ public:
protected:
friend class Main;
+ HasServerFeatureCallback has_server_feature_callback;
RenderThreadMode _render_thread_mode;
- // functions used by main to initialize/deintialize the OS
+ // functions used by main to initialize/deinitialize the OS
void add_logger(Logger *p_logger);
virtual void initialize_core() = 0;
@@ -151,8 +148,8 @@ public:
static OS *get_singleton();
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR);
- void print(const char *p_format, ...);
- void printerr(const char *p_format, ...);
+ void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
+ void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0;
virtual String get_stdin_string(bool p_block = true) = 0;
@@ -183,9 +180,16 @@ public:
virtual VideoMode get_video_mode(int p_screen = 0) const = 0;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0;
+ enum VideoDriver {
+ VIDEO_DRIVER_GLES3,
+ VIDEO_DRIVER_GLES2,
+ VIDEO_DRIVER_MAX,
+ };
+
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
virtual int get_current_video_driver() const = 0;
+
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
@@ -241,7 +245,8 @@ public:
virtual void set_ime_active(const bool p_active) {}
virtual void set_ime_position(const Point2 &p_pos) {}
- virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {}
+ virtual Point2 get_ime_selection() const { return Point2(); }
+ virtual String get_ime_text() const { return String(); }
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; }
virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; }
@@ -264,6 +269,7 @@ public:
virtual bool has_environment(const String &p_var) const = 0;
virtual String get_environment(const String &p_var) const = 0;
+ virtual bool set_environment(const String &p_var, const String &p_value) const = 0;
virtual String get_name() = 0;
virtual List<String> get_cmdline_args() const { return _cmdline; }
@@ -326,6 +332,7 @@ public:
virtual TimeZoneInfo get_time_zone_info() const = 0;
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
+ virtual uint64_t get_system_time_msecs() const;
virtual void delay_usec(uint32_t p_usec) const = 0;
virtual uint64_t get_ticks_usec() const = 0;
@@ -379,10 +386,10 @@ public:
virtual void print_resources_in_use(bool p_short = false);
virtual void print_all_resources(String p_to_file = "");
- virtual int get_static_memory_usage() const;
- virtual int get_static_memory_peak_usage() const;
- virtual int get_dynamic_memory_usage() const;
- virtual int get_free_static_memory() const;
+ virtual uint64_t get_static_memory_usage() const;
+ virtual uint64_t get_static_memory_peak_usage() const;
+ virtual uint64_t get_dynamic_memory_usage() const;
+ virtual uint64_t get_free_static_memory() const;
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
@@ -479,6 +486,7 @@ public:
enum EngineContext {
CONTEXT_EDITOR,
CONTEXT_PROJECTMAN,
+ CONTEXT_ENGINE,
};
virtual void set_context(int p_context);
@@ -501,6 +509,8 @@ public:
virtual void force_process_input(){};
bool has_feature(const String &p_feature);
+ void set_has_server_feature_callback(HasServerFeatureCallback p_callback);
+
bool is_layered_allowed() const { return _allow_layered; }
bool is_hidpi_allowed() const { return _allow_hidpi; }
@@ -508,6 +518,7 @@ public:
bool is_restart_on_exit_set() const;
List<String> get_restart_on_exit_arguments() const;
+ virtual void process_and_drop_events() {}
OS();
virtual ~OS();
};
diff --git a/core/os/rw_lock.cpp b/core/os/rw_lock.cpp
index 35489490ed..b70d5d73a0 100644
--- a/core/os/rw_lock.cpp
+++ b/core/os/rw_lock.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "rw_lock.h"
-#include "error_macros.h"
+#include "core/error_macros.h"
#include <stddef.h>
diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h
index 3e53300c9f..8632e84e61 100644
--- a/core/os/rw_lock.h
+++ b/core/os/rw_lock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef RWLOCK_H
#define RWLOCK_H
-#include "error_list.h"
+#include "core/error_list.h"
class RWLock {
protected:
@@ -57,9 +57,7 @@ class RWLockRead {
public:
RWLockRead(const RWLock *p_lock) {
- if (p_lock) {
- lock = const_cast<RWLock *>(p_lock);
- }
+ lock = const_cast<RWLock *>(p_lock);
if (lock) lock->read_lock();
}
~RWLockRead() {
diff --git a/core/os/semaphore.cpp b/core/os/semaphore.cpp
index 0377aeeb29..5d3100760d 100644
--- a/core/os/semaphore.cpp
+++ b/core/os/semaphore.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "semaphore.h"
-#include "error_macros.h"
+
+#include "core/error_macros.h"
Semaphore *(*Semaphore::create_func)() = 0;
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index f3021bf74c..ccbba0dacd 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,12 @@
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
-#include "error_list.h"
+#include "core/error_list.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
class Semaphore {
protected:
static Semaphore *(*create_func)();
diff --git a/core/os/thread.cpp b/core/os/thread.cpp
index 250cf80a37..e00d20a9fe 100644
--- a/core/os/thread.cpp
+++ b/core/os/thread.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/thread.h b/core/os/thread.h
index c2947bccab..e7a6e8cb1f 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,13 +31,13 @@
#ifndef THREAD_H
#define THREAD_H
-#include "typedefs.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-#include "ustring.h"
-
typedef void (*ThreadCreateCallback)(void *p_userdata);
class Thread {
diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp
index b6371235c4..63f724f81c 100644
--- a/core/os/thread_dummy.cpp
+++ b/core/os/thread_dummy.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "thread_dummy.h"
-#include "memory.h"
+#include "core/os/memory.h"
Thread *ThreadDummy::create(ThreadCreateCallback p_callback, void *p_user, const Thread::Settings &p_settings) {
return memnew(ThreadDummy);
diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h
index 74957b95fe..4a7785484b 100644
--- a/core/os/thread_dummy.h
+++ b/core/os/thread_dummy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef THREAD_DUMMY_H
#define THREAD_DUMMY_H
-#include "mutex.h"
-#include "rw_lock.h"
-#include "semaphore.h"
-#include "thread.h"
+#include "core/os/mutex.h"
+#include "core/os/rw_lock.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
class ThreadDummy : public Thread {
diff --git a/core/os/thread_safe.cpp b/core/os/thread_safe.cpp
index acb37df02b..9eecd1c3dd 100644
--- a/core/os/thread_safe.cpp
+++ b/core/os/thread_safe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
/*************************************************************************/
#include "thread_safe.h"
-#include "error_macros.h"
-#include "os/memory.h"
+
+#include "core/error_macros.h"
+#include "core/os/memory.h"
ThreadSafe::ThreadSafe() {
diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h
index f0876f38a1..ddbf17da7f 100644
--- a/core/os/thread_safe.h
+++ b/core/os/thread_safe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef THREAD_SAFE_H
#define THREAD_SAFE_H
-#include "os/mutex.h"
+#include "core/os/mutex.h"
class ThreadSafe {
diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h
index 3ff7db2a44..58c8773d7f 100644
--- a/core/os/threaded_array_processor.h
+++ b/core/os/threaded_array_processor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,11 @@
#ifndef THREADED_ARRAY_PROCESSOR_H
#define THREADED_ARRAY_PROCESSOR_H
-#include "os/mutex.h"
-#include "os/os.h"
-#include "os/thread.h"
-#include "safe_refcount.h"
-#include "thread_safe.h"
+#include "core/os/mutex.h"
+#include "core/os/os.h"
+#include "core/os/thread.h"
+#include "core/os/thread_safe.h"
+#include "core/safe_refcount.h"
template <class C, class U>
struct ThreadArrayProcessData {
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index 45e060fa4a..6c17f42b13 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,8 @@
#include "packed_data_container.h"
-#include "core_string_names.h"
-#include "io/marshalls.h"
+#include "core/core_string_names.h"
+#include "core/io/marshalls.h"
Variant PackedDataContainer::getvar(const Variant &p_key, bool *r_valid) const {
diff --git a/core/packed_data_container.h b/core/packed_data_container.h
index fe36417000..25c83548be 100644
--- a/core/packed_data_container.h
+++ b/core/packed_data_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef PACKED_DATA_CONTAINER_H
#define PACKED_DATA_CONTAINER_H
-#include "resource.h"
+#include "core/resource.h"
class PackedDataContainer : public Resource {
diff --git a/core/pair.h b/core/pair.h
index 1d35ae1b6c..9afaa726cb 100644
--- a/core/pair.h
+++ b/core/pair.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,7 +37,11 @@ struct Pair {
F first;
S second;
- Pair() {}
+ Pair() :
+ first(),
+ second() {
+ }
+
Pair(F p_first, const S &p_second) :
first(p_first),
second(p_second) {
diff --git a/core/path_remap.cpp b/core/path_remap.cpp
index 80308d72c0..548c9c85d7 100644
--- a/core/path_remap.cpp
+++ b/core/path_remap.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/path_remap.h b/core/path_remap.h
index 5e25628aeb..3829fa5a1f 100644
--- a/core/path_remap.h
+++ b/core/path_remap.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index 8952314212..a283d8db1d 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,11 +30,11 @@
#include "pool_allocator.h"
+#include "core/error_macros.h"
+#include "core/os/copymem.h"
+#include "core/os/memory.h"
#include "core/os/os.h"
-#include "error_macros.h"
-#include "os/copymem.h"
-#include "os/memory.h"
-#include "print_string.h"
+#include "core/print_string.h"
#include <assert.h>
diff --git a/core/pool_allocator.h b/core/pool_allocator.h
index d9731aa3eb..282e0bd634 100644
--- a/core/pool_allocator.h
+++ b/core/pool_allocator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef POOL_ALLOCATOR_H
#define POOL_ALLOCATOR_H
-#include "typedefs.h"
+#include "core/typedefs.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/core/dvector.cpp b/core/pool_vector.cpp
index b679df55ad..b9d2316315 100644
--- a/core/dvector.cpp
+++ b/core/pool_vector.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* dvector.cpp */
+/* pool_vector.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "dvector.h"
+#include "pool_vector.h"
-Mutex *dvector_lock = NULL;
+Mutex *pool_vector_lock = NULL;
PoolAllocator *MemoryPool::memory_pool = NULL;
uint8_t *MemoryPool::pool_memory = NULL;
diff --git a/core/dvector.h b/core/pool_vector.h
index e03a755e6c..102a620f17 100644
--- a/core/dvector.h
+++ b/core/pool_vector.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* dvector.h */
+/* pool_vector.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DVECTOR_H
-#define DVECTOR_H
+#ifndef POOL_VECTOR_H
+#define POOL_VECTOR_H
-#include "os/copymem.h"
-#include "os/memory.h"
-#include "os/rw_lock.h"
-#include "pool_allocator.h"
-#include "safe_refcount.h"
-#include "ustring.h"
+#include "core/os/copymem.h"
+#include "core/os/memory.h"
+#include "core/os/rw_lock.h"
+#include "core/pool_allocator.h"
+#include "core/safe_refcount.h"
+#include "core/ustring.h"
struct MemoryPool {
@@ -56,12 +56,12 @@ struct MemoryPool {
Alloc *free_list;
- Alloc() {
- mem = NULL;
- lock = 0;
- pool_id = POOL_ALLOCATOR_INVALID_ID;
- size = 0;
- free_list = NULL;
+ Alloc() :
+ lock(0),
+ mem(NULL),
+ pool_id(POOL_ALLOCATOR_INVALID_ID),
+ size(0),
+ free_list(NULL) {
}
};
@@ -149,7 +149,7 @@ class PoolVector {
}
}
- if (old_alloc->refcount.unref() == true) {
+ if (old_alloc->refcount.unref()) {
//this should never happen but..
#ifdef DEBUG_ENABLED
@@ -188,19 +188,19 @@ class PoolVector {
}
}
- void _reference(const PoolVector &p_dvector) {
+ void _reference(const PoolVector &p_pool_vector) {
- if (alloc == p_dvector.alloc)
+ if (alloc == p_pool_vector.alloc)
return;
_unreference();
- if (!p_dvector.alloc) {
+ if (!p_pool_vector.alloc) {
return;
}
- if (p_dvector.alloc->refcount.ref()) {
- alloc = p_dvector.alloc;
+ if (p_pool_vector.alloc->refcount.ref()) {
+ alloc = p_pool_vector.alloc;
}
}
@@ -209,7 +209,7 @@ class PoolVector {
if (!alloc)
return;
- if (alloc->refcount.unref() == false) {
+ if (!alloc->refcount.unref()) {
alloc = NULL;
return;
}
@@ -460,11 +460,11 @@ public:
void invert();
- void operator=(const PoolVector &p_dvector) { _reference(p_dvector); }
+ void operator=(const PoolVector &p_pool_vector) { _reference(p_pool_vector); }
PoolVector() { alloc = NULL; }
- PoolVector(const PoolVector &p_dvector) {
+ PoolVector(const PoolVector &p_pool_vector) {
alloc = NULL;
- _reference(p_dvector);
+ _reference(p_pool_vector);
}
~PoolVector() { _unreference(); }
};
@@ -640,4 +640,4 @@ void PoolVector<T>::invert() {
}
}
-#endif
+#endif // POOL_VECTOR_H
diff --git a/core/print_string.cpp b/core/print_string.cpp
index e1e42d2b56..d91d49f53b 100644
--- a/core/print_string.cpp
+++ b/core/print_string.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "print_string.h"
-#include "os/os.h"
+#include "core/os/os.h"
#include <stdio.h>
diff --git a/core/print_string.h b/core/print_string.h
index c1d2d0ff3a..6fcffd417b 100644
--- a/core/print_string.h
+++ b/core/print_string.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef PRINT_STRING_H
#define PRINT_STRING_H
-#include "ustring.h"
+#include "core/ustring.h"
extern void (*_print_func)(String);
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 890789ec6f..6b4895d688 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,19 +30,18 @@
#include "project_settings.h"
-#include "bind/core_bind.h"
-#include "core_string_names.h"
-#include "io/file_access_network.h"
-#include "io/file_access_pack.h"
-#include "io/marshalls.h"
-#include "os/dir_access.h"
-#include "os/file_access.h"
-#include "os/keyboard.h"
-#include "os/os.h"
-#include "variant_parser.h"
-#include <zlib.h>
+#include "core/bind/core_bind.h"
+#include "core/core_string_names.h"
+#include "core/io/file_access_network.h"
+#include "core/io/file_access_pack.h"
+#include "core/io/marshalls.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/os/keyboard.h"
+#include "core/os/os.h"
+#include "core/variant_parser.h"
-#define FORMAT_VERSION 4
+#include <zlib.h>
ProjectSettings *ProjectSettings::singleton = NULL;
@@ -59,7 +58,7 @@ String ProjectSettings::get_resource_path() const {
String ProjectSettings::localize_path(const String &p_path) const {
if (resource_path == "")
- return p_path; //not initialied yet
+ return p_path; //not initialized yet
if (p_path.begins_with("res://") || p_path.begins_with("user://") ||
(p_path.is_abs_path() && !p_path.begins_with(resource_path)))
@@ -270,9 +269,9 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack) {
return true;
}
-void ProjectSettings::_convert_to_last_version() {
- if (!has_setting("config_version") || (int)get_setting("config_version") <= 3) {
+void ProjectSettings::_convert_to_last_version(int p_from_version) {
+ if (p_from_version <= 3) {
// Converts the actions from array to dictionary (array of events to dictionary with deadzone + events)
for (Map<StringName, ProjectSettings::VariantContainer>::Element *E = props.front(); E; E = E->next()) {
Variant value = E->get().variant;
@@ -287,9 +286,28 @@ void ProjectSettings::_convert_to_last_version() {
}
}
-Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
-
- //If looking for files in network, just use network!
+/*
+ * This method is responsible for loading a project.godot file and/or data file
+ * using the following merit order:
+ * - If using NetworkClient, try to lookup project file or fail.
+ * - If --main-pack was passed by the user (`p_main_pack`), load it or fail.
+ * - Search for .pck file matching binary name. There are two possibilities:
+ * o exec_path.get_basename() + '.pck' (e.g. 'win_game.exe' -> 'win_game.pck')
+ * o exec_path + '.pck' (e.g. 'linux_game' -> 'linux_game.pck')
+ * For each tentative, if the file exists, load it or fail.
+ * - On relevant platforms (Android/iOS), lookup project file in OS resource path.
+ * If found, load it or fail.
+ * - Lookup project file in passed `p_path` (--path passed by the user), i.e. we
+ * are running from source code.
+ * If not found and `p_upwards` is true (--upwards passed by the user), look for
+ * project files in parent folders up to the system root (used to run a game
+ * from command line while in a subfolder).
+ * If a project file is found, load it or fail.
+ * If nothing was found, error out.
+ */
+Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
+
+ // If looking for files in a network client, use it directly
if (FileAccessNetworkClient::get_singleton()) {
@@ -301,9 +319,7 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
return err;
}
- String exec_path = OS::get_singleton()->get_executable_path();
-
- //Attempt with a passed main pack first
+ // Attempt with a user-defined main pack first
if (p_main_pack != "") {
@@ -319,25 +335,39 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
return err;
}
- //Attempt with execname.pck
+ // Attempt with exec_name.pck
+ // (This is the usual case when distributing a Godot game.)
+
+ // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle)
+ // or the exec path's basename + '.pck' (Windows).
+ // We need to test both possibilities as extensions for Linux binaries are optional
+ // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck').
+
+ String exec_path = OS::get_singleton()->get_executable_path();
+
if (exec_path != "") {
bool found = false;
- // get our filename without our path (note, using exec_path.get_file before get_basename anymore because not all file systems have dots in their file names!)
- String filebase_name = exec_path.get_file().get_basename();
+ String exec_dir = exec_path.get_base_dir();
+ String exec_filename = exec_path.get_file();
+ String exec_basename = exec_filename.get_basename();
+
+ // Try to load data pack at the location of the executable
+ // As mentioned above, we have two potential names to attempt
- // try to open at the location of executable
- String datapack_name = exec_path.get_base_dir().plus_file(filebase_name) + ".pck";
- if (_load_resource_pack(datapack_name)) {
+ if (_load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) ||
+ _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck"))) {
found = true;
} else {
- datapack_name = filebase_name + ".pck";
- if (_load_resource_pack(datapack_name)) {
+ // If we couldn't find them next to the executable, we attempt
+ // the current working directory. Same story, two tests.
+ if (_load_resource_pack(exec_basename + ".pck") ||
+ _load_resource_pack(exec_filename + ".pck")) {
found = true;
}
}
- // if we opened our package, try and load our project...
+ // If we opened our package, try and load our project
if (found) {
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
if (err == OK) {
@@ -349,42 +379,37 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
}
}
- //Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this)
- if (OS::get_singleton()->get_resource_dir() != "") {
- //OS will call Globals->get_resource_path which will be empty if not overridden!
- //if the OS would rather use somewhere else, then it will not be empty.
+ // Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this)
+ if (OS::get_singleton()->get_resource_dir() != "") {
+ // OS will call ProjectSettings->get_resource_path which will be empty if not overridden!
+ // If the OS would rather use a specific location, then it will not be empty.
resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/");
- if (resource_path.length() && resource_path[resource_path.length() - 1] == '/')
+ if (resource_path != "" && resource_path[resource_path.length() - 1] == '/') {
resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end
-
- // data.pck and data.zip are deprecated and no longer supported, apologies.
- // make sure this is loaded from the resource path
+ }
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
if (err == OK) {
// Optional, we don't mind if it fails
_load_settings_text("res://override.cfg");
}
-
return err;
}
- //Nothing was found, try to find a project.godot somewhere!
+ // Nothing was found, try to find a project file in provided path (`p_path`)
+ // or, if requested (`p_upwards`) in parent directories.
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
ERR_FAIL_COND_V(!d, ERR_CANT_CREATE);
-
d->change_dir(p_path);
- String candidate = d->get_current_dir();
String current_dir = d->get_current_dir();
-
+ String candidate = current_dir;
bool found = false;
Error err;
while (true) {
-
err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary"));
if (err == OK) {
// Optional, we don't mind if it fails
@@ -395,10 +420,10 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
}
if (p_upwards) {
- // Try to load settings ascending through dirs shape!
+ // Try to load settings ascending through parent directories
d->change_dir("..");
if (d->get_current_dir() == current_dir)
- break; //not doing anything useful
+ break; // not doing anything useful
current_dir = d->get_current_dir();
} else {
break;
@@ -415,11 +440,21 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
if (resource_path.length() && resource_path[resource_path.length() - 1] == '/')
resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end
- _convert_to_last_version();
-
return OK;
}
+Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
+ Error err = _setup(p_path, p_main_pack, p_upwards);
+ if (err == OK) {
+ String custom_settings = GLOBAL_DEF("application/config/project_settings_override", "");
+ if (custom_settings != "") {
+ _load_settings_text(custom_settings);
+ }
+ }
+
+ return err;
+}
+
bool ProjectSettings::has_setting(String p_var) const {
_THREAD_SAFE_METHOD_
@@ -466,7 +501,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) {
d.resize(vlen);
f->get_buffer(d.ptrw(), vlen);
Variant value;
- Error err = decode_variant(value, d.ptr(), d.size());
+ err = decode_variant(value, d.ptr(), d.size());
ERR_EXPLAIN("Error decoding property: " + key);
ERR_CONTINUE(err != OK);
set(key, value);
@@ -495,8 +530,8 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
int lines = 0;
String error_text;
-
String section;
+ int config_version = 0;
while (true) {
@@ -507,6 +542,9 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
if (err == ERR_FILE_EOF) {
memdelete(f);
+ // If we're loading a project.godot from source code, we can operate some
+ // ProjectSettings conversions if need be.
+ _convert_to_last_version(config_version);
return OK;
} else if (err != OK) {
ERR_PRINTS("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted.");
@@ -516,13 +554,13 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
if (assign != String()) {
if (section == String() && assign == "config_version") {
- int config_version = value;
- if (config_version > FORMAT_VERSION) {
+ config_version = value;
+ if (config_version > CONFIG_VERSION) {
memdelete(f);
- ERR_FAIL_COND_V(config_version > FORMAT_VERSION, ERR_FILE_CANT_OPEN);
+ ERR_EXPLAIN(vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
+ ERR_FAIL_COND_V(config_version > CONFIG_VERSION, ERR_FILE_CANT_OPEN);
}
} else {
- // config_version is checked and dropped
if (section == String()) {
set(assign, value);
} else {
@@ -618,7 +656,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
file->store_string(key);
int len;
- Error err = encode_variant(p_custom_features, NULL, len);
+ err = encode_variant(p_custom_features, NULL, len);
if (err != OK) {
memdelete(file);
ERR_FAIL_V(err);
@@ -656,7 +694,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
file->store_string(key);
int len;
- Error err = encode_variant(value, NULL, len);
+ err = encode_variant(value, NULL, len);
if (err != OK)
memdelete(file);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
@@ -698,7 +736,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_line("; param=value ; assign values to parameters");
file->store_line("");
- file->store_string("config_version=" + itos(FORMAT_VERSION) + "\n");
+ file->store_string("config_version=" + itos(CONFIG_VERSION) + "\n");
if (p_custom_features != String())
file->store_string("custom_features=\"" + p_custom_features + "\"\n");
file->store_string("\n");
@@ -965,6 +1003,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("application/run/disable_stderr", false);
GLOBAL_DEF("application/config/use_custom_user_dir", false);
GLOBAL_DEF("application/config/custom_user_dir_name", "");
+ GLOBAL_DEF("application/config/project_settings_override", "");
action = Dictionary();
action["deadzone"] = Variant(0.5f);
@@ -1124,14 +1163,13 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("input/ui_end", action);
input_presets.push_back("input/ui_end");
- //GLOBAL_DEF("display/window/handheld/orientation", "landscape");
-
custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects");
GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
+ custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1");
//assigning here, because using GLOBAL_GET on every block for compressing can be slow
Compression::zstd_long_distance_matching = GLOBAL_DEF("compression/formats/zstd/long_distance_matching", false);
diff --git a/core/project_settings.h b/core/project_settings.h
index 75ebc5acc8..0ff18ab3f5 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,10 @@
#ifndef GLOBAL_CONFIG_H
#define GLOBAL_CONFIG_H
-#include "object.h"
-#include "os/thread_safe.h"
-#include "set.h"
+#include "core/object.h"
+#include "core/os/thread_safe.h"
+#include "core/set.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -105,16 +106,20 @@ protected:
Error _save_custom_bnd(const String &p_file);
- void _convert_to_last_version();
+ void _convert_to_last_version(int p_from_version);
bool _load_resource_pack(const String &p_pack);
void _add_property_info_bind(const Dictionary &p_info);
+ Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false);
+
protected:
static void _bind_methods();
public:
+ static const int CONFIG_VERSION = 4;
+
void set_setting(const String &p_setting, const Variant &p_value);
Variant get_setting(const String &p_setting) const;
@@ -149,8 +154,6 @@ public:
void set_disable_feature_overrides(bool p_disable);
- void register_global_defaults();
-
bool is_using_datapack() const;
void set_registering_order(bool p_enable);
diff --git a/core/ref_ptr.cpp b/core/ref_ptr.cpp
index e3ef817df1..961f143e5c 100644
--- a/core/ref_ptr.cpp
+++ b/core/ref_ptr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,8 +30,8 @@
#include "ref_ptr.h"
-#include "reference.h"
-#include "resource.h"
+#include "core/reference.h"
+#include "core/resource.h"
void RefPtr::operator=(const RefPtr &p_other) {
diff --git a/core/ref_ptr.h b/core/ref_ptr.h
index a074718d22..f745ababa1 100644
--- a/core/ref_ptr.h
+++ b/core/ref_ptr.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
* It's basically an opaque container of a Reference reference, so Variant can use it.
*/
-#include "rid.h"
+#include "core/rid.h"
class RefPtr {
diff --git a/core/reference.cpp b/core/reference.cpp
index 6e1520d81d..7b5145184a 100644
--- a/core/reference.cpp
+++ b/core/reference.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "reference.h"
-#include "script_language.h"
+#include "core/script_language.h"
bool Reference::init_ref() {
@@ -139,8 +139,8 @@ void WeakRef::set_ref(const REF &p_ref) {
ref = p_ref.is_valid() ? p_ref->get_instance_id() : 0;
}
-WeakRef::WeakRef() {
- ref = 0;
+WeakRef::WeakRef() :
+ ref(0) {
}
void WeakRef::_bind_methods() {
diff --git a/core/reference.h b/core/reference.h
index 25e02180fa..f3fcc922c7 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef REFERENCE_H
#define REFERENCE_H
-#include "class_db.h"
-#include "object.h"
-#include "ref_ptr.h"
-#include "safe_refcount.h"
+#include "core/class_db.h"
+#include "core/object.h"
+#include "core/ref_ptr.h"
+#include "core/safe_refcount.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 859015f44b..97c96b4018 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,45 +30,46 @@
#include "register_core_types.h"
-#include "bind/core_bind.h"
-#include "class_db.h"
-#include "compressed_translation.h"
+#include "core/bind/core_bind.h"
+#include "core/class_db.h"
+#include "core/compressed_translation.h"
+#include "core/core_string_names.h"
+#include "core/engine.h"
+#include "core/func_ref.h"
+#include "core/input_map.h"
+#include "core/io/config_file.h"
+#include "core/io/http_client.h"
+#include "core/io/image_loader.h"
+#include "core/io/marshalls.h"
+#include "core/io/multiplayer_api.h"
+#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/packet_peer.h"
+#include "core/io/packet_peer_udp.h"
+#include "core/io/pck_packer.h"
+#include "core/io/resource_format_binary.h"
+#include "core/io/resource_importer.h"
+#include "core/io/stream_peer_ssl.h"
+#include "core/io/tcp_server.h"
+#include "core/io/translation_loader_po.h"
#include "core/io/xml_parser.h"
-#include "core_string_names.h"
-#include "engine.h"
-#include "func_ref.h"
-#include "geometry.h"
-#include "input_map.h"
-#include "io/config_file.h"
-#include "io/http_client.h"
-#include "io/image_loader.h"
-#include "io/marshalls.h"
-#include "io/multiplayer_api.h"
-#include "io/networked_multiplayer_peer.h"
-#include "io/packet_peer.h"
-#include "io/packet_peer_udp.h"
-#include "io/pck_packer.h"
-#include "io/resource_format_binary.h"
-#include "io/resource_import.h"
-#include "io/stream_peer_ssl.h"
-#include "io/tcp_server.h"
-#include "io/translation_loader_po.h"
-#include "math/a_star.h"
-#include "math/expression.h"
-#include "math/triangle_mesh.h"
-#include "os/input.h"
-#include "os/main_loop.h"
-#include "packed_data_container.h"
-#include "path_remap.h"
-#include "project_settings.h"
-#include "translation.h"
-
-#include "undo_redo.h"
-static ResourceFormatSaverBinary *resource_saver_binary = NULL;
-static ResourceFormatLoaderBinary *resource_loader_binary = NULL;
-static ResourceFormatImporter *resource_format_importer = NULL;
-
-static ResourceFormatLoaderImage *resource_format_image = NULL;
+#include "core/math/a_star.h"
+#include "core/math/expression.h"
+#include "core/math/geometry.h"
+#include "core/math/random_number_generator.h"
+#include "core/math/triangle_mesh.h"
+#include "core/os/input.h"
+#include "core/os/main_loop.h"
+#include "core/packed_data_container.h"
+#include "core/path_remap.h"
+#include "core/project_settings.h"
+#include "core/translation.h"
+#include "core/undo_redo.h"
+
+static Ref<ResourceFormatSaverBinary> resource_saver_binary;
+static Ref<ResourceFormatLoaderBinary> resource_loader_binary;
+static Ref<ResourceFormatImporter> resource_format_importer;
+static Ref<ResourceFormatLoaderImage> resource_format_image;
+static Ref<TranslationLoaderPO> resource_format_po;
static _ResourceLoader *_resource_loader = NULL;
static _ResourceSaver *_resource_saver = NULL;
@@ -76,7 +77,6 @@ static _OS *_os = NULL;
static _Engine *_engine = NULL;
static _ClassDB *_classdb = NULL;
static _Marshalls *_marshalls = NULL;
-static TranslationLoaderPO *resource_format_po = NULL;
static _JSON *_json = NULL;
static IP *ip = NULL;
@@ -99,24 +99,25 @@ void register_core_types() {
_global_mutex = Mutex::create();
StringName::setup();
+ ResourceLoader::initialize();
register_global_constants();
register_variant_methods();
CoreStringNames::create();
- resource_format_po = memnew(TranslationLoaderPO);
+ resource_format_po.instance();
ResourceLoader::add_resource_format_loader(resource_format_po);
- resource_saver_binary = memnew(ResourceFormatSaverBinary);
+ resource_saver_binary.instance();
ResourceSaver::add_resource_format_saver(resource_saver_binary);
- resource_loader_binary = memnew(ResourceFormatLoaderBinary);
+ resource_loader_binary.instance();
ResourceLoader::add_resource_format_loader(resource_loader_binary);
- resource_format_importer = memnew(ResourceFormatImporter);
+ resource_format_importer.instance();
ResourceLoader::add_resource_format_loader(resource_format_importer);
- resource_format_image = memnew(ResourceFormatLoaderImage);
+ resource_format_image.instance();
ResourceLoader::add_resource_format_loader(resource_format_image);
ClassDB::register_class<Object>();
@@ -142,13 +143,14 @@ void register_core_types() {
ClassDB::register_virtual_class<InputEventGesture>();
ClassDB::register_class<InputEventMagnifyGesture>();
ClassDB::register_class<InputEventPanGesture>();
+ ClassDB::register_class<InputEventMIDI>();
ClassDB::register_class<FuncRef>();
ClassDB::register_virtual_class<StreamPeer>();
ClassDB::register_class<StreamPeerBuffer>();
- ClassDB::register_custom_instance_class<StreamPeerTCP>();
- ClassDB::register_custom_instance_class<TCP_Server>();
- ClassDB::register_custom_instance_class<PacketPeerUDP>();
+ ClassDB::register_class<StreamPeerTCP>();
+ ClassDB::register_class<TCP_Server>();
+ ClassDB::register_class<PacketPeerUDP>();
ClassDB::register_custom_instance_class<StreamPeerSSL>();
ClassDB::register_virtual_class<IP>();
ClassDB::register_virtual_class<PacketPeer>();
@@ -156,7 +158,6 @@ void register_core_types() {
ClassDB::register_virtual_class<NetworkedMultiplayerPeer>();
ClassDB::register_class<MultiplayerAPI>();
ClassDB::register_class<MainLoop>();
- //ClassDB::register_type<OptimizedSaver>();
ClassDB::register_class<Translation>();
ClassDB::register_class<PHashTranslation>();
ClassDB::register_class<UndoRedo>();
@@ -165,6 +166,9 @@ void register_core_types() {
ClassDB::register_virtual_class<ResourceInteractiveLoader>();
+ ClassDB::register_class<ResourceFormatLoader>();
+ ClassDB::register_class<ResourceFormatSaver>();
+
ClassDB::register_class<_File>();
ClassDB::register_class<_Directory>();
ClassDB::register_class<_Thread>();
@@ -181,6 +185,7 @@ void register_core_types() {
ClassDB::register_virtual_class<PackedDataContainerRef>();
ClassDB::register_class<AStar>();
ClassDB::register_class<EncodedObjectAsID>();
+ ClassDB::register_class<RandomNumberGenerator>();
ClassDB::register_class<JSONParseResult>();
@@ -200,6 +205,7 @@ void register_core_types() {
void register_core_settings() {
//since in register core types, globals may not e present
GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16));
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater"));
}
void register_core_singletons() {
@@ -246,20 +252,26 @@ void unregister_core_types() {
memdelete(_geometry);
- if (resource_format_image)
- memdelete(resource_format_image);
- if (resource_saver_binary)
- memdelete(resource_saver_binary);
- if (resource_loader_binary)
- memdelete(resource_loader_binary);
- if (resource_format_importer)
- memdelete(resource_format_importer);
+ ResourceLoader::remove_resource_format_loader(resource_format_image);
+ resource_format_image.unref();
+
+ ResourceSaver::remove_resource_format_saver(resource_saver_binary);
+ resource_saver_binary.unref();
+
+ ResourceLoader::remove_resource_format_loader(resource_loader_binary);
+ resource_loader_binary.unref();
- memdelete(resource_format_po);
+ ResourceLoader::remove_resource_format_loader(resource_format_importer);
+ resource_format_importer.unref();
+
+ ResourceLoader::remove_resource_format_loader(resource_format_po);
+ resource_format_po.unref();
if (ip)
memdelete(ip);
+ ResourceLoader::finalize();
+
ObjectDB::cleanup();
unregister_variant_methods();
diff --git a/core/register_core_types.h b/core/register_core_types.h
index 201da5cd07..b5a6aa985b 100644
--- a/core/register_core_types.h
+++ b/core/register_core_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/resource.cpp b/core/resource.cpp
index 3078eb135a..74c93cd790 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,11 +30,12 @@
#include "resource.h"
-#include "core_string_names.h"
-#include "io/resource_loader.h"
-#include "os/file_access.h"
+#include "core/core_string_names.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
+#include "core/script_language.h"
#include "scene/main/node.h" //only so casting works
-#include "script_language.h"
+
#include <stdio.h>
void Resource::emit_changed() {
@@ -230,7 +231,7 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
Variant p = get(E->get().name);
if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) {
- p = p.duplicate(p_subresources); //does not make a long of sense but should work?
+ r->set(E->get().name, p.duplicate(p_subresources));
} else if (p.get_type() == Variant::OBJECT && (p_subresources || (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) {
RES sr = p;
@@ -378,9 +379,9 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("duplicate", "subresources"), &Resource::duplicate, DEFVAL(false));
ADD_SIGNAL(MethodInfo("changed"));
ADD_GROUP("Resource", "resource_");
- ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "resource_local_to_scene"), "set_local_to_scene", "is_local_to_scene");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resource_local_to_scene"), "set_local_to_scene", "is_local_to_scene");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_path", "get_path");
- ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "resource_name"), "set_name", "get_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_name"), "set_name", "get_name");
BIND_VMETHOD(MethodInfo("_setup_local_to_scene"));
}
diff --git a/core/resource.h b/core/resource.h
index 60c63bfe7f..a4d9e998ac 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,12 @@
#ifndef RESOURCE_H
#define RESOURCE_H
-#include "class_db.h"
-#include "object.h"
-#include "ref_ptr.h"
-#include "reference.h"
-#include "safe_refcount.h"
-#include "self_list.h"
+#include "core/class_db.h"
+#include "core/object.h"
+#include "core/ref_ptr.h"
+#include "core/reference.h"
+#include "core/safe_refcount.h"
+#include "core/self_list.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/core/rid.cpp b/core/rid.cpp
index 9661af9271..73cf7f24bb 100644
--- a/core/rid.cpp
+++ b/core/rid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/rid.h b/core/rid.h
index 42306aea36..c7a71a03a0 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,11 @@
#ifndef RID_H
#define RID_H
-#include "list.h"
-#include "os/memory.h"
-#include "safe_refcount.h"
-#include "set.h"
-#include "typedefs.h"
+#include "core/list.h"
+#include "core/os/memory.h"
+#include "core/safe_refcount.h"
+#include "core/set.h"
+#include "core/typedefs.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -118,7 +118,6 @@ protected:
p_rid._data->_owner = NULL;
}
-#
#endif
public:
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index 00628a4ab3..e10cb8b5f8 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
-#include "vector.h"
+#include "core/vector.h"
template <typename T>
class RingBuffer {
@@ -135,6 +135,12 @@ public:
return p_n;
};
+ inline int decrease_write(int p_n) {
+ p_n = MIN(p_n, data_left());
+ inc(write_pos, size_mask + 1 - p_n);
+ return p_n;
+ }
+
Error write(const T &p_v) {
ERR_FAIL_COND_V(space_left() < 1, FAILED);
data.write[inc(write_pos, 1)] = p_v;
diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp
index 692ff722f3..8b0b3c3151 100644
--- a/core/safe_refcount.cpp
+++ b/core/safe_refcount.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/safe_refcount.h b/core/safe_refcount.h
index 36bcf5e576..f6b8f80271 100644
--- a/core/safe_refcount.h
+++ b/core/safe_refcount.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,9 @@
#ifndef SAFE_REFCOUNT_H
#define SAFE_REFCOUNT_H
-#include "os/mutex.h"
-/* x86/x86_64 GCC */
-
+#include "core/os/mutex.h"
+#include "core/typedefs.h"
#include "platform_config.h"
-#include "typedefs.h"
// Atomic functions, these are used for multithread safe reference counters!
diff --git a/core/script_debugger_local.cpp b/core/script_debugger_local.cpp
index 6949b5802b..ac4dafcf59 100644
--- a/core/script_debugger_local.cpp
+++ b/core/script_debugger_local.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "script_debugger_local.h"
-#include "scene/main/scene_tree.h"
-#include "os/os.h"
+#include "core/os/os.h"
+#include "scene/main/scene_tree.h"
void ScriptDebuggerLocal::debug(ScriptLanguage *p_script, bool p_can_continue) {
diff --git a/core/script_debugger_local.h b/core/script_debugger_local.h
index 7eea6ef215..19151d4cb0 100644
--- a/core/script_debugger_local.h
+++ b/core/script_debugger_local.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef SCRIPT_DEBUGGER_LOCAL_H
#define SCRIPT_DEBUGGER_LOCAL_H
-#include "list.h"
-#include "script_language.h"
+#include "core/list.h"
+#include "core/script_language.h"
class ScriptDebuggerLocal : public ScriptDebugger {
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 2b9b5d6037..e7ff7a3aef 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,12 +30,12 @@
#include "script_debugger_remote.h"
-#include "engine.h"
-#include "io/ip.h"
-#include "io/marshalls.h"
-#include "os/input.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/engine.h"
+#include "core/io/ip.h"
+#include "core/io/marshalls.h"
+#include "core/os/input.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "scene/main/node.h"
#include "scene/resources/packed_scene.h"
@@ -77,18 +77,19 @@ Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_por
for (int i = 0; i < tries; i++) {
if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
+ print_verbose("Remote Debugger: Connected!");
break;
} else {
const int ms = waits[i];
OS::get_singleton()->delay_usec(ms * 1000);
- ERR_PRINTS("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec.");
+ print_verbose("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec.");
};
};
if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
- ERR_PRINTS("Remote Debugger: Unable to connect.");
+ ERR_PRINTS("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()));
return FAILED;
};
@@ -97,36 +98,6 @@ Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_por
return OK;
}
-static int _ScriptDebuggerRemote_found_id = 0;
-static Object *_ScriptDebuggerRemote_find = NULL;
-static void _ScriptDebuggerRemote_debug_func(Object *p_obj) {
-
- if (_ScriptDebuggerRemote_find == p_obj) {
- _ScriptDebuggerRemote_found_id = p_obj->get_instance_id();
- }
-}
-
-static ObjectID safe_get_instance_id(const Variant &p_v) {
-
- Object *o = p_v;
- if (o == NULL)
- return 0;
- else {
-
- REF r = p_v;
- if (r.is_valid()) {
-
- return r->get_instance_id();
- } else {
-
- _ScriptDebuggerRemote_found_id = 0;
- _ScriptDebuggerRemote_find = NULL;
- ObjectDB::debug_objects(_ScriptDebuggerRemote_debug_func);
- return _ScriptDebuggerRemote_found_id;
- }
- }
-}
-
void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_variable) {
packet_peer_stream->put_var(p_name);
@@ -137,7 +108,7 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_
}
int len = 0;
- Error err = encode_variant(var, NULL, len);
+ Error err = encode_variant(var, NULL, len, true);
if (err != OK)
ERR_PRINT("Failed to encode variant");
@@ -168,10 +139,6 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
ERR_FAIL();
}
- if (allow_focus_steal_pid) {
- OS::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid);
- }
-
packet_peer_stream->put_var("debug_enter");
packet_peer_stream->put_var(2);
packet_peer_stream->put_var(p_can_continue);
@@ -344,6 +311,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
} else {
OS::get_singleton()->delay_usec(10000);
+ OS::get_singleton()->process_and_drop_events();
}
}
@@ -607,8 +575,14 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) {
for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) {
String script_path = sc->key() == si->get_script().ptr() ? "" : sc->key()->get_path().get_file() + "/";
- PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key());
- properties.push_back(PropertyDesc(pi, E->value()));
+ if (E->value().get_type() == Variant::OBJECT) {
+ Variant id = ((Object *)E->value())->get_instance_id();
+ PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
+ properties.push_back(PropertyDesc(pi, id));
+ } else {
+ PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key());
+ properties.push_back(PropertyDesc(pi, E->value()));
+ }
}
}
}
@@ -621,8 +595,14 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
Map<StringName, Variant> constants;
s->get_constants(&constants);
for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
- PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key());
- properties.push_front(PropertyDesc(pi, E->value()));
+ if (E->value().get_type() == Variant::OBJECT) {
+ Variant id = ((Object *)E->value())->get_instance_id();
+ PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
+ properties.push_front(PropertyDesc(pi, E->value()));
+ } else {
+ PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key());
+ properties.push_front(PropertyDesc(pi, E->value()));
+ }
}
}
}
@@ -661,11 +641,13 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
prop.push_back(Variant());
} else {
prop.push_back(pi.hint);
- if (res.is_null())
- prop.push_back(pi.hint_string);
- else
- prop.push_back(String("RES:") + res->get_path());
+ prop.push_back(pi.hint_string);
prop.push_back(pi.usage);
+
+ if (!res.is_null()) {
+ var = res->get_path();
+ }
+
prop.push_back(var);
}
send_props.push_back(prop);
@@ -1073,10 +1055,6 @@ void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p
physics_frame_time = p_physics_frame_time;
}
-void ScriptDebuggerRemote::set_allow_focus_steal_pid(OS::ProcessID p_pid) {
- allow_focus_steal_pid = p_pid;
-}
-
ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func = NULL;
ScriptDebuggerRemote::ScriptDebuggerRemote() :
@@ -1084,21 +1062,20 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
max_frame_functions(16),
skip_profile_frame(false),
reload_all_scripts(false),
- tcp_client(StreamPeerTCP::create_ref()),
+ tcp_client(Ref<StreamPeerTCP>(memnew(StreamPeerTCP))),
packet_peer_stream(Ref<PacketPeerStream>(memnew(PacketPeerStream))),
last_perf_time(0),
performance(Engine::get_singleton()->get_singleton_object("Performance")),
requested_quit(false),
mutex(Mutex::create()),
- max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")),
max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
- max_errors_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_frame")),
- char_count(0),
n_messages_dropped(0),
+ max_errors_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_frame")),
n_errors_dropped(0),
+ max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")),
+ char_count(0),
last_msec(0),
msec_count(0),
- allow_focus_steal_pid(0),
locking(false),
poll_every(0),
request_scene_tree(NULL),
@@ -1115,7 +1092,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
eh.userdata = this;
add_error_handler(&eh);
- profile_info.resize(CLAMP(int(ProjectSettings::get_singleton()->get("debug/settings/profiler/max_functions")), 128, 65535));
+ profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
profile_info_ptrs.resize(profile_info.size());
}
diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h
index b68fc4f9c9..1fc9d7c7f1 100644
--- a/core/script_debugger_remote.h
+++ b/core/script_debugger_remote.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,11 @@
#ifndef SCRIPT_DEBUGGER_REMOTE_H
#define SCRIPT_DEBUGGER_REMOTE_H
-#include "io/packet_peer.h"
-#include "io/stream_peer_tcp.h"
-#include "list.h"
-#include "os/os.h"
-#include "script_language.h"
+#include "core/io/packet_peer.h"
+#include "core/io/stream_peer_tcp.h"
+#include "core/list.h"
+#include "core/os/os.h"
+#include "core/script_language.h"
class ScriptDebuggerRemote : public ScriptDebugger {
@@ -99,8 +99,6 @@ class ScriptDebuggerRemote : public ScriptDebugger {
uint64_t last_msec;
uint64_t msec_count;
- OS::ProcessID allow_focus_steal_pid;
-
bool locking; //hack to avoid a deadloop
static void _print_handler(void *p_this, const String &p_string, bool p_error);
@@ -174,8 +172,6 @@ public:
virtual void profiling_end();
virtual void profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
- void set_allow_focus_steal_pid(OS::ProcessID p_pid);
-
ScriptDebuggerRemote();
~ScriptDebuggerRemote();
};
diff --git a/core/script_language.cpp b/core/script_language.cpp
index e146fb773c..1c244661b0 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,13 +29,15 @@
/*************************************************************************/
#include "script_language.h"
-#include "project_settings.h"
+
+#include "core/project_settings.h"
ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES];
int ScriptServer::_language_count = 0;
bool ScriptServer::scripting_enabled = true;
bool ScriptServer::reload_scripts_on_save = false;
+bool ScriptServer::languages_finished = false;
ScriptEditRequestFunction ScriptServer::edit_request_func = NULL;
void Script::_notification(int p_what) {
@@ -129,6 +131,7 @@ void ScriptServer::finish_languages() {
_languages[i]->finish();
}
global_classes_clear();
+ languages_finished = true;
}
void ScriptServer::set_reload_scripts_on_save(bool p_enable) {
@@ -375,7 +378,7 @@ ScriptDebugger::ScriptDebugger() {
bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_value) {
- if (build_failed)
+ if (script->is_placeholder_fallback_enabled())
return false;
if (values.has(p_name)) {
@@ -406,7 +409,12 @@ bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) co
return true;
}
- if (!build_failed) {
+ if (constants.has(p_name)) {
+ r_ret = constants[p_name];
+ return true;
+ }
+
+ if (!script->is_placeholder_fallback_enabled()) {
Variant defval;
if (script->get_property_default_value(p_name, defval)) {
r_ret = defval;
@@ -419,7 +427,7 @@ bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) co
void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
- if (build_failed) {
+ if (script->is_placeholder_fallback_enabled()) {
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
p_properties->push_back(E->get());
}
@@ -441,6 +449,13 @@ Variant::Type PlaceHolderScriptInstance::get_property_type(const StringName &p_n
*r_is_valid = true;
return values[p_name].get_type();
}
+
+ if (constants.has(p_name)) {
+ if (r_is_valid)
+ *r_is_valid = true;
+ return constants[p_name].get_type();
+ }
+
if (r_is_valid)
*r_is_valid = false;
@@ -449,7 +464,7 @@ Variant::Type PlaceHolderScriptInstance::get_property_type(const StringName &p_n
void PlaceHolderScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
- if (build_failed)
+ if (script->is_placeholder_fallback_enabled())
return;
if (script.is_valid()) {
@@ -458,7 +473,7 @@ void PlaceHolderScriptInstance::get_method_list(List<MethodInfo> *p_list) const
}
bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
- if (build_failed)
+ if (script->is_placeholder_fallback_enabled())
return false;
if (script.is_valid()) {
@@ -469,8 +484,6 @@ bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, const Map<StringName, Variant> &p_values) {
- build_failed = false;
-
Set<StringName> new_values;
for (const List<PropertyInfo>::Element *E = p_properties.front(); E; E = E->next()) {
@@ -512,11 +525,14 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c
owner->_change_notify();
}
//change notify
+
+ constants.clear();
+ script->get_constants(&constants);
}
void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid) {
- if (build_failed) {
+ if (script->is_placeholder_fallback_enabled()) {
Map<StringName, Variant>::Element *E = values.find(p_name);
if (E) {
@@ -526,8 +542,8 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name,
}
bool found = false;
- for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_name) {
+ for (const List<PropertyInfo>::Element *F = properties.front(); F; F = F->next()) {
+ if (F->get().name == p_name) {
found = true;
break;
}
@@ -543,7 +559,7 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name,
Variant PlaceHolderScriptInstance::property_get_fallback(const StringName &p_name, bool *r_valid) {
- if (build_failed) {
+ if (script->is_placeholder_fallback_enabled()) {
const Map<StringName, Variant>::Element *E = values.find(p_name);
if (E) {
@@ -551,6 +567,13 @@ Variant PlaceHolderScriptInstance::property_get_fallback(const StringName &p_nam
*r_valid = true;
return E->value();
}
+
+ E = constants.find(p_name);
+ if (E) {
+ if (r_valid)
+ *r_valid = true;
+ return E->value();
+ }
}
if (r_valid)
diff --git a/core/script_language.h b/core/script_language.h
index 573e7b4fa1..65fb0f0268 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,11 @@
#ifndef SCRIPT_LANGUAGE_H
#define SCRIPT_LANGUAGE_H
-#include "io/multiplayer_api.h"
-#include "map.h"
-#include "pair.h"
-#include "resource.h"
+#include "core/io/multiplayer_api.h"
+#include "core/map.h"
+#include "core/pair.h"
+#include "core/resource.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -53,6 +54,7 @@ class ScriptServer {
static int _language_count;
static bool scripting_enabled;
static bool reload_scripts_on_save;
+ static bool languages_finished;
struct GlobalScriptClass {
StringName language;
@@ -90,6 +92,8 @@ public:
static void init_languages();
static void finish_languages();
+
+ static bool are_languages_finished() { return languages_finished; }
};
class ScriptInstance;
@@ -127,6 +131,7 @@ public:
virtual MethodInfo get_method_info(const StringName &p_method) const = 0;
virtual bool is_tool() const = 0;
+ virtual bool is_valid() const = 0;
virtual ScriptLanguage *get_language() const = 0;
@@ -144,6 +149,8 @@ public:
virtual void get_constants(Map<StringName, Variant> *p_constants) {}
virtual void get_members(Set<StringName> *p_constants) {}
+ virtual bool is_placeholder_fallback_enabled() const { return false; }
+
Script() {}
};
@@ -329,11 +336,10 @@ class PlaceHolderScriptInstance : public ScriptInstance {
Object *owner;
List<PropertyInfo> properties;
Map<StringName, Variant> values;
+ Map<StringName, Variant> constants;
ScriptLanguage *language;
Ref<Script> script;
- bool build_failed;
-
public:
virtual bool set(const StringName &p_name, const Variant &p_value);
virtual bool get(const StringName &p_name, Variant &r_ret) const;
@@ -359,13 +365,10 @@ public:
void update(const List<PropertyInfo> &p_properties, const Map<StringName, Variant> &p_values); //likely changed in editor
- void set_build_failed(bool p_build_failed) { build_failed = p_build_failed; }
- bool get_build_failed() const { return build_failed; }
-
virtual bool is_placeholder() const { return true; }
- virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid);
- virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid);
+ virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = NULL);
+ virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = NULL);
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
diff --git a/core/self_list.h b/core/self_list.h
index 6e84e1cd5f..314d440977 100644
--- a/core/self_list.h
+++ b/core/self_list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef SELF_LIST_H
#define SELF_LIST_H
-#include "typedefs.h"
+#include "core/typedefs.h"
template <class T>
class SelfList {
diff --git a/core/set.h b/core/set.h
index d79dd81644..81250068af 100644
--- a/core/set.h
+++ b/core/set.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef SET_H
#define SET_H
-#include "os/memory.h"
-#include "typedefs.h"
+#include "core/os/memory.h"
+#include "core/typedefs.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -595,6 +595,7 @@ public:
return e;
}
+ inline bool empty() const { return _data.size_cache == 0; }
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
diff --git a/core/simple_type.h b/core/simple_type.h
index a645d03181..d5aa47d54f 100644
--- a/core/simple_type.h
+++ b/core/simple_type.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/sort.h b/core/sort_array.h
index 97983829e1..0f258aec3e 100644
--- a/core/sort.h
+++ b/core/sort_array.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* sort.h */
+/* sort_array.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,13 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SORT_H
-#define SORT_H
+#ifndef SORT_ARRAY_H
+#define SORT_ARRAY_H
-#include "typedefs.h"
-/**
- @author ,,, <red@lunatea>
-*/
+#include "core/typedefs.h"
#define ERR_BAD_COMPARE(cond) \
if (unlikely(cond)) { \
@@ -330,4 +327,4 @@ public:
}
};
-#endif
+#endif // SORT_ARRAY_H
diff --git a/core/string_buffer.h b/core/string_buffer.h
index 5d3be0ecf1..835991bc87 100644
--- a/core/string_buffer.h
+++ b/core/string_buffer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,7 @@
#ifndef STRING_BUFFER_H
#define STRING_BUFFER_H
-#include "ustring.h"
-#include <string.h>
+#include "core/ustring.h"
template <int SHORT_BUFFER_SIZE = 64>
class StringBuffer {
diff --git a/core/string_builder.cpp b/core/string_builder.cpp
index 8ab7e0ea8f..35526e0d70 100644
--- a/core/string_builder.cpp
+++ b/core/string_builder.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string_builder.h b/core/string_builder.h
index 596b3bf730..40d70e8f45 100644
--- a/core/string_builder.h
+++ b/core/string_builder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string_db.cpp b/core/string_name.cpp
index 067e4493a1..10b71ad3ac 100644
--- a/core/string_db.cpp
+++ b/core/string_name.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* string_db.cpp */
+/* string_name.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "string_db.h"
+#include "string_name.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
StaticCString StaticCString::create(const char *p_ptr) {
StaticCString scs;
diff --git a/core/string_db.h b/core/string_name.h
index 965385b136..0984b0181f 100644
--- a/core/string_db.h
+++ b/core/string_name.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* string_db.h */
+/* string_name.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef STRING_DB_H
-#define STRING_DB_H
+#ifndef STRING_NAME_H
+#define STRING_NAME_H
-#include "os/mutex.h"
-#include "safe_refcount.h"
-#include "ustring.h"
+#include "core/os/mutex.h"
+#include "core/safe_refcount.h"
+#include "core/ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -169,4 +169,4 @@ public:
StringName _scs_create(const char *p_chr);
-#endif
+#endif // STRING_NAME_H
diff --git a/core/translation.cpp b/core/translation.cpp
index 82a16d0b17..6921f1d9f1 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,9 @@
#include "translation.h"
-#include "io/resource_loader.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/io/resource_loader.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
// ISO 639-1 language codes, with the addition of glibc locales with their
// regional identifiers. This list must match the language names (in English)
@@ -938,11 +938,14 @@ void TranslationServer::set_locale(const String &p_locale) {
if (!is_locale_valid(univ_locale)) {
String trimmed_locale = get_trimmed_locale(univ_locale);
+ print_verbose(vformat("Unsupported locale '%s', falling back to '%s'.", p_locale, trimmed_locale));
- ERR_EXPLAIN("Invalid locale: " + trimmed_locale);
- ERR_FAIL_COND(!is_locale_valid(trimmed_locale));
-
- locale = trimmed_locale;
+ if (!is_locale_valid(trimmed_locale)) {
+ ERR_PRINTS(vformat("Unsupported locale '%s', falling back to 'en'.", trimmed_locale));
+ locale = "en";
+ } else {
+ locale = trimmed_locale;
+ }
} else {
locale = univ_locale;
}
@@ -1049,7 +1052,7 @@ StringName TranslationServer::translate(const StringName &p_message) const {
if (fallback.length() >= 2) {
const CharType *fptr = &fallback[0];
- bool near_match = false;
+ near_match = false;
for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
const Ref<Translation> &t = E->get();
diff --git a/core/translation.h b/core/translation.h
index e7c0dcbc07..b12bad0d72 100644
--- a/core/translation.h
+++ b/core/translation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#ifndef TRANSLATION_H
#define TRANSLATION_H
-#include "resource.h"
+#include "core/resource.h"
class Translation : public Resource {
diff --git a/core/type_info.h b/core/type_info.h
index bf497f1e5f..c38688fea1 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/typedefs.h b/core/typedefs.h
index 094f1bbfd5..03514466c0 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#define TYPEDEFS_H
#include <stddef.h>
+
/**
* Basic definitions and simple functions to be used everywhere.
*/
@@ -43,6 +44,7 @@
#define _MKSTR(m_x) _STR(m_x)
#endif
+//should always inline no matter what
#ifndef _ALWAYS_INLINE_
#if defined(__GNUC__) && (__GNUC__ >= 4)
@@ -57,10 +59,17 @@
#endif
+//should always inline, except in some cases because it makes debugging harder
#ifndef _FORCE_INLINE_
+
+#ifdef DISABLE_FORCED_INLINE
+#define _FORCE_INLINE_ inline
+#else
#define _FORCE_INLINE_ _ALWAYS_INLINE_
#endif
+#endif
+
//custom, gcc-safe offsetof, because gcc complains a lot.
template <class T>
T *_nullptr() {
@@ -96,19 +105,21 @@ T *_nullptr() {
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
#endif
-#include "int_types.h"
+#include "core/int_types.h"
-#include "error_list.h"
-#include "error_macros.h"
+#include "core/error_list.h"
+#include "core/error_macros.h"
/** Generic ABS function, for math uses please use Math::abs */
#ifndef ABS
-#define ABS(m_v) ((m_v < 0) ? (-(m_v)) : (m_v))
+#define ABS(m_v) (((m_v) < 0) ? (-(m_v)) : (m_v))
#endif
+#define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
+
#ifndef SGN
-#define SGN(m_v) ((m_v < 0) ? (-1.0) : (+1.0))
+#define SGN(m_v) (((m_v) < 0) ? (-1.0) : (+1.0))
#endif
#ifndef MIN
@@ -239,21 +250,34 @@ static inline int get_shift_from_power_of_2(unsigned int p_pixel) {
}
/** Swap 16 bits value for endianness */
+#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap16)
+#define BSWAP16(x) __builtin_bswap16(x)
+#else
static inline uint16_t BSWAP16(uint16_t x) {
return (x >> 8) | (x << 8);
}
+#endif
+
/** Swap 32 bits value for endianness */
+#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap32)
+#define BSWAP32(x) __builtin_bswap32(x)
+#else
static inline uint32_t BSWAP32(uint32_t x) {
return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
}
-/** Swap 64 bits value for endianness */
+#endif
+/** Swap 64 bits value for endianness */
+#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap64)
+#define BSWAP64(x) __builtin_bswap64(x)
+#else
static inline uint64_t BSWAP64(uint64_t x) {
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}
+#endif
/** When compiling with RTTI, we can add an "extra"
* layer of safeness in many operations, so dynamic_cast
@@ -296,4 +320,12 @@ struct _GlobalLock {
#define unlikely(x) x
#endif
+#if defined(__GNUC__)
+#define _PRINTF_FORMAT_ATTRIBUTE_2_0 __attribute__((format(printf, 2, 0)))
+#define _PRINTF_FORMAT_ATTRIBUTE_2_3 __attribute__((format(printf, 2, 3)))
+#else
+#define _PRINTF_FORMAT_ATTRIBUTE_2_0
+#define _PRINTF_FORMAT_ATTRIBUTE_2_3
+#endif
+
#endif // TYPEDEFS_H
diff --git a/core/ucaps.h b/core/ucaps.h
index 95bac1aac6..5dd81296dd 100644
--- a/core/ucaps.h
+++ b/core/ucaps.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 3d90608dd7..e13164d50f 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "undo_redo.h"
-#include "os/os.h"
+#include "core/os/os.h"
void UndoRedo::_discard_redo() {
@@ -234,7 +234,13 @@ void UndoRedo::_pop_history_tail() {
}
actions.remove(0);
- current_action--;
+ if (current_action >= 0) {
+ current_action--;
+ }
+}
+
+bool UndoRedo::is_commiting_action() const {
+ return commiting > 0;
}
void UndoRedo::commit_action() {
@@ -244,8 +250,9 @@ void UndoRedo::commit_action() {
if (action_level > 0)
return; //still nested
+ commiting++;
redo(); // perform action
-
+ commiting--;
if (callback && actions.size() > 0) {
callback(callback_ud, actions[actions.size() - 1].name);
}
@@ -258,17 +265,31 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
Operation &op = E->get();
Object *obj = ObjectDB::get_instance(op.object);
- if (!obj) {
- //corruption
- clear_history();
- ERR_FAIL_COND(!obj);
- }
+ if (!obj) //may have been deleted and this is fine
+ continue;
switch (op.type) {
case Operation::TYPE_METHOD: {
- obj->call(op.name, VARIANT_ARGS_FROM_ARRAY(op.args));
+ Vector<const Variant *> argptrs;
+ argptrs.resize(VARIANT_ARG_MAX);
+ int argc = 0;
+
+ for (int i = 0; i < VARIANT_ARG_MAX; i++) {
+ if (op.args[i].get_type() == Variant::NIL) {
+ break;
+ }
+ argptrs.write[i] = &op.args[i];
+ argc++;
+ }
+ argptrs.resize(argc);
+
+ Variant::CallError ce;
+ obj->call(op.name, (const Variant **)argptrs.ptr(), argc, ce);
+ if (ce.error != Variant::CallError::CALL_OK) {
+ ERR_PRINTS("Error calling method from signal '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, (const Variant **)argptrs.ptr(), argc, ce));
+ }
#ifdef TOOLS_ENABLED
Resource *res = Object::cast_to<Resource>(obj);
if (res)
@@ -305,6 +326,7 @@ bool UndoRedo::redo() {
if ((current_action + 1) >= actions.size())
return false; //nothing to redo
+
current_action++;
_process_operation_list(actions.write[current_action].do_ops.front());
@@ -321,11 +343,10 @@ bool UndoRedo::undo() {
_process_operation_list(actions.write[current_action].undo_ops.front());
current_action--;
version--;
-
return true;
}
-void UndoRedo::clear_history() {
+void UndoRedo::clear_history(bool p_increase_version) {
ERR_FAIL_COND(action_level > 0);
_discard_redo();
@@ -333,7 +354,8 @@ void UndoRedo::clear_history() {
while (actions.size())
_pop_history_tail();
- //version++;
+ if (p_increase_version)
+ version++;
}
String UndoRedo::get_current_action_name() const {
@@ -369,6 +391,7 @@ void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_ca
UndoRedo::UndoRedo() {
+ commiting = 0;
version = 1;
action_level = 0;
current_action = -1;
@@ -467,6 +490,7 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE));
ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action);
+ ClassDB::bind_method(D_METHOD("is_commiting_action"), &UndoRedo::is_commiting_action);
//ClassDB::bind_method(D_METHOD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
//ClassDB::bind_method(D_METHOD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method);
@@ -493,7 +517,7 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_undo_property", "object", "property", "value"), &UndoRedo::add_undo_property);
ClassDB::bind_method(D_METHOD("add_do_reference", "object"), &UndoRedo::add_do_reference);
ClassDB::bind_method(D_METHOD("add_undo_reference", "object"), &UndoRedo::add_undo_reference);
- ClassDB::bind_method(D_METHOD("clear_history"), &UndoRedo::clear_history);
+ ClassDB::bind_method(D_METHOD("clear_history", "increase_version"), &UndoRedo::clear_history, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_current_action_name"), &UndoRedo::get_current_action_name);
ClassDB::bind_method(D_METHOD("get_version"), &UndoRedo::get_version);
ClassDB::bind_method(D_METHOD("redo"), &UndoRedo::redo);
diff --git a/core/undo_redo.h b/core/undo_redo.h
index 3a17c78851..b626149ce6 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef UNDO_REDO_H
#define UNDO_REDO_H
-#include "object.h"
-#include "resource.h"
+#include "core/object.h"
+#include "core/resource.h"
class UndoRedo : public Object {
@@ -94,6 +94,8 @@ private:
MethodNotifyCallback method_callback;
PropertyNotifyCallback property_callback;
+ int commiting;
+
protected:
static void _bind_methods();
@@ -107,12 +109,13 @@ public:
void add_do_reference(Object *p_object);
void add_undo_reference(Object *p_object);
+ bool is_commiting_action() const;
void commit_action();
bool redo();
bool undo();
String get_current_action_name() const;
- void clear_history();
+ void clear_history(bool p_increase_version = true);
uint64_t get_version() const;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 96e3a3d784..ff8fcaaaaf 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,12 +30,13 @@
#include "ustring.h"
-#include "color.h"
-#include "math_funcs.h"
-#include "os/memory.h"
-#include "print_string.h"
-#include "ucaps.h"
-#include "variant.h"
+#include "core/color.h"
+#include "core/math/math_funcs.h"
+#include "core/os/memory.h"
+#include "core/print_string.h"
+#include "core/translation.h"
+#include "core/ucaps.h"
+#include "core/variant.h"
#include "thirdparty/misc/md5.h"
#include "thirdparty/misc/sha256.h"
@@ -48,7 +49,7 @@
#endif
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
-#define snprintf _snprintf
+#define snprintf _snprintf_s
#endif
#define MAX_DIGITS 6
@@ -57,6 +58,9 @@
#define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
+const char CharString::_null = 0;
+const CharType String::_null = 0;
+
bool is_symbol(CharType c) {
return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
}
@@ -178,7 +182,7 @@ void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
resize(p_length + 1);
set(p_length, 0);
- CharType *dst = &operator[](0);
+ CharType *dst = ptrw();
for (int i = 0; i < p_length; i++) {
dst[i] = p_char[i];
@@ -249,7 +253,7 @@ String &String::operator+=(const String &p_str) {
resize(length() + p_str.size());
const CharType *src = p_str.c_str();
- CharType *dst = &operator[](0);
+ CharType *dst = ptrw();
set(length(), 0);
@@ -288,7 +292,7 @@ String &String::operator+=(const char *p_str) {
resize(from + src_len + 1);
- CharType *dst = &operator[](0);
+ CharType *dst = ptrw();
set(length(), 0);
@@ -585,6 +589,8 @@ String String::camelcase_to_underscore(bool lowercase) const {
bool is_upper = cstr[i] >= A && cstr[i] <= Z;
bool is_number = cstr[i] >= '0' && cstr[i] <= '9';
bool are_next_2_lower = false;
+ bool is_next_lower = false;
+ bool is_next_number = false;
bool was_precedent_upper = cstr[i - 1] >= A && cstr[i - 1] <= Z;
bool was_precedent_number = cstr[i - 1] >= '0' && cstr[i - 1] <= '9';
@@ -592,7 +598,18 @@ String String::camelcase_to_underscore(bool lowercase) const {
are_next_2_lower = cstr[i + 1] >= a && cstr[i + 1] <= z && cstr[i + 2] >= a && cstr[i + 2] <= z;
}
- bool should_split = ((is_upper && !was_precedent_upper && !was_precedent_number) || (was_precedent_upper && is_upper && are_next_2_lower) || (is_number && !was_precedent_number));
+ if (i + 1 < this->size()) {
+ is_next_lower = cstr[i + 1] >= a && cstr[i + 1] <= z;
+ is_next_number = cstr[i + 1] >= '0' && cstr[i + 1] <= '9';
+ }
+
+ const bool cond_a = is_upper && !was_precedent_upper && !was_precedent_number;
+ const bool cond_b = was_precedent_upper && is_upper && are_next_2_lower;
+ const bool cond_c = is_number && !was_precedent_number;
+ const bool can_break_number_letter = is_number && !was_precedent_number && is_next_lower;
+ const bool can_break_letter_number = !is_number && was_precedent_number && (is_next_lower || is_next_number);
+
+ bool should_split = cond_a || cond_b || cond_c || can_break_number_letter || can_break_letter_number;
if (should_split) {
new_string += this->substr(start_index, i - start_index) + "_";
start_index = i;
@@ -1342,6 +1359,9 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err));
+ if (!p_utf8)
+ return true;
+
String aux;
int cstr_size = 0;
@@ -1417,7 +1437,7 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
resize(str_size + 1);
- CharType *dst = &operator[](0);
+ CharType *dst = ptrw();
dst[str_size] = 0;
while (cstr_size) {
@@ -1827,8 +1847,8 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
int sign, expSign = false;
double fraction, dblExp;
const double *d;
- register const C *p;
- register int c;
+ const C *p;
+ int c;
int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional
* part. Under normal circumstances, it is
@@ -2376,6 +2396,10 @@ int String::find(const char *p_str, int p_from) const {
return -1;
}
+int String::find_char(const CharType &p_char, int p_from) const {
+ return _cowdata.find(p_char, p_from);
+}
+
int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
if (p_from < 0)
@@ -2760,16 +2784,13 @@ String String::format(const Variant &values, String placeholder) const {
if (value_arr.size() == 2) {
Variant v_key = value_arr[0];
- String key;
-
- key = v_key.get_construct_string();
+ String key = v_key;
if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
key = key.substr(1, key.length() - 2);
}
Variant v_val = value_arr[1];
- String val;
- val = v_val.get_construct_string();
+ String val = v_val;
if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
val = val.substr(1, val.length() - 2);
@@ -2781,8 +2802,7 @@ String String::format(const Variant &values, String placeholder) const {
}
} else { //Array structure ["RobotGuy","Logis","rookie"]
Variant v_val = values_arr[i];
- String val;
- val = v_val.get_construct_string();
+ String val = v_val;
if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
val = val.substr(1, val.length() - 2);
@@ -2801,8 +2821,8 @@ String String::format(const Variant &values, String placeholder) const {
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
- String key = E->get().get_construct_string();
- String val = d[E->get()].get_construct_string();
+ String key = E->get();
+ String val = d[E->get()];
if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
key = key.substr(1, key.length() - 2);
@@ -2928,12 +2948,12 @@ String String::left(int p_pos) const {
String String::right(int p_pos) const {
- if (p_pos >= size())
- return *this;
-
- if (p_pos < 0)
+ if (p_pos >= length())
return "";
+ if (p_pos <= 0)
+ return *this;
+
return substr(p_pos, (length() - p_pos));
}
@@ -3050,7 +3070,7 @@ String String::lstrip(const String &p_chars) const {
for (beg = 0; beg < len; beg++) {
- if (p_chars.find(&ptr()[beg]) == -1)
+ if (p_chars.find_char(get(beg)) == -1)
break;
}
@@ -3067,7 +3087,7 @@ String String::rstrip(const String &p_chars) const {
for (end = len - 1; end >= 0; end--) {
- if (p_chars.find(&ptr()[end]) == -1)
+ if (p_chars.find_char(get(end)) == -1)
break;
}
@@ -3091,7 +3111,7 @@ String String::simplify_path() const {
} else if (s.begins_with("user://")) {
drive = "user://";
- s = s.substr(6, s.length());
+ s = s.substr(7, s.length());
} else if (s.begins_with("/") || s.begins_with("\\")) {
drive = s.substr(0, 1);
@@ -3466,7 +3486,7 @@ String String::xml_unescape() const {
if (len == 0)
return String();
str.resize(len + 1);
- _xml_unescape(c_str(), l, &str[0]);
+ _xml_unescape(c_str(), l, str.ptrw());
str[len] = 0;
return str;
}
@@ -3568,9 +3588,12 @@ bool String::is_valid_integer() const {
bool String::is_valid_hex_number(bool p_with_prefix) const {
- int from = 0;
int len = length();
+ if (len == 0)
+ return false;
+
+ int from = 0;
if (len != 1 && (operator[](0) == '+' || operator[](0) == '-'))
from++;
@@ -4025,7 +4048,7 @@ String String::sprintf(const Array &values, bool *error) const {
str = str.pad_decimals(min_decimals);
// Show sign
- if (show_sign && value >= 0) {
+ if (show_sign && str.left(1) != "-") {
str = str.insert(0, "+");
}
@@ -4204,8 +4227,6 @@ String String::unquote() const {
return substr(1, length() - 2);
}
-#include "translation.h"
-
#ifdef TOOLS_ENABLED
String TTR(const String &p_text) {
diff --git a/core/ustring.h b/core/ustring.h
index 01397f6912..cb3d87378a 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,21 +28,56 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RSTRING_H
-#define RSTRING_H
+#ifndef USTRING_H
+#define USTRING_H
-#include "array.h"
-#include "cowdata.h"
-#include "typedefs.h"
-#include "vector.h"
+#include "core/array.h"
+#include "core/cowdata.h"
+#include "core/typedefs.h"
+#include "core/vector.h"
/**
- @author red <red@killy>
+ @author Juan Linietsky <reduzio@gmail.com>
*/
+template <class T>
+class CharProxy {
+ friend class CharString;
+ friend class String;
+
+ const int _index;
+ CowData<T> &_cowdata;
+ static const T _null = 0;
+
+ _FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &cowdata) :
+ _index(p_index),
+ _cowdata(cowdata) {}
+
+public:
+ _FORCE_INLINE_ operator T() const {
+ if (unlikely(_index == _cowdata.size()))
+ return _null;
+
+ return _cowdata.get(_index);
+ }
+
+ _FORCE_INLINE_ const T *operator&() const {
+ return _cowdata.ptr() + _index;
+ }
+
+ _FORCE_INLINE_ void operator=(const T &other) const {
+ _cowdata.set(_index, other);
+ }
+
+ _FORCE_INLINE_ void operator=(const CharProxy<T> &other) const {
+ _cowdata.set(_index, other.operator T());
+ }
+};
+
class CharString {
CowData<char> _cowdata;
+ static const char _null;
public:
_FORCE_INLINE_ char *ptrw() { return _cowdata.ptrw(); }
@@ -50,11 +85,15 @@ public:
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
Error resize(int p_size) { return _cowdata.resize(p_size); }
- _FORCE_INLINE_ char get(int p_index) { return _cowdata.get(p_index); }
- _FORCE_INLINE_ const char get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ char get(int p_index) const { return _cowdata.get(p_index); }
_FORCE_INLINE_ void set(int p_index, const char &p_elem) { _cowdata.set(p_index, p_elem); }
- _FORCE_INLINE_ char &operator[](int p_index) { return _cowdata.get_m(p_index); }
- _FORCE_INLINE_ const char &operator[](int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ const char &operator[](int p_index) const {
+ if (unlikely(p_index == _cowdata.size()))
+ return _null;
+
+ return _cowdata.get(p_index);
+ }
+ _FORCE_INLINE_ CharProxy<char> operator[](int p_index) { return CharProxy<char>(p_index, _cowdata); }
_FORCE_INLINE_ CharString() {}
_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
@@ -63,7 +102,7 @@ public:
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
const char *get_data() const;
- operator const char *() { return get_data(); };
+ operator const char *() const { return get_data(); };
};
typedef wchar_t CharType;
@@ -82,6 +121,7 @@ struct StrRange {
class String {
CowData<CharType> _cowdata;
+ static const CharType _null;
void copy_from(const char *p_cstr);
void copy_from(const CharType *p_cstr, const int p_clip_to = -1);
@@ -102,13 +142,18 @@ public:
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ CharType get(int p_index) { return _cowdata.get(p_index); }
- _FORCE_INLINE_ const CharType get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ CharType get(int p_index) const { return _cowdata.get(p_index); }
_FORCE_INLINE_ void set(int p_index, const CharType &p_elem) { _cowdata.set(p_index, p_elem); }
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
Error resize(int p_size) { return _cowdata.resize(p_size); }
- _FORCE_INLINE_ CharType &operator[](int p_index) { return _cowdata.get_m(p_index); }
- _FORCE_INLINE_ const CharType &operator[](int p_index) const { return _cowdata.get(p_index); }
+
+ _FORCE_INLINE_ const CharType &operator[](int p_index) const {
+ if (unlikely(p_index == _cowdata.size()))
+ return _null;
+
+ return _cowdata.get(p_index);
+ }
+ _FORCE_INLINE_ CharProxy<CharType> operator[](int p_index) { return CharProxy<CharType>(p_index, _cowdata); }
bool operator==(const String &p_str) const;
bool operator!=(const String &p_str) const;
@@ -149,7 +194,8 @@ public:
/* complex helpers */
String substr(int p_from, int p_chars) const;
int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
- int find(const char *p_str, int p_from) const; ///< return <0 if failed
+ int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed
+ int find_char(const CharType &p_char, int p_from = 0) const; ///< return <0 if failed
int find_last(const String &p_str) const; ///< return <0 if failed
int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive
int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed
@@ -366,4 +412,4 @@ String RTR(const String &);
bool is_symbol(CharType c);
bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);
-#endif
+#endif // USTRING_H
diff --git a/core/variant.cpp b/core/variant.cpp
index b0e97900a2..2ee2e8e293 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,14 +30,14 @@
#include "variant.h"
-#include "core_string_names.h"
-#include "io/marshalls.h"
-#include "math_funcs.h"
-#include "print_string.h"
-#include "resource.h"
+#include "core/core_string_names.h"
+#include "core/io/marshalls.h"
+#include "core/math/math_funcs.h"
+#include "core/print_string.h"
+#include "core/resource.h"
+#include "core/variant_parser.h"
#include "scene/gui/control.h"
#include "scene/main/node.h"
-#include "variant_parser.h"
String Variant::get_type_name(Variant::Type p_type) {
@@ -858,7 +858,7 @@ bool Variant::is_one() const {
// atomic types
case BOOL: {
- return _data._bool == true;
+ return _data._bool;
} break;
case INT: {
@@ -1662,7 +1662,17 @@ Variant::operator Transform() const {
return Transform(*_data._basis, Vector3());
else if (type == QUAT)
return Transform(Basis(*reinterpret_cast<const Quat *>(_data._mem)), Vector3());
- else
+ else if (type == TRANSFORM2D) {
+ const Transform2D &t = *_data._transform2d;
+ Transform m;
+ m.basis.elements[0][0] = t.elements[0][0];
+ m.basis.elements[1][0] = t.elements[0][1];
+ m.basis.elements[0][1] = t.elements[1][0];
+ m.basis.elements[1][1] = t.elements[1][1];
+ m.origin[0] = t.elements[2][0];
+ m.origin[1] = t.elements[2][1];
+ return m;
+ } else
return Transform();
}
@@ -1721,6 +1731,14 @@ Variant::operator RID() const {
else if (type == OBJECT && !_get_obj().ref.is_null()) {
return _get_obj().ref.get_rid();
} else if (type == OBJECT && _get_obj().obj) {
+#ifdef DEBUG_ENABLED
+ if (ScriptDebugger::get_singleton()) {
+ if (!ObjectDB::instance_validate(_get_obj().obj)) {
+ ERR_EXPLAIN("Invalid pointer (object was deleted)");
+ ERR_FAIL_V(RID());
+ };
+ };
+#endif
Variant::CallError ce;
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, NULL, 0, ce);
if (ce.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::_RID) {
@@ -2798,27 +2816,37 @@ uint32_t Variant::hash() const {
const PoolVector<uint8_t> &arr = *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
int len = arr.size();
- PoolVector<uint8_t>::Read r = arr.read();
-
- return hash_djb2_buffer((uint8_t *)&r[0], len);
+ if (likely(len)) {
+ PoolVector<uint8_t>::Read r = arr.read();
+ return hash_djb2_buffer((uint8_t *)&r[0], len);
+ } else {
+ return hash_djb2_one_64(0);
+ }
} break;
case POOL_INT_ARRAY: {
const PoolVector<int> &arr = *reinterpret_cast<const PoolVector<int> *>(_data._mem);
int len = arr.size();
- PoolVector<int>::Read r = arr.read();
-
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
+ if (likely(len)) {
+ PoolVector<int>::Read r = arr.read();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
+ } else {
+ return hash_djb2_one_64(0);
+ }
} break;
case POOL_REAL_ARRAY: {
const PoolVector<real_t> &arr = *reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
int len = arr.size();
- PoolVector<real_t>::Read r = arr.read();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
+ if (likely(len)) {
+ PoolVector<real_t>::Read r = arr.read();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
+ } else {
+ return hash_djb2_one_float(0.0);
+ }
} break;
case POOL_STRING_ARRAY: {
@@ -2826,10 +2854,13 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
const PoolVector<String> &arr = *reinterpret_cast<const PoolVector<String> *>(_data._mem);
int len = arr.size();
- PoolVector<String>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_32(r[i].hash(), hash);
+ if (likely(len)) {
+ PoolVector<String>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_32(r[i].hash(), hash);
+ }
}
return hash;
@@ -2839,48 +2870,54 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
const PoolVector<Vector2> &arr = *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
int len = arr.size();
- PoolVector<Vector2>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].x, hash);
- hash = hash_djb2_one_float(r[i].y, hash);
+ if (likely(len)) {
+ PoolVector<Vector2>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_float(r[i].x, hash);
+ hash = hash_djb2_one_float(r[i].y, hash);
+ }
}
return hash;
-
} break;
case POOL_VECTOR3_ARRAY: {
uint32_t hash = 5831;
const PoolVector<Vector3> &arr = *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
int len = arr.size();
- PoolVector<Vector3>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].x, hash);
- hash = hash_djb2_one_float(r[i].y, hash);
- hash = hash_djb2_one_float(r[i].z, hash);
+ if (likely(len)) {
+ PoolVector<Vector3>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_float(r[i].x, hash);
+ hash = hash_djb2_one_float(r[i].y, hash);
+ hash = hash_djb2_one_float(r[i].z, hash);
+ }
}
return hash;
-
} break;
case POOL_COLOR_ARRAY: {
uint32_t hash = 5831;
const PoolVector<Color> &arr = *reinterpret_cast<const PoolVector<Color> *>(_data._mem);
int len = arr.size();
- PoolVector<Color>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].r, hash);
- hash = hash_djb2_one_float(r[i].g, hash);
- hash = hash_djb2_one_float(r[i].b, hash);
- hash = hash_djb2_one_float(r[i].a, hash);
+ if (likely(len)) {
+ PoolVector<Color>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_float(r[i].r, hash);
+ hash = hash_djb2_one_float(r[i].g, hash);
+ hash = hash_djb2_one_float(r[i].b, hash);
+ hash = hash_djb2_one_float(r[i].a, hash);
+ }
}
return hash;
-
} break;
default: {}
}
diff --git a/core/variant.h b/core/variant.h
index 577a33aa4d..9215d15bf0 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,23 +35,23 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
-#include "aabb.h"
-#include "array.h"
-#include "color.h"
-#include "dictionary.h"
-#include "dvector.h"
-#include "face3.h"
-#include "io/ip_address.h"
-#include "matrix3.h"
-#include "node_path.h"
-#include "plane.h"
-#include "quat.h"
-#include "ref_ptr.h"
-#include "rid.h"
-#include "transform.h"
-#include "transform_2d.h"
-#include "ustring.h"
-#include "vector3.h"
+#include "core/array.h"
+#include "core/color.h"
+#include "core/dictionary.h"
+#include "core/io/ip_address.h"
+#include "core/math/aabb.h"
+#include "core/math/basis.h"
+#include "core/math/face3.h"
+#include "core/math/plane.h"
+#include "core/math/quat.h"
+#include "core/math/transform.h"
+#include "core/math/transform_2d.h"
+#include "core/math/vector3.h"
+#include "core/node_path.h"
+#include "core/pool_vector.h"
+#include "core/ref_ptr.h"
+#include "core/rid.h"
+#include "core/ustring.h"
class RefPtr;
class Object;
@@ -69,6 +69,13 @@ typedef PoolVector<Vector2> PoolVector2Array;
typedef PoolVector<Vector3> PoolVector3Array;
typedef PoolVector<Color> PoolColorArray;
+// Temporary workaround until c++11 alignas()
+#ifdef __GNUC__
+#define GCC_ALIGNED_8 __attribute__((aligned(8)))
+#else
+#define GCC_ALIGNED_8
+#endif
+
class Variant {
public:
// If this changes the table in variant_op must be updated
@@ -116,7 +123,7 @@ public:
};
private:
- friend class _VariantCall;
+ friend struct _VariantCall;
// Variant takes 20 bytes when real_t is float, and 36 if double
// it only allocates extra memory for aabb/matrix.
@@ -132,7 +139,6 @@ private:
_FORCE_INLINE_ const ObjData &_get_obj() const;
union {
-
bool _bool;
int64_t _int;
double _real;
@@ -142,7 +148,7 @@ private:
Transform *_transform;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
- } _data;
+ } _data GCC_ALIGNED_8;
void reference(const Variant &p_variant);
void clear();
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 8b18b274b6..25a0f3957c 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,11 +31,11 @@
#include "variant.h"
#include "core/color_names.inc"
-#include "core_string_names.h"
-#include "io/compression.h"
-#include "object.h"
-#include "os/os.h"
-#include "script_language.h"
+#include "core/core_string_names.h"
+#include "core/io/compression.h"
+#include "core/object.h"
+#include "core/os/os.h"
+#include "core/script_language.h"
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
@@ -155,9 +155,7 @@ struct _VariantCall {
funcdata.default_args = p_defaultarg;
funcdata._const = p_const;
funcdata.returns = p_has_return;
-#ifdef DEBUG_ENABLED
funcdata.return_type = p_return;
-#endif
if (p_argtype1.name) {
funcdata.arg_types.push_back(p_argtype1.type);
@@ -293,6 +291,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(String, is_valid_identifier);
VCALL_LOCALMEM0R(String, is_valid_integer);
VCALL_LOCALMEM0R(String, is_valid_float);
+ VCALL_LOCALMEM1R(String, is_valid_hex_number);
VCALL_LOCALMEM0R(String, is_valid_html_color);
VCALL_LOCALMEM0R(String, is_valid_ip_address);
VCALL_LOCALMEM0R(String, to_int);
@@ -481,11 +480,12 @@ struct _VariantCall {
VCALL_LOCALMEM0(Dictionary, clear);
VCALL_LOCALMEM1R(Dictionary, has);
VCALL_LOCALMEM1R(Dictionary, has_all);
- VCALL_LOCALMEM1(Dictionary, erase);
+ VCALL_LOCALMEM1R(Dictionary, erase);
VCALL_LOCALMEM0R(Dictionary, hash);
VCALL_LOCALMEM0R(Dictionary, keys);
VCALL_LOCALMEM0R(Dictionary, values);
VCALL_LOCALMEM1R(Dictionary, duplicate);
+ VCALL_LOCALMEM2R(Dictionary, get);
VCALL_LOCALMEM2(Array, set);
VCALL_LOCALMEM1R(Array, get);
@@ -1227,15 +1227,15 @@ bool Variant::has_method(const StringName &p_method) const {
#endif
}
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[type];
- return fd.functions.has(p_method);
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type];
+ return tf.functions.has(p_method);
}
Vector<Variant::Type> Variant::get_method_argument_types(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Vector<Variant::Type>();
@@ -1244,9 +1244,9 @@ Vector<Variant::Type> Variant::get_method_argument_types(Variant::Type p_type, c
bool Variant::is_method_const(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return false;
@@ -1255,9 +1255,9 @@ bool Variant::is_method_const(Variant::Type p_type, const StringName &p_method)
Vector<StringName> Variant::get_method_argument_names(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Vector<StringName>();
@@ -1266,9 +1266,9 @@ Vector<StringName> Variant::get_method_argument_names(Variant::Type p_type, cons
Variant::Type Variant::get_method_return_type(Variant::Type p_type, const StringName &p_method, bool *r_has_return) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Variant::NIL;
@@ -1280,9 +1280,9 @@ Variant::Type Variant::get_method_return_type(Variant::Type p_type, const String
Vector<Variant> Variant::get_method_default_arguments(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Vector<Variant>();
@@ -1291,9 +1291,9 @@ Vector<Variant> Variant::get_method_default_arguments(Variant::Type p_type, cons
void Variant::get_method_list(List<MethodInfo> *p_list) const {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type];
- for (const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.front(); E; E = E->next()) {
+ for (const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.front(); E; E = E->next()) {
const _VariantCall::FuncData &fd = E->get();
@@ -1405,11 +1405,11 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va
Map<StringName, int>::Element *E = cd.value.find(p_value);
if (!E) {
- Map<StringName, Variant>::Element *E = cd.variant_value.find(p_value);
- if (E) {
+ Map<StringName, Variant>::Element *F = cd.variant_value.find(p_value);
+ if (F) {
if (r_valid)
*r_valid = true;
- return E->get();
+ return F->get();
} else {
return -1;
}
@@ -1535,6 +1535,7 @@ void register_variant_methods() {
ADDFUNC0R(STRING, BOOL, String, is_valid_identifier, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_integer, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_float, varray());
+ ADDFUNC1R(STRING, BOOL, String, is_valid_hex_number, BOOL, "with_prefix", varray(false));
ADDFUNC0R(STRING, BOOL, String, is_valid_html_color, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_ip_address, varray());
ADDFUNC0R(STRING, INT, String, to_int, varray());
@@ -1679,6 +1680,7 @@ void register_variant_methods() {
ADDFUNC0R(DICTIONARY, ARRAY, Dictionary, keys, varray());
ADDFUNC0R(DICTIONARY, ARRAY, Dictionary, values, varray());
ADDFUNC1R(DICTIONARY, DICTIONARY, Dictionary, duplicate, BOOL, "deep", varray(false));
+ ADDFUNC2R(DICTIONARY, NIL, Dictionary, get, NIL, "key", NIL, "default", varray(Variant()));
ADDFUNC0R(ARRAY, INT, Array, size, varray());
ADDFUNC0R(ARRAY, BOOL, Array, empty, varray());
@@ -1895,6 +1897,7 @@ void register_variant_methods() {
_VariantCall::add_constant(Variant::VECTOR3, "AXIS_Z", Vector3::AXIS_Z);
_VariantCall::add_variant_constant(Variant::VECTOR3, "ZERO", Vector3(0, 0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR3, "ONE", Vector3(1, 1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(Math_INF, Math_INF, Math_INF));
_VariantCall::add_variant_constant(Variant::VECTOR3, "LEFT", Vector3(-1, 0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3, "RIGHT", Vector3(1, 0, 0));
@@ -1904,6 +1907,7 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF));
_VariantCall::add_variant_constant(Variant::VECTOR2, "LEFT", Vector2(-1, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "RIGHT", Vector2(1, 0));
diff --git a/core/variant_construct_string.cpp b/core/variant_construct_string.cpp
deleted file mode 100644
index 2250c03f3d..0000000000
--- a/core/variant_construct_string.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/*************************************************************************/
-/* variant_construct_string.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "variant.h"
-
-class VariantConstruct {
-
- enum TokenType {
- TK_CURLY_BRACKET_OPEN,
- TK_CURLY_BRACKET_CLOSE,
- TK_BRACKET_OPEN,
- TK_BRACKET_CLOSE,
- TK_IDENTIFIER,
- TK_STRING,
- TK_NUMBER,
- TK_COLON,
- TK_COMMA,
- TK_EOF,
- TK_MAX
- };
-
- enum Expecting {
-
- EXPECT_OBJECT,
- EXPECT_OBJECT_KEY,
- EXPECT_COLON,
- EXPECT_OBJECT_VALUE,
- };
-
- struct Token {
-
- TokenType type;
- Variant value;
- };
-
- static const char *tk_name[TK_MAX];
-
- static String _print_var(const Variant &p_var);
-
- static Error _get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
- static Error _parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud);
- static Error _parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud);
- static Error _parse_dict(Dictionary &dict, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud);
-
-public:
- static Error parse(const String &p_string, Variant &r_ret, String &r_err_str, int &r_err_line, Variant::ObjectConstruct *p_construct, void *p_ud);
-};
-
-const char *VariantConstruct::tk_name[TK_MAX] = {
- "'{'",
- "'}'",
- "'['",
- "']'",
- "identifier",
- "string",
- "number",
- "':'",
- "','",
- "EOF",
-};
-
-Error VariantConstruct::_get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) {
-
- while (true) {
- switch (p_str[index]) {
-
- case '\n': {
-
- line++;
- index++;
- break;
- };
- case 0: {
- r_token.type = TK_EOF;
- return OK;
- } break;
- case '{': {
-
- r_token.type = TK_CURLY_BRACKET_OPEN;
- index++;
- return OK;
- };
- case '}': {
-
- r_token.type = TK_CURLY_BRACKET_CLOSE;
- index++;
- return OK;
- };
- case '[': {
-
- r_token.type = TK_BRACKET_OPEN;
- index++;
- return OK;
- };
- case ']': {
-
- r_token.type = TK_BRACKET_CLOSE;
- index++;
- return OK;
- };
- case ':': {
-
- r_token.type = TK_COLON;
- index++;
- return OK;
- };
- case ',': {
-
- r_token.type = TK_COMMA;
- index++;
- return OK;
- };
- case '"': {
-
- index++;
- String str;
- while (true) {
- if (p_str[index] == 0) {
- r_err_str = "Unterminated String";
- return ERR_PARSE_ERROR;
- } else if (p_str[index] == '"') {
- index++;
- break;
- } else if (p_str[index] == '\\') {
- //escaped characters...
- index++;
- CharType next = p_str[index];
- if (next == 0) {
- r_err_str = "Unterminated String";
- return ERR_PARSE_ERROR;
- }
- CharType res = 0;
-
- switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
- case '\"': res = '\"'; break;
- case '\\': res = '\\'; break;
- case '/': res = '/'; break;
- case 'u': {
- //hexnumbarh - oct is deprecated
-
- for (int j = 0; j < 4; j++) {
- CharType c = p_str[index + j + 1];
- if (c == 0) {
- r_err_str = "Unterminated String";
- return ERR_PARSE_ERROR;
- }
- if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
-
- r_err_str = "Malformed hex constant in string";
- return ERR_PARSE_ERROR;
- }
- CharType v;
- if (c >= '0' && c <= '9') {
- v = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- v = c - 'a';
- v += 10;
- } else if (c >= 'A' && c <= 'F') {
- v = c - 'A';
- v += 10;
- } else {
- ERR_PRINT("BUG");
- v = 0;
- }
-
- res <<= 4;
- res |= v;
- }
- index += 4; //will add at the end anyway
-
- } break;
- default: {
-
- r_err_str = "Invalid escape sequence";
- return ERR_PARSE_ERROR;
- } break;
- }
-
- str += res;
-
- } else {
- if (p_str[index] == '\n')
- line++;
- str += p_str[index];
- }
- index++;
- }
-
- r_token.type = TK_STRING;
- r_token.value = str;
- return OK;
-
- } break;
- default: {
-
- if (p_str[index] <= 32) {
- index++;
- break;
- }
-
- if (p_str[index] == '-' || (p_str[index] >= '0' && p_str[index] <= '9')) {
- //a number
- const CharType *rptr;
- double number = String::to_double(&p_str[index], &rptr);
- index += (rptr - &p_str[index]);
- r_token.type = TK_NUMBER;
- r_token.value = number;
- return OK;
-
- } else if ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
-
- String id;
-
- while ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
-
- id += p_str[index];
- index++;
- }
-
- r_token.type = TK_IDENTIFIER;
- r_token.value = id;
- return OK;
- } else {
- r_err_str = "Unexpected character.";
- return ERR_PARSE_ERROR;
- }
- }
- }
- }
-
- return ERR_PARSE_ERROR;
-}
-
-Error VariantConstruct::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- if (token.type == TK_CURLY_BRACKET_OPEN) {
-
- Dictionary d;
- Error err = _parse_dict(d, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
- value = d;
- return OK;
- } else if (token.type == TK_BRACKET_OPEN) {
-
- Array a;
- Error err = _parse_array(a, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
- value = a;
- return OK;
-
- } else if (token.type == TK_IDENTIFIER) {
-
- String id = token.value;
- if (id == "true")
- value = true;
- else if (id == "false")
- value = false;
- else if (id == "null")
- value = Variant();
- else {
- r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
- return ERR_PARSE_ERROR;
- }
- return OK;
-
- } else if (token.type == TK_NUMBER) {
-
- value = token.value;
- return OK;
- } else if (token.type == TK_STRING) {
-
- value = token.value;
- return OK;
- } else {
- r_err_str = "Expected value, got " + String(tk_name[token.type]) + ".";
- return ERR_PARSE_ERROR;
- }
-
- return ERR_PARSE_ERROR;
-}
-
-Error VariantConstruct::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- Token token;
- bool need_comma = false;
-
- while (index < p_len) {
-
- Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
- return err;
-
- if (token.type == TK_BRACKET_CLOSE) {
-
- return OK;
- }
-
- if (need_comma) {
-
- if (token.type != TK_COMMA) {
-
- r_err_str = "Expected ','";
- return ERR_PARSE_ERROR;
- } else {
- need_comma = false;
- continue;
- }
- }
-
- Variant v;
- err = _parse_value(v, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
-
- array.push_back(v);
- need_comma = true;
- }
-
- return OK;
-}
-
-Error VariantConstruct::_parse_dict(Dictionary &dict, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- bool at_key = true;
- Variant key;
- Token token;
- bool need_comma = false;
-
- while (index < p_len) {
-
- if (at_key) {
-
- Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
- return err;
-
- if (token.type == TK_CURLY_BRACKET_CLOSE) {
-
- return OK;
- }
-
- if (need_comma) {
-
- if (token.type != TK_COMMA) {
-
- r_err_str = "Expected '}' or ','";
- return ERR_PARSE_ERROR;
- } else {
- need_comma = false;
- continue;
- }
- }
-
- err = _parse_value(key, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
-
- if (err != OK)
- return err;
-
- err = _get_token(p_str, index, p_len, token, line, r_err_str);
-
- if (err != OK)
- return err;
-
- if (token.type != TK_COLON) {
-
- r_err_str = "Expected ':'";
- return ERR_PARSE_ERROR;
- }
- at_key = false;
- } else {
-
- Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
- return err;
-
- Variant v;
- err = _parse_value(v, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
- dict[key] = v;
- need_comma = true;
- at_key = true;
- }
- }
-
- return OK;
-}
-
-Error VariantConstruct::parse(const String &p_string, Variant &r_ret, String &r_err_str, int &r_err_line, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- const CharType *str = p_string.ptr();
- int idx = 0;
- int len = p_string.length();
- Token token;
- r_err_line = 0;
- String aux_key;
-
- Error err = _get_token(str, idx, len, token, r_err_line, r_err_str);
- if (err)
- return err;
-
- return _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str, p_construct, p_ud);
-}
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index bfa69b1fde..b40b6ce4a6 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,9 @@
#include "variant.h"
-#include "core_string_names.h"
-#include "object.h"
-#include "script_language.h"
+#include "core/core_string_names.h"
+#include "core/object.h"
+#include "core/script_language.h"
#define CASE_TYPE_ALL(PREFIX, OP) \
CASE_TYPE(PREFIX, OP, INT) \
@@ -521,7 +521,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem);
const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem);
- _RETURN((*arr_a == *arr_b) == false);
+ _RETURN(*arr_a != *arr_b);
}
CASE_TYPE(math, OP_NOT_EQUAL, ARRAY) {
@@ -1656,13 +1656,13 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} else if (p_index == CoreStringNames::singleton->a) {
return v->a;
} else if (p_index == CoreStringNames::singleton->r8) {
- return int(v->r * 255.0);
+ return int(Math::round(v->r * 255.0));
} else if (p_index == CoreStringNames::singleton->g8) {
- return int(v->g * 255.0);
+ return int(Math::round(v->g * 255.0));
} else if (p_index == CoreStringNames::singleton->b8) {
- return int(v->b * 255.0);
+ return int(Math::round(v->b * 255.0));
} else if (p_index == CoreStringNames::singleton->a8) {
- return int(v->a * 255.0);
+ return int(Math::round(v->a * 255.0));
} else if (p_index == CoreStringNames::singleton->h) {
return v->get_h();
} else if (p_index == CoreStringNames::singleton->s) {
@@ -2149,7 +2149,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
int idx = p_index;
if (idx < 0)
idx += 4;
- if (idx >= 0 || idx < 4) {
+ if (idx >= 0 && idx < 4) {
Color *v = reinterpret_cast<Color *>(_data._mem);
(*v)[idx] = p_value;
valid = true;
@@ -2524,7 +2524,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
int idx = p_index;
if (idx < 0)
idx += 4;
- if (idx >= 0 || idx < 4) {
+ if (idx >= 0 && idx < 4) {
const Color *v = reinterpret_cast<const Color *>(_data._mem);
valid = true;
return (*v)[idx];
@@ -3496,15 +3496,15 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
case COLOR: {
const Color *ca = reinterpret_cast<const Color *>(a._data._mem);
const Color *cb = reinterpret_cast<const Color *>(b._data._mem);
- float r = ca->r + cb->r * c;
- float g = ca->g + cb->g * c;
- float b = ca->b + cb->b * c;
- float a = ca->a + cb->a * c;
- r = r > 1.0 ? 1.0 : r;
- g = g > 1.0 ? 1.0 : g;
- b = b > 1.0 ? 1.0 : b;
- a = a > 1.0 ? 1.0 : a;
- r_dst = Color(r, g, b, a);
+ float new_r = ca->r + cb->r * c;
+ float new_g = ca->g + cb->g * c;
+ float new_b = ca->b + cb->b * c;
+ float new_a = ca->a + cb->a * c;
+ new_r = new_r > 1.0 ? 1.0 : new_r;
+ new_g = new_g > 1.0 ? 1.0 : new_g;
+ new_b = new_b > 1.0 ? 1.0 : new_b;
+ new_a = new_a > 1.0 ? 1.0 : new_a;
+ r_dst = Color(new_r, new_g, new_b, new_a);
}
return;
default: {
@@ -3521,7 +3521,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
//not as efficient but..
real_t va = a;
real_t vb = b;
- r_dst = (1.0 - c) * va + vb * c;
+ r_dst = va + (vb - va) * c;
} else {
r_dst = a;
@@ -3542,13 +3542,13 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
case INT: {
int64_t va = a._data._int;
int64_t vb = b._data._int;
- r_dst = int((1.0 - c) * va + vb * c);
+ r_dst = int(va + (vb - va) * c);
}
return;
case REAL: {
real_t va = a._data._real;
real_t vb = b._data._real;
- r_dst = (1.0 - c) * va + vb * c;
+ r_dst = va + (vb - va) * c;
}
return;
case STRING: {
@@ -3556,7 +3556,9 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
String sa = *reinterpret_cast<const String *>(a._data._mem);
String sb = *reinterpret_cast<const String *>(b._data._mem);
String dst;
- int csize = sb.length() * c + sa.length() * (1.0 - c);
+ int sa_len = sa.length();
+ int sb_len = sb.length();
+ int csize = sa_len + (sb_len - sa_len) * c;
if (csize == 0) {
r_dst = "";
return;
@@ -3654,11 +3656,55 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case POOL_INT_ARRAY: {
- r_dst = a;
+ const PoolVector<int> *arr_a = reinterpret_cast<const PoolVector<int> *>(a._data._mem);
+ const PoolVector<int> *arr_b = reinterpret_cast<const PoolVector<int> *>(b._data._mem);
+ int sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ PoolVector<int> v;
+ v.resize(sz);
+ {
+ PoolVector<int>::Write vw = v.write();
+ PoolVector<int>::Read ar = arr_a->read();
+ PoolVector<int>::Read br = arr_b->read();
+
+ Variant va;
+ for (int i = 0; i < sz; i++) {
+ Variant::interpolate(ar[i], br[i], c, va);
+ vw[i] = va;
+ }
+ }
+ r_dst = v;
+ }
}
return;
case POOL_REAL_ARRAY: {
- r_dst = a;
+ const PoolVector<real_t> *arr_a = reinterpret_cast<const PoolVector<real_t> *>(a._data._mem);
+ const PoolVector<real_t> *arr_b = reinterpret_cast<const PoolVector<real_t> *>(b._data._mem);
+ int sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ PoolVector<real_t> v;
+ v.resize(sz);
+ {
+ PoolVector<real_t>::Write vw = v.write();
+ PoolVector<real_t>::Read ar = arr_a->read();
+ PoolVector<real_t>::Read br = arr_b->read();
+
+ Variant va;
+ for (int i = 0; i < sz; i++) {
+ Variant::interpolate(ar[i], br[i], c, va);
+ vw[i] = va;
+ }
+ }
+ r_dst = v;
+ }
}
return;
case POOL_STRING_ARRAY: {
@@ -3715,7 +3761,27 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case POOL_COLOR_ARRAY: {
- r_dst = a;
+ const PoolVector<Color> *arr_a = reinterpret_cast<const PoolVector<Color> *>(a._data._mem);
+ const PoolVector<Color> *arr_b = reinterpret_cast<const PoolVector<Color> *>(b._data._mem);
+ int sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ PoolVector<Color> v;
+ v.resize(sz);
+ {
+ PoolVector<Color>::Write vw = v.write();
+ PoolVector<Color>::Read ar = arr_a->read();
+ PoolVector<Color>::Read br = arr_b->read();
+
+ for (int i = 0; i < sz; i++) {
+ vw[i] = ar[i].linear_interpolate(br[i], c);
+ }
+ }
+ r_dst = v;
+ }
}
return;
default: {
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 446aee286d..0056fc75b6 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,10 +30,10 @@
#include "variant_parser.h"
+#include "core/io/resource_loader.h"
+#include "core/os/input_event.h"
+#include "core/os/keyboard.h"
#include "core/string_buffer.h"
-#include "io/resource_loader.h"
-#include "os/input_event.h"
-#include "os/keyboard.h"
CharType VariantParser::StreamFile::get_char() {
@@ -728,7 +728,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
bool at_key = true;
String key;
- Token token;
+ Token token2;
bool need_comma = false;
while (true) {
@@ -740,11 +740,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
if (at_key) {
- Error err = get_token(p_stream, token, line, r_err_str);
+ Error err = get_token(p_stream, token2, line, r_err_str);
if (err != OK)
return err;
- if (token.type == TK_PARENTHESIS_CLOSE) {
+ if (token2.type == TK_PARENTHESIS_CLOSE) {
Reference *reference = Object::cast_to<Reference>(obj);
if (reference) {
value = REF(reference);
@@ -756,7 +756,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
if (need_comma) {
- if (token.type != TK_COMMA) {
+ if (token2.type != TK_COMMA) {
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
@@ -766,18 +766,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
}
- if (token.type != TK_STRING) {
+ if (token2.type != TK_STRING) {
r_err_str = "Expected property name as string";
return ERR_PARSE_ERROR;
}
- key = token.value;
+ key = token2.value;
- err = get_token(p_stream, token, line, r_err_str);
+ err = get_token(p_stream, token2, line, r_err_str);
if (err != OK)
return err;
- if (token.type != TK_COLON) {
+ if (token2.type != TK_COLON) {
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
@@ -785,12 +785,12 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
at_key = false;
} else {
- Error err = get_token(p_stream, token, line, r_err_str);
+ Error err = get_token(p_stream, token2, line, r_err_str);
if (err != OK)
return err;
Variant v;
- err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
+ err = parse_value(token2, v, p_stream, line, r_err_str, p_res_parser);
if (err)
return err;
obj->set(key, v);
@@ -882,11 +882,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- String id = token.value;
+ String id2 = token.value;
Ref<InputEvent> ie;
- if (id == "NONE") {
+ if (id2 == "NONE") {
get_token(p_stream, token, line, r_err_str);
@@ -895,7 +895,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "KEY") {
+ } else if (id2 == "KEY") {
Ref<InputEventKey> key;
key.instance();
@@ -954,7 +954,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "MBUTTON") {
+ } else if (id2 == "MBUTTON") {
Ref<InputEventMouseButton> mb;
mb.instance();
@@ -980,7 +980,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "JBUTTON") {
+ } else if (id2 == "JBUTTON") {
Ref<InputEventJoypadButton> jb;
jb.instance();
@@ -1006,7 +1006,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "JAXIS") {
+ } else if (id2 == "JAXIS") {
Ref<InputEventJoypadMotion> jm;
jm.instance();
@@ -1429,10 +1429,10 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
break;
if (parsing_tag && token.type == TK_PERIOD) {
- r_tag.name += "."; //support tags such as [someprop.Anroid] for specific platforms
+ r_tag.name += "."; //support tags such as [someprop.Android] for specific platforms
get_token(p_stream, token, line, r_err_str);
} else if (parsing_tag && token.type == TK_COLON) {
- r_tag.name += ":"; //support tags such as [someprop.Anroid] for specific platforms
+ r_tag.name += ":"; //support tags such as [someprop.Android] for specific platforms
get_token(p_stream, token, line, r_err_str);
} else {
parsing_tag = false;
@@ -1597,7 +1597,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::INT: {
- p_store_string_func(p_store_string_ud, itos(p_variant.operator int()));
+ p_store_string_func(p_store_string_ud, itos(p_variant.operator int64_t()));
} break;
case Variant::REAL: {
diff --git a/core/variant_parser.h b/core/variant_parser.h
index 8d95595234..ac4c96a8de 100644
--- a/core/variant_parser.h
+++ b/core/variant_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,9 @@
#ifndef VARIANT_PARSER_H
#define VARIANT_PARSER_H
-#include "os/file_access.h"
-#include "resource.h"
-#include "variant.h"
+#include "core/os/file_access.h"
+#include "core/resource.h"
+#include "core/variant.h"
class VariantParser {
public:
@@ -45,7 +45,8 @@ public:
CharType saved;
- Stream() { saved = 0; }
+ Stream() :
+ saved(0) {}
virtual ~Stream() {}
};
diff --git a/core/vector.h b/core/vector.h
index 52e8758f9b..93ee003519 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,24 +36,19 @@
* @author Juan Linietsky
* Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use PoolVector for large arrays.
*/
-#include "cowdata.h"
-#include "error_macros.h"
-#include "os/memory.h"
-#include "sort.h"
+
+#include "core/cowdata.h"
+#include "core/error_macros.h"
+#include "core/os/memory.h"
+#include "core/sort_array.h"
template <class T>
class VectorWriteProxy {
- friend class Vector<T>;
- CowData<T> *_parent;
-
- _FORCE_INLINE_ VectorWriteProxy(CowData<T> *parent) :
- _parent(parent){};
-
public:
_FORCE_INLINE_ T &operator[](int p_index) {
- CRASH_BAD_INDEX(p_index, _parent->size());
+ CRASH_BAD_INDEX(p_index, ((Vector<T> *)(this))->_cowdata.size());
- return _parent->ptrw()[p_index];
+ return ((Vector<T> *)(this))->_cowdata.ptrw()[p_index];
}
};
@@ -61,39 +56,42 @@ template <class T>
class Vector {
friend class VectorWriteProxy<T>;
- CowData<T> *_cowdata;
-
public:
VectorWriteProxy<T> write;
+private:
+ CowData<T> _cowdata;
+
+public:
bool push_back(const T &p_elem);
- void remove(int p_index) { _cowdata->remove(p_index); }
+ void remove(int p_index) { _cowdata.remove(p_index); }
void erase(const T &p_val) {
int idx = find(p_val);
if (idx >= 0) remove(idx);
};
void invert();
- _FORCE_INLINE_ T *ptrw() { return _cowdata->ptrw(); }
- _FORCE_INLINE_ const T *ptr() const { return _cowdata->ptr(); }
+ _FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
+ _FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ bool empty() const { return _cowdata->empty(); }
+ _FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
- _FORCE_INLINE_ T get(int p_index) { return _cowdata->get(p_index); }
- _FORCE_INLINE_ const T get(int p_index) const { return _cowdata->get(p_index); }
- _FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata->set(p_index, p_elem); }
- _FORCE_INLINE_ int size() const { return _cowdata->size(); }
- Error resize(int p_size) { return _cowdata->resize(p_size); }
- _FORCE_INLINE_ const T &operator[](int p_index) const { return _cowdata->get(p_index); }
- Error insert(int p_pos, const T &p_val) { return _cowdata->insert(p_pos, p_val); }
+ _FORCE_INLINE_ T get(int p_index) { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ const T get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
+ _FORCE_INLINE_ int size() const { return _cowdata.size(); }
+ Error resize(int p_size) { return _cowdata.resize(p_size); }
+ _FORCE_INLINE_ const T &operator[](int p_index) const { return _cowdata.get(p_index); }
+ Error insert(int p_pos, const T &p_val) { return _cowdata.insert(p_pos, p_val); }
+ int find(const T &p_val, int p_from = 0) const { return _cowdata.find(p_val, p_from); }
void append_array(const Vector<T> &p_other);
template <class C>
void sort_custom() {
- int len = _cowdata->size();
+ int len = _cowdata.size();
if (len == 0)
return;
@@ -109,7 +107,7 @@ public:
void ordered_insert(const T &p_val) {
int i;
- for (i = 0; i < _cowdata->size(); i++) {
+ for (i = 0; i < _cowdata.size(); i++) {
if (p_val < operator[](i)) {
break;
@@ -118,36 +116,14 @@ public:
insert(i, p_val);
}
- int find(const T &p_val, int p_from = 0) const {
- int ret = -1;
- if (p_from < 0 || size() == 0)
- return ret;
-
- for (int i = p_from; i < size(); i++) {
-
- if (ptr()[i] == p_val) {
- ret = i;
- break;
- };
- };
-
- return ret;
- }
-
- _FORCE_INLINE_ Vector() :
- _cowdata(new CowData<T>()),
- write(VectorWriteProxy<T>(_cowdata)) {}
- _FORCE_INLINE_ Vector(const Vector &p_from) :
- _cowdata(new CowData<T>()),
- write(VectorWriteProxy<T>(_cowdata)) { _cowdata->_ref(p_from._cowdata); }
+ _FORCE_INLINE_ Vector() {}
+ _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); }
inline Vector &operator=(const Vector &p_from) {
- _cowdata->_ref(p_from._cowdata);
+ _cowdata._ref(p_from._cowdata);
return *this;
}
- _FORCE_INLINE_ ~Vector() {
- delete _cowdata;
- }
+ _FORCE_INLINE_ ~Vector() {}
};
template <class T>
diff --git a/core/version.h b/core/version.h
index d39172865a..05fec9d0a6 100644
--- a/core/version.h
+++ b/core/version.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "version_generated.gen.h"
+#include "core/version_generated.gen.h"
// Godot versions are of the form <major>.<minor> for the initial release,
// and then <major>.<minor>.<patch> for subsequent bugfix releases where <patch> != 0
@@ -41,9 +41,14 @@
#ifdef VERSION_PATCH
// Example: "3.1.4"
#define VERSION_NUMBER "" VERSION_BRANCH "." _MKSTR(VERSION_PATCH)
+// Version number encoded as hexadecimal int with one byte for each number,
+// for easy comparison from code.
+// Example: 3.1.4 will be 0x030104, making comparison easy from script.
+#define VERSION_HEX 0x10000 * VERSION_MAJOR + 0x100 * VERSION_MINOR + VERSION_PATCH
#else
// Example: "3.1"
#define VERSION_NUMBER "" VERSION_BRANCH
+#define VERSION_HEX 0x10000 * VERSION_MAJOR + 0x100 * VERSION_MINOR
#endif // VERSION_PATCH
// Describes the full configuration of that Godot version, including the version number,
diff --git a/core/vmap.h b/core/vmap.h
index ce0ddc4ec6..f46ed70a0f 100644
--- a/core/vmap.h
+++ b/core/vmap.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,27 +31,28 @@
#ifndef VMAP_H
#define VMAP_H
-#include "cowdata.h"
-#include "typedefs.h"
+#include "core/cowdata.h"
+#include "core/typedefs.h"
template <class T, class V>
class VMap {
-
- struct _Pair {
+public:
+ struct Pair {
T key;
V value;
- _FORCE_INLINE_ _Pair() {}
+ _FORCE_INLINE_ Pair() {}
- _FORCE_INLINE_ _Pair(const T &p_key, const V &p_value) {
+ _FORCE_INLINE_ Pair(const T &p_key, const V &p_value) {
key = p_key;
value = p_value;
}
};
- CowData<_Pair> _cowdata;
+private:
+ CowData<Pair> _cowdata;
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
@@ -61,7 +62,7 @@ class VMap {
int low = 0;
int high = _cowdata.size() - 1;
- const _Pair *a = _cowdata.ptr();
+ const Pair *a = _cowdata.ptr();
int middle = 0;
#if DEBUG_ENABLED
@@ -95,7 +96,7 @@ class VMap {
int low = 0;
int high = _cowdata.size() - 1;
int middle;
- const _Pair *a = _cowdata.ptr();
+ const Pair *a = _cowdata.ptr();
while (low <= high) {
middle = (low + high) / 2;
@@ -121,7 +122,7 @@ public:
_cowdata.get_m(pos).value = p_val;
return pos;
}
- _cowdata.insert(pos, _Pair(p_key, p_val));
+ _cowdata.insert(pos, Pair(p_key, p_val));
return pos;
}
@@ -152,12 +153,12 @@ public:
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
_FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
- const _Pair *get_array() const {
+ const Pair *get_array() const {
return _cowdata.ptr();
}
- _Pair *get_array() {
+ Pair *get_array() {
return _cowdata.ptrw();
}
diff --git a/core/vset.h b/core/vset.h
index 7f4d8e7f62..678ec507ba 100644
--- a/core/vset.h
+++ b/core/vset.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,8 +31,8 @@
#ifndef VSET_H
#define VSET_H
-#include "typedefs.h"
-#include "vector.h"
+#include "core/typedefs.h"
+#include "core/vector.h"
template <class T>
class VSet {