You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Add signal support to Godot Android plugin:
Supports registering and emitting signal from a Godot Android plugin
This commit is contained in:
@@ -34,6 +34,8 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -41,8 +43,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import org.godotengine.godot.BuildConfig;
|
||||
import org.godotengine.godot.Godot;
|
||||
|
||||
/**
|
||||
@@ -70,7 +74,10 @@ import org.godotengine.godot.Godot;
|
||||
*/
|
||||
public abstract class GodotPlugin {
|
||||
|
||||
private static final String TAG = GodotPlugin.class.getSimpleName();
|
||||
|
||||
private final Godot godot;
|
||||
private final ConcurrentHashMap<String, SignalInfo> registeredSignals = new ConcurrentHashMap<>();
|
||||
|
||||
public GodotPlugin(Godot godot) {
|
||||
this.godot = godot;
|
||||
@@ -118,6 +125,13 @@ public abstract class GodotPlugin {
|
||||
nativeRegisterMethod(getPluginName(), method.getName(), method.getReturnType().getName(), pt);
|
||||
}
|
||||
|
||||
// Register the signals for this plugin.
|
||||
for (SignalInfo signalInfo : getPluginSignals()) {
|
||||
String signalName = signalInfo.getName();
|
||||
nativeRegisterSignal(getPluginName(), signalName, signalInfo.getParamTypesNames());
|
||||
registeredSignals.put(signalName, signalInfo);
|
||||
}
|
||||
|
||||
// Get the list of gdnative libraries to register.
|
||||
Set<String> gdnativeLibrariesPaths = getPluginGDNativeLibrariesPaths();
|
||||
if (!gdnativeLibrariesPaths.isEmpty()) {
|
||||
@@ -220,7 +234,17 @@ public abstract class GodotPlugin {
|
||||
* Returns the list of methods to be exposed to Godot.
|
||||
*/
|
||||
@NonNull
|
||||
public abstract List<String> getPluginMethods();
|
||||
public List<String> getPluginMethods() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of signals to be exposed to Godot.
|
||||
*/
|
||||
@NonNull
|
||||
public Set<SignalInfo> getPluginSignals() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the paths for the plugin's gdnative libraries.
|
||||
@@ -252,6 +276,49 @@ public abstract class GodotPlugin {
|
||||
godot.runOnRenderThread(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a registered Godot signal.
|
||||
* @param signalName
|
||||
* @param signalArgs
|
||||
*/
|
||||
protected void emitSignal(final String signalName, final Object... signalArgs) {
|
||||
try {
|
||||
// Check that the given signal is among the registered set.
|
||||
SignalInfo signalInfo = registeredSignals.get(signalName);
|
||||
if (signalInfo == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Signal " + signalName + " is not registered for this plugin.");
|
||||
}
|
||||
|
||||
// Validate the arguments count.
|
||||
Class<?>[] signalParamTypes = signalInfo.getParamTypes();
|
||||
if (signalArgs.length != signalParamTypes.length) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid arguments count. Should be " + signalParamTypes.length + " but is " + signalArgs.length);
|
||||
}
|
||||
|
||||
// Validate the argument's types.
|
||||
for (int i = 0; i < signalParamTypes.length; i++) {
|
||||
if (!signalParamTypes[i].isInstance(signalArgs[i])) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid type for argument #" + i + ". Should be of type " + signalParamTypes[i].getName());
|
||||
}
|
||||
}
|
||||
|
||||
runOnRenderThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeEmitSignal(getPluginName(), signalName, signalArgs);
|
||||
}
|
||||
});
|
||||
} catch (IllegalArgumentException exception) {
|
||||
Log.w(TAG, exception.getMessage());
|
||||
if (BuildConfig.DEBUG) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to setup a {@link GodotPlugin} instance.
|
||||
* @param p_name Name of the instance.
|
||||
@@ -272,4 +339,20 @@ public abstract class GodotPlugin {
|
||||
* @param gdnlibPaths Paths to the libraries relative to the 'assets' directory.
|
||||
*/
|
||||
private native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths);
|
||||
|
||||
/**
|
||||
* Used to complete registration of the {@link GodotPlugin} instance's methods.
|
||||
* @param pluginName Name of the plugin
|
||||
* @param signalName Name of the signal to register
|
||||
* @param signalParamTypes Signal parameters types
|
||||
*/
|
||||
private native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes);
|
||||
|
||||
/**
|
||||
* Used to emit signal by {@link GodotPlugin} instance.
|
||||
* @param pluginName Name of the plugin
|
||||
* @param signalName Name of the signal to emit
|
||||
* @param signalParams Signal parameters
|
||||
*/
|
||||
private native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*************************************************************************/
|
||||
/* SignalInfo.java */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* 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.plugin;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Store information about a {@link GodotPlugin}'s signal.
|
||||
*/
|
||||
public final class SignalInfo {
|
||||
|
||||
private final String name;
|
||||
private final Class<?>[] paramTypes;
|
||||
private final String[] paramTypesNames;
|
||||
|
||||
public SignalInfo(@NonNull String signalName, Class<?>... paramTypes) {
|
||||
if (TextUtils.isEmpty(signalName)) {
|
||||
throw new IllegalArgumentException("Invalid signal name: " + signalName);
|
||||
}
|
||||
|
||||
this.name = signalName;
|
||||
this.paramTypes = paramTypes == null ? new Class<?>[ 0 ] : paramTypes;
|
||||
this.paramTypesNames = new String[this.paramTypes.length];
|
||||
for (int i = 0; i < this.paramTypes.length; i++) {
|
||||
this.paramTypesNames[i] = this.paramTypes[i].getName();
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
Class<?>[] getParamTypes() {
|
||||
return paramTypes;
|
||||
}
|
||||
|
||||
String[] getParamTypesNames() {
|
||||
return paramTypesNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SignalInfo{"
|
||||
+
|
||||
"name='" + name + '\'' +
|
||||
", paramsTypes=" + Arrays.toString(paramTypes) +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SignalInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SignalInfo that = (SignalInfo)o;
|
||||
|
||||
return name.equals(that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user