Skip to content

Commit

Permalink
Embedding game process in editor
Browse files Browse the repository at this point in the history
  • Loading branch information
Hilderin committed Sep 29, 2024
1 parent 2ab283a commit 8eda5b1
Show file tree
Hide file tree
Showing 35 changed files with 1,078 additions and 134 deletions.
3 changes: 3 additions & 0 deletions doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,9 @@
<constant name="FEATURE_NATIVE_DIALOG_FILE" value="25" enum="Feature">
Display server supports spawning dialogs for selecting files or directories using the operating system's native look-and-feel. See [method file_dialog_show] and [method file_dialog_with_options_show]. [b]Windows, macOS, Linux (X11/Wayland)[/b]
</constant>
<constant name="FEATURE_WINDOW_EMBEDDING" value="25" enum="Feature">
Display server supports embedding a window from another process. [b]Windows, Linux (X11)[/b]
</constant>
<constant name="MOUSE_MODE_VISIBLE" value="0" enum="MouseMode">
Makes the mouse cursor visible if it is hidden.
</constant>
Expand Down
172 changes: 100 additions & 72 deletions editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/plugins/game_editor_plugin.h"
#include "editor/run_instances_dialog.h"
#include "main/main.h"
#include "servers/display_server.h"
Expand All @@ -46,63 +47,10 @@ String EditorRun::get_running_scene() const {
return running_scene;
}

Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
List<String> args;

for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_PROJECT)) {
args.push_back(a);
}

String resource_path = ProjectSettings::get_singleton()->get_resource_path();
if (!resource_path.is_empty()) {
args.push_back("--path");
args.push_back(resource_path.replace(" ", "%20"));
}

const String debug_uri = EditorDebuggerNode::get_singleton()->get_server_uri();
if (debug_uri.size()) {
args.push_back("--remote-debug");
args.push_back(debug_uri);
}

args.push_back("--editor-pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));

bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisions", false);
bool debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false);
bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
bool debug_avoidance = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_avoidance", false);
bool debug_canvas_redraw = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_canvas_redraw", false);

if (debug_collisions) {
args.push_back("--debug-collisions");
}

if (debug_paths) {
args.push_back("--debug-paths");
}

if (debug_navigation) {
args.push_back("--debug-navigation");
}

if (debug_avoidance) {
args.push_back("--debug-avoidance");
}

if (debug_canvas_redraw) {
args.push_back("--debug-canvas-item-redraw");
}

if (p_write_movie != "") {
args.push_back("--write-movie");
args.push_back(p_write_movie);
args.push_back("--fixed-fps");
args.push_back(itos(GLOBAL_GET("editor/movie_writer/fps")));
if (bool(GLOBAL_GET("editor/movie_writer/disable_vsync"))) {
args.push_back("--disable-vsync");
}
}
void EditorRun::get_default_instance_setting(DisplayServer::WindowMode &r_window_mode, Rect2i &r_screen_rect) {
// Default = Windowed.
r_window_mode = DisplayServer::WINDOW_MODE_WINDOWED;
r_screen_rect = Rect2i();

int screen = EDITOR_GET("run/window_placement/screen");
if (screen == -5) {
Expand Down Expand Up @@ -160,44 +108,114 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {

switch (window_placement) {
case 0: { // top left
args.push_back("--position");
args.push_back(itos(screen_rect.position.x) + "," + itos(screen_rect.position.y));
r_screen_rect = Rect2i(screen_rect.position, window_size);
} break;
case 1: { // centered
Vector2 pos = (screen_rect.position) + ((screen_rect.size - window_size) / 2).floor();
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
r_screen_rect = Rect2i(pos, window_size);
} break;
case 2: { // custom pos
Vector2 pos = EDITOR_GET("run/window_placement/rect_custom_position");
pos += screen_rect.position;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
r_screen_rect = Rect2i(pos, window_size);
} break;
case 3: { // force maximized
r_window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED;
Vector2 pos = screen_rect.position + screen_rect.size / 2;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
args.push_back("--maximized");
r_screen_rect = Rect2i(pos, window_size);
} break;
case 4: { // force fullscreen
r_window_mode = DisplayServer::WINDOW_MODE_FULLSCREEN;
Vector2 pos = screen_rect.position + screen_rect.size / 2;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
args.push_back("--fullscreen");
r_screen_rect = Rect2i(pos, window_size);
} break;
}
} else {
// Unable to get screen info, skip setting position.
switch (window_placement) {
case 3: { // force maximized
args.push_back("--maximized");
r_window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED;
} break;
case 4: { // force fullscreen
args.push_back("--fullscreen");
r_window_mode = DisplayServer::WINDOW_MODE_FULLSCREEN;
} break;
}
}
}

Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
List<String> args;

for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_PROJECT)) {
args.push_back(a);
}

String resource_path = ProjectSettings::get_singleton()->get_resource_path();
if (!resource_path.is_empty()) {
args.push_back("--path");
args.push_back(resource_path.replace(" ", "%20"));
}

const String debug_uri = EditorDebuggerNode::get_singleton()->get_server_uri();
if (debug_uri.size()) {
args.push_back("--remote-debug");
args.push_back(debug_uri);
}

args.push_back("--editor-pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));

bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisions", false);
bool debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false);
bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
bool debug_avoidance = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_avoidance", false);
bool debug_canvas_redraw = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_canvas_redraw", false);

if (debug_collisions) {
args.push_back("--debug-collisions");
}

if (debug_paths) {
args.push_back("--debug-paths");
}

if (debug_navigation) {
args.push_back("--debug-navigation");
}

if (debug_avoidance) {
args.push_back("--debug-avoidance");
}

if (debug_canvas_redraw) {
args.push_back("--debug-canvas-item-redraw");
}

if (p_write_movie != "") {
args.push_back("--write-movie");
args.push_back(p_write_movie);
args.push_back("--fixed-fps");
args.push_back(itos(GLOBAL_GET("editor/movie_writer/fps")));
if (bool(GLOBAL_GET("editor/movie_writer/disable_vsync"))) {
args.push_back("--disable-vsync");
}
}

DisplayServer::WindowMode window_mode;
Rect2i screen_rect;
get_default_instance_setting(window_mode, screen_rect);

if(window_mode == DisplayServer::WINDOW_MODE_FULLSCREEN) {
args.push_back("--fullscreen");
}
else if(window_mode == DisplayServer::WINDOW_MODE_MAXIMIZED) {
args.push_back("--maximized");
}

if(screen_rect != Rect2i())
{
args.push_back("--position");
args.push_back(itos(screen_rect.position.x) + "," + itos(screen_rect.position.y));
}

List<String> breakpoints;
EditorNode::get_editor_data().get_editor_breakpoints(&breakpoints);
Expand Down Expand Up @@ -234,6 +252,9 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
List<String> instance_args(args);
RunInstancesDialog::get_singleton()->get_argument_list_for_instance(i, instance_args);
RunInstancesDialog::get_singleton()->apply_custom_features(i);
if(GameEditor::get_singleton()) {
GameEditor::get_singleton()->get_argument_list_for_instance(i, instance_args);
}

if (OS::get_singleton()->is_stdout_verbose()) {
print_line(vformat("Running: %s", exec));
Expand Down Expand Up @@ -286,6 +307,13 @@ void EditorRun::stop() {
running_scene = "";
}

OS::ProcessID EditorRun::get_current_process() const {
if (pids.is_empty()) {
return 0;
}
return pids.get(0);
}

EditorRun::EditorRun() {
status = STATUS_STOP;
running_scene = "";
Expand Down
3 changes: 3 additions & 0 deletions editor/editor_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define EDITOR_RUN_H

#include "core/os/os.h"
#include "servers/display_server.h"

class EditorRun {
public:
Expand All @@ -58,6 +59,8 @@ class EditorRun {
void stop_child_process(OS::ProcessID p_pid);
bool has_child_process(OS::ProcessID p_pid) const;
int get_child_process_count() const { return pids.size(); }
OS::ProcessID get_current_process() const;
void get_default_instance_setting(DisplayServer::WindowMode &r_window_mode, Rect2i &r_screen_rect);

EditorRun();
};
Expand Down
8 changes: 8 additions & 0 deletions editor/gui/editor_run_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ void EditorRunBar::stop_child_process(OS::ProcessID p_pid) {
}
}

OS::ProcessID EditorRunBar::get_current_process() const {
return editor_run.get_current_process();
}

void EditorRunBar::set_movie_maker_enabled(bool p_enabled) {
write_movie_button->set_pressed(p_enabled);
}
Expand All @@ -353,6 +357,10 @@ bool EditorRunBar::is_movie_maker_enabled() const {
return write_movie_button->is_pressed();
}

void EditorRunBar::get_default_instance_setting(DisplayServer::WindowMode &r_window_mode, Rect2i &r_screen_rect) {
editor_run.get_default_instance_setting(r_window_mode, r_screen_rect);
}

HBoxContainer *EditorRunBar::get_buttons_container() {
return main_hbox;
}
Expand Down
3 changes: 3 additions & 0 deletions editor/gui/editor_run_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ class EditorRunBar : public MarginContainer {

OS::ProcessID has_child_process(OS::ProcessID p_pid) const;
void stop_child_process(OS::ProcessID p_pid);
OS::ProcessID get_current_process() const;

void set_movie_maker_enabled(bool p_enabled);
bool is_movie_maker_enabled() const;

void get_default_instance_setting(DisplayServer::WindowMode &r_window_mode, Rect2i &r_screen_rect);

Button *get_pause_button() { return pause_button; }

HBoxContainer *get_buttons_container();
Expand Down
1 change: 1 addition & 0 deletions editor/icons/AutoFocus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/EmbeddedProcess.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/KeepAspect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 8eda5b1

Please sign in to comment.