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 Dec 4, 2024
1 parent 98ddec4 commit b680e4d
Show file tree
Hide file tree
Showing 44 changed files with 1,707 additions and 133 deletions.
8 changes: 8 additions & 0 deletions core/config/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,14 @@ void Engine::set_freeze_time_scale(bool p_frozen) {
freeze_time_scale = p_frozen;
}

void Engine::set_embedded_in_editor(bool p_enabled) {
embedded_in_editor = p_enabled;
}

bool Engine::is_embedded_in_editor() const {
return embedded_in_editor;
}

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 @@ -87,6 +87,7 @@ class Engine {
bool editor_hint = false;
bool project_manager_hint = false;
bool extension_reloading = false;
bool embedded_in_editor = false;

bool _print_header = true;

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

void set_freeze_time_scale(bool p_frozen);
void set_embedded_in_editor(bool p_enabled);
bool is_embedded_in_editor() const;

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

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

String Engine::get_write_movie_path() const {
return ::Engine::get_singleton()->get_write_movie_path();
}
Expand Down Expand Up @@ -1974,6 +1978,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_in_editor"), &Engine::is_embedded_in_editor);

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

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

bool is_embedded_in_editor() 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
2 changes: 2 additions & 0 deletions core/os/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ bool OS::has_feature(const String &p_feature) {
return _in_editor;
} else if (p_feature == "editor_runtime") {
return !_in_editor;
} else if (p_feature == "embedded_in_editor") {
return _embedded_in_editor;
}
#else
if (p_feature == "template") {
Expand Down
1 change: 1 addition & 0 deletions core/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class OS {
bool _stderr_enabled = true;
bool _writing_movie = false;
bool _in_editor = false;
bool _embedded_in_editor = false;

CompositeLogger *_logger = nullptr;

Expand Down
3 changes: 3 additions & 0 deletions doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,9 @@
<constant name="FEATURE_NATIVE_DIALOG_FILE_EXTRA" value="26" enum="Feature">
The display server supports all features of [constant FEATURE_NATIVE_DIALOG_FILE], with the added functionality of Options and native dialog file access to [code]res://[/code] and [code]user://[/code] paths. 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="27" 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
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_in_editor" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the engine is running embedded in the editor. This is useful to prevent attempting to update window mode or window flags that are not supported when running the project embedded in the editor.
</description>
</method>
<method name="is_in_physics_frame" qualifiers="const">
<return type="bool" />
<description>
Expand Down
8 changes: 7 additions & 1 deletion editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,9 @@ void EditorNode::_notification(int p_what) {
}

// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused.
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
if (unfocused_low_processor_usage_mode_enabled) {
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
}
} break;

case NOTIFICATION_WM_ABOUT: {
Expand Down Expand Up @@ -6713,6 +6715,10 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
return eta.exitcode;
}

void EditorNode::set_unfocused_low_processor_usage_mode_enabled(bool p_enabled) {
unfocused_low_processor_usage_mode_enabled = p_enabled;
}

EditorNode::EditorNode() {
DEV_ASSERT(!singleton);
singleton = this;
Expand Down
4 changes: 4 additions & 0 deletions editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ class EditorNode : public Node {

bool was_window_windowed_last = false;

bool unfocused_low_processor_usage_mode_enabled = true;

static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
static int build_callback_count;
Expand Down Expand Up @@ -788,6 +790,8 @@ class EditorNode : public Node {
HashMap<StringName, Variant> get_modified_properties_for_node(Node *p_node, bool p_node_references_only);
HashMap<StringName, Variant> get_modified_properties_reference_to_nodes(Node *p_node, List<Node *> &p_nodes_referenced_by);

void set_unfocused_low_processor_usage_mode_enabled(bool p_enabled);

struct AdditiveNodeEntry {
Node *node = nullptr;
NodePath parent;
Expand Down
7 changes: 7 additions & 0 deletions editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,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 (instance_starting_callback) {
instance_starting_callback(i, instance_args);
}

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

OS::ProcessID EditorRun::get_current_process() const {
return pids.front()->get();
}

EditorRun::EditorRun() {
status = STATUS_STOP;
running_scene = "";
Expand Down
5 changes: 5 additions & 0 deletions editor/editor_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#include "core/os/os.h"

typedef void (*EditorRunInstanceStarting)(int p_index, List<String> &r_arguments);

class EditorRun {
public:
enum Status {
Expand All @@ -48,6 +50,8 @@ class EditorRun {
String running_scene;

public:
inline static EditorRunInstanceStarting instance_starting_callback = nullptr;

Status get_status() const;
String get_running_scene() const;

Expand All @@ -58,6 +62,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
4 changes: 4 additions & 0 deletions editor/gui/editor_run_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,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
1 change: 1 addition & 0 deletions editor/gui/editor_run_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,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
10 changes: 10 additions & 0 deletions editor/gui/editor_scene_tabs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@

#include "editor_scene_tabs.h"

#include "editor/editor_main_screen.h"
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_settings.h"
#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_run_bar.h"
#include "editor/inspector_dock.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/box_container.h"
Expand Down Expand Up @@ -90,6 +92,14 @@ void EditorSceneTabs::_scene_tab_hovered(int p_tab) {
if (!bool(EDITOR_GET("interface/scene_tabs/show_thumbnail_on_hover"))) {
return;
}

// Currently the tab previews are displayed under the running game process when embed.
// Right now, the easiest technique to fix that is to prevent displaying the tab preview
// when the user is in the Game View.
if (EditorNode::get_singleton()->get_editor_main_screen()->get_selected_index() == EditorMainScreen::EDITOR_GAME && EditorRunBar::get_singleton()->is_playing()) {
return;
}

int current_tab = scene_tabs->get_current_tab();

if (p_tab == current_tab || p_tab < 0) {
Expand Down
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 b680e4d

Please sign in to comment.