Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax restriction on loading v1 Android plugins on Godot 4.2+ #81368

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@
* <p>
* A Godot Android plugin is an Android library with the following requirements:
* <p>
* - The library must have a 'compileOnly' dependency on the Godot Android library: `compileOnly "org.godotengine:godot:<godotLibVersion>"`
* - The plugin must have a dependency on the Godot Android library: `implementation "org.godotengine:godot:<godotLibVersion>"`
* <p>
* - The library must include a <meta-data> tag in its Android manifest with the following format:
* - The plugin must include a <meta-data> tag in its Android manifest with the following format:
* <meta-data android:name="org.godotengine.plugin.v2.[PluginName]" android:value="[plugin.init.ClassFullName]" />
* <p>
* Where:
* <p>
* - 'PluginName' is the name of the plugin.
* <p>
* - 'plugin.init.ClassFullName' is the full name (package + class name) of the plugin init class
* extending {@link GodotPlugin}.
* <p>
Expand All @@ -83,6 +86,10 @@ public abstract class GodotPlugin {
private final Godot godot;
private final ConcurrentHashMap<String, SignalInfo> registeredSignals = new ConcurrentHashMap<>();

/**
* Base constructor passing a {@link Godot} instance through which the plugin can access Godot's
* APIs and lifecycle events.
*/
public GodotPlugin(Godot godot) {
this.godot = godot;
}
Expand All @@ -109,11 +116,11 @@ protected Activity getActivity() {
*/
public final void onRegisterPluginWithGodotNative() {
registeredSignals.putAll(
registerPluginWithGodotNative(this, getPluginName(), getPluginSignals()));
registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals()));
}

private static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject,
String pluginName, Set<SignalInfo> pluginSignals) {
String pluginName, List<String> pluginMethods, Set<SignalInfo> pluginSignals) {
nativeRegisterSingleton(pluginName, pluginObject);

Set<Method> filteredMethods = new HashSet<>();
Expand All @@ -124,6 +131,14 @@ private static Map<String, SignalInfo> registerPluginWithGodotNative(Object plug
// Check if the method is annotated with {@link UsedByGodot}.
if (method.getAnnotation(UsedByGodot.class) != null) {
filteredMethods.add(method);
} else {
// For backward compatibility, process the methods from the given <pluginMethods> argument.
for (String methodName : pluginMethods) {
if (methodName.equals(method.getName())) {
filteredMethods.add(method);
break;
}
}
}
}

Expand Down Expand Up @@ -260,6 +275,17 @@ public void onVkSurfaceCreated(Surface surface) {}
@NonNull
public abstract String getPluginName();

/**
* Returns the list of methods to be exposed to Godot.
*
* @deprecated Use the {@link UsedByGodot} annotation instead.
*/
@NonNull
@Deprecated
public List<String> getPluginMethods() {
return Collections.emptyList();
}

/**
* Returns the list of signals to be exposed to Godot.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ public final class GodotPluginRegistry {
private static final String TAG = GodotPluginRegistry.class.getSimpleName();

/**
* Prefix used for version 1 of the Godot plugin, compatible with Godot 3.x
* Prefix used for version 1 of the Godot plugin, mostly compatible with Godot 3.x
*/
private static final String GODOT_PLUGIN_V1_NAME_PREFIX = "org.godotengine.plugin.v1.";
/**
* Prefix used for version 2 of the Godot plugin, compatible with Godot 4.x
* Prefix used for version 2 of the Godot plugin, compatible with Godot 4.2+
*/
private static final String GODOT_PLUGIN_V2_NAME_PREFIX = "org.godotengine.plugin.v2.";

Expand Down Expand Up @@ -130,12 +130,18 @@ private void loadPlugins(Godot godot) {
return;
}

int godotPluginV2NamePrefixLength = GODOT_PLUGIN_V2_NAME_PREFIX.length();
for (String metaDataName : metaData.keySet()) {
// Parse the meta-data looking for entry with the Godot plugin name prefix.
String pluginName = null;
if (metaDataName.startsWith(GODOT_PLUGIN_V2_NAME_PREFIX)) {
String pluginName = metaDataName.substring(godotPluginV2NamePrefixLength).trim();
Log.i(TAG, "Initializing Godot v2 plugin " + pluginName);
pluginName = metaDataName.substring(GODOT_PLUGIN_V2_NAME_PREFIX.length()).trim();
} else if (metaDataName.startsWith(GODOT_PLUGIN_V1_NAME_PREFIX)) {
pluginName = metaDataName.substring(GODOT_PLUGIN_V1_NAME_PREFIX.length()).trim();
Log.w(TAG, "Godot v1 plugin are deprecated in Godot 4.2 and higher: " + pluginName);
}

if (!TextUtils.isEmpty(pluginName)) {
Log.i(TAG, "Initializing Godot plugin " + pluginName);

// Retrieve the plugin class full name.
String pluginHandleClassFullName = metaData.getString(metaDataName);
Expand All @@ -155,22 +161,17 @@ private void loadPlugins(Godot godot) {
"Meta-data plugin name does not match the value returned by the plugin handle: " + pluginName + " =/= " + pluginHandle.getPluginName());
}
registry.put(pluginName, pluginHandle);
Log.i(TAG, "Completed initialization for Godot v2 plugin " + pluginHandle.getPluginName());
} catch (ClassNotFoundException | IllegalAccessException |
InstantiationException | NoSuchMethodException |
InvocationTargetException e) {
Log.w(TAG, "Unable to load Godot v2 plugin " + pluginName, e);
Log.i(TAG, "Completed initialization for Godot plugin " + pluginHandle.getPluginName());
} catch (Exception e) {
Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
}
} else {
Log.w(TAG, "Invalid plugin loader class for " + pluginName);
}
} else if (metaDataName.startsWith(GODOT_PLUGIN_V1_NAME_PREFIX)) {
String v1PluginName = metaDataName.substring(GODOT_PLUGIN_V1_NAME_PREFIX.length()).trim();
Log.w(TAG, "Godot 4 does not support Godot 3 (v1) plugin: " + v1PluginName);
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable load Godot Android v2 plugins from the manifest file.", e);
} catch (Exception e) {
Log.e(TAG, "Unable load Godot Android plugins from the manifest file.", e);
}
}
}