diff options
author | Sven Gothel <[email protected]> | 2023-08-04 11:13:33 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-08-04 11:13:33 +0200 |
commit | 3ad38748d7ef50a3631506eabcd3ae3417faa84d (patch) | |
tree | fac3ea1f1ff1a68c90df0076088908e196908489 | |
parent | 1250d960d8bf2ee9ab8726a18a837115d6930815 (diff) |
JavaCallbackEmitter.emitJavaKeyClass(): Use directBufferAddress for compound types in equals and hashCode, i.e. use memory identitypulled
Use case is having a compound-type as userParam, which also acts as key, see MessageCallback13, Test4JavaCallback.chapter13().
The Java compound instance is re-created using the actual identical native memory (address),
which has been stored or passed in the native toolkit.
5 files changed, 259 insertions, 16 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java b/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java index 5e83016..01ffe8f 100644 --- a/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java @@ -386,7 +386,9 @@ public final class JavaCallbackEmitter { unit.emitln(" &&"); unit.emit (" "); } - if( jType.isPrimitive() || idx == info.setFuncUserParamIdx ) { + if( jType.isCompoundTypeWrapper() ) { + unit.emit(name+".getDirectBufferAddress() == o2."+name+".getDirectBufferAddress()"); + } else if( jType.isPrimitive() || idx == info.setFuncUserParamIdx ) { unit.emit(name+" == o2."+name); } else { unit.emit(name+".equals( o2."+name+" )"); @@ -419,6 +421,8 @@ public final class JavaCallbackEmitter { } else { unit.emitln(name+";"); } + } else if( jType.isCompoundTypeWrapper() ) { + unit.emitln("HashUtil.getAddrHash32_EqualDist( "+name+".getDirectBufferAddress() );"); } else { if( idx == info.setFuncUserParamIdx ) { unit.emitln("System.identityHashCode( "+name+" );"); 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 0c1ff93..92ab2f6 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test4JavaCallback.java @@ -40,10 +40,12 @@ import com.jogamp.gluegen.test.junit.generation.Bindingtest2.AlEventCallback0Key import com.jogamp.gluegen.test.junit.generation.Bindingtest2.AlEventCallback1Key; import com.jogamp.gluegen.test.junit.generation.Bindingtest2.MessageCallback11aKey; import com.jogamp.gluegen.test.junit.generation.Bindingtest2.MessageCallback11bKey; +import com.jogamp.gluegen.test.junit.generation.Bindingtest2.MessageCallback13Key; import com.jogamp.gluegen.test.junit.generation.Bindingtest2.T2_CallbackFunc01; import com.jogamp.gluegen.test.junit.generation.Bindingtest2.T2_CallbackFunc11; import com.jogamp.gluegen.test.junit.generation.Bindingtest2.T2_CallbackFunc12a; import com.jogamp.gluegen.test.junit.generation.Bindingtest2.T2_CallbackFunc12b; +import com.jogamp.gluegen.test.junit.generation.Bindingtest2.T2_CallbackFunc13; import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest2Impl; import org.junit.AfterClass; @@ -1674,54 +1676,54 @@ public class Test4JavaCallback extends BaseClass { public void chapter12b() throws Exception { final Bindingtest2 bt2 = new Bindingtest2Impl(); - final AtomicReference<T2_Callback12LogMessage> messageExpected = new AtomicReference<>(null); - final AtomicReference<String> messageReturned = new AtomicReference<>(null); + final AtomicReference<T2_Callback12LogMessage> expMessage = new AtomicReference<>(null); + final AtomicReference<String> hasReturnedMsg = new AtomicReference<>(null); final T2_CallbackFunc12b logCallBack = new T2_CallbackFunc12b() { int expParam0 = 1; @Override public void callback(final int param0, final T2_Callback12LogMessage usrParam) { - assertEquals(messageExpected.get(), usrParam); // compare value, not object hash value (reference) - messageReturned.set("Result-"+usrParam.getMessage()); + assertEquals(expMessage.get(), usrParam); // compare value, not object hash value (reference) + hasReturnedMsg.set("Result-"+usrParam.getMessage()); Assert.assertEquals(expParam0++, param0); } }; bt2.SetLogCallBack12b(logCallBack); - messageReturned.set(null); + hasReturnedMsg.set(null); { final T2_Callback12LogMessage logMessage = T2_Callback12LogMessage.create(); logMessage.setCategory("TEST"); logMessage.setMessage("Example"); logMessage.setLevel(Bindingtest2.LOG_Info); - messageExpected.set(logMessage); + expMessage.set(logMessage); bt2.LogCallBack12bInject(logMessage, 1); - Assert.assertEquals(messageReturned.get(), "Result-Example"); + Assert.assertEquals("Result-Example", hasReturnedMsg.get()); } - messageReturned.set(null); + hasReturnedMsg.set(null); { final T2_Callback12LogMessage logMessage = T2_Callback12LogMessage.create(); logMessage.setCategory("IDK"); logMessage.setMessage("John Doe is absent."); logMessage.setLevel(Bindingtest2.LOG_Warning); - messageExpected.set(logMessage); + expMessage.set(logMessage); bt2.LogCallBack12bInject(logMessage, 2); - Assert.assertEquals(messageReturned.get(), "Result-John Doe is absent."); + Assert.assertEquals("Result-John Doe is absent.", hasReturnedMsg.get()); } bt2.SetLogCallBack12b(null); - messageReturned.set(null); + hasReturnedMsg.set(null); { final T2_Callback12LogMessage logMessage = T2_Callback12LogMessage.create(); logMessage.setCategory("SANITY"); logMessage.setMessage("Callback is now unset"); logMessage.setLevel(Bindingtest2.LOG_Fatal); - messageExpected.set(logMessage); + expMessage.set(logMessage); bt2.LogCallBack12bInject(logMessage, 3); - Assert.assertEquals(messageReturned.get(), null); + Assert.assertEquals(null, hasReturnedMsg.get()); } } private static void assertEquals(final T2_Callback12LogMessage exp, final T2_Callback12LogMessage has) { @@ -1735,6 +1737,174 @@ public class Test4JavaCallback extends BaseClass { Assert.assertEquals(exp.getLevel(), has.getLevel()); } + /** + * Test Bindingtest2 with T2_CallbackFunc13 JavaCallback via MessageCallback13() + */ + @Test + public void chapter13() throws Exception { + final Bindingtest2 bt2 = new Bindingtest2Impl(); + + // + // Key 1 + // + final AtomicReference<String> hasReturnedMsgKey1 = new AtomicReference<>(null); + final T2_CallbackFunc13 callbackKey1 = new T2_CallbackFunc13() { + int localCallCount = 1; + + @Override + public void callback(final String msg1, final T2_Callback13UserType info, final String msg2, final T2_Callback13UserKey1 usrParamKey1, final long usrKey2) { + Assert.assertEquals(localCallCount, info.getANumber()); + final String strKey1 = String.valueOf( usrParamKey1.getKeyValue1() ); + final String strKey2 = String.valueOf( usrKey2 ); + Assert.assertEquals(strKey1, msg1); + Assert.assertEquals(strKey2, msg2); + hasReturnedMsgKey1.set("Result1-"+localCallCount+"-"+strKey1+"."+strKey2); + System.err.println("Callback: "+hasReturnedMsgKey1.get()); + localCallCount++; + } + }; + + // key 1 + 1 = ibdex 2 + final T2_Callback13UserKey1 key1a = T2_Callback13UserKey1.create(); + key1a.setKeyValue1(1); + final long key1b = 1; + final MessageCallback13Key expKey1 = new MessageCallback13Key(key1a, key1b); + bt2.MessageCallback13("a debug message - key2", callbackKey1, key1a, key1b); + + // + // Key 2 + // + final AtomicReference<String> hasReturnedMsgKey2 = new AtomicReference<>(null); + final T2_CallbackFunc13 callbackKey2 = new T2_CallbackFunc13() { + int localCallCount = 1; + + @Override + public void callback(final String msg1, final T2_Callback13UserType info, final String msg2, final T2_Callback13UserKey1 usrParamKey2, final long usrKey2) { + Assert.assertEquals(localCallCount, info.getANumber()); + final String strKey1 = String.valueOf( usrParamKey2.getKeyValue1() ); + final String strKey2 = String.valueOf( usrKey2 ); + Assert.assertEquals(strKey1, msg1); + Assert.assertEquals(strKey2, msg2); + hasReturnedMsgKey2.set("Result2-"+localCallCount+"-"+strKey1+"."+strKey2); + System.err.println("Callback: "+hasReturnedMsgKey2.get()); + localCallCount++; + } + }; + + // key 2 + 2 = ibdex 4 + final T2_Callback13UserKey1 key2a = T2_Callback13UserKey1.create(); + key2a.setKeyValue1(2); + final long key2b = 2; + final MessageCallback13Key expKey2 = new MessageCallback13Key(key2a, key2b); + bt2.MessageCallback13("a debug message - key2", callbackKey2, key2a, key2b); + + // Check keys + final Set<MessageCallback13Key> keys = bt2.getMessageCallback13Keys(); + Assert.assertNotNull(keys); + Assert.assertEquals(2, keys.size()); + { + System.err.println("XXX expKey1[key1a 0x"+Long.toHexString(key1a.getDirectBufferAddress())+", hash 0x"+Integer.toHexString(System.identityHashCode(key1a))+"]"); + System.err.println("XXX expKey1 hash 0x"+Integer.toHexString(expKey1.hashCode())); + + System.err.println("XXX expKey2[key1a 0x"+Long.toHexString(key2a.getDirectBufferAddress())+", hash 0x"+Integer.toHexString(System.identityHashCode(key2a))+"]"); + System.err.println("XXX expKey2 hash 0x"+Integer.toHexString(expKey2.hashCode())); + + final MessageCallback13Key[] keys0 = keys.toArray(new MessageCallback13Key[2]); + Assert.assertEquals(2, keys0.length); + final MessageCallback13Key hasKey1, hasKey2; + if( 1 == keys0[0].usrKey2 ) { + // keys0[0] -> hasKey1, keys0[1] -> hasKey2 + hasKey1 = keys0[0]; + hasKey2 = keys0[1]; + } else { + // keys0[0] -> hasKey2, keys0[1] -> hasKey1 + hasKey1 = keys0[1]; + hasKey2 = keys0[0]; + } + System.err.println("XXX hasKey1 hash 0x"+Integer.toHexString(hasKey1.hashCode())); + System.err.println("XXX hasKey2 hash 0x"+Integer.toHexString(hasKey2.hashCode())); + + Assert.assertEquals(key1a.getDirectBufferAddress(), hasKey1.usrParamKey1.getDirectBufferAddress()); + Assert.assertEquals(key1b, hasKey1.usrKey2); + Assert.assertEquals(expKey1, hasKey1); + Assert.assertEquals(expKey1.hashCode(), hasKey1.hashCode()); + final T2_CallbackFunc13 cb1 = bt2.getMessageCallback13(hasKey1); + Assert.assertNotNull(cb1); + final T2_Callback13UserKey1 up1 = bt2.getMessageCallback13UserParam(hasKey1); + Assert.assertNotNull(up1); + + Assert.assertEquals(key2a.getDirectBufferAddress(), hasKey2.usrParamKey1.getDirectBufferAddress()); + Assert.assertEquals(key2b, hasKey2.usrKey2); + Assert.assertEquals(expKey2, hasKey2); + Assert.assertEquals(expKey2.hashCode(), hasKey2.hashCode()); + final T2_CallbackFunc13 cb2 = bt2.getMessageCallback13(hasKey2); + Assert.assertNotNull(cb2); + final T2_Callback13UserKey1 up2 = bt2.getMessageCallback13UserParam(hasKey2); + Assert.assertNotNull(up2); + } + + // Send -> Key1 + int key1CallCount = 1; + final T2_Callback13UserType info1 = T2_Callback13UserType.create(); + hasReturnedMsgKey1.set(null); + { + final String expReturnedMsg = "Result1-"+key1CallCount+"-"+String.valueOf(key1a.getKeyValue1())+"."+String.valueOf(key1b); + info1.setANumber(key1CallCount); + bt2.InjectMessageCallback13(String.valueOf(key1a.getKeyValue1()), info1, String.valueOf(key1b), key1a, key1b); + Assert.assertEquals(expReturnedMsg, hasReturnedMsgKey1.get()); + key1CallCount++; + } + // Send -> Key2 + int key2CallCount = 1; + final T2_Callback13UserType info2 = T2_Callback13UserType.create(); + hasReturnedMsgKey2.set(null); + { + final String expReturnedMsg = "Result2-"+key2CallCount+"-"+String.valueOf(key2a.getKeyValue1())+"."+String.valueOf(key2b); + info2.setANumber(key2CallCount); + bt2.InjectMessageCallback13(String.valueOf(key2a.getKeyValue1()), info2, String.valueOf(key2b), key2a, key2b); + Assert.assertEquals(expReturnedMsg, hasReturnedMsgKey2.get()); + key2CallCount++; + } + + // Send -> Key1 + hasReturnedMsgKey1.set(null); + { + final String expReturnedMsg = "Result1-"+key1CallCount+"-"+String.valueOf(key1a.getKeyValue1())+"."+String.valueOf(key1b); + info1.setANumber(key1CallCount); + bt2.InjectMessageCallback13(String.valueOf(key1a.getKeyValue1()), info1, String.valueOf(key1b), key1a, key1b); + Assert.assertEquals(expReturnedMsg, hasReturnedMsgKey1.get()); + key1CallCount++; + } + // Send -> Key2 + hasReturnedMsgKey2.set(null); + { + final String expReturnedMsg = "Result2-"+key2CallCount+"-"+String.valueOf(key2a.getKeyValue1())+"."+String.valueOf(key2b); + info2.setANumber(key2CallCount); + bt2.InjectMessageCallback13(String.valueOf(key2a.getKeyValue1()), info2, String.valueOf(key2b), key2a, key2b); + Assert.assertEquals(expReturnedMsg, hasReturnedMsgKey2.get()); + key2CallCount++; + } + + // Send -> Key1 -> nil + bt2.MessageCallback13("turned off - key1", null, key1a, key1b); + hasReturnedMsgKey1.set(null); + { + final String expReturnedMsg = null; + info1.setANumber(key1CallCount); + bt2.InjectMessageCallback13(String.valueOf(key1a.getKeyValue1()), info1, String.valueOf(key1b), key1a, key1b); + Assert.assertEquals(expReturnedMsg, hasReturnedMsgKey1.get()); + } + // Send -> Key2 -> nil + bt2.MessageCallback13("turned off - key1", null, key2a, key2b); + hasReturnedMsgKey2.set(null); + { + final String expReturnedMsg = null; + info2.setANumber(key2CallCount); + bt2.InjectMessageCallback13(String.valueOf(key2a.getKeyValue1()), info2, String.valueOf(key2b), key2a, key2b); + Assert.assertEquals(expReturnedMsg, hasReturnedMsgKey2.get()); + } + } + static private String toHexString(final int v) { return "0x"+Integer.toHexString(v); } public static void main(final String args[]) throws IOException { diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c index 52b2124..d181592 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c @@ -358,3 +358,36 @@ void LogCallBack12bInject(const T2_Callback12LogMessage* message, int param0) { } } +// +// + +static const int MAX_C13_BUFFER = 10; + +static T2_CallbackFunc13 MessageCallback13_callback[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + +void MessageCallback13(const char* debugMsg, T2_CallbackFunc13 cbFunc, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */) { + int id = usrParamKey1->keyValue1 + usrKey2; + if( id < 0 || MAX_C13_BUFFER <= id ) { + fprintf(stderr, "Error: MessageCallback13: id not in range [0..%d), is %d\n", MAX_C13_BUFFER, id); + } else { + MessageCallback13_callback[id] = cbFunc; + fprintf(stderr, "XXX MessageCallback13 id %d -> func %p, user %p, debugMsg '%s'\n", id, cbFunc, usrParamKey1, debugMsg); + } + fflush(NULL); +} + +void InjectMessageCallback13(const char* msg1, const T2_Callback13UserType* info, const char* msg2, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */) { + int id = usrParamKey1->keyValue1 + usrKey2; + if( id < 0 || MAX_C13_BUFFER <= id ) { + fprintf(stderr, "Error: InjectMessageCallback13: id not in range [0..%d), is %d\n", MAX_C13_BUFFER, id); + fflush(NULL); + return; + } + if( NULL != MessageCallback13_callback[id] ) { + fprintf(stderr, "XXX InjectMessageCallback13: id %d, func %p, user %p, msg1 '%s', msg2 '%s', key1 %d, key2 %zd\n", + id, MessageCallback13_callback[id], usrParamKey1, msg1, msg2, usrParamKey1->keyValue1, usrKey2); + fflush(NULL); + (*MessageCallback13_callback[id])(msg1, info, msg2, usrParamKey1, usrKey2); + } +} + 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 e1fc193..44b6468 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg @@ -193,10 +193,28 @@ JavaCallbackDef SetLogCallBack12a -1 T2_CallbackFunc12a -1 # # End JavaCallback +# Begin JavaCallback +# # typedef void ( * T2_CallbackFunc12b)(int param0, const T2_Callback12LogMessage* usrParam1); # void SetLogCallBack12b(T2_CallbackFunc12b cbFunc); # void LogCallBack12bInject(const T2_Callback12LogMessage* message); JavaCallbackDef SetLogCallBack12b -1 T2_CallbackFunc12b -1 +# +# End JavaCallback + +# Begin JavaCallback +# +# typedef void ( * T2_CallbackFunc13)(const char* msg1, const T2_Callback13UserType* info, const char* msg2, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */); +# void MessageCallback13(const char* debugMsg, T2_CallbackFunc13 cbFunc, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */); +# void InjectMessageCallback13(const char* msg1, const T2_Callback13UserType* info, const char* msg2, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */); + +ArgumentIsString T2_CallbackFunc13 0 2 +ArgumentIsString InjectMessageCallback13 0 2 +ArgumentIsString MessageCallback13 0 +JavaCallbackDef MessageCallback13 2 T2_CallbackFunc13 3 +JavaCallbackKey MessageCallback13 2 3 T2_CallbackFunc13 3 4 +# +# End JavaCallback CustomCCode #include "test2.h" @@ -207,6 +225,8 @@ Import com.jogamp.gluegen.test.junit.generation.T2_ThreadAffinity Import com.jogamp.gluegen.test.junit.generation.T2_UserData Import com.jogamp.gluegen.test.junit.generation.T2_Callback11UserType Import com.jogamp.gluegen.test.junit.generation.T2_Callback12LogMessage +Import com.jogamp.gluegen.test.junit.generation.T2_Callback13UserType +Import com.jogamp.gluegen.test.junit.generation.T2_Callback13UserKey1 Import com.jogamp.gluegen.test.junit.generation.Test4JavaCallback.ALCcontext CustomJavaCode Bindingtest2Impl private static Bindingtest2ProcAddressTable _table = new Bindingtest2ProcAddressTable(); diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h index 235cc14..653fcc2 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h @@ -70,7 +70,7 @@ void InjectMessageCallback01(size_t id, const char* msg); // ALBUFFERCALLBACKTYPESOFT (similar to OpenAL's AL_SOFT_callback_buffer) // // typedef void ( * ALBUFFERCALLBACKTYPESOFT)(int buffer, void *userptr, void *sampledata, int numbytes); -typedef void ( * ALBUFFERCALLBACKTYPESOFT)(int buffer, void *userptr, int sampledata, int numbytes); +typedef void ( * ALBUFFERCALLBACKTYPESOFT)(int buffer /* key */, void *userptr, int sampledata, int numbytes); void alBufferCallback0(int buffer /* key */, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void *userptr); // void alBufferCallback0Inject(int buffer, void *sampledata, int numbytes); @@ -100,7 +100,7 @@ typedef struct { size_t id; } T2_Callback11UserType; -typedef void ( * T2_CallbackFunc11)(size_t id, const T2_Callback11UserType* usrParam, long val); +typedef void ( * T2_CallbackFunc11)(size_t id /* key */, const T2_Callback11UserType* usrParam, long val); void MessageCallback11a(size_t id /* key */, T2_CallbackFunc11 cbFunc, const T2_Callback11UserType* usrParam); void MessageCallback11aInject(size_t id, long val); @@ -138,3 +138,19 @@ typedef void ( * T2_CallbackFunc12b)(int param0, const T2_Callback12LogMessage* void SetLogCallBack12b(T2_CallbackFunc12b cbFunc); void LogCallBack12bInject(const T2_Callback12LogMessage* message, int param0); +// +// T2_CallbackFunc13 +// +typedef struct { + int aNumber; +} T2_Callback13UserType; + +typedef struct { + int keyValue1; +} T2_Callback13UserKey1; + +typedef void ( * T2_CallbackFunc13)(const char* msg1, const T2_Callback13UserType* info, const char* msg2, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */); + +void MessageCallback13(const char* debugMsg, T2_CallbackFunc13 cbFunc, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */); +void InjectMessageCallback13(const char* msg1, const T2_Callback13UserType* info, const char* msg2, const T2_Callback13UserKey1* usrParamKey1 /* key */, size_t usrKey2 /* key */); + |