summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--doc/GlueGen_Mapping.html154
-rw-r--r--doc/GlueGen_Mapping.md124
-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
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java418
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg19
8 files changed, 734 insertions, 271 deletions
diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html
index e173c01..9520f34 100644
--- a/doc/GlueGen_Mapping.html
+++ b/doc/GlueGen_Mapping.html
@@ -1994,6 +1994,10 @@ Definition</h4>
<p>If no keys are defined via <code>JavaCallbackKey</code>, or manually
injected using a custom <code>SetCallback-KeyClass</code>, see below,
the <code>CallbackFunction</code> has global scope.</p>
+<p>In case keys are defined via <code>JavaCallbackKey</code> and no
+manually injected custom <code>SetCallback-KeyClass</code> used, a
+public <code>SetCallback-KeyClass</code> is being generated covering the
+defined keys.</p>
<p>Keys allow to limit the scope, i.e. map multiple
<code>CallbackFunction</code> to the different keys.</p>
<p>Key arguments must match in <code>SetCallbackFunction</code> to
@@ -2008,18 +2012,62 @@ callback scope, i.e. the callback and all resources will be mapped to
this key. The optional <code>SetCallback-KeyClass</code> may override
this semantic.</li>
</ul>
-<p>Beside generating the actual function mapping of the API, additional
-query methods are generated, passing the keys as its paramters</p>
-<ul>
-<li><code>boolean is&lt;SetCallbackFunctionName&gt;Mapped((key-arg)*)</code>
-queries whether <code>SetCallbackFunctionName</code> is mapped.</li>
-<li><code>ALBUFFERCALLBACKTYPESOFT get&lt;SetCallbackFunctionName&gt;((key-arg)*)</code>
+<h4
+id="javacallback-generated-interfaces-classes-and-methods"><em>JavaCallback</em>
+Generated Interfaces, Classes and Methods</h4>
+<p>The public <code>CallbackFunction</code> interface is generated.</p>
+<p>The default public <code>SetCallback-KeyClass</code> is generated if
+keys are used and no custom class is specified, see above.</p>
+<p>The public toolkit API <code>SetCallbackFunction</code> method is
+being generated.</p>
+<p>Additional public <em>maintenance</em> methods are generated. In case
+keys are being used, they expect <code>SetCallback-KeyClass</code> as an
+argument, otherwise they expect no argument for global scope.</p>
+<p>In case keys are defined and hence <code>SetCallback-KeyClass</code>
+used, the additional <em>maintenance</em> methods are:</p>
+<ul>
+<li><em>Set&lt;<code>SetCallback-KeyClass</code>&gt;
+get<code>SetCallbackFunctionName</code>Keys()</em></li>
+<li><em>boolean
+is<code>SetCallbackFunctionName</code>Mapped(<code>SetCallback-KeyClass</code>)</em>
+queries whether <code>SetCallbackFunctionName</code> is mapped to
+key.</li>
+<li><em><code>CallbackFunction</code>
+get<code>SetCallbackFunctionName</code>(<code>SetCallback-KeyClass</code>)</em>
returns the mapped <code>CallbackFunction</code>, null if not
mapped</li>
-<li><code>Object get&lt;SetCallbackFunctionName&gt;UserParam((key-arg)*)</code>
+<li><em>Object
+get<code>SetCallbackFunctionName</code>UserParam(<code>SetCallback-KeyClass</code>)</em>
+returns the mapped <code>userParam</code> object, null if not
+mapped</li>
+<li><em>void
+release<code>SetCallbackFunctionName</code>(<code>SetCallback-KeyClass</code>)</em>
+releases the mapped <code>CallbackFunction</code> data set associated
+via <code>SetCallbackFunctionName</code>.</li>
+<li><em>int releaseAll<code>SetCallbackFunctionName</code>()</em>
+releases complete mapped <code>CallbackFunction</code> data set
+associated via <code>SetCallbackFunctionName</code>.</li>
+</ul>
+<p>In no keys are defined and hence global scope used, the additional
+<em>maintenance</em> methods are:</p>
+<ul>
+<li><em>boolean is<code>SetCallbackFunctionName</code>Mapped()</em>
+queries whether <code>SetCallbackFunctionName</code> is mapped.</li>
+<li><em><code>CallbackFunction</code>
+get<code>SetCallbackFunctionName</code>()</em> returns the mapped
+<code>CallbackFunction</code>, null if not mapped</li>
+<li><em>Object get<code>SetCallbackFunctionName</code>UserParam()</em>
returns the mapped <code>userParam</code> object, null if not
mapped</li>
+<li><em>void release<code>SetCallbackFunctionName</code>()</em> releases
+the mapped <code>CallbackFunction</code> data set associated via
+<code>SetCallbackFunctionName</code>.</li>
</ul>
+<p>Note that the <em>release<code>SetCallbackFunctionName</code>(*)</em>
+and <em>releaseAll<code>SetCallbackFunctionName</code>()</em> methods
+are not the <em>proper toolkit API way</em> to remove the callback, try
+to use original <code>SetCallbackFunctionName</code> API method instead
+using a <code>null</code> <code>CallbackFunction</code> reference.</p>
<h4 id="custom-setcallback-keyclass">Custom
<code>SetCallback-KeyClass</code></h4>
<p>The <code>SetCallback-KeyClass</code> is the optional user-written
@@ -2094,10 +2142,11 @@ ArgumentIsString InjectMessageCallback01 1
#
# This callback has no keys defines, rendering it of global scope!
#
-# Explicit queries are generated, passing the keys as paramters
+# Explicit maintenance methods are generated, passing the keys as paramters
# - `boolean isMessageCallback01Mapped()` queries whether `MessageCallback0` is mapped globally
# - `T2_CallbackFunc01 getMessageCallback01()` returns the global T2_CallbackFunc01, null if not mapped
# - `Object getMessageCallback01UserParam()` returns the global `usrParam` object, null if not mapped
+# - `void releaseMessageCallback01()` releases callback data skipping toolkit API. Favor passing `null` callback ref to `MessageCallback01(..)`
JavaCallbackDef MessageCallback01 T2_CallbackFunc01 2</code></pre>
<p>Note that <a
href="#libraryonload-librarybasename-for-jni_onload-"><code>LibraryOnLoad Bindingtest2</code></a>
@@ -2121,34 +2170,20 @@ thread to the <code>JavaVM*</code> generating a new
/** Entry point (through function pointer) to C language function: &lt;br&gt; &lt;code&gt;void MessageCallback01(T2_CallbackFunc01 cbFunc, void * usrParam)&lt;/code&gt;&lt;br&gt; */
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam);
+ /** Returns if callback is mapped for &lt;br&gt; &lt;code&gt; public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)&lt;/code&gt; **/
public boolean isMessageCallback01Mapped();
+
+ /** Returns T2_CallbackFunc01 callback for &lt;br&gt; &lt;code&gt; public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)&lt;/code&gt; **/
public T2_CallbackFunc01 getMessageCallback01();
+
+ /** Returns user-param for &lt;br&gt; &lt;code&gt; public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)&lt;/code&gt; **/
public Object getMessageCallback01UserParam();
+ /** Releases callback data skipping toolkit API. Favor passing `null` callback ref to &lt;br&gt; &lt;code&gt; public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)&lt;/code&gt; **/
+ public void releaseMessageCallback01();
+
/** Entry point (through function pointer) to C language function: &lt;br&gt; &lt;code&gt;void InjectMessageCallback01(size_t id, const char * msg)&lt;/code&gt;&lt;br&gt; */
public void InjectMessageCallback01(long id, String msg);</code></pre>
-<p>Implementation utilizes the default <code>SetCallback-KeyClass</code>
-implementation for
-<code>void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)</code>,
-which is key-less and hence minimalistic.</p>
-<pre><code> private static class MessageCallback01Key {
- MessageCallback01Key() {
- }
- @Override
- public boolean equals(final Object o) {
- if( this == o ) {
- return true;
- }
- if( !(o instanceof MessageCallback01Key) ) {
- return false;
- }
- return true;
- }
- @Override
- public int hashCode() {
- return 0;
- }
- }</code></pre>
<h3 id="javacallback-example-2a-default-keyclass">JavaCallback Example
2a (Default <em>KeyClass</em>)</h3>
<p>This examples is derived from OpenAL's
@@ -2173,9 +2208,12 @@ buffer.</p>
# The `buffer` key allows setting one callback per buffer-name, compatible with the `AL_SOFT_callback_buffer` spec.
#
# Explicit queries are generated, passing the keys as paramters
- # - `boolean isAlBufferCallback0Mapped(int buffer)` queries whether `alBufferCallback0` is mapped to `buffer`.
- # - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(int buffer)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
- # - `Object getAlBufferCallback0UserParam(int buffer)` returns the `buffer` mapped `userptr` object, null if not mapped
+ # - `Set&lt;AlBufferCallback0Key&gt; getAlBufferCallback0Keys()` returns set of Key { int buffer }
+ # - `boolean isAlBufferCallback0Mapped(AlBufferCallback0Key)` queries whether `alBufferCallback0` is mapped to `buffer`.
+ # - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(AlBufferCallback0Key)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
+ # - `Object getAlBufferCallback0UserParam(AlBufferCallback0Key)` returns the `buffer` mapped `userptr` object, null if not mapped
+ # - `void releaseAllAlBufferCallback0()` releases all callback data mapped via Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to `alBufferCallback0(..)`
+ # - `void releaseAlBufferCallback0(AlBufferCallback0Key)` releases callback data mapped to Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to `alBufferCallback0(..)`
JavaCallbackDef alBufferCallback0 ALBUFFERCALLBACKTYPESOFT 1
JavaCallbackKey alBufferCallback0 0</code></pre>
<p>leading to the following interface</p>
@@ -2186,23 +2224,11 @@ buffer.</p>
}
...
-
- /** Entry point (through function pointer) to C language function: &lt;br&gt; &lt;code&gt;void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void * userptr)&lt;/code&gt;&lt;br&gt; */
- public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr);
-
- public boolean isAlBufferCallback0Mapped(int buffer);
- public ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(int buffer);
- public Object getAlBufferCallback0UserParam(int buffer);
-
- /** Entry point (through function pointer) to C language function: &lt;br&gt; &lt;code&gt;void alEventCallbackInject(int eventType, int object, int param, const char * msg)&lt;/code&gt;&lt;br&gt; */
- public void alEventCallbackInject(int eventType, int object, int param, String msg); </code></pre>
-<p>Implementation utilizes the default <code>SetCallback-KeyClass</code>
-implementation for
-<code>void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code>,
-which uses one key, i.e. <code>buffer</code>.</p>
-<pre><code> private static class AlBufferCallback0Key {
- private final int buffer;
- AlBufferCallback0Key(int buffer) {
+
+ /** Key { int buffer } for &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public static class AlBufferCallback0Key {
+ public final int buffer;
+ public AlBufferCallback0Key(int buffer) {
this.buffer = buffer;
}
@Override
@@ -2222,7 +2248,33 @@ which uses one key, i.e. <code>buffer</code>.</p>
int hash = buffer;
return hash;
}
- }</code></pre>
+ }
+
+ ...
+
+ /** Entry point (through function pointer) to C language function: &lt;br&gt; &lt;code&gt;void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void * userptr)&lt;/code&gt;&lt;br&gt; */
+ public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr);
+
+ /** Returns set of Key { int buffer } for &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public Set&lt;AlBufferCallback0Key&gt; getAlBufferCallback0Keys();
+
+ /** Returns whether callback Key { int buffer } is mapped for &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public boolean isAlBufferCallback0Mapped(AlBufferCallback0Key key);
+
+ /** Returns ALBUFFERCALLBACKTYPESOFT callback mapped to Key { int buffer } for &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(AlBufferCallback0Key key);
+
+ /** Returns user-param mapped to Key { int buffer } for &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public Object getAlBufferCallback0UserParam(AlBufferCallback0Key key);
+
+ /** Releases all callback data mapped via Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public int releaseAllAlBufferCallback0();
+
+ /** Releases callback data mapped to Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to &lt;br&gt; &lt;code&gt; public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)&lt;/code&gt; **/
+ public void releaseAlBufferCallback0(AlBufferCallback0Key key);
+
+ /** Entry point (through function pointer) to C language function: &lt;br&gt; &lt;code&gt;void alEventCallbackInject(int eventType, int object, int param, const char * msg)&lt;/code&gt;&lt;br&gt; */
+ public void alEventCallbackInject(int eventType, int object, int param, String msg); </code></pre>
<h3 id="javacallback-example-2b-custom-keyclass">JavaCallback Example 2b
(Custom <em>KeyClass</em>)</h3>
<p>Same as example 2a, but implementing a custom
diff --git a/doc/GlueGen_Mapping.md b/doc/GlueGen_Mapping.md
index 9a169d7..f43f7a6 100644
--- a/doc/GlueGen_Mapping.md
+++ b/doc/GlueGen_Mapping.md
@@ -800,6 +800,9 @@ If mapping the `CallbackFunction` to keys, the user must specify the same key ar
If no keys are defined via `JavaCallbackKey`, or manually injected using a custom `SetCallback-KeyClass`, see below,
the `CallbackFunction` has global scope.
+In case keys are defined via `JavaCallbackKey` and no manually injected custom `SetCallback-KeyClass` used,
+a public `SetCallback-KeyClass` is being generated covering the defined keys.
+
Keys allow to limit the scope, i.e. map multiple `CallbackFunction` to the different keys.
Key arguments must match in `SetCallbackFunction` to remove a previously set `CallbackFunction`.
@@ -808,11 +811,32 @@ Key arguments must match in `SetCallbackFunction` to remove a previously set `Ca
- `SetCallbackFunction`: `SetCallbackFunction` name of the native toolkit API responsible to set the callback
- `SetCallback-ParamIdx`: List of parameter indices of the `SetCallbackFunction`, denoting the key(s) limiting the callback scope, i.e. the callback and all resources will be mapped to this key. The optional `SetCallback-KeyClass` may override this semantic.
-Beside generating the actual function mapping of the API, additional query methods are generated, passing the keys as its paramters
-- `boolean is<SetCallbackFunctionName>Mapped((key-arg)*)` queries whether `SetCallbackFunctionName` is mapped.
-- `ALBUFFERCALLBACKTYPESOFT get<SetCallbackFunctionName>((key-arg)*)` returns the mapped `CallbackFunction`, null if not mapped
-- `Object get<SetCallbackFunctionName>UserParam((key-arg)*)` returns the mapped `userParam` object, null if not mapped
+#### *JavaCallback* Generated Interfaces, Classes and Methods
+
+The public `CallbackFunction` interface is generated.
+
+The default public `SetCallback-KeyClass` is generated if keys are used and no custom class is specified, see above.
+
+The public toolkit API `SetCallbackFunction` method is being generated.
+
+Additional public *maintenance* methods are generated. In case keys are being used, they expect `SetCallback-KeyClass` as an argument, otherwise they expect no argument for global scope.
+
+In case keys are defined and hence `SetCallback-KeyClass` used, the additional *maintenance* methods are:
+- *Set<`SetCallback-KeyClass`> get`SetCallbackFunctionName`Keys()*
+- *boolean is`SetCallbackFunctionName`Mapped(`SetCallback-KeyClass`)* queries whether `SetCallbackFunctionName` is mapped to key.
+- *`CallbackFunction` get`SetCallbackFunctionName`(`SetCallback-KeyClass`)* returns the mapped `CallbackFunction`, null if not mapped
+- *Object get`SetCallbackFunctionName`UserParam(`SetCallback-KeyClass`)* returns the mapped `userParam` object, null if not mapped
+- *void release`SetCallbackFunctionName`(`SetCallback-KeyClass`)* releases the mapped `CallbackFunction` data set associated via `SetCallbackFunctionName`.
+- *int releaseAll`SetCallbackFunctionName`()* releases complete mapped `CallbackFunction` data set associated via `SetCallbackFunctionName`.
+
+In no keys are defined and hence global scope used, the additional *maintenance* methods are:
+- *boolean is`SetCallbackFunctionName`Mapped()* queries whether `SetCallbackFunctionName` is mapped.
+- *`CallbackFunction` get`SetCallbackFunctionName`()* returns the mapped `CallbackFunction`, null if not mapped
+- *Object get`SetCallbackFunctionName`UserParam()* returns the mapped `userParam` object, null if not mapped
+- *void release`SetCallbackFunctionName`()* releases the mapped `CallbackFunction` data set associated via `SetCallbackFunctionName`.
+Note that the *release`SetCallbackFunctionName`(\*)* and *releaseAll`SetCallbackFunctionName`()* methods are not the *proper toolkit API way* to remove the callback,
+try to use original `SetCallbackFunctionName` API method instead using a `null` `CallbackFunction` reference.
#### Custom `SetCallback-KeyClass`
@@ -872,10 +896,11 @@ ArgumentIsString InjectMessageCallback01 1
#
# This callback has no keys defines, rendering it of global scope!
#
-# Explicit queries are generated, passing the keys as paramters
+# Explicit maintenance methods are generated, passing the keys as paramters
# - `boolean isMessageCallback01Mapped()` queries whether `MessageCallback0` is mapped globally
# - `T2_CallbackFunc01 getMessageCallback01()` returns the global T2_CallbackFunc01, null if not mapped
# - `Object getMessageCallback01UserParam()` returns the global `usrParam` object, null if not mapped
+# - `void releaseMessageCallback01()` releases callback data skipping toolkit API. Favor passing `null` callback ref to `MessageCallback01(..)`
JavaCallbackDef MessageCallback01 T2_CallbackFunc01 2
```
@@ -898,37 +923,22 @@ public interface Bindingtest2 {
/** Entry point (through function pointer) to C language function: <br> <code>void MessageCallback01(T2_CallbackFunc01 cbFunc, void * usrParam)</code><br> */
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam);
+ /** Returns if callback is mapped for <br> <code> public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)</code> **/
public boolean isMessageCallback01Mapped();
+
+ /** Returns T2_CallbackFunc01 callback for <br> <code> public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)</code> **/
public T2_CallbackFunc01 getMessageCallback01();
+
+ /** Returns user-param for <br> <code> public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)</code> **/
public Object getMessageCallback01UserParam();
+ /** Releases callback data skipping toolkit API. Favor passing `null` callback ref to <br> <code> public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)</code> **/
+ public void releaseMessageCallback01();
+
/** Entry point (through function pointer) to C language function: <br> <code>void InjectMessageCallback01(size_t id, const char * msg)</code><br> */
public void InjectMessageCallback01(long id, String msg);
```
-Implementation utilizes the default `SetCallback-KeyClass` implementation for `void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)`,
-which is key-less and hence minimalistic.
-```
- private static class MessageCallback01Key {
- MessageCallback01Key() {
- }
- @Override
- public boolean equals(final Object o) {
- if( this == o ) {
- return true;
- }
- if( !(o instanceof MessageCallback01Key) ) {
- return false;
- }
- return true;
- }
- @Override
- public int hashCode() {
- return 0;
- }
- }
-```
-
### JavaCallback Example 2a (Default *KeyClass*)
This examples is derived from OpenAL's `AL_SOFT_callback_buffer` extension.
@@ -956,9 +966,12 @@ and the following GlueGen configuration
# The `buffer` key allows setting one callback per buffer-name, compatible with the `AL_SOFT_callback_buffer` spec.
#
# Explicit queries are generated, passing the keys as paramters
- # - `boolean isAlBufferCallback0Mapped(int buffer)` queries whether `alBufferCallback0` is mapped to `buffer`.
- # - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(int buffer)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
- # - `Object getAlBufferCallback0UserParam(int buffer)` returns the `buffer` mapped `userptr` object, null if not mapped
+ # - `Set<AlBufferCallback0Key> getAlBufferCallback0Keys()` returns set of Key { int buffer }
+ # - `boolean isAlBufferCallback0Mapped(AlBufferCallback0Key)` queries whether `alBufferCallback0` is mapped to `buffer`.
+ # - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(AlBufferCallback0Key)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
+ # - `Object getAlBufferCallback0UserParam(AlBufferCallback0Key)` returns the `buffer` mapped `userptr` object, null if not mapped
+ # - `void releaseAllAlBufferCallback0()` releases all callback data mapped via Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to `alBufferCallback0(..)`
+ # - `void releaseAlBufferCallback0(AlBufferCallback0Key)` releases callback data mapped to Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to `alBufferCallback0(..)`
JavaCallbackDef alBufferCallback0 ALBUFFERCALLBACKTYPESOFT 1
JavaCallbackKey alBufferCallback0 0
```
@@ -972,24 +985,11 @@ leading to the following interface
}
...
-
- /** Entry point (through function pointer) to C language function: <br> <code>void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void * userptr)</code><br> */
- public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr);
-
- public boolean isAlBufferCallback0Mapped(int buffer);
- public ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(int buffer);
- public Object getAlBufferCallback0UserParam(int buffer);
-
- /** Entry point (through function pointer) to C language function: <br> <code>void alEventCallbackInject(int eventType, int object, int param, const char * msg)</code><br> */
- public void alEventCallbackInject(int eventType, int object, int param, String msg);
-```
-
-Implementation utilizes the default `SetCallback-KeyClass` implementation for `void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)`,
-which uses one key, i.e. `buffer`.
-```
- private static class AlBufferCallback0Key {
- private final int buffer;
- AlBufferCallback0Key(int buffer) {
+
+ /** Key { int buffer } for <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public static class AlBufferCallback0Key {
+ public final int buffer;
+ public AlBufferCallback0Key(int buffer) {
this.buffer = buffer;
}
@Override
@@ -1010,6 +1010,32 @@ which uses one key, i.e. `buffer`.
return hash;
}
}
+
+ ...
+
+ /** Entry point (through function pointer) to C language function: <br> <code>void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void * userptr)</code><br> */
+ public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr);
+
+ /** Returns set of Key { int buffer } for <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public Set<AlBufferCallback0Key> getAlBufferCallback0Keys();
+
+ /** Returns whether callback Key { int buffer } is mapped for <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public boolean isAlBufferCallback0Mapped(AlBufferCallback0Key key);
+
+ /** Returns ALBUFFERCALLBACKTYPESOFT callback mapped to Key { int buffer } for <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(AlBufferCallback0Key key);
+
+ /** Returns user-param mapped to Key { int buffer } for <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public Object getAlBufferCallback0UserParam(AlBufferCallback0Key key);
+
+ /** Releases all callback data mapped via Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public int releaseAllAlBufferCallback0();
+
+ /** Releases callback data mapped to Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to <br> <code> public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)</code> **/
+ public void releaseAlBufferCallback0(AlBufferCallback0Key key);
+
+ /** Entry point (through function pointer) to C language function: <br> <code>void alEventCallbackInject(int eventType, int object, int param, const char * msg)</code><br> */
+ public void alEventCallbackInject(int eventType, int object, int param, String msg);
```
### JavaCallback Example 2b (Custom *KeyClass*)
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 ");
}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java
index e43d73e..badd299 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java
@@ -29,9 +29,11 @@
package com.jogamp.gluegen.test.junit.generation;
import java.io.IOException;
+import java.util.Set;
import com.jogamp.common.os.NativeLibrary;
import com.jogamp.gluegen.test.junit.generation.Bindingtest2.ALBUFFERCALLBACKTYPESOFT;
+import com.jogamp.gluegen.test.junit.generation.Bindingtest2.AlBufferCallback0Key;
import com.jogamp.gluegen.test.junit.generation.Bindingtest2.T2_CallbackFunc01;
import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest2Impl;
@@ -214,6 +216,9 @@ public class Test4JavaCallback extends BaseClass {
final int buffer1 = 1;
final int buffer2 = 2;
final int buffer3 = 3;
+ final AlBufferCallback0Key buffer1Key = new AlBufferCallback0Key(buffer1);
+ final AlBufferCallback0Key buffer2Key = new AlBufferCallback0Key(buffer2);
+ final AlBufferCallback0Key buffer3Key = new AlBufferCallback0Key(buffer3);
final MyUserParam02 myUserParam01 = new MyUserParam02( 1);
final MyUserParam02 myUserParam02 = new MyUserParam02( 2);
Assert.assertEquals( 1, myUserParam01.i);
@@ -223,33 +228,48 @@ public class Test4JavaCallback extends BaseClass {
Assert.assertEquals( 0, myUserParam02.j);
Assert.assertEquals( 0, myUserParam02.buffer);
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(0, bt2.getAlBufferCallback0Keys().size());
// 1st mapping: buffer1 -> myCallback01, myUserParam01
bt2.alBufferCallback0(buffer1, 0, 0, myCallback01, myUserParam01);
- Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(1, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
// 2nd mapping: buffer2 -> myCallback02, myUserParam02
bt2.alBufferCallback0(buffer2, 0, 0, myCallback02, myUserParam02);
- Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1));
- Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1));
- Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback0UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1));
- Assert.assertEquals(myCallback02, bt2.getAlBufferCallback0(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(myCallback02, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(2, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(true, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
{
bt2.alBufferCallback0Inject(buffer1, 10, 100); // buffer1 -> myCallback01, myUserParam01
@@ -274,15 +294,15 @@ public class Test4JavaCallback extends BaseClass {
// Switch the callback function for buffer2 -> myCallback01, myUserParam02
bt2.alBufferCallback0(buffer2, 0, 0, myCallback01, myUserParam02);
- Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1));
- Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1));
- Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback0UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
{
bt2.alBufferCallback0Inject(buffer1, 11, 101); // buffer1 -> myCallback01, myUserParam01
@@ -307,27 +327,41 @@ public class Test4JavaCallback extends BaseClass {
// Just release the buffer2 callback and mapped resources
bt2.alBufferCallback0(buffer2, 0, 0, null, myUserParam02); // usrptr is not key, only buffer is key!
- Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(1, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
// Just release the buffer1 callback and mapped resources
bt2.alBufferCallback0(buffer1, 0, 0, null, null); // usrptr is not key, only buffer is key!
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(0, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(false, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
{
bt2.alBufferCallback0Inject(buffer2, 1, 10); // unmapped, no change in data
@@ -373,6 +407,9 @@ public class Test4JavaCallback extends BaseClass {
final int buffer1 = 1;
final int buffer2 = 2;
final int buffer3 = 3;
+ final CustomAlBufferCallback1Key buffer1Key = new CustomAlBufferCallback1Key(buffer1);
+ final CustomAlBufferCallback1Key buffer2Key = new CustomAlBufferCallback1Key(buffer2);
+ final CustomAlBufferCallback1Key buffer3Key = new CustomAlBufferCallback1Key(buffer3);
final MyUserParam02 myUserParam01 = new MyUserParam02( 1);
final MyUserParam02 myUserParam02 = new MyUserParam02( 2);
Assert.assertEquals( 1, myUserParam01.i);
@@ -382,33 +419,48 @@ public class Test4JavaCallback extends BaseClass {
Assert.assertEquals( 0, myUserParam02.j);
Assert.assertEquals( 0, myUserParam02.buffer);
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3Key));
+ Assert.assertEquals(0, bt2.getAlBufferCallback1Keys().size());
// 1st mapping: buffer1 -> myCallback01, myUserParam01
bt2.alBufferCallback1(buffer1, 0, 0, myCallback01, myUserParam01);
- Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3Key));
+ Assert.assertEquals(1, bt2.getAlBufferCallback1Keys().size());
+ {
+ final Set<CustomAlBufferCallback1Key> keys = bt2.getAlBufferCallback1Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
// 2nd mapping: buffer2 -> myCallback02, myUserParam02
bt2.alBufferCallback1(buffer2, 0, 0, myCallback02, myUserParam02);
- Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1));
- Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1));
- Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback1UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1));
- Assert.assertEquals(myCallback02, bt2.getAlBufferCallback1(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1Key));
+ Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1Key));
+ Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback1UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1Key));
+ Assert.assertEquals(myCallback02, bt2.getAlBufferCallback1(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3Key));
+ Assert.assertEquals(2, bt2.getAlBufferCallback1Keys().size());
+ {
+ final Set<CustomAlBufferCallback1Key> keys = bt2.getAlBufferCallback1Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(true, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
{
bt2.alBufferCallback1Inject(buffer1, 10, 100); // buffer1 -> myCallback01, myUserParam01
@@ -433,15 +485,15 @@ public class Test4JavaCallback extends BaseClass {
// Switch the callback function for buffer2 -> myCallback01, myUserParam02
bt2.alBufferCallback1(buffer2, 0, 0, myCallback01, myUserParam02);
- Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1));
- Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1));
- Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback1UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1Key));
+ Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1Key));
+ Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback1UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3Key));
{
bt2.alBufferCallback1Inject(buffer1, 11, 101); // buffer1 -> myCallback01, myUserParam01
@@ -466,27 +518,41 @@ public class Test4JavaCallback extends BaseClass {
// Just release the buffer2 callback and mapped resources
bt2.alBufferCallback1(buffer2, 0, 0, null, myUserParam02); // usrptr is not key, only buffer is key!
- Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3));
- Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3));
- Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3));
+ Assert.assertEquals(true, bt2.isAlBufferCallback1Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback1UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback1(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3Key));
+ Assert.assertEquals(1, bt2.getAlBufferCallback1Keys().size());
+ {
+ final Set<CustomAlBufferCallback1Key> keys = bt2.getAlBufferCallback1Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
// Just release the buffer1 callback and mapped resources
bt2.alBufferCallback1(buffer1, 0, 0, null, null); // usrptr is not key, only buffer is key!
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer1));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2));
- Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer1));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer2));
- Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback1Mapped(buffer3Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1UserParam(buffer3Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback1(buffer3Key));
+ Assert.assertEquals(0, bt2.getAlBufferCallback1Keys().size());
+ {
+ final Set<CustomAlBufferCallback1Key> keys = bt2.getAlBufferCallback1Keys();
+ Assert.assertEquals(false, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
{
bt2.alBufferCallback1Inject(buffer2, 1, 10); // unmapped, no change in data
@@ -521,6 +587,166 @@ public class Test4JavaCallback extends BaseClass {
}
}
+ /**
+ * Test in depth lifecycle of Bindingtest2 with ALBUFFERCALLBACKTYPESOFT JavaCallback via alBufferCallback1()
+ * using the default AlBufferCallback1Key class.
+ */
+ @Test
+ public void chapter04() throws Exception {
+ final Bindingtest2 bt2 = new Bindingtest2Impl();
+
+ final long[] id_res = { -1 };
+ final ALBUFFERCALLBACKTYPESOFT myCallback01 = new ALBUFFERCALLBACKTYPESOFT() {
+ @Override
+ public void callback(final int buffer, final Object userptr, final int sampledata, final int numbytes) {
+ final MyUserParam02 myUserParam = (MyUserParam02)userptr;
+ id_res[0] = sampledata + numbytes + myUserParam.i;
+ myUserParam.j = id_res[0];
+ myUserParam.buffer = buffer;
+ System.err.println("chapter04.myCallback01: buffer "+buffer+", sampledata "+sampledata+", numbytes "+numbytes);
+ }
+ };
+ final ALBUFFERCALLBACKTYPESOFT myCallback02 = new ALBUFFERCALLBACKTYPESOFT() {
+ @Override
+ public void callback(final int buffer, final Object userptr, final int sampledata, final int numbytes) {
+ final MyUserParam02 myUserParam = (MyUserParam02)userptr;
+ id_res[0] = sampledata * numbytes + myUserParam.i;
+ myUserParam.j = id_res[0];
+ myUserParam.buffer = buffer;
+ System.err.println("chapter04.myCallback02: buffer "+buffer+", sampledata "+sampledata+", numbytes "+numbytes);
+ }
+ };
+ final int buffer1 = 1;
+ final int buffer2 = 2;
+ final int buffer3 = 3;
+ final AlBufferCallback0Key buffer1Key = new AlBufferCallback0Key(buffer1);
+ final AlBufferCallback0Key buffer2Key = new AlBufferCallback0Key(buffer2);
+ final AlBufferCallback0Key buffer3Key = new AlBufferCallback0Key(buffer3);
+ final MyUserParam02 myUserParam01 = new MyUserParam02( 1);
+ final MyUserParam02 myUserParam02 = new MyUserParam02( 2);
+ Assert.assertEquals( 1, myUserParam01.i);
+ Assert.assertEquals( 0, myUserParam01.j);
+ Assert.assertEquals( 0, myUserParam01.buffer);
+ Assert.assertEquals( 2, myUserParam02.i);
+ Assert.assertEquals( 0, myUserParam02.j);
+ Assert.assertEquals( 0, myUserParam02.buffer);
+
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(0, bt2.getAlBufferCallback0Keys().size());
+
+ // 1st mapping: buffer1 -> myCallback01, myUserParam01
+ bt2.alBufferCallback0(buffer1, 0, 0, myCallback01, myUserParam01);
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(1, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
+
+ // 2nd mapping: buffer2 -> myCallback02, myUserParam02
+ bt2.alBufferCallback0(buffer2, 0, 0, myCallback02, myUserParam02);
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(myUserParam02, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(myCallback02, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(2, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(true, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
+
+ {
+ bt2.alBufferCallback0Inject(buffer1, 10, 100); // buffer1 -> myCallback01, myUserParam01
+ Assert.assertEquals(10+100+1, id_res[0]);
+ Assert.assertEquals( 1, myUserParam01.i);
+ Assert.assertEquals(10+100+1, myUserParam01.j);
+ Assert.assertEquals( 1, myUserParam01.buffer);
+ Assert.assertEquals( 2, myUserParam02.i);
+ Assert.assertEquals( 0, myUserParam02.j);
+ Assert.assertEquals( 0, myUserParam02.buffer);
+ }
+ {
+ bt2.alBufferCallback0Inject(buffer2, 10, 100); // buffer2 -> myCallback02, myUserParam02
+ Assert.assertEquals(10*100+2, id_res[0]);
+ Assert.assertEquals( 1, myUserParam01.i);
+ Assert.assertEquals(10+100+1, myUserParam01.j);
+ Assert.assertEquals( 1, myUserParam01.buffer);
+ Assert.assertEquals( 2, myUserParam02.i);
+ Assert.assertEquals(10*100+2, myUserParam02.j);
+ Assert.assertEquals( 2, myUserParam02.buffer);
+ }
+
+ // Just release the buffer2 callback and mapped resources
+ bt2.releaseAlBufferCallback0(buffer2Key);
+ // bt2.alBufferCallback0(buffer2, 0, 0, null, myUserParam02); // usrptr is not key, only buffer is key!
+ Assert.assertEquals(true, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(myUserParam01, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(myCallback01, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(1, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(true, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
+
+ // Just release the buffer1 callback and mapped resources
+ bt2.releaseAlBufferCallback0(buffer1Key);
+ // bt2.alBufferCallback0(buffer1, 0, 0, null, null); // usrptr is not key, only buffer is key!
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer1Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer2Key));
+ Assert.assertEquals(false, bt2.isAlBufferCallback0Mapped(buffer3Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0UserParam(buffer3Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer1Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer2Key));
+ Assert.assertEquals(null, bt2.getAlBufferCallback0(buffer3Key));
+ Assert.assertEquals(0, bt2.getAlBufferCallback0Keys().size());
+ {
+ final Set<AlBufferCallback0Key> keys = bt2.getAlBufferCallback0Keys();
+ Assert.assertEquals(false, keys.contains(buffer1Key));
+ Assert.assertEquals(false, keys.contains(buffer2Key));
+ Assert.assertEquals(false, keys.contains(buffer3Key));
+ }
+
+ if( false ){
+ bt2.alBufferCallback0Inject(buffer2, 1, 10); // unmapped, no change in data
+ Assert.assertEquals( 1+ 10+2, id_res[0]);
+ Assert.assertEquals( 1, myUserParam01.i);
+ Assert.assertEquals(11+101+1, myUserParam01.j);
+ Assert.assertEquals( 1, myUserParam01.buffer);
+ Assert.assertEquals( 2, myUserParam02.i);
+ Assert.assertEquals( 1+ 10+2, myUserParam02.j);
+ Assert.assertEquals( 2, myUserParam02.buffer);
+ }
+ }
+
public static class CustomAlBufferCallback1Key {
private final int buffer;
public CustomAlBufferCallback1Key(final int buffer) {
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
index de713cf..812676e 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
@@ -62,10 +62,11 @@ ArgumentIsString InjectMessageCallback01 1
#
# This callback has no keys defines, rendering it of global scope!
#
-# Explicit queries are generated, passing the keys as paramters
+# Explicit maintenance methods are generated, passing the keys as paramters
# - `boolean isMessageCallback01Mapped()` queries whether `MessageCallback0` is mapped globally
# - `T2_CallbackFunc01 getMessageCallback01()` returns the global T2_CallbackFunc01, null if not mapped
# - `Object getMessageCallback01UserParam()` returns the global `usrParam` object, null if not mapped
+# - `void releaseMessageCallback01()` releases callback data skipping toolkit API. Favor passing `null` callback ref to `MessageCallback01(..)`
JavaCallbackDef MessageCallback01 T2_CallbackFunc01 2
#
# End JavaCallback
@@ -87,10 +88,11 @@ ArgumentIsString alEventCallbackInject 3
# This callback has no keys defines, rendering it of global scope!
# The global key-less scope matches `AL_SOFT_events` semantics.
#
-# Explicit queries are generated, passing the keys as paramters
+# Explicit maintenance methods are generated, passing the keys as paramters
# - `boolean isAlEventCallbackMapped()` queries whether `alEventCallback` is mapped globally
# - `ALEVENTPROCSOFT getAlEventCallback()` returns the global ALEVENTPROCSOFT, null if not mapped
# - `Object getAlEventCallbackUserParam()` returns the global `userParam` object, null if not mapped
+# - `void releaseAlEventCallback()` releases callback data skipping toolkit API. Favor passing `null` callback ref to `alEventCallback(..)`
JavaCallbackDef alEventCallback ALEVENTPROCSOFT 5
JavaCallbackKey alEventCallback
#
@@ -115,10 +117,13 @@ JavaCallbackKey alEventCallback
# This callback defines one key, `buffer`, index 0 of alBufferCallback0(..) parameter list, limiting it to buffer-name scope!
# The `buffer` key allows setting one callback per buffer-name, compatible with the `AL_SOFT_callback_buffer` spec.
#
-# Explicit queries are generated, passing the keys as paramters
-# - `boolean isAlBufferCallback0Mapped(int buffer)` queries whether `alBufferCallback0` is mapped to `buffer`.
-# - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(int buffer)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
-# - `Object getAlBufferCallback0UserParam(int buffer)` returns the `buffer` mapped `userptr` object, null if not mapped
+# Explicit maintenance methods are generated, passing the keys as paramters
+# - `Set<AlBufferCallback0Key> getAlBufferCallback0Keys()` returns set of Key { int buffer }
+# - `boolean isAlBufferCallback0Mapped(AlBufferCallback0Key)` queries whether `alBufferCallback0` is mapped to `buffer`.
+# - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(AlBufferCallback0Key)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
+# - `Object getAlBufferCallback0UserParam(AlBufferCallback0Key)` returns the `buffer` mapped `userptr` object, null if not mapped
+# - `void releaseAllAlBufferCallback0()` releases all callback data mapped via Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to `alBufferCallback0(..)`
+# - `void releaseAlBufferCallback0(AlBufferCallback0Key)` releases callback data mapped to Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to `alBufferCallback0(..)`
JavaCallbackDef alBufferCallback0 ALBUFFERCALLBACKTYPESOFT 1
JavaCallbackKey alBufferCallback0 0
#
@@ -142,7 +147,7 @@ JavaCallbackKey alBufferCallback0 0
# This callback defines one key, `buffer`, index 0 of alBufferCallback1(..) parameter list, limiting it to buffer-name scope!
# The `buffer` key allows setting one callback per buffer-name, compatible with the `AL_SOFT_callback_buffer` spec.
#
-# Explicit queries are generated, passing the keys as paramters
+# Explicit maintenance methods are generated, passing the keys as paramters
# - `boolean isAlBufferCallback1Mapped(int buffer)` queries whether `alBufferCallback1` is mapped to `buffer`.
# - `ALBUFFERCALLBACKTYPESOFT getAlBufferCallback1(int buffer)` returns the `buffer` mapped ALEVENTPROCSOFT, null if not mapped
# - `Object getAlBufferCallback1UserParam(int buffer)` returns the `buffer` mapped `userptr` object, null if not mapped