Skip to content

Commit

Permalink
Add support for specifying whether to play the current scene or a spe…
Browse files Browse the repository at this point in the history
…cific scene in XR or regular mode

The functionality is only activated for the XR Editor, when a project has OpenXR enabled.
  • Loading branch information
m4gr3d committed Jan 4, 2025
1 parent 2582793 commit da33e3e
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 33 deletions.
8 changes: 7 additions & 1 deletion editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ String EditorRun::get_running_scene() const {
return running_scene;
}

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

for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_PROJECT)) {
Expand Down Expand Up @@ -223,6 +223,12 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
args.push_back(p_scene);
}

if (p_run_args != nullptr) {
for (const String &run_arg : *p_run_args) {
args.push_back(run_arg);
}
}

String exec = OS::get_singleton()->get_executable_path();
int instance_count = RunInstancesDialog::get_singleton()->get_instance_count();
for (int i = 0; i < instance_count; i++) {
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class EditorRun {
Status get_status() const;
String get_running_scene() const;

Error run(const String &p_scene, const String &p_write_movie = "");
Error run(const String &p_scene, const String &p_write_movie = "", List<String> *p_run_args = nullptr);
void run_native_notify() { status = STATUS_PLAY; }
void stop();

Expand Down
110 changes: 89 additions & 21 deletions editor/gui/editor_run_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@
#include "editor/gui/editor_quick_open_dialog.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel_container.h"

#ifndef _3D_DISABLED
#include "servers/xr_server.h"
#endif // _3D_DISABLED

EditorRunBar *EditorRunBar::singleton = nullptr;

void EditorRunBar::_notification(int p_what) {
Expand Down Expand Up @@ -124,33 +129,66 @@ void EditorRunBar::_write_movie_toggled(bool p_enabled) {
}
}

void EditorRunBar::_quick_run_selected(const String &p_file_path) {
play_custom_scene(p_file_path);
void EditorRunBar::_quick_run_selected(const String &p_file_path, int p_id) {
List<String> play_args;
if (p_id == 0) {
// Play in regular mode, xr mode off
play_args.push_back("--xr-mode");
play_args.push_back("off");
} else if (p_id == 1) {
// Play in xr mode
play_args.push_back("--xr-mode");
play_args.push_back("on");
}

play_custom_scene(p_file_path, &play_args);
}

void EditorRunBar::_play_custom_pressed() {
void EditorRunBar::_play_custom_pressed(int p_id) {
if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CUSTOM) {
stop_playing();

EditorNode::get_singleton()->get_quick_open_dialog()->popup_dialog({ "PackedScene" }, callable_mp(this, &EditorRunBar::_quick_run_selected));
EditorNode::get_singleton()->get_quick_open_dialog()->popup_dialog({ "PackedScene" }, callable_mp(this, &EditorRunBar::_quick_run_selected).bind(p_id));
play_custom_scene_button->set_pressed(false);
} else {
List<String> play_args;
if (p_id == 0) {
// Play in regular mode, xr mode off
play_args.push_back("--xr-mode");
play_args.push_back("off");
} else if (p_id == 1) {
// Play in xr mode
play_args.push_back("--xr-mode");
play_args.push_back("on");
}

// Reload if already running a custom scene.
String last_custom_scene = run_custom_filename; // This is necessary to have a copy of the string.
play_custom_scene(last_custom_scene);
play_custom_scene(last_custom_scene, &play_args);
}
}

void EditorRunBar::_play_current_pressed() {
void EditorRunBar::_play_current_pressed(int p_id) {
List<String> play_args;
if (p_id == 0) {
// Play in regular mode, xr mode off
play_args.push_back("--xr-mode");
play_args.push_back("off");
} else if (p_id == 1) {
// Play in xr mode
play_args.push_back("--xr-mode");
play_args.push_back("on");
}

if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CURRENT) {
play_current_scene();
play_current_scene(false, &play_args);
} else {
// Reload if already running the current scene.
play_current_scene(true);
play_current_scene(true, &play_args);
}
}

void EditorRunBar::_run_scene(const String &p_scene_path) {
void EditorRunBar::_run_scene(const String &p_scene_path, List<String> *p_run_args) {
ERR_FAIL_COND_MSG(current_mode == RUN_CUSTOM && p_scene_path.is_empty(), "Attempting to run a custom scene with an empty path.");

if (editor_run.get_status() == EditorRun::STATUS_PLAY) {
Expand Down Expand Up @@ -235,7 +273,7 @@ void EditorRunBar::_run_scene(const String &p_scene_path) {
}

EditorDebuggerNode::get_singleton()->start();
Error error = editor_run.run(run_filename, write_movie_file);
Error error = editor_run.run(run_filename, write_movie_file, p_run_args);
if (error != OK) {
EditorDebuggerNode::get_singleton()->stop();
EditorNode::get_singleton()->show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));
Expand Down Expand Up @@ -289,25 +327,25 @@ void EditorRunBar::play_main_scene(bool p_from_native) {
}
}

void EditorRunBar::play_current_scene(bool p_reload) {
void EditorRunBar::play_current_scene(bool p_reload, List<String> *p_play_args) {
String last_current_scene = run_current_filename; // This is necessary to have a copy of the string.

EditorNode::get_singleton()->save_default_environment();
stop_playing();

current_mode = RunMode::RUN_CURRENT;
if (p_reload) {
_run_scene(last_current_scene);
_run_scene(last_current_scene, p_play_args);
} else {
_run_scene();
_run_scene("", p_play_args);
}
}

void EditorRunBar::play_custom_scene(const String &p_custom) {
void EditorRunBar::play_custom_scene(const String &p_custom, List<String> *p_play_args) {
stop_playing();

current_mode = RunMode::RUN_CUSTOM;
_run_scene(p_custom);
_run_scene(p_custom, p_play_args);
}

void EditorRunBar::stop_playing() {
Expand Down Expand Up @@ -465,25 +503,55 @@ EditorRunBar::EditorRunBar() {
main_hbox->add_child(run_native);
run_native->connect("native_run", callable_mp(this, &EditorRunBar::_run_native));

play_scene_button = memnew(Button);
bool add_play_xr_mode_options = false;
#ifndef _3D_DISABLED
if (OS::get_singleton()->has_feature("xr_editor") &&
(XRServer::get_xr_mode() == XRServer::XRMODE_ON ||
(XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT && GLOBAL_GET("xr/openxr/enabled")))) {
// If this is the XR editor and openxr is enabled, we turn the `play_scene_button` and
// `play_custom_scene_button` into MenuButtons to provide the option to start a scene in
// either regular mode or XR mode.
add_play_xr_mode_options = true;
}
#endif // _3D_DISABLED

if (add_play_xr_mode_options) {
MenuButton *menu_button = memnew(MenuButton);
PopupMenu *popup = menu_button->get_popup();
popup->add_item(TTRC("Run Current Scene in Regular mode"), 0);
popup->add_item(TTRC("Run Current Scene in XR mode"), 1);
popup->connect(SceneStringName(id_pressed), callable_mp(this, &EditorRunBar::_play_current_pressed));
play_scene_button = menu_button;
} else {
play_scene_button = memnew(Button);
play_scene_button->set_toggle_mode(true);
play_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_current_pressed).bind(-1));
}
main_hbox->add_child(play_scene_button);
play_scene_button->set_theme_type_variation("RunBarButton");
play_scene_button->set_toggle_mode(true);
play_scene_button->set_focus_mode(Control::FOCUS_NONE);
play_scene_button->set_tooltip_text(TTRC("Run the currently edited scene."));
play_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_current_pressed));

ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTRC("Run Current Scene"), Key::F6);
ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R);
play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene"));

play_custom_scene_button = memnew(Button);
if (add_play_xr_mode_options) {
MenuButton *menu_button = memnew(MenuButton);
PopupMenu *popup = menu_button->get_popup();
popup->add_item(TTRC("Run Specific Scene in Regular mode"), 0);
popup->add_item(TTRC("Run Specific Scene in XR mode"), 1);
popup->connect(SceneStringName(id_pressed), callable_mp(this, &EditorRunBar::_play_custom_pressed));
play_custom_scene_button = menu_button;
} else {
play_custom_scene_button = memnew(Button);
play_custom_scene_button->set_toggle_mode(true);
play_custom_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_custom_pressed).bind(-1));
}
main_hbox->add_child(play_custom_scene_button);
play_custom_scene_button->set_theme_type_variation("RunBarButton");
play_custom_scene_button->set_toggle_mode(true);
play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE);
play_custom_scene_button->set_tooltip_text(TTRC("Run a specific scene."));
play_custom_scene_button->connect(SceneStringName(pressed), callable_mp(this, &EditorRunBar::_play_custom_pressed));

ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTRC("Run Specific Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5);
ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R);
Expand Down
12 changes: 6 additions & 6 deletions editor/gui/editor_run_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ class EditorRunBar : public MarginContainer {
void _update_play_buttons();

void _write_movie_toggled(bool p_enabled);
void _quick_run_selected(const String &p_file_path);
void _quick_run_selected(const String &p_file_path, int p_id = -1);

void _play_current_pressed();
void _play_custom_pressed();
void _play_current_pressed(int p_id = -1);
void _play_custom_pressed(int p_id = -1);

void _run_scene(const String &p_scene_path = "");
void _run_scene(const String &p_scene_path = "", List<String> *p_run_args = nullptr);
void _run_native(const Ref<EditorExportPreset> &p_preset);

void _profiler_autostart_indicator_pressed();
Expand All @@ -96,8 +96,8 @@ class EditorRunBar : public MarginContainer {
static EditorRunBar *get_singleton() { return singleton; }

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 play_current_scene(bool p_reload = false, List<String> *p_play_args = nullptr);
void play_custom_scene(const String &p_custom, List<String> *p_play_args = nullptr);

void stop_playing();
bool is_playing() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ open class GodotEditor : BaseGodotEditor() {
companion object {
private val TAG = GodotEditor::class.java.simpleName

/** Default behavior, means we check project settings **/
private const val XR_MODE_DEFAULT = "default"

/**
* Ignore project settings, OpenXR is disabled
*/
private const val XR_MODE_OFF = "off"

/**
* Ignore project settings, OpenXR is enabled
*/
private const val XR_MODE_ON = "on"

internal val XR_RUN_GAME_INFO = EditorWindowInfo(GodotXRGame::class.java, 1667, ":GodotXRGame")

internal val USE_SCENE_PERMISSIONS = listOf("com.oculus.permission.USE_SCENE", "horizonos.permission.USE_SCENE")
Expand All @@ -58,23 +71,23 @@ open class GodotEditor : BaseGodotEditor() {

override fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo {
var hasEditor = false
var xrModeOn = false
var xrMode = XR_MODE_DEFAULT

var i = 0
while (i < args.size) {
when (args[i++]) {
EDITOR_ARG, EDITOR_ARG_SHORT, EDITOR_PROJECT_MANAGER_ARG, EDITOR_PROJECT_MANAGER_ARG_SHORT -> hasEditor = true
XR_MODE_ARG -> {
val argValue = args[i++]
xrModeOn = xrModeOn || ("on" == argValue)
xrMode = args[i++]
}
}
}

return if (hasEditor) {
EDITOR_MAIN_INFO
} else {
val openxrEnabled = GodotLib.getGlobal("xr/openxr/enabled").toBoolean()
val openxrEnabled = xrMode == XR_MODE_ON ||
(xrMode == XR_MODE_DEFAULT && GodotLib.getGlobal("xr/openxr/enabled").toBoolean())
if (openxrEnabled && isNativeXRDevice()) {
XR_RUN_GAME_INFO
} else {
Expand Down

0 comments on commit da33e3e

Please sign in to comment.