From: Olaf Wintermann Date: Mon, 16 Jun 2025 19:50:06 +0000 (+0200) Subject: handle global obj create/destroy callback to manage UiObject instances X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=31f053120518be2533bac0fe5657e75add3cabc6;p=rssreader.git handle global obj create/destroy callback to manage UiObject instances --- diff --git a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java index 4e205dd..b515588 100644 --- a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java +++ b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java @@ -98,6 +98,22 @@ public class Toolkit { } } + private static void onObjectCreate(MemorySegment obj, MemorySegment unused) { + // Is this object already registered? + // normal toplevel objects created by the java bindings should be already + // in the toplevelObjects map, but it is possible that other sources create objects + Toolkit toolkit = Toolkit.getInstance(); + if(toolkit.toplevelObjects.containsKey(obj.address())) { + return; + } + new UiObject(obj); // this will register the object + } + + private static void onObjectDestroy(MemorySegment obj, MemorySegment unused) { + Toolkit toolkit = Toolkit.getInstance(); + toolkit.toplevelObjects.remove(obj.address()); + } + public static void runApplication(Application app) { Toolkit toolkit = Toolkit.getInstance(); toolkit.app = app; @@ -107,6 +123,8 @@ public class Toolkit { MethodHandle onstartup = toolkit.linker.downcallHandle(toolkit.lib.find("ui_onstartup").orElseThrow(), handlerSig); MethodHandle onshutdown = toolkit.linker.downcallHandle(toolkit.lib.find("ui_onexit").orElseThrow(), handlerSig); MethodHandle onopen = toolkit.linker.downcallHandle(toolkit.lib.find("ui_onopen").orElseThrow(), handlerSig); + MethodHandle regobjcreate = toolkit.linker.downcallHandle(toolkit.lib.find("ui_register_object_creation_callback").orElseThrow(), handlerSig); + MethodHandle regobjdestroy = toolkit.linker.downcallHandle(toolkit.lib.find("ui_register_object_destruction_callback").orElseThrow(), handlerSig); // get java wrapper method handles MethodHandle onstartupCallback = null; @@ -151,6 +169,27 @@ public class Toolkit { onshutdown.invoke(onShutdownFunc, MemorySegment.NULL); onopen.invoke(onOpenFunc, MemorySegment.NULL); + // register object callbacks + MethodHandle onObjectCreateCallback = MethodHandles.lookup().findStatic( + Toolkit.class, + "onObjectCreate", + MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class)); + MethodHandle onObjectDestroyCallback = MethodHandles.lookup().findStatic( + Toolkit.class, + "onObjectDestroy", + MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class)); + MemorySegment onObjectCreateCallbackFunc = toolkit.linker.upcallStub( + onObjectCreateCallback, + callbackDescriptor, + arena); + MemorySegment onObjectDestroyCallbackFunc = toolkit.linker.upcallStub( + onObjectDestroyCallback, + callbackDescriptor, + arena); + + regobjcreate.invoke(onObjectCreateCallbackFunc, MemorySegment.NULL); + regobjdestroy.invoke(onObjectDestroyCallbackFunc, MemorySegment.NULL); + // run ui_main(), which invokes the application callback functions Toolkit.mainloop(); } catch (Throwable e) { diff --git a/ui-java/src/main/java/de/unixwork/ui/UiObject.java b/ui-java/src/main/java/de/unixwork/ui/UiObject.java index 36364f6..2ad08fd 100644 --- a/ui-java/src/main/java/de/unixwork/ui/UiObject.java +++ b/ui-java/src/main/java/de/unixwork/ui/UiObject.java @@ -24,7 +24,6 @@ public class UiObject extends Context { // TODO: maybe the C toolkit code should also handle toplevel object creation and call a callback // because there is some dynamic UiObject creation Toolkit.getInstance().registerToplevelObject(this); - // TODO: handle UiObject destroy event try { // must be called for Context methods to work