summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/input_default.cpp40
-rw-r--r--main/input_default.h3
-rw-r--r--main/main.cpp80
-rw-r--r--main/tests/test_io.cpp133
-rw-r--r--main/tests/test_io.h45
-rw-r--r--main/tests/test_main.cpp7
-rw-r--r--main/tests/test_oa_hash_map.cpp31
-rw-r--r--main/tests/test_shader_lang.cpp2
-rw-r--r--main/tests/test_string.cpp173
9 files changed, 251 insertions, 263 deletions
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 913c143025..b1084900d6 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -261,6 +261,13 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
+ // Notes on mouse-touch emulation:
+ // - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects
+ // as true mouse events. The only difference is the situation is flagged as emulated so they are not
+ // emulated back to touch events in an endless loop.
+ // - Emulated touch events are handed right to the main loop (i.e., the SceneTree) because they don't
+ // require additional handling by this class.
+
_THREAD_SAFE_METHOD_
Ref<InputEventKey> k = p_event;
@@ -316,11 +323,21 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool
}
}
- if (emulate_mouse_from_touch) {
+ Ref<InputEventScreenTouch> st = p_event;
+
+ if (st.is_valid()) {
+
+ if (st->is_pressed()) {
+ SpeedTrack &track = touch_speed_track[st->get_index()];
+ track.reset();
+ } else {
+ // Since a pointer index may not occur again (OSs may or may not reuse them),
+ // imperatively remove it from the map to keep no fossil entries in it
+ touch_speed_track.erase(st->get_index());
+ }
- Ref<InputEventScreenTouch> st = p_event;
+ if (emulate_mouse_from_touch) {
- if (st.is_valid()) {
bool translate = false;
if (st->is_pressed()) {
if (mouse_from_touch_index == -1) {
@@ -351,10 +368,18 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool
_parse_input_event_impl(button_event, true);
}
}
+ }
+
+ Ref<InputEventScreenDrag> sd = p_event;
+
+ if (sd.is_valid()) {
+
+ SpeedTrack &track = touch_speed_track[sd->get_index()];
+ track.update(sd->get_relative());
+ sd->set_speed(track.speed);
- Ref<InputEventScreenDrag> sd = p_event;
+ if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) {
- if (sd.is_valid() && sd->get_index() == mouse_from_touch_index) {
Ref<InputEventMouseMotion> motion_event;
motion_event.instance();
@@ -404,6 +429,7 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool
action.physics_frame = Engine::get_singleton()->get_physics_frames();
action.idle_frame = Engine::get_singleton()->get_idle_frames();
action.pressed = p_event->is_action_pressed(E->key());
+ action.strength = 0.f;
action_state[E->key()] = action;
}
action_state[E->key()].strength = p_event->get_action_strength(E->key());
@@ -530,13 +556,14 @@ Point2i InputDefault::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_moti
void InputDefault::iteration(float p_step) {
}
-void InputDefault::action_press(const StringName &p_action) {
+void InputDefault::action_press(const StringName &p_action, float p_strength) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
action.idle_frame = Engine::get_singleton()->get_idle_frames();
action.pressed = true;
+ action.strength = p_strength;
action_state[p_action] = action;
}
@@ -548,6 +575,7 @@ void InputDefault::action_release(const StringName &p_action) {
action.physics_frame = Engine::get_singleton()->get_physics_frames();
action.idle_frame = Engine::get_singleton()->get_idle_frames();
action.pressed = false;
+ action.strength = 0.f;
action_state[p_action] = action;
}
diff --git a/main/input_default.h b/main/input_default.h
index b420ec124b..b6767669f0 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -117,6 +117,7 @@ class InputDefault : public Input {
};
SpeedTrack mouse_speed_track;
+ Map<int, SpeedTrack> touch_speed_track;
Map<int, Joypad> joy_names;
int fallback_mapping;
@@ -226,7 +227,7 @@ public:
void set_main_loop(MainLoop *p_main_loop);
void set_mouse_position(const Point2 &p_posf);
- void action_press(const StringName &p_action);
+ void action_press(const StringName &p_action, float p_strength = 1.f);
void action_release(const StringName &p_action);
void iteration(float p_step);
diff --git a/main/main.cpp b/main/main.cpp
index 3eb0b7f354..7383294167 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -115,9 +115,11 @@ static bool editor = false;
static bool project_manager = false;
static String locale;
static bool show_help = false;
-static bool auto_build_solutions = false;
static bool auto_quit = false;
static OS::ProcessID allow_focus_steal_pid = 0;
+#ifdef TOOLS_ENABLED
+static bool auto_build_solutions = false;
+#endif
// Display
@@ -720,6 +722,29 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
I = N;
}
+ // Network file system needs to be configured before globals, since globals are based on the
+ // 'project.godot' file which will only be available through the network if this is enabled
+ FileAccessNetwork::configure();
+ if (remotefs != "") {
+
+ file_access_network_client = memnew(FileAccessNetworkClient);
+ int port;
+ if (remotefs.find(":") != -1) {
+ port = remotefs.get_slicec(':', 1).to_int();
+ remotefs = remotefs.get_slicec(':', 0);
+ } else {
+ port = 6010;
+ }
+
+ Error err = file_access_network_client->connect(remotefs, port, remotefs_pass);
+ if (err) {
+ OS::get_singleton()->printerr("Could not connect to remotefs: %s:%i.\n", remotefs.utf8().get_data(), port);
+ goto error;
+ }
+
+ FileAccess::make_default<FileAccessNetwork>(FileAccess::ACCESS_RESOURCES);
+ }
+
if (globals->setup(project_path, main_pack, upwards) == OK) {
found_project = true;
} else {
@@ -727,16 +752,22 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#ifdef TOOLS_ENABLED
editor = false;
#else
- OS::get_singleton()->print("Error: Could not load game path '%s'.\n", project_path.ascii().get_data());
+ String error_msg = "Error: Could not load game data at path '" + project_path + "'. Is the .pck file missing?\n";
+ OS::get_singleton()->print(error_msg.ascii().get_data());
+ OS::get_singleton()->alert(error_msg);
goto error;
#endif
}
GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60);
+ ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/multithreaded_server/rid_pool_prealloc", PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1")); // No negative and limit to 500 due to crashes
GLOBAL_DEF("network/limits/debugger_stdout/max_chars_per_second", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_chars_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_chars_per_second", PROPERTY_HINT_RANGE, "0, 4096, 1, or_greater"));
GLOBAL_DEF("network/limits/debugger_stdout/max_messages_per_frame", 10);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_messages_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_messages_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_frame", 10);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
if (debug_mode == "remote") {
@@ -760,28 +791,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
script_debugger = memnew(ScriptDebuggerLocal);
OS::get_singleton()->initialize_debugging();
}
-
- FileAccessNetwork::configure();
-
- if (remotefs != "") {
-
- file_access_network_client = memnew(FileAccessNetworkClient);
- int port;
- if (remotefs.find(":") != -1) {
- port = remotefs.get_slicec(':', 1).to_int();
- remotefs = remotefs.get_slicec(':', 0);
- } else {
- port = 6010;
- }
-
- Error err = file_access_network_client->connect(remotefs, port, remotefs_pass);
- if (err) {
- OS::get_singleton()->printerr("Could not connect to remotefs: %s:%i.\n", remotefs.utf8().get_data(), port);
- goto error;
- }
-
- FileAccess::make_default<FileAccessNetwork>(FileAccess::ACCESS_RESOURCES);
- }
if (script_debugger) {
//there is a debugger, parse breakpoints
@@ -809,6 +818,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF("logging/file_logging/enable_file_logging", false);
GLOBAL_DEF("logging/file_logging/log_path", "user://logs/log.txt");
GLOBAL_DEF("logging/file_logging/max_log_files", 10);
+ ProjectSettings::get_singleton()->set_custom_property_info("logging/file_logging/max_log_files", PropertyInfo(Variant::INT, "logging/file_logging/max_log_files", PROPERTY_HINT_RANGE, "0,20,1,or_greater")); //no negative numbers
if (FileAccess::get_create_func(FileAccess::ACCESS_USERDATA) && GLOBAL_GET("logging/file_logging/enable_file_logging")) {
String base_path = GLOBAL_GET("logging/file_logging/log_path");
int max_files = GLOBAL_GET("logging/file_logging/max_log_files");
@@ -871,13 +881,17 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_fallback", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_fallback", PROPERTY_HINT_ENUM, "Best,Never"));
GLOBAL_DEF("display/window/size/width", 1024);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width", PropertyInfo(Variant::INT, "display/window/size/width", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/height", 600);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height", PropertyInfo(Variant::INT, "display/window/size/height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/resizable", true);
GLOBAL_DEF("display/window/size/borderless", false);
GLOBAL_DEF("display/window/size/fullscreen", false);
GLOBAL_DEF("display/window/size/always_on_top", false);
GLOBAL_DEF("display/window/size/test_width", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width", PropertyInfo(Variant::INT, "display/window/size/test_width", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/test_height", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_height", PropertyInfo(Variant::INT, "display/window/size/test_height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution
if (use_custom_res) {
@@ -995,6 +1009,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60));
Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5));
Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0));
+ ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,120,1,or_greater"));
GLOBAL_DEF("debug/settings/stdout/print_fps", false);
@@ -1003,10 +1018,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (frame_delay == 0) {
frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("application/run/frame_delay_msec", PropertyInfo(Variant::INT, "application/run/frame_delay_msec", PROPERTY_HINT_RANGE, "0,100,1,or_greater")); // No negative numbers
}
OS::get_singleton()->set_low_processor_usage_mode(GLOBAL_DEF("application/run/low_processor_mode", false));
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(GLOBAL_DEF("application/run/low_processor_mode_sleep_usec", 8000));
+ ProjectSettings::get_singleton()->set_custom_property_info("application/run/low_processor_mode_sleep_usec", PropertyInfo(Variant::INT, "application/run/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "0,33200,1,or_greater")); // No negative numbers
Engine::get_singleton()->set_frame_delay(frame_delay);
@@ -1635,7 +1652,7 @@ bool Main::start() {
GLOBAL_DEF("display/window/stretch/aspect", "ignore");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand"));
GLOBAL_DEF("display/window/stretch/shrink", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::STRING, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1,8,1"));
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::REAL, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1,8,1"));
sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
@@ -1680,12 +1697,17 @@ bool Main::start() {
#ifdef TOOLS_ENABLED
if (editor) {
- Error serr = editor_node->load_scene(local_game_path);
- if (serr != OK)
- ERR_PRINT("Failed to load scene");
+ if (game_path != GLOBAL_GET("application/run/main_scene") || !editor_node->has_scenes_in_session()) {
+ Error serr = editor_node->load_scene(local_game_path);
+ if (serr != OK)
+ ERR_PRINT("Failed to load scene");
+ }
OS::get_singleton()->set_context(OS::CONTEXT_EDITOR);
}
#endif
+ if (!editor) {
+ OS::get_singleton()->set_context(OS::CONTEXT_ENGINE);
+ }
}
if (!project_manager && !editor) { // game
@@ -1975,6 +1997,8 @@ void Main::cleanup() {
memdelete(arvr_server);
}
+ ImageLoader::cleanup();
+
unregister_driver_types();
unregister_module_types();
unregister_platform_apis();
diff --git a/main/tests/test_io.cpp b/main/tests/test_io.cpp
deleted file mode 100644
index 4e43ee6a54..0000000000
--- a/main/tests/test_io.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*************************************************************************/
-/* test_io.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 "test_io.h"
-
-#ifdef MINIZIP_ENABLED
-
-#include "core/io/resource_loader.h"
-#include "core/io/resource_saver.h"
-#include "core/os/dir_access.h"
-#include "core/os/main_loop.h"
-#include "core/os/os.h"
-#include "core/print_string.h"
-#include "core/project_settings.h"
-#include "scene/resources/texture.h"
-
-#include "core/io/file_access_memory.h"
-
-namespace TestIO {
-
-class TestMainLoop : public MainLoop {
-
- bool quit;
-
-public:
- virtual void input_event(const Ref<InputEvent> &p_event) {
- }
- virtual bool idle(float p_time) {
- return false;
- }
-
- virtual void request_quit() {
-
- quit = true;
- }
- virtual void init() {
-
- quit = true;
- }
- virtual bool iteration(float p_time) {
-
- return quit;
- }
- virtual void finish() {
- }
-};
-
-MainLoop *test() {
-
- print_line("this is test io");
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->change_dir(".");
- print_line("Opening current dir " + da->get_current_dir());
- String entry;
- da->list_dir_begin();
- while ((entry = da->get_next()) != "") {
-
- print_line("entry " + entry + " is dir: " + Variant(da->current_is_dir()));
- };
- da->list_dir_end();
-
- RES texture = ResourceLoader::load("test_data/rock.png");
- ERR_FAIL_COND_V(texture.is_null(), NULL);
-
- ResourceSaver::save("test_data/rock.xml", texture);
-
- print_line("localize paths");
- print_line(ProjectSettings::get_singleton()->localize_path("algo.xml"));
- print_line(ProjectSettings::get_singleton()->localize_path("c:\\windows\\algo.xml"));
- print_line(ProjectSettings::get_singleton()->localize_path(ProjectSettings::get_singleton()->get_resource_path() + "/something/something.xml"));
- print_line(ProjectSettings::get_singleton()->localize_path("somedir/algo.xml"));
-
- {
-
- FileAccess *z = FileAccess::open("test_data/archive.zip", FileAccess::READ);
- int len = z->get_len();
- Vector<uint8_t> zip;
- zip.resize(len);
- z->get_buffer(zip.ptrw(), len);
- z->close();
- memdelete(z);
-
- FileAccessMemory::register_file("a_package", zip);
- FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_RESOURCES);
- FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_FILESYSTEM);
- FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_USERDATA);
-
- print_line("archive test");
- };
-
- print_line("test done");
-
- return memnew(TestMainLoop);
-}
-} // namespace TestIO
-
-#else
-
-namespace TestIO {
-
-MainLoop *test() {
-
- return NULL;
-}
-} // namespace TestIO
-#endif
diff --git a/main/tests/test_io.h b/main/tests/test_io.h
deleted file mode 100644
index ffebd05160..0000000000
--- a/main/tests/test_io.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* test_io.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 TEST_IO_H
-#define TEST_IO_H
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
-#include "core/os/main_loop.h"
-
-namespace TestIO {
-
-MainLoop *test();
-}
-
-#endif
diff --git a/main/tests/test_main.cpp b/main/tests/test_main.cpp
index 714a254371..a36b619ba0 100644
--- a/main/tests/test_main.cpp
+++ b/main/tests/test_main.cpp
@@ -37,7 +37,6 @@
#include "test_gdscript.h"
#include "test_gui.h"
#include "test_image.h"
-#include "test_io.h"
#include "test_math.h"
#include "test_oa_hash_map.h"
#include "test_ordered_hash_map.h"
@@ -57,7 +56,6 @@ const char **tests_get_names() {
"render",
"oa_hash_map",
"gui",
- "io",
"shaderlang",
"gd_tokenizer",
"gd_parser",
@@ -111,11 +109,6 @@ MainLoop *test_main(String p_test, const List<String> &p_args) {
}
#endif
- if (p_test == "io") {
-
- return TestIO::test();
- }
-
if (p_test == "shaderlang") {
return TestShaderLang::test();
diff --git a/main/tests/test_oa_hash_map.cpp b/main/tests/test_oa_hash_map.cpp
index 0e34faace7..deaba285cf 100644
--- a/main/tests/test_oa_hash_map.cpp
+++ b/main/tests/test_oa_hash_map.cpp
@@ -48,7 +48,7 @@ MainLoop *test() {
map.set(1337, 21);
map.set(42, 11880);
- int value;
+ int value = 0;
map.lookup(42, value);
OS::get_singleton()->print("capacity %d\n", map.get_capacity());
@@ -92,6 +92,35 @@ MainLoop *test() {
}
}
+ // stress test / test for issue #22928
+ {
+ OAHashMap<int, int> map;
+ int dummy;
+ const int N = 1000;
+ uint32_t *keys = new uint32_t[N];
+
+ Math::seed(0);
+
+ // insert a couple of random keys (with a dummy value, which is ignored)
+ for (int i = 0; i < N; i++) {
+ keys[i] = Math::rand();
+ map.set(keys[i], dummy);
+
+ if (!map.lookup(keys[i], dummy))
+ OS::get_singleton()->print("could not find 0x%X despite it was just inserted!\n", unsigned(keys[i]));
+ }
+
+ // check whether the keys are still present
+ for (int i = 0; i < N; i++) {
+ if (!map.lookup(keys[i], dummy)) {
+ OS::get_singleton()->print("could not find 0x%X despite it has been inserted previously! (not checking the other keys, breaking...)\n", unsigned(keys[i]));
+ break;
+ }
+ }
+
+ delete[] keys;
+ }
+
return NULL;
}
} // namespace TestOAHashMap
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index 9df5973376..357143e499 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -180,7 +180,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
String scode = dump_node_code(bnode->statements[i], p_level);
- if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) {
+ if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) {
code += scode; //use directly
} else {
code += _mktab(p_level) + scode + ";\n";
diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp
index 74157d63c9..7e19c7bf3e 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -480,7 +480,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish % frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
//////// INTS
@@ -491,7 +491,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Int left padded with zeroes.
format = "fish %05d frog";
@@ -500,7 +500,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 00005 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Int left padded with spaces.
format = "fish %5d frog";
@@ -509,7 +509,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Int right padded with spaces.
format = "fish %-5d frog";
@@ -518,7 +518,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Int with sign (positive).
format = "fish %+d frog";
@@ -527,7 +527,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish +5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Negative int.
format = "fish %d frog";
@@ -536,7 +536,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish -5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Hex (lower)
format = "fish %x frog";
@@ -545,7 +545,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 2d frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Hex (upper)
format = "fish %X frog";
@@ -554,7 +554,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 2D frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Octal
format = "fish %o frog";
@@ -563,7 +563,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 143 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
////// REALS
@@ -574,7 +574,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real left-padded
format = "fish %11f frog";
@@ -583,7 +583,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real right-padded
format = "fish %-11f frog";
@@ -592,7 +592,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real given int.
format = "fish %f frog";
@@ -601,7 +601,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99.000000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real with sign (positive).
format = "fish %+f frog";
@@ -610,7 +610,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish +99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real with 1 decimals.
format = "fish %.1f frog";
@@ -619,7 +619,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 100.0 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real with 12 decimals.
format = "fish %.12f frog";
@@ -628,7 +628,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000000000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Real with no decimals.
format = "fish %.f frog";
@@ -637,7 +637,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 100 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
/////// Strings.
@@ -648,7 +648,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// String left-padded
format = "fish %10s frog";
@@ -657,7 +657,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// String right-padded
format = "fish %-10s frog";
@@ -666,7 +666,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
///// Characters
@@ -677,7 +677,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish A frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Character as int.
format = "fish %c frog";
@@ -686,7 +686,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish A frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
///// Dynamic width
@@ -698,7 +698,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Int dynamic width
format = "fish %*d frog";
@@ -708,7 +708,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Float dynamic width
format = "fish %*.*f frog";
@@ -719,7 +719,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == String("fish 99.990 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
///// Errors
@@ -730,7 +730,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "not enough arguments for format string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// More arguments than formats.
format = "fish %s frog";
@@ -740,7 +740,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "not all arguments converted during string formatting" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Incomplete format.
format = "fish %10";
@@ -749,7 +749,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "incomplete format" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Bad character in format string
format = "fish %&f frog";
@@ -758,7 +758,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "unsupported format character" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Too many decimals.
format = "fish %2.2.2f frog";
@@ -767,7 +767,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "too many decimal points in format" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// * not a number
format = "fish %*f frog";
@@ -777,7 +777,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "* wants number" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Character too long.
format = "fish %c frog";
@@ -786,7 +786,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "%c requires number or single-character string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
// Character bad type.
format = "fish %c frog";
@@ -795,7 +795,7 @@ bool test_28() {
output = format.sprintf(args, &error);
success = (output == "%c requires number or single-character string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
return state;
}
@@ -819,37 +819,127 @@ bool test_29() {
String ip4 = "192.168.0.1";
bool success = ip4.is_valid_ip_address();
OS::get_singleton()->print("Is valid ipv4: %ls, %s\n", ip4.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
ip4 = "192.368.0.1";
success = (!ip4.is_valid_ip_address());
OS::get_singleton()->print("Is invalid ipv4: %ls, %s\n", ip4.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
String ip6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
success = ip6.is_valid_ip_address();
OS::get_singleton()->print("Is valid ipv6: %ls, %s\n", ip6.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
ip6 = "2001:0db8:85j3:0000:0000:8a2e:0370:7334";
success = (!ip6.is_valid_ip_address());
OS::get_singleton()->print("Is invalid ipv6: %ls, %s\n", ip6.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
ip6 = "2001:0db8:85f345:0000:0000:8a2e:0370:7334";
success = (!ip6.is_valid_ip_address());
OS::get_singleton()->print("Is invalid ipv6: %ls, %s\n", ip6.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
ip6 = "2001:0db8::0:8a2e:370:7334";
success = (ip6.is_valid_ip_address());
OS::get_singleton()->print("Is valid ipv6: %ls, %s\n", ip6.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
ip6 = "::ffff:192.168.0.1";
success = (ip6.is_valid_ip_address());
OS::get_singleton()->print("Is valid ipv6: %ls, %s\n", ip6.c_str(), success ? "OK" : "FAIL");
- if (!success) state = false;
+ state = state && success;
+
+ return state;
+};
+
+bool test_30() {
+ bool state = true;
+ bool success = true;
+ String input = "bytes2var";
+ String output = "Bytes 2 Var";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "linear2db";
+ output = "Linear 2 Db";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "vector3";
+ output = "Vector 3";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "sha256";
+ output = "Sha 256";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "2db";
+ output = "2 Db";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "PascalCase";
+ output = "Pascal Case";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "PascalPascalCase";
+ output = "Pascal Pascal Case";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "snake_case";
+ output = "Snake Case";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "snake_snake_case";
+ output = "Snake Snake Case";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "sha256sum";
+ output = "Sha 256 Sum";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "cat2dog";
+ output = "Cat 2 Dog";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "function(name)";
+ output = "Function(name)";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls (existing incorrect behavior): %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "snake_case_function(snake_case_arg)";
+ output = "Snake Case Function(snake Case Arg)";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls (existing incorrect behavior): %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
+
+ input = "snake_case_function( snake_case_arg )";
+ output = "Snake Case Function( Snake Case Arg )";
+ success = (input.capitalize() == output);
+ state = state && success;
+ OS::get_singleton()->print("Capitalize %ls: %ls, %s\n", input.c_str(), output.c_str(), success ? "OK" : "FAIL");
return state;
};
@@ -887,6 +977,7 @@ TestFunc test_funcs[] = {
test_27,
test_28,
test_29,
+ test_30,
0
};