]> uap-core.de Git - rssreader.git/commitdiff
fix obj/ctx registration
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 27 Jun 2025 18:54:22 +0000 (20:54 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 27 Jun 2025 18:54:22 +0000 (20:54 +0200)
ui-java/src/main/java/de/unixwork/ui/Toolkit.java
ui-java/src/main/java/de/unixwork/ui/UiObjectFuncs.java

index 6c1e13b350bb6a9c10595a6e785118a0b1633051..60e3deafa795ff4eeb1adf81f552d366e3e155de 100644 (file)
@@ -15,6 +15,11 @@ public class Toolkit {
     private HashMap<Long, Document> documents = new HashMap<>();
     private HashMap<Long, Context> contexts = new HashMap<>(); // TODO: maybe we can replace the UiObject and Document maps with just this context map
 
+    // Is the global obj creation callback enabled?
+    // Before creating an object manually from java, isObjRegEnabled must be disabled
+    // and the object/context must be registered manually
+    private boolean isObjRegEnabled = true;
+
     // used for all strings and other memory, that is expected to be const
     // and the UI toolkit does not create copies
     private final Arena staticArena = Arena.ofShared();
@@ -56,6 +61,14 @@ public class Toolkit {
         UiObjectFuncs.init(linker, lib);
     }
 
+    public void setIsObjRegEnabled(boolean value) {
+        isObjRegEnabled = value;
+    }
+
+    public boolean isObjRegEnabled() {
+        return isObjRegEnabled;
+    }
+
     private void initFunctions() {
         FunctionDescriptor sigv_v = FunctionDescriptor.ofVoid(); // void func(void)
         FunctionDescriptor sigm_m = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS); // void* func(void*)
@@ -184,6 +197,9 @@ public class Toolkit {
         // 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.isObjRegEnabled() == false) {
+            return;
+        }
         if(toolkit.toplevelObjects.containsKey(obj.address())) {
             return;
         }
@@ -314,7 +330,9 @@ public class Toolkit {
     }
 
     public void registerContext(Context ctx) {
-        contexts.put(ctx.getCtx().address(), ctx);
+        long address = ctx.getCtx().address();
+        contexts.putIfAbsent(address, ctx); // currently, there are subobjects, that have the same context as a toplevel object
+        // TODO: remove this notice when subobjects are removed from toolkit
     }
 
     public Context getContext(long address) {
index 1de1827ce475a55d8463684c9faa5b8ac9de5cd1..9a2749f3ff45549836c3eda2f0b8a608911a9b24 100644 (file)
@@ -29,12 +29,20 @@ class UiObjectFuncs {
 
     UiObject window(String title) {
         MemorySegment obj = null;
+        Toolkit toolkit = Toolkit.getInstance();
+        // Automatic object registration MUST be disabled!
+        // usually the toolkit calls a global obj creation callback, which is used to register
+        // unknown UiObject instances in the java runtime. However, when we manually create an UiObject
+        // we don't want that
+        toolkit.setIsObjRegEnabled(false);
         try (Arena arena = Arena.ofConfined()) {
             MemorySegment cstr = arena.allocateFrom(title);
             obj = (MemorySegment) ui_window.invoke(cstr, MemorySegment.NULL);
         } catch (Throwable e) {
+            toolkit.setIsObjRegEnabled(true);
             throw new RuntimeException(e);
         }
+        toolkit.setIsObjRegEnabled(true);
 
         return new UiObject(obj);
     }