From: Olaf Wintermann Date: Fri, 27 Jun 2025 18:54:22 +0000 (+0200) Subject: fix obj/ctx registration X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=cfcd318c61bc354ff630b8b96380be9479479157;p=rssreader.git fix obj/ctx registration --- 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 6c1e13b..60e3dea 100644 --- a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java +++ b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java @@ -15,6 +15,11 @@ public class Toolkit { private HashMap documents = new HashMap<>(); private HashMap 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) { diff --git a/ui-java/src/main/java/de/unixwork/ui/UiObjectFuncs.java b/ui-java/src/main/java/de/unixwork/ui/UiObjectFuncs.java index 1de1827..9a2749f 100644 --- a/ui-java/src/main/java/de/unixwork/ui/UiObjectFuncs.java +++ b/ui-java/src/main/java/de/unixwork/ui/UiObjectFuncs.java @@ -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); }