summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/SCsub3
-rw-r--r--main/input_default.cpp15
-rw-r--r--main/input_default.h3
-rw-r--r--main/main.cpp169
-rw-r--r--main/main.h9
-rw-r--r--main/tests/SCsub4
-rw-r--r--main/tests/test_gdscript.cpp3
-rw-r--r--main/tests/test_gui.cpp2
-rw-r--r--main/tests/test_shader_lang.cpp3
9 files changed, 133 insertions, 78 deletions
diff --git a/main/SCsub b/main/SCsub
index 9af102600e..e7fe6ab4e1 100644
--- a/main/SCsub
+++ b/main/SCsub
@@ -1,6 +1,7 @@
#!/usr/bin/env python
Import('env')
+
from platform_methods import run_in_subprocess
import main_builders
@@ -15,8 +16,6 @@ env.CommandNoCache("#main/default_controller_mappings.gen.cpp", controller_datab
env.main_sources.append("#main/default_controller_mappings.gen.cpp")
-Export('env')
-
env.Depends("#main/splash.gen.h", "#main/splash.png")
env.CommandNoCache("#main/splash.gen.h", "#main/splash.png", run_in_subprocess(main_builders.make_splash))
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 2efbb3f849..913c143025 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -343,9 +343,9 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool
button_event->set_pressed(st->is_pressed());
button_event->set_button_index(BUTTON_LEFT);
if (st->is_pressed()) {
- button_event->set_button_mask(mouse_button_mask | (1 << BUTTON_LEFT - 1));
+ button_event->set_button_mask(mouse_button_mask | (1 << (BUTTON_LEFT - 1)));
} else {
- button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1));
+ button_event->set_button_mask(mouse_button_mask & ~(1 << (BUTTON_LEFT - 1)));
}
_parse_input_event_impl(button_event, true);
@@ -576,7 +576,7 @@ void InputDefault::ensure_touch_mouse_raised() {
button_event->set_global_position(mouse_pos);
button_event->set_pressed(false);
button_event->set_button_index(BUTTON_LEFT);
- button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1));
+ button_event->set_button_mask(mouse_button_mask & ~(1 << (BUTTON_LEFT - 1)));
_parse_input_event_impl(button_event, true);
}
@@ -598,7 +598,13 @@ Input::CursorShape InputDefault::get_default_cursor_shape() {
void InputDefault::set_default_cursor_shape(CursorShape p_shape) {
default_shape = p_shape;
- OS::get_singleton()->set_cursor_shape((OS::CursorShape)p_shape);
+ // The default shape is set in Viewport::_gui_input_event. To instantly
+ // see the shape in the viewport we need to trigger a mouse motion event.
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+ mm->set_position(mouse_pos);
+ mm->set_global_position(mouse_pos);
+ parse_input_event(mm);
}
void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
@@ -630,6 +636,7 @@ InputDefault::InputDefault() {
emulate_mouse_from_touch = false;
mouse_from_touch_index = -1;
main_loop = NULL;
+ default_shape = CURSOR_ARROW;
hat_map_default[HAT_UP].type = TYPE_BUTTON;
hat_map_default[HAT_UP].index = JOY_DPAD_UP;
diff --git a/main/input_default.h b/main/input_default.h
index 4441ade04e..b420ec124b 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -119,7 +119,8 @@ class InputDefault : public Input {
SpeedTrack mouse_speed_track;
Map<int, Joypad> joy_names;
int fallback_mapping;
- CursorShape default_shape = CURSOR_ARROW;
+
+ CursorShape default_shape;
public:
enum HatMask {
diff --git a/main/main.cpp b/main/main.cpp
index db82ff8f6e..3eb0b7f354 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -34,6 +34,7 @@
#include "core/io/file_access_network.h"
#include "core/io/file_access_pack.h"
#include "core/io/file_access_zip.h"
+#include "core/io/image_loader.h"
#include "core/io/ip.h"
#include "core/io/resource_loader.h"
#include "core/io/stream_peer_ssl.h"
@@ -77,63 +78,94 @@
#include "editor/project_manager.h"
#endif
-static ProjectSettings *globals = NULL;
+/* Static members */
+
+// Singletons
+
+// Initialized in setup()
static Engine *engine = NULL;
+static ProjectSettings *globals = NULL;
static InputMap *input_map = NULL;
-static bool _start_success = false;
-static ScriptDebugger *script_debugger = NULL;
-AudioServer *audio_server = NULL;
-ARVRServer *arvr_server = NULL;
-PhysicsServer *physics_server = NULL;
-Physics2DServer *physics_2d_server = NULL;
-
-static MessageQueue *message_queue = NULL;
+static TranslationServer *translation_server = NULL;
static Performance *performance = NULL;
-
static PackedData *packed_data = NULL;
#ifdef MINIZIP_ENABLED
static ZipArchive *zip_packed_data = NULL;
#endif
static FileAccessNetworkClient *file_access_network_client = NULL;
-static TranslationServer *translation_server = NULL;
+static ScriptDebugger *script_debugger = NULL;
+static MessageQueue *message_queue = NULL;
+
+// Initialized in setup2()
+static AudioServer *audio_server = NULL;
+static ARVRServer *arvr_server = NULL;
+static PhysicsServer *physics_server = NULL;
+static Physics2DServer *physics_2d_server = NULL;
+// We error out if setup2() doesn't turn this true
+static bool _start_success = false;
+
+// Drivers
+
+static int video_driver_idx = -1;
+static int audio_driver_idx = -1;
+
+// Engine config/tools
+
+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;
+
+// Display
static OS::VideoMode video_mode;
+static int init_screen = -1;
+static bool init_fullscreen = false;
static bool init_maximized = false;
static bool init_windowed = false;
-static bool init_fullscreen = false;
static bool init_always_on_top = false;
static bool init_use_custom_pos = false;
+static Vector2 init_custom_pos;
+static bool force_lowdpi = false;
+
+// Debug
+
+static bool use_debug_profiler = false;
#ifdef DEBUG_ENABLED
static bool debug_collisions = false;
static bool debug_navigation = false;
#endif
static int frame_delay = 0;
-static Vector2 init_custom_pos;
-static int video_driver_idx = -1;
-static int audio_driver_idx = -1;
-static String locale;
-static bool use_debug_profiler = false;
-static bool force_lowdpi = false;
-static int init_screen = -1;
-static bool use_vsync = true;
-static bool editor = false;
-static bool show_help = false;
static bool disable_render_loop = false;
static int fixed_fps = -1;
-static bool auto_build_solutions = false;
-static bool auto_quit = false;
static bool print_fps = false;
-static OS::ProcessID allow_focus_steal_pid = 0;
-
-static bool project_manager = false;
+/* Helper methods */
+// Used by Mono module, should likely be registered in Engine singleton instead
+// FIXME: This is also not 100% accurate, `project_manager` is only true when it was requested,
+// but not if e.g. we fail to load and project and fallback to the manager.
bool Main::is_project_manager() {
return project_manager;
}
-void initialize_physics() {
+static String unescape_cmdline(const String &p_str) {
+ return p_str.replace("%20", " ");
+}
+static String get_full_version_string() {
+ String hash = String(VERSION_HASH);
+ if (hash.length() != 0)
+ hash = "." + hash.left(7);
+ return String(VERSION_FULL_BUILD) + hash;
+}
+
+// FIXME: Could maybe be moved to PhysicsServerManager and Physics2DServerManager directly
+// to have less code in main.cpp.
+void initialize_physics() {
/// 3D Physics Server
physics_server = PhysicsServerManager::new_server(ProjectSettings::get_singleton()->get(PhysicsServerManager::setting_property_name));
if (!physics_server) {
@@ -161,19 +193,6 @@ void finalize_physics() {
memdelete(physics_2d_server);
}
-static String unescape_cmdline(const String &p_str) {
-
- return p_str.replace("%20", " ");
-}
-
-static String get_full_version_string() {
-
- String hash = String(VERSION_HASH);
- if (hash.length() != 0)
- hash = "." + hash.left(7);
- return String(VERSION_FULL_BUILD) + hash;
-}
-
//#define DEBUG_INIT
#ifdef DEBUG_INIT
#define MAIN_PRINT(m_txt) print_line(m_txt)
@@ -278,6 +297,32 @@ void Main::print_help(const char *p_binary) {
#endif
}
+/* Engine initialization
+ *
+ * Consists of several methods that are called by each platform's specific main(argc, argv).
+ * To fully understand engine init, one should therefore start from the platform's main and
+ * see how it calls into the Main class' methods.
+ *
+ * The initialization is typically done in 3 steps (with the setup2 step triggered either
+ * automatically by setup, or manually in the platform's main).
+ *
+ * - setup(execpath, argc, argv, p_second_phase) is the main entry point for all platforms,
+ * responsible for the initialization of all low level singletons and core types, and parsing
+ * command line arguments to configure things accordingly.
+ * If p_second_phase is true, it will chain into setup2() (default behaviour). This is
+ * disabled on some platforms (Android, iOS, UWP) which trigger the second step in their
+ * own time.
+ *
+ * - setup2(p_main_tid_override) registers high level servers and singletons, displays the
+ * boot splash, then registers higher level types (scene, editor, etc.).
+ *
+ * - start() is the last step and that's where command line tools can run, or the main loop
+ * can be created eventually and the project settings put into action. That's also where
+ * the editor node is created, if relevant.
+ * start() does it own argument parsing for a subset of the command line arguments described
+ * in help, it's a bit messy and should be globalized with the setup() parsing somehow.
+ */
+
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
RID_OwnerBase::init_rid();
@@ -1003,15 +1048,6 @@ error:
if (file_access_network_client)
memdelete(file_access_network_client);
- // Note 1: *zip_packed_data live into *packed_data
- // Note 2: PackedData::~PackedData destroy this.
- /*
-#ifdef MINIZIP_ENABLED
- if (zip_packed_data)
- memdelete( zip_packed_data );
-#endif
-*/
-
unregister_core_driver_types();
unregister_core_types();
@@ -1089,9 +1125,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
boot_logo_path = boot_logo_path.strip_edges();
if (boot_logo_path != String()) {
- print_line("Boot splash path: " + boot_logo_path);
boot_logo.instance();
- Error err = boot_logo->load(boot_logo_path);
+ Error err = ImageLoader::load_image(boot_logo_path, boot_logo);
if (err)
ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash.");
}
@@ -1210,7 +1245,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
}
// everything the main loop needs to know about frame timings
-
static MainTimerSync main_timer_sync;
bool Main::start() {
@@ -1673,7 +1707,7 @@ bool Main::start() {
if (iconpath != "") {
Ref<Image> icon;
icon.instance();
- if (icon->load(iconpath) == OK) {
+ if (ImageLoader::load_image(iconpath, icon) == OK) {
OS::get_singleton()->set_icon(icon);
hasicon = true;
}
@@ -1713,13 +1747,23 @@ bool Main::start() {
return true;
}
+/* Main iteration
+ *
+ * This is the iteration of the engine's game loop, advancing the state of physics,
+ * rendering and audio.
+ * It's called directly by the platform's OS::run method, where the loop is created
+ * and monitored.
+ *
+ * The OS implementation can impact its draw step with the Main::force_redraw() method.
+ */
+
uint64_t Main::last_ticks = 0;
uint64_t Main::target_ticks = 0;
uint32_t Main::frames = 0;
uint32_t Main::frame = 0;
bool Main::force_redraw_requested = false;
-//for performance metrics
+// For performance metrics
static uint64_t physics_process_max = 0;
static uint64_t idle_process_max = 0;
@@ -1743,11 +1787,6 @@ bool Main::iteration() {
Engine::get_singleton()->_frame_step = step;
- /*
- if (time_accum+step < frame_slice)
- return false;
- */
-
uint64_t physics_process_ticks = 0;
uint64_t idle_process_ticks = 0;
@@ -1891,9 +1930,15 @@ bool Main::iteration() {
}
void Main::force_redraw() {
-
force_redraw_requested = true;
-};
+}
+
+/* Engine deinitialization
+ *
+ * Responsible for freeing all the memory allocated by previous setup steps,
+ * so that the engine closes cleanly without leaking memory or crashing.
+ * The order matters as some of those steps are linked with each other.
+ */
void Main::cleanup() {
diff --git a/main/main.h b/main/main.h
index bd56e21d94..23a19dddec 100644
--- a/main/main.h
+++ b/main/main.h
@@ -49,13 +49,16 @@ class Main {
static bool force_redraw_requested;
public:
+ static bool is_project_manager();
+
static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true);
static Error setup2(Thread::ID p_main_tid_override = 0);
static bool start();
+
static bool iteration();
- static void cleanup();
static void force_redraw();
- static bool is_project_manager();
+
+ static void cleanup();
};
-#endif
+#endif // MAIN_H
diff --git a/main/tests/SCsub b/main/tests/SCsub
index 26a0819ee8..437d9ed777 100644
--- a/main/tests/SCsub
+++ b/main/tests/SCsub
@@ -5,9 +5,5 @@ Import('env')
env.tests_sources = []
env.add_source_files(env.tests_sources, "*.cpp")
-Export('env')
-
-# SConscript('math/SCsub');
-
lib = env.add_library("tests", env.tests_sources)
env.Prepend(LIBS=[lib])
diff --git a/main/tests/test_gdscript.cpp b/main/tests/test_gdscript.cpp
index 412e809732..4d2fa2a26d 100644
--- a/main/tests/test_gdscript.cpp
+++ b/main/tests/test_gdscript.cpp
@@ -357,6 +357,9 @@ static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_i
_parser_show_block(cf_node->body, p_indent + 1);
} break;
+ case GDScriptParser::ControlFlowNode::CF_MATCH: {
+ // FIXME: Implement
+ } break;
case GDScriptParser::ControlFlowNode::CF_SWITCH: {
} break;
diff --git a/main/tests/test_gui.cpp b/main/tests/test_gui.cpp
index d25eedbf6f..271353f1dd 100644
--- a/main/tests/test_gui.cpp
+++ b/main/tests/test_gui.cpp
@@ -60,8 +60,6 @@ namespace TestGUI {
class TestMainLoop : public SceneTree {
- Control *control;
-
public:
virtual void request_quit() {
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index 2cd39d0208..9df5973376 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -194,6 +194,9 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
code = vnode->name;
} break;
+ case SL::Node::TYPE_VARIABLE_DECLARATION: {
+ // FIXME: Implement
+ } break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;
return get_constant_text(cnode->datatype, cnode->values);