summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-07-01 18:57:37 +0200
committerSven Gothel <[email protected]>2023-07-01 18:57:37 +0200
commit8766fcfdce4dd864fe6764b063a0f9a4b17327c1 (patch)
tree4fb5a2441b0a3fb9f3d12c6456f316b42b579cac /src/java/com/jogamp
parent6200b9122a90ef8c2af8b9205b4b1c90b1aa5074 (diff)
GlueGen JavaCallback: Only produce default 'Key' class if keys are used, expose 'Key' to public and use it. Expose release*() and get*Keys() methods
Further we use a dedicated lock Object used in the Java implementation. TODO: Native static callback dispatch code shall - (also) acquire the lock - handle case where the data has been released already to render this solution thread-safe and data-race free
Diffstat (limited to 'src/java/com/jogamp')
-rw-r--r--src/java/com/jogamp/gluegen/CMethodBindingEmitter.java2
-rw-r--r--src/java/com/jogamp/gluegen/JavaConfiguration.java2
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java5
-rw-r--r--src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java281
4 files changed, 222 insertions, 68 deletions
diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
index 43d11b7..9be4a36 100644
--- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
@@ -569,7 +569,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
final String capIfaceName = CodeGenUtils.capitalizeString( getInterfaceName() );
unit.emitln("JNIEXPORT void JNICALL");
unit.emit(JavaEmitter.getJNIMethodNamePrefix(getJavaPackageName(), getJavaClassName()));
- unit.emitln("_release"+capIfaceName+"MapImpl(JNIEnv *env, jobject _unused, jlong jnativeUserParam) {");
+ unit.emitln("_release"+capIfaceName+"Impl(JNIEnv *env, jobject _unused, jlong jnativeUserParam) {");
unit.emitln(" T_"+jcbNativeBasename+"* nativeUserParam = (T_"+jcbNativeBasename+"*) (intptr_t) jnativeUserParam;");
unit.emitln(" if( NULL != nativeUserParam ) {");
unit.emitln(" (*env)->DeleteGlobalRef(env, nativeUserParam->cbFunc);");
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java
index 1fe2747..3e2e680 100644
--- a/src/java/com/jogamp/gluegen/JavaConfiguration.java
+++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java
@@ -2293,6 +2293,7 @@ public class JavaConfiguration {
boolean setFuncProcessed;
int setFuncCBParamIdx;
int setFuncUserParamIdx;
+ boolean keyClassEmitted;
public JavaCallbackInfo(final String cbFuncTypeName, final String cbSimpleClazzName, final String cbFQClazzName, final String cbMethodSignature,
final FunctionType cbFuncType, final MethodBinding cbFuncBinding, final int cbFuncUserParamIdx,
@@ -2326,6 +2327,7 @@ public class JavaConfiguration {
this.setFuncProcessed = false;
this.setFuncCBParamIdx = -1;
this.setFuncUserParamIdx = -1;
+ this.keyClassEmitted = false;
}
public void setFuncProcessed(final int cbParamIdx, final int userParamIdx) {
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 7674e1f..c00d2ed 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -74,6 +74,7 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.MachineDataInfo;
import com.jogamp.common.util.ArrayHashMap;
+import com.jogamp.common.util.HashUtil;
import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
import com.jogamp.gluegen.JavaConfiguration.JavaCallbackDef;
import com.jogamp.gluegen.JavaConfiguration.JavaCallbackInfo;
@@ -2930,6 +2931,10 @@ public class JavaEmitter implements GlueEmitter {
imports.add(DynamicLookupHelper.class.getPackage().getName()+".*");
imports.add(Buffers.class.getPackage().getName()+".*");
imports.add(Buffer.class.getPackage().getName()+".*");
+ imports.add(HashUtil.class.getPackage().getName()+".*");
+ imports.add("java.util.Set");
+ imports.add("java.util.Map");
+ imports.add("java.util.HashMap");
imports.add("java.nio.charset.Charset");
imports.add("java.nio.charset.StandardCharsets");
diff --git a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
index 977596f..985056d 100644
--- a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
@@ -50,8 +50,6 @@ import com.jogamp.gluegen.cgram.types.Type;
import java.io.PrintWriter;
import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -459,17 +457,31 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
private static final boolean DEBUG_JAVACALLBACK = false;
- private final void emitJavaCallbackKeyClass(final String KeyClassName) {
- unit.emitln(" private static class "+KeyClassName+" {");
+ private final void emitJavaCallbackBirefAPIDoc(final String actionText, final String relationToKey, final String noKeyText, final String relationToFunc) {
+ unit.emit(" /** "+actionText);
+ if( javaCallback.setFuncKeyIndices.size() > 0 ) {
+ unit.emit(relationToKey);
+ unit.emit("Key { "+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+" } ");
+ } else {
+ unit.emit(noKeyText);
+ }
+ unit.emit(relationToFunc);
+ unit.emit("<br> <code>");
+ emitSignature();
+ unit.emitln("</code> **/");
+ }
+ private final void emitJavaCallbackKeyClass(final String capIfaceName, final String keyClassName) {
+ emitJavaCallbackBirefAPIDoc("", "", "", "for ");
+ unit.emitln(" public static class "+keyClassName+" {");
binding.forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
if( !cType.isVoid() && javaCallback.setFuncKeyIndices.contains(idx) ) {
- unit.emitln(" private final "+jType+" "+name+";");
+ unit.emitln(" public final "+jType+" "+name+";");
return true;
} else {
return false;
}
} );
- unit.emitln(" "+KeyClassName+"("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {");
+ unit.emitln(" public "+keyClassName+"("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {");
binding.forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
if( !cType.isVoid() && javaCallback.setFuncKeyIndices.contains(idx) ) {
unit.emitln(" this."+name+" = "+name+";");
@@ -484,14 +496,14 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
unit.emitln(" if( this == o ) {");
unit.emitln(" return true;");
unit.emitln(" }");
- unit.emitln(" if( !(o instanceof "+KeyClassName+") ) {");
+ unit.emitln(" if( !(o instanceof "+keyClassName+") ) {");
unit.emitln(" return false;");
unit.emitln(" }");
{
final int count = binding.forEachParameter( ( final int idx, final int consumedCount, final Type cType, final JavaType jType, final String name ) -> {
if( !cType.isVoid() && javaCallback.setFuncKeyIndices.contains(idx) ) {
if( 0 == consumedCount ) {
- unit.emitln(" final "+KeyClassName+" o2 = ("+KeyClassName+")o;");
+ unit.emitln(" final "+keyClassName+" o2 = ("+keyClassName+")o;");
unit.emit (" return ");
} else {
unit.emitln(" &&");
@@ -526,7 +538,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
}
if( jType.isPrimitive() ) {
if( jType.isLong() ) {
- unit.emitln("Long.valueOf( "+name+" ).hashCode();");
+ unit.emitln("HashUtil.getAddrHash32_EqualDist( "+name+" );");
} else {
unit.emitln(name+";");
}
@@ -550,14 +562,13 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
}
unit.emitln(" }");
unit.emitln(" }");
- unit.emitln();
}
- private final void emitJavaCallbackUsrParamClass(final String UsrParamClassName) {
- unit.emitln(" private static class "+UsrParamClassName+" {");
+ private final void emitJavaCallbackDataClass(final String capIfaceName, final String dataClassName) {
+ unit.emitln(" private static class "+dataClassName+" {");
unit.emitln(" final "+javaCallback.cbFuncTypeName+" func;");
unit.emitln(" final Object param;");
unit.emitln(" final long nativeParam;");
- unit.emitln(" "+UsrParamClassName+"("+javaCallback.cbFuncTypeName+" func, Object param, long nativeParam) {");
+ unit.emitln(" "+dataClassName+"("+javaCallback.cbFuncTypeName+" func, Object param, long nativeParam) {");
unit.emitln(" this.func = func;");
unit.emitln(" this.param = param;");
unit.emitln(" this.nativeParam = nativeParam;");
@@ -586,68 +597,193 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
if( null != javaCallback && !isPrivateNativeMethod ) {
final String capIfaceName = CodeGenUtils.capitalizeString( getInterfaceName() );
final String lowIfaceName = CodeGenUtils.decapitalizeString( getInterfaceName() );
+ final String lockInstanceName = lowIfaceName+"Lock";
+ final String dataMapInstanceName = lowIfaceName+"DataMap";
+ final String dataInstanceName = lowIfaceName+"Data";
+ final boolean useDataMap = javaCallback.setFuncKeyIndices.size() > 0;
+ final boolean customKeyClass;
+ final String KeyClassName;
+ if( null != javaCallback.setFuncKeyClassName ) {
+ customKeyClass = true;;
+ KeyClassName = javaCallback.setFuncKeyClassName;
+ } else {
+ customKeyClass = false;
+ KeyClassName = CodeGenUtils.capitalizeString(capIfaceName+"Key");
+ }
+ final String DataClassName = CodeGenUtils.capitalizeString( javaCallback.cbFuncTypeName+"Data" );
+ final String fqUsrParamClassName = cfg.packageName()+"."+cfg.className()+"."+DataClassName;
unit.emitln();
if( isInterface() ) {
- unit.emitln(" public boolean is"+capIfaceName+"Mapped("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" public "+javaCallback.cbFuncTypeName+" get"+capIfaceName+"("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" public Object get"+capIfaceName+"UserParam("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
+ if( useDataMap ) {
+ if( !customKeyClass && !javaCallback.keyClassEmitted ) {
+ emitJavaCallbackKeyClass(capIfaceName, KeyClassName);
+ unit.emitln();
+ javaCallback.keyClassEmitted = true;
+ }
+ emitJavaCallbackBirefAPIDoc("Returns ", "set of ", "", "for ");
+ unit.emitln(" public Set<"+KeyClassName+"> get"+capIfaceName+"Keys();");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Returns ", "whether callback ", "if callback ", "is mapped for ");
+ unit.emitln(" public boolean is"+capIfaceName+"Mapped("+KeyClassName+" key);");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Returns "+javaCallback.cbFuncTypeName+" callback ", "mapped to ", "", "for ");
+ unit.emitln(" public "+javaCallback.cbFuncTypeName+" get"+capIfaceName+"("+KeyClassName+" key);");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public Object get"+capIfaceName+"UserParam("+KeyClassName+" key);");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Releases all callback data ", "mapped via ", "", "skipping toolkit API. Favor passing `null` callback ref to ");
+ unit.emitln(" public int releaseAll"+capIfaceName+"();");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Releases callback data ", "mapped to ", "", "skipping toolkit API. Favor passing `null` callback ref to ");
+ unit.emitln(" public void release"+capIfaceName+"("+KeyClassName+" key);");
+ unit.emitln();
+ } else {
+ emitJavaCallbackBirefAPIDoc("Returns ", "whether callback ", "if callback ", "is mapped for ");
+ unit.emitln(" public boolean is"+capIfaceName+"Mapped();");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Returns "+javaCallback.cbFuncTypeName+" callback ", "mapped to ", "", "for ");
+ unit.emitln(" public "+javaCallback.cbFuncTypeName+" get"+capIfaceName+"();");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public Object get"+capIfaceName+"UserParam();");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Releases callback data ", "", "", "skipping toolkit API. Favor passing `null` callback ref to ");
+ unit.emitln(" public void release"+capIfaceName+"();");
+ unit.emitln();
+ }
} else {
- final String usrMapInstanceName = lowIfaceName+"UsrMap";
- final boolean customKeyClass;
- final String KeyClassName;
- if( null != javaCallback.setFuncKeyClassName ) {
- customKeyClass = true;;
- KeyClassName = javaCallback.setFuncKeyClassName;
+ if( useDataMap ) {
+ if( !customKeyClass && !javaCallback.keyClassEmitted ) {
+ emitJavaCallbackKeyClass(capIfaceName, KeyClassName);
+ unit.emitln();
+ javaCallback.keyClassEmitted = true;
+ }
+ emitJavaCallbackBirefAPIDoc("Returns ", "set of ", "", "for ");
+ unit.emitln(" public final Set<"+KeyClassName+"> get"+capIfaceName+"Keys() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" return "+dataMapInstanceName+".keySet();");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Returns ", "whether callback ", "if callback ", "is mapped for ");
+ unit.emitln(" public final boolean is"+capIfaceName+"Mapped("+KeyClassName+" key) {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" return null != "+dataMapInstanceName+".get(key);");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+
+ emitJavaCallbackBirefAPIDoc("Returns "+javaCallback.cbFuncTypeName+" callback ", "mapped to ", "", "for ");
+ unit.emitln(" public final "+javaCallback.cbFuncTypeName+" get"+capIfaceName+"("+KeyClassName+" key) {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataMapInstanceName+".get(key);");
+ unit.emitln(" return null != value ? value.func : null;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+
+ emitJavaCallbackBirefAPIDoc("Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public final Object get"+capIfaceName+"UserParam("+KeyClassName+" key) {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataMapInstanceName+".get(key);");
+ unit.emitln(" return null != value ? value.param : null;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Releases all callback data ", "mapped via ", "", "skipping toolkit API. Favor passing `null` callback ref to ");
+ unit.emitln(" public final int releaseAll"+capIfaceName+"() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final Set<"+KeyClassName+"> keySet = "+dataMapInstanceName+".keySet();");
+ unit.emitln(" final "+KeyClassName+"[] keys = keySet.toArray(new "+KeyClassName+"[keySet.size()]);");
+ unit.emitln(" for(int i=0; i<keys.length; ++i) {");
+ unit.emitln(" final "+KeyClassName+" key = keys[i];");
+ unit.emitln(" release"+capIfaceName+"(key);");
+ unit.emitln(" }");
+ unit.emitln(" return keys.length;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+ emitJavaCallbackBirefAPIDoc("Releases callback data ", "mapped to ", "", "skipping toolkit API. Favor passing `null` callback ref to ");
+ unit.emitln(" public final void release"+capIfaceName+"("+KeyClassName+" key) {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataMapInstanceName+".remove(key);");
+ if( DEBUG_JAVACALLBACK ) {
+ unit.emitln(" System.err.println(\"ZZZ Release \"+key+\" -> value.nativeParam 0x\"+Long.toHexString(null!=value?value.nativeParam:0));");
+ }
+ unit.emitln(" if( null != value ) {");
+ unit.emitln(" release"+capIfaceName+"Impl(value.nativeParam);");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln(" }");
} else {
- customKeyClass = false;
- KeyClassName = CodeGenUtils.capitalizeString(capIfaceName+"Key");
+ emitJavaCallbackBirefAPIDoc("Returns ", "whether callback ", "if callback ", "is mapped for ");
+ unit.emitln(" public final boolean is"+capIfaceName+"Mapped() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" return null != "+dataInstanceName+";");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+
+ emitJavaCallbackBirefAPIDoc("Returns "+javaCallback.cbFuncTypeName+" callback ", "mapped to ", "", "for ");
+ unit.emitln(" public final "+javaCallback.cbFuncTypeName+" get"+capIfaceName+"() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataInstanceName+";");
+ unit.emitln(" return null != value ? value.func : null;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+
+ emitJavaCallbackBirefAPIDoc("Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public final Object get"+capIfaceName+"UserParam() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataInstanceName+";");
+ unit.emitln(" return null != value ? value.param : null;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+
+ emitJavaCallbackBirefAPIDoc("Releases callback data ", "", "", "skipping toolkit API. Favor passing `null` callback ref to ");
+ unit.emitln(" public final void release"+capIfaceName+"() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataInstanceName+";");
+ unit.emitln(" "+dataInstanceName+" = null;");
+ if( DEBUG_JAVACALLBACK ) {
+ unit.emitln(" System.err.println(\"ZZZ Release \"+key+\" -> value.nativeParam 0x\"+Long.toHexString(null!=value?value.nativeParam:0));");
+ }
+ unit.emitln(" if( null != value ) {");
+ unit.emitln(" release"+capIfaceName+"Impl(value.nativeParam);");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ }
+ unit.emitln(" private native void release"+capIfaceName+"Impl(long nativeUserParam);");
+ unit.emitln();
+ unit.emitln(" private final void add"+capIfaceName+"("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, true).toString()+DataClassName+" value) {");
+ if( useDataMap ) {
+ unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
+ unit.emitln(" final "+DataClassName+" old = "+dataMapInstanceName+".put(key, value);");
+ } else {
+ unit.emitln(" final "+DataClassName+" old = "+dataInstanceName+";");
+ unit.emitln(" "+dataInstanceName+" = value;");
}
- final String UsrParamClassName = CodeGenUtils.capitalizeString( javaCallback.cbFuncTypeName+"UserParam" );
- final String fqUsrParamClassName = cfg.packageName()+"."+cfg.className()+"."+UsrParamClassName;
- unit.emitln(" public final boolean is"+capIfaceName+"Mapped("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {");
- unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" return null != "+usrMapInstanceName+".get(key);");
- unit.emitln(" }");
- unit.emitln(" public final "+javaCallback.cbFuncTypeName+" get"+capIfaceName+"("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {");
- unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" final "+UsrParamClassName+" value = "+usrMapInstanceName+".get(key);");
- unit.emitln(" return null != value ? value.func : null;");
- unit.emitln(" }");
- unit.emitln(" public final Object get"+capIfaceName+"UserParam("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {");
- unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" final "+UsrParamClassName+" value = "+usrMapInstanceName+".get(key);");
- unit.emitln(" return null != value ? value.param : null;");
- unit.emitln(" }");
- unit.emitln(" private final void add"+capIfaceName+"Map("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, true).toString()+UsrParamClassName+" value) {");
- unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" final "+UsrParamClassName+" old = "+usrMapInstanceName+".put(key, value);");
if( DEBUG_JAVACALLBACK ) {
unit.emitln(" System.err.println(\"ZZZ Map \"+key+\" -> value.nativeParam 0x\"+Long.toHexString(null!=value?value.nativeParam:0));");
}
unit.emitln(" if( null != old ) {");
- unit.emitln(" release"+capIfaceName+"MapImpl(old.nativeParam);");
+ unit.emitln(" release"+capIfaceName+"Impl(old.nativeParam);");
unit.emitln(" }");
unit.emitln(" }");
- unit.emitln(" private final void release"+capIfaceName+"Map("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {");
- unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
- unit.emitln(" final "+UsrParamClassName+" value = "+usrMapInstanceName+".remove(key);");
- if( DEBUG_JAVACALLBACK ) {
- unit.emitln(" System.err.println(\"ZZZ Release \"+key+\" -> value.nativeParam 0x\"+Long.toHexString(null!=value?value.nativeParam:0));");
- }
- unit.emitln(" if( null != value ) {");
- unit.emitln(" release"+capIfaceName+"MapImpl(value.nativeParam);");
- unit.emitln(" }");
- unit.emitln(" }");
- unit.emitln(" private native void release"+capIfaceName+"MapImpl(long nativeUserParam);");
- unit.emitln();
- if( !customKeyClass ) {
- emitJavaCallbackKeyClass(KeyClassName);
- }
if( !cfg.emittedJavaCallbackUserParamClasses.contains(fqUsrParamClassName) ) {
- emitJavaCallbackUsrParamClass(UsrParamClassName);
+ emitJavaCallbackDataClass(capIfaceName, DataClassName);
cfg.emittedJavaCallbackUserParamClasses.add(fqUsrParamClassName);
}
- unit.emitln(" private final java.util.Map<"+KeyClassName+", "+UsrParamClassName+"> "+usrMapInstanceName+" = new java.util.HashMap<"+KeyClassName+", "+UsrParamClassName+">();");
+ if( useDataMap ) {
+ unit.emitln(" private final Map<"+KeyClassName+", "+DataClassName+"> "+dataMapInstanceName+" = new HashMap<"+KeyClassName+", "+DataClassName+">();");
+ } else {
+ unit.emitln(" private "+DataClassName+" "+dataInstanceName+" = null;");
+ }
+ unit.emitln(" private final Object "+lockInstanceName+" = new Object();");
unit.emitln();
}
}
@@ -768,8 +904,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
if( null != javaCallback ) {
final String lowIfaceName = CodeGenUtils.decapitalizeString( getInterfaceName() );
- final String usrMapInstanceName = lowIfaceName+"UsrMap";
- unit.emitln(" synchronized( "+usrMapInstanceName+" ) {");
+ final String lockInstanceName = lowIfaceName+"Lock";
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
unit.emitln(" final long[] nativeUserParam = { 0 };");
unit.emitln();
}
@@ -806,18 +942,29 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
if( null != javaCallback ) {
final String funcArgName = binding.getArgumentName(javaCallback.setFuncCBParamIdx);
final String userParamArgName = binding.getArgumentName(javaCallback.setFuncUserParamIdx);
- final String UsrParamClassName = CodeGenUtils.capitalizeString( javaCallback.cbFuncTypeName+"UserParam" );
+ final String DataClassName = CodeGenUtils.capitalizeString( javaCallback.cbFuncTypeName+"Data" );
+ final boolean useDataMap = javaCallback.setFuncKeyIndices.size() > 0;
+ final String KeyClassName;
+ if( null != javaCallback.setFuncKeyClassName ) {
+ KeyClassName = javaCallback.setFuncKeyClassName;
+ } else {
+ KeyClassName = CodeGenUtils.capitalizeString(capIfaceName+"Key");
+ }
if( DEBUG_JAVACALLBACK ) {
unit.emitln(" System.err.println(\"ZZZ returned nativeUserParam 0x\"+Long.toHexString(nativeUserParam[0]));");
}
unit.emitln();
unit.emitln(" if( 0 != nativeUserParam[0] ) {");
unit.emitln(" // callback registrated -> add will release a previously mapped instance ");
- unit.emitln(" add"+capIfaceName+"Map("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, true).toString()+
- "new "+UsrParamClassName+"("+funcArgName+", "+userParamArgName+", nativeUserParam[0]));");
+ unit.emitln(" add"+capIfaceName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, true).toString()+
+ "new "+DataClassName+"("+funcArgName+", "+userParamArgName+", nativeUserParam[0]));");
unit.emitln(" } else {");
unit.emitln(" // callback released (null func) -> release a previously mapped instance ");
- unit.emitln(" release"+capIfaceName+"Map("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");");
+ if( useDataMap ) {
+ unit.emitln(" release"+capIfaceName+"( new "+KeyClassName+"( "+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+" ) );");
+ } else {
+ unit.emitln(" release"+capIfaceName+"();");
+ }
unit.emitln(" }");
unit.emitln(" } // synchronized ");
}