Fix 'save & restart' logic for the Android Editor

This commit is contained in:
Fredia Huya-Kouadio 2022-11-15 08:46:45 -08:00
parent 1ad9992ab7
commit 5aab84befb
3 changed files with 57 additions and 27 deletions

View file

@ -2488,6 +2488,9 @@ void Main::cleanup(bool p_force) {
OS::get_singleton()->delete_main_loop(); OS::get_singleton()->delete_main_loop();
// Storing it for use when restarting as it's being cleared right below.
const String execpath = OS::get_singleton()->get_executable_path();
OS::get_singleton()->_cmdline.clear(); OS::get_singleton()->_cmdline.clear();
OS::get_singleton()->_execpath = ""; OS::get_singleton()->_execpath = "";
OS::get_singleton()->_local_clipboard = ""; OS::get_singleton()->_local_clipboard = "";
@ -2558,10 +2561,9 @@ void Main::cleanup(bool p_force) {
if (OS::get_singleton()->is_restart_on_exit_set()) { if (OS::get_singleton()->is_restart_on_exit_set()) {
//attempt to restart with arguments //attempt to restart with arguments
String exec = OS::get_singleton()->get_executable_path();
List<String> args = OS::get_singleton()->get_restart_on_exit_arguments(); List<String> args = OS::get_singleton()->get_restart_on_exit_arguments();
OS::ProcessID pid = 0; OS::ProcessID pid = 0;
OS::get_singleton()->execute(exec, args, false, &pid); OS::get_singleton()->execute(execpath, args, false, &pid);
OS::get_singleton()->set_restart_on_exit(false, List<String>()); //clear list (uses memory) OS::get_singleton()->set_restart_on_exit(false, List<String>()); //clear list (uses memory)
} }

View file

@ -37,10 +37,12 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Debug import android.os.Debug
import android.os.Environment import android.os.Environment
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.window.layout.WindowMetricsCalculator import androidx.window.layout.WindowMetricsCalculator
import org.godotengine.godot.FullScreenGodotApp import org.godotengine.godot.FullScreenGodotApp
import org.godotengine.godot.utils.PermissionsUtil import org.godotengine.godot.utils.PermissionsUtil
import org.godotengine.godot.utils.ProcessPhoenix
import java.util.* import java.util.*
import kotlin.math.min import kotlin.math.min
@ -56,12 +58,17 @@ import kotlin.math.min
open class GodotEditor : FullScreenGodotApp() { open class GodotEditor : FullScreenGodotApp() {
companion object { companion object {
private val TAG = GodotEditor::class.java.simpleName
private const val WAIT_FOR_DEBUGGER = false private const val WAIT_FOR_DEBUGGER = false
private const val COMMAND_LINE_PARAMS = "command_line_params" private const val COMMAND_LINE_PARAMS = "command_line_params"
private const val EDITOR_ARG = "--editor" private const val EDITOR_ARG = "--editor"
private const val EDITOR_ARG_SHORT = "-e"
private const val PROJECT_MANAGER_ARG = "--project-manager" private const val PROJECT_MANAGER_ARG = "--project-manager"
private const val PROJECT_MANAGER_ARG_SHORT = "-p"
} }
private val commandLineParams = ArrayList<String>() private val commandLineParams = ArrayList<String>()
@ -105,13 +112,13 @@ open class GodotEditor : FullScreenGodotApp() {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen) Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen)
for (arg in args) { for (arg in args) {
if (EDITOR_ARG == arg) { if (EDITOR_ARG == arg || EDITOR_ARG_SHORT == arg) {
targetClass = GodotEditor::class.java targetClass = GodotEditor::class.java
launchAdjacent = false launchAdjacent = false
break break
} }
if (PROJECT_MANAGER_ARG == arg) { if (PROJECT_MANAGER_ARG == arg || PROJECT_MANAGER_ARG_SHORT == arg) {
targetClass = GodotProjectManager::class.java targetClass = GodotProjectManager::class.java
launchAdjacent = false launchAdjacent = false
break break
@ -125,7 +132,13 @@ open class GodotEditor : FullScreenGodotApp() {
if (launchAdjacent) { if (launchAdjacent) {
newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT) newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT)
} }
startActivity(newInstance) if (targetClass == javaClass) {
Log.d(TAG, "Restarting $targetClass")
ProcessPhoenix.triggerRebirth(this, newInstance)
} else {
Log.d(TAG, "Starting $targetClass")
startActivity(newInstance)
}
} }
// Get the screen's density scale // Get the screen's density scale

View file

@ -112,6 +112,40 @@ static void _initialize_java_modules() {
} }
} }
static void _terminate(JNIEnv *env, bool p_restart = false) {
step.set(-1); // Ensure no further steps are attempted and no further events are sent
// lets cleanup
if (java_class_wrapper) {
memdelete(java_class_wrapper);
}
if (input_handler) {
delete input_handler;
}
// Whether restarting is handled by 'Main::cleanup()'
bool restart_on_cleanup = false;
if (os_android) {
restart_on_cleanup = os_android->is_restart_on_exit_set();
os_android->main_loop_end();
Main::cleanup();
delete os_android;
}
if (godot_io_java) {
delete godot_io_java;
}
if (godot_java) {
godot_java->destroy_offscreen_gl(env);
if (!restart_on_cleanup) {
if (p_restart) {
godot_java->restart(env);
} else {
godot_java->force_quit(env);
}
}
delete godot_java;
}
}
extern "C" { extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height) { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height) {
@ -145,24 +179,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
} }
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) {
// lets cleanup _terminate(env, false);
if (java_class_wrapper) {
memdelete(java_class_wrapper);
}
if (godot_io_java) {
delete godot_io_java;
}
if (godot_java) {
godot_java->destroy_offscreen_gl(env);
delete godot_java;
}
if (input_handler) {
delete input_handler;
}
if (os_android) {
os_android->main_loop_end();
delete os_android;
}
} }
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) { JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) {
@ -225,9 +242,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en
os_android->set_offscreen_gl_available(godot_java->create_offscreen_gl(env)); os_android->set_offscreen_gl_available(godot_java->create_offscreen_gl(env));
} else { } else {
// GL context recreated because it was lost; restart app to let it reload everything // GL context recreated because it was lost; restart app to let it reload everything
step.set(-1); // Ensure no further steps are attempted and no further events are sent _terminate(env, true);
os_android->main_loop_end();
godot_java->restart(env);
} }
} }
} }
@ -276,7 +291,7 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env,
bool should_swap_buffers = false; bool should_swap_buffers = false;
if (os_android->main_loop_iterate(&should_swap_buffers)) { if (os_android->main_loop_iterate(&should_swap_buffers)) {
godot_java->force_quit(env); _terminate(env, false);
} }
return should_swap_buffers; return should_swap_buffers;