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 Oct 4, 2024
1 parent 2ab283a commit dacd56b
Show file tree
Hide file tree
Showing 42 changed files with 1,185 additions and 112 deletions.
8 changes: 8 additions & 0 deletions core/config/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,14 @@ void Engine::set_suspend(bool p_enabled) {
suspended = p_enabled;
}

void Engine::set_embedded(bool p_enabled) {
embedded = p_enabled;
}

bool Engine::is_embedded() const {
return embedded;
}

Engine::Engine() {
singleton = this;
}
Expand Down
3 changes: 3 additions & 0 deletions core/config/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Engine {
bool editor_hint = false;
bool project_manager_hint = false;
bool extension_reloading = false;
bool embedded = false;

bool _print_header = true;

Expand Down Expand Up @@ -194,6 +195,8 @@ class Engine {
bool notify_frame_server_synced();

void set_suspend(bool p_enabled);
void set_embedded(bool p_enabled);
bool is_embedded() const;

Engine();
virtual ~Engine();
Expand Down
9 changes: 9 additions & 0 deletions core/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,14 @@ bool Engine::is_editor_hint() const {
return ::Engine::get_singleton()->is_editor_hint();
}

void Engine::set_embedded(bool p_enabled) {
::Engine::get_singleton()->set_embedded(p_enabled);
}

bool Engine::is_embedded() const {
return ::Engine::get_singleton()->is_embedded();
}

String Engine::get_write_movie_path() const {
return ::Engine::get_singleton()->get_write_movie_path();
}
Expand Down Expand Up @@ -1926,6 +1934,7 @@ void Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_script_language", "index"), &Engine::get_script_language);

ClassDB::bind_method(D_METHOD("is_editor_hint"), &Engine::is_editor_hint);
ClassDB::bind_method(D_METHOD("is_embedded"), &Engine::is_embedded);

ClassDB::bind_method(D_METHOD("get_write_movie_path"), &Engine::get_write_movie_path);

Expand Down
3 changes: 3 additions & 0 deletions core/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ class Engine : public Object {
void set_editor_hint(bool p_enabled);
bool is_editor_hint() const;

void set_embedded(bool p_enabled);
bool is_embedded() const;

// `set_write_movie_path()` is not exposed to the scripting API as changing it at run-time has no effect.
String get_write_movie_path() const;

Expand Down
8 changes: 7 additions & 1 deletion doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,12 @@
<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="26" enum="Feature">
Display server supports embedding a window from another process. [b]Windows, Linux (X11)[/b]
</constant>
<constant name="FEATURE_WINDOW_HIDDEN" value="27" enum="Feature">
Display server supports hiding a window without destroying it. [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 Expand Up @@ -2092,7 +2098,7 @@
<constant name="WINDOW_FLAG_MOUSE_PASSTHROUGH" value="7" enum="WindowFlags">
All mouse events are passed to the underlying window of the same application.
</constant>
<constant name="WINDOW_FLAG_MAX" value="8" enum="WindowFlags">
<constant name="WINDOW_FLAG_MAX" value="9" enum="WindowFlags">
Max value of the [enum WindowFlags].
</constant>
<constant name="WINDOW_EVENT_MOUSE_ENTER" value="0" enum="WindowEvent">
Expand Down
6 changes: 6 additions & 0 deletions doc/classes/Engine.xml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@
[b]Note:[/b] To detect whether the script is running on an editor [i]build[/i] (such as when pressing [kbd]F5[/kbd]), use [method OS.has_feature] with the [code]"editor"[/code] argument instead. [code]OS.has_feature("editor")[/code] evaluate to [code]true[/code] both when the script is running in the editor and when running the project from the editor, but returns [code]false[/code] when run from an exported project.
</description>
</method>
<method name="is_embedded" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the game is running embedded in the editor, otherwise returns [code]false[/code]. This is useful to prevent attempting to update window mode or window flags that are not supported when running embedded in the editor.
</description>
</method>
<method name="is_in_physics_frame" qualifiers="const">
<return type="bool" />
<description>
Expand Down
11 changes: 10 additions & 1 deletion doc/classes/Window.xml
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,11 @@
Emitted when the mouse cursor leaves the [Window]'s visible area, that is not occluded behind other [Control]s or windows, provided its [member Viewport.gui_disable_input] is [code]false[/code] and regardless if it's currently focused or not.
</description>
</signal>
<signal name="position_changed">
<description>
Emitted when the [Window] moved.
</description>
</signal>
<signal name="theme_changed">
<description>
Emitted when the [constant NOTIFICATION_THEME_CHANGED] notification is sent.
Expand Down Expand Up @@ -842,7 +847,11 @@
All mouse events are passed to the underlying window of the same application.
[b]Note:[/b] This flag has no effect in embedded windows.
</constant>
<constant name="FLAG_MAX" value="8" enum="Flags">
<constant name="FLAG_HIDDEN" value="8" enum="Flags">
Thie window is hidden but not destroyed.
[b]Note:[/b] This flag is implemented only on Windows and Linux (X11).
</constant>
<constant name="FLAG_MAX" value="9" enum="Flags">
Max value of the [enum Flags].
</constant>
<constant name="CONTENT_SCALE_MODE_DISABLED" value="0" enum="ContentScaleMode">
Expand Down
13 changes: 13 additions & 0 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 Down Expand Up @@ -175,12 +176,14 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
args.push_back(itos(pos.x) + "," + itos(pos.y));
} break;
case 3: { // force 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");
} break;
case 4: { // force fullscreen

Vector2 pos = screen_rect.position + screen_rect.size / 2;
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
Expand Down Expand Up @@ -234,6 +237,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 +292,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
2 changes: 2 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,7 @@ 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;

EditorRun();
};
Expand Down
32 changes: 32 additions & 0 deletions editor/gui/editor_run_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,34 @@ void EditorRunBar::play_custom_scene(const String &p_custom) {
current_mode = RunMode::RUN_CUSTOM;
_run_scene(p_custom);
}
void EditorRunBar::restart() {
if (!is_playing()) {
return;
}

RunMode last_current_mode = current_mode;
String last_run_custom_filename = run_custom_filename;
String last_run_current_filename = run_current_filename;

stop_playing();

switch (last_current_mode) {
case RunMode::RUN_MAIN: {
_run_scene();
} break;
case RunMode::RUN_CUSTOM: {
play_custom_scene(last_run_custom_filename);
} break;
case RunMode::RUN_CURRENT: {
_run_scene(last_run_current_filename);
} break;
case RunMode::STOPPED: {
// Nothing to do.
} break;
}

current_mode = last_current_mode;
}

void EditorRunBar::stop_playing() {
if (editor_run.get_status() == EditorRun::STATUS_STOP) {
Expand Down Expand Up @@ -345,6 +373,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 Down
2 changes: 2 additions & 0 deletions editor/gui/editor_run_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class EditorRunBar : public MarginContainer {
void play_main_scene(bool p_from_native = false);
void play_current_scene(bool p_reload = false);
void play_custom_scene(const String &p_custom);
void restart();

void stop_playing();
bool is_playing() const;
Expand All @@ -105,6 +106,7 @@ 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;
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 dacd56b

Please sign in to comment.