You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-02 16:48:55 +00:00
Enable Gradle builds on the Android editor via a dedicated build app
Co-authored-by: Logan Lang <devloglogan@gmail.com>
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:installLocation="auto">
|
||||
|
||||
<queries>
|
||||
<package android:name="org.godotengine.godot_gradle_build_environment" />
|
||||
</queries>
|
||||
|
||||
<supports-screens
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
|
||||
@@ -53,11 +53,12 @@ import androidx.core.content.edit
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.window.layout.WindowMetricsCalculator
|
||||
import org.godotengine.editor.buildprovider.GradleBuildProvider
|
||||
import org.godotengine.editor.embed.EmbeddedGodotGame
|
||||
import org.godotengine.editor.embed.GameMenuFragment
|
||||
import org.godotengine.editor.utils.signApk
|
||||
import org.godotengine.editor.utils.verifyApk
|
||||
import org.godotengine.godot.BuildConfig
|
||||
import org.godotengine.godot.BuildProvider
|
||||
import org.godotengine.godot.Godot
|
||||
import org.godotengine.godot.GodotActivity
|
||||
import org.godotengine.godot.GodotLib
|
||||
@@ -171,6 +172,7 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
|
||||
}
|
||||
}
|
||||
|
||||
internal val gradleBuildProvider: GradleBuildProvider = GradleBuildProvider(this, this)
|
||||
internal val editorMessageDispatcher = EditorMessageDispatcher(this)
|
||||
private val editorLoadingIndicator: View? by lazy { findViewById(R.id.editor_loading_indicator) }
|
||||
|
||||
@@ -262,6 +264,11 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
|
||||
setupGameMenuBar()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
gradleBuildProvider.buildEnvDisconnect()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onNewIntent(newIntent: Intent) {
|
||||
if (newIntent.hasCategory(HYBRID_APP_PANEL_CATEGORY) || newIntent.hasCategory(HYBRID_APP_IMMERSIVE_CATEGORY)) {
|
||||
val params = retrieveCommandLineParamsFromLaunchIntent(newIntent)
|
||||
@@ -968,4 +975,8 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
|
||||
}
|
||||
|
||||
override fun isGameEmbeddingSupported() = !isNativeXRDevice(applicationContext)
|
||||
|
||||
override fun getBuildProvider(): BuildProvider? {
|
||||
return gradleBuildProvider
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/**************************************************************************/
|
||||
/* GradleBuildEnvironmentClient.kt */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
package org.godotengine.editor.buildprovider
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Message
|
||||
import android.os.Messenger
|
||||
import android.os.RemoteException
|
||||
import android.util.Log
|
||||
import kotlin.collections.set
|
||||
|
||||
private const val MSG_EXECUTE_GRADLE = 1
|
||||
private const val MSG_COMMAND_RESULT = 2
|
||||
private const val MSG_COMMAND_OUTPUT = 3
|
||||
private const val MSG_CANCEL_COMMAND = 4
|
||||
private const val MSG_CLEAN_PROJECT = 5
|
||||
|
||||
internal class GradleBuildEnvironmentClient(private val context: Context) {
|
||||
|
||||
companion object {
|
||||
private val TAG = GradleBuildEnvironmentClient::class.java.simpleName
|
||||
}
|
||||
|
||||
private var bound: Boolean = false
|
||||
private var outgoingMessenger: Messenger? = null
|
||||
private val connection = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
outgoingMessenger = Messenger(service)
|
||||
bound = true
|
||||
|
||||
Log.i(TAG, "Service connected")
|
||||
for (callable in connectionCallbacks) {
|
||||
callable()
|
||||
}
|
||||
connectionCallbacks.clear()
|
||||
connecting = false
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
outgoingMessenger = null
|
||||
bound = false
|
||||
Log.i(TAG, "Service disconnected")
|
||||
}
|
||||
}
|
||||
|
||||
private inner class IncomingHandler: Handler() {
|
||||
override fun handleMessage(msg: Message) {
|
||||
when (msg.what) {
|
||||
MSG_COMMAND_RESULT -> {
|
||||
this@GradleBuildEnvironmentClient.receiveCommandResult(msg)
|
||||
}
|
||||
MSG_COMMAND_OUTPUT -> {
|
||||
this@GradleBuildEnvironmentClient.receiveCommandOutput(msg)
|
||||
}
|
||||
else -> super.handleMessage(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
private val incomingMessenger = Messenger(IncomingHandler())
|
||||
|
||||
private val connectionCallbacks = mutableListOf<() -> Unit>()
|
||||
private var connecting = false
|
||||
private var executionId = 1000
|
||||
|
||||
private class ExecutionInfo(val outputCallback: (Int, String) -> Unit, val resultCallback: (Int) -> Unit)
|
||||
private val executionMap = HashMap<Int, ExecutionInfo>()
|
||||
|
||||
fun connect(callback: () -> Unit): Boolean {
|
||||
if (bound) {
|
||||
callback()
|
||||
return true;
|
||||
}
|
||||
connectionCallbacks.add(callback)
|
||||
if (connecting) {
|
||||
return true;
|
||||
}
|
||||
connecting = true;
|
||||
|
||||
val intent = Intent("org.godotengine.action.BUILD_PROVIDER").apply {
|
||||
setPackage("org.godotengine.godot_gradle_build_environment")
|
||||
}
|
||||
val info = context.packageManager.resolveService(intent, 0)
|
||||
if (info == null) {
|
||||
connecting = false;
|
||||
Log.e(TAG, "Unable to resolve service")
|
||||
return false
|
||||
}
|
||||
|
||||
val result = context.bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
||||
if (!result) {
|
||||
Log.e(TAG, "Unable to bind to service")
|
||||
connecting = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fun disconnect() {
|
||||
if (bound) {
|
||||
context.unbindService(connection)
|
||||
bound = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNextExecutionId(outputCallback: (Int, String) -> Unit, resultCallback: (Int) -> Unit): Int {
|
||||
val id = executionId++
|
||||
executionMap[id] = ExecutionInfo(outputCallback, resultCallback)
|
||||
return id
|
||||
}
|
||||
|
||||
fun execute(arguments: Array<String>, projectPath: String, gradleBuildDir: String, outputCallback: (Int, String) -> Unit, resultCallback: (Int) -> Unit): Int {
|
||||
if (outgoingMessenger == null) {
|
||||
return -1
|
||||
}
|
||||
|
||||
val msg: Message = Message.obtain(null, MSG_EXECUTE_GRADLE, getNextExecutionId(outputCallback, resultCallback),0)
|
||||
msg.replyTo = incomingMessenger
|
||||
|
||||
val data = Bundle()
|
||||
data.putStringArrayList("arguments", ArrayList(arguments.toList()))
|
||||
data.putString("project_path", projectPath)
|
||||
data.putString("gradle_build_directory", gradleBuildDir)
|
||||
msg.data = data
|
||||
|
||||
try {
|
||||
outgoingMessenger?.send(msg)
|
||||
} catch (e: RemoteException) {
|
||||
Log.e(TAG, "Unable to execute Gradle command: gradlew ${arguments.joinToString(" ")}", e)
|
||||
e.printStackTrace()
|
||||
executionMap.remove(msg.arg1)
|
||||
resultCallback(255)
|
||||
return -1
|
||||
}
|
||||
|
||||
return msg.arg1
|
||||
}
|
||||
|
||||
private fun receiveCommandResult(msg: Message) {
|
||||
val executionInfo = executionMap.remove(msg.arg1)
|
||||
executionInfo?.resultCallback?.invoke(msg.arg2)
|
||||
}
|
||||
|
||||
private fun receiveCommandOutput(msg: Message) {
|
||||
val data = msg.data
|
||||
val line = data.getString("line")
|
||||
|
||||
if (line != null) {
|
||||
val executionInfo = executionMap.get(msg.arg1)
|
||||
executionInfo?.outputCallback?.invoke(msg.arg2, line)
|
||||
}
|
||||
}
|
||||
|
||||
fun cancel(jobId: Int) {
|
||||
if (outgoingMessenger == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val msg: Message = Message.obtain(null, MSG_CANCEL_COMMAND, jobId, 0)
|
||||
try {
|
||||
outgoingMessenger?.send(msg)
|
||||
} catch (e: RemoteException) {
|
||||
Log.e(TAG, "Unable to cancel Gradle command: ${jobId}", e)
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun cleanProject(projectPath: String, gradleBuildDir: String, resultCallback: (Int) -> Unit) {
|
||||
if (outgoingMessenger == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val emptyOutputCallback: (Int, String) -> Unit = { outputType, line -> }
|
||||
|
||||
val msg: Message = Message.obtain(null, MSG_CLEAN_PROJECT, getNextExecutionId(emptyOutputCallback, resultCallback), 0)
|
||||
msg.replyTo = incomingMessenger
|
||||
|
||||
val data = Bundle()
|
||||
data.putString("project_path", projectPath)
|
||||
data.putString("gradle_build_directory", gradleBuildDir)
|
||||
msg.data = data
|
||||
|
||||
try {
|
||||
outgoingMessenger?.send(msg)
|
||||
} catch (e: RemoteException) {
|
||||
Log.e(TAG, "Unable to clean Gradle project", e)
|
||||
executionMap.remove(msg.arg1)
|
||||
resultCallback(0)
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/**************************************************************************/
|
||||
/* GradleBuildProvider.kt */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
package org.godotengine.editor.buildprovider
|
||||
|
||||
import android.content.Context
|
||||
import org.godotengine.godot.BuildProvider
|
||||
import org.godotengine.godot.GodotHost
|
||||
import org.godotengine.godot.variant.Callable
|
||||
|
||||
internal class GradleBuildProvider(
|
||||
val context: Context,
|
||||
val host: GodotHost,
|
||||
) : BuildProvider {
|
||||
|
||||
val gradleBuildEnvironmentClient = GradleBuildEnvironmentClient(context)
|
||||
|
||||
val godot get() = host.godot
|
||||
|
||||
override fun buildEnvConnect(callback: Callable): Boolean {
|
||||
return gradleBuildEnvironmentClient.connect {
|
||||
godot?.runOnRenderThread {
|
||||
callback.call()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildEnvDisconnect() {
|
||||
gradleBuildEnvironmentClient.disconnect()
|
||||
}
|
||||
|
||||
override fun buildEnvExecute(
|
||||
buildTool: String,
|
||||
arguments: Array<String>,
|
||||
projectPath: String,
|
||||
buildDir: String,
|
||||
outputCallback: Callable,
|
||||
resultCallback: Callable
|
||||
): Int {
|
||||
if (buildTool != "gradle") {
|
||||
return -1;
|
||||
}
|
||||
val outputCb: (Int, String) -> Unit = { outputType, line ->
|
||||
godot?.runOnRenderThread {
|
||||
outputCallback.call(outputType, line)
|
||||
}
|
||||
}
|
||||
val resultCb: (Int) -> Unit = { exitCode ->
|
||||
godot?.runOnRenderThread {
|
||||
resultCallback.call(exitCode)
|
||||
}
|
||||
}
|
||||
return gradleBuildEnvironmentClient.execute(arguments, projectPath, buildDir, outputCb, resultCb)
|
||||
}
|
||||
|
||||
override fun buildEnvCancel(jobId: Int) {
|
||||
gradleBuildEnvironmentClient.cancel(jobId)
|
||||
}
|
||||
|
||||
override fun buildEnvCleanProject(projectPath: String, buildDir: String, callback: Callable) {
|
||||
val cb: (Int) -> Unit = { exitCode ->
|
||||
godot?.runOnRenderThread {
|
||||
callback.call()
|
||||
}
|
||||
}
|
||||
gradleBuildEnvironmentClient.cleanProject(projectPath, buildDir, cb)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**************************************************************************/
|
||||
/* BuildProvider.java */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
package org.godotengine.godot;
|
||||
|
||||
import org.godotengine.godot.variant.Callable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Provides an environment for executing build commands.
|
||||
*/
|
||||
public interface BuildProvider {
|
||||
/**
|
||||
* Connects to the build environment.
|
||||
*
|
||||
* @param callback The callback to call when connected
|
||||
* @return Whether or not connecting is possible
|
||||
*/
|
||||
boolean buildEnvConnect(@NonNull Callable callback);
|
||||
|
||||
/**
|
||||
* Disconnects from the build environment.
|
||||
*/
|
||||
void buildEnvDisconnect();
|
||||
|
||||
/**
|
||||
* Executes a command via the build environment.
|
||||
*
|
||||
* @param buildTool The build tool to execute (for example, "gradle")
|
||||
* @param arguments The argument for the command
|
||||
* @param projectPath The working directory to use when executing the command
|
||||
* @param buildDir The build directory within the project
|
||||
* @param outputCallback The callback to call for each line of output from the command
|
||||
* @param resultCallback The callback to call when the command is finished running
|
||||
* @return A positive job id, if successful; otherwise, a negative number
|
||||
*/
|
||||
int buildEnvExecute(String buildTool, @NonNull String[] arguments, @NonNull String projectPath, @NonNull String buildDir, @NonNull Callable outputCallback, @NonNull Callable resultCallback);
|
||||
|
||||
/**
|
||||
* Cancels a command executed via the build environment.
|
||||
*
|
||||
* @param jobId The job id returned from buildEnvExecute()
|
||||
*/
|
||||
void buildEnvCancel(int jobId);
|
||||
|
||||
/**
|
||||
* Requests that a project be cleaned up via the build environment.
|
||||
*
|
||||
* @param projectPath The working directory to use when executing the command
|
||||
* @param buildDir The build directory within the project
|
||||
*/
|
||||
void buildEnvCleanProject(@NonNull String projectPath, @NonNull String buildDir, @NonNull Callable callback);
|
||||
}
|
||||
@@ -75,6 +75,7 @@ import org.godotengine.godot.utils.benchmarkFile
|
||||
import org.godotengine.godot.utils.dumpBenchmark
|
||||
import org.godotengine.godot.utils.endBenchmarkMeasure
|
||||
import org.godotengine.godot.utils.useBenchmark
|
||||
import org.godotengine.godot.variant.Callable as GodotCallable
|
||||
import org.godotengine.godot.xr.XRMode
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
@@ -1304,4 +1305,64 @@ class Godot private constructor(val context: Context) {
|
||||
private fun nativeOnEditorWorkspaceSelected(workspace: String) {
|
||||
primaryHost?.onEditorWorkspaceSelected(workspace)
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvConnect(callback: GodotCallable): Boolean {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
return buildProvider?.buildEnvConnect(callback) ?: false
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to connect to build environment", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvDisconnect() {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvDisconnect()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to disconnect from build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvExecute(buildTool: String, arguments: Array<String>, projectPath: String, buildDir: String, outputCallback: GodotCallable, resultCallback: GodotCallable): Int {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
return buildProvider?.buildEnvExecute(
|
||||
buildTool,
|
||||
arguments,
|
||||
projectPath,
|
||||
buildDir,
|
||||
outputCallback,
|
||||
resultCallback
|
||||
) ?: -1
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to execute Gradle command in build environment", e);
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvCancel(jobId: Int) {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvCancel(jobId)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to cancel command in build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private fun nativeBuildEnvCleanProject(projectPath: String, buildDir: String, callback: GodotCallable) {
|
||||
try {
|
||||
val buildProvider = primaryHost?.getBuildProvider()
|
||||
buildProvider?.buildEnvCleanProject(projectPath, buildDir, callback)
|
||||
} catch(e: Exception) {
|
||||
Log.e(TAG, "Unable to clean project in build environment", e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Messenger;
|
||||
import android.text.TextUtils;
|
||||
@@ -496,4 +495,12 @@ public class GodotFragment extends Fragment implements IDownloaderClient, GodotH
|
||||
parentHost.onEditorWorkspaceSelected(workspace);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuildProvider getBuildProvider() {
|
||||
if (parentHost != null) {
|
||||
return parentHost.getBuildProvider();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,4 +166,13 @@ public interface GodotHost {
|
||||
activity.runOnUiThread(action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the build provider, if available.
|
||||
*
|
||||
* @return the build provider, if available; otherwise, null.
|
||||
*/
|
||||
default @Nullable BuildProvider getBuildProvider() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class Callable private constructor(private val nativeCallablePointer: Long) {
|
||||
/**
|
||||
* Calls the method represented by this [Callable]. Arguments can be passed and should match the method's signature.
|
||||
*/
|
||||
internal fun call(vararg params: Any): Any? {
|
||||
fun call(vararg params: Any): Any? {
|
||||
if (nativeCallablePointer == 0L) {
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user