]> uap-core.de Git - rssreader.git/commitdiff
handle global obj create/destroy callback to manage UiObject instances
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Mon, 16 Jun 2025 19:50:06 +0000 (21:50 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Mon, 16 Jun 2025 19:50:06 +0000 (21:50 +0200)
ui-java/src/main/java/de/unixwork/ui/Toolkit.java
ui-java/src/main/java/de/unixwork/ui/UiObject.java

index 4e205dd1f244a4ef0c9e4d97ebfdf40f8bbd237b..b515588de0bd84d631293d664329ab740a57f20c 100644 (file)
@@ -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) {
index 36364f68a87553b11b1dd3bc34f58537321424fc..2ad08fd504b2d26ce00cf85cd959bd53d281d517 100644 (file)
@@ -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