From: Olaf Wintermann Date: Sat, 14 Jun 2025 20:31:31 +0000 (+0200) Subject: implement Context and UiString X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=3c6f2d021a1dcf8e874a6b14c89134b02cd68134;p=rssreader.git implement Context and UiString --- diff --git a/ui-java/src/main/java/de/unixwork/ui/Context.java b/ui-java/src/main/java/de/unixwork/ui/Context.java new file mode 100644 index 0000000..17d6f1c --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/Context.java @@ -0,0 +1,26 @@ +package de.unixwork.ui; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + +public abstract class Context { + private MemorySegment ptr; + + private Arena arena = Arena.ofShared(); + + protected void setCtx(MemorySegment ptr) { + this.ptr = ptr; + } + + public MemorySegment getCtx() { + return ptr; + } + + public UiString string() { + return string(null); + } + + public UiString string(String name) { + return new UiString(this, name); + } +} diff --git a/ui-java/src/main/java/de/unixwork/ui/Document.java b/ui-java/src/main/java/de/unixwork/ui/Document.java new file mode 100644 index 0000000..e2477c7 --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/Document.java @@ -0,0 +1,4 @@ +package de.unixwork.ui; + +public class Document { +} diff --git a/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java b/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java index 160bfcf..f286c11 100644 --- a/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java +++ b/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java @@ -6,6 +6,8 @@ import java.lang.invoke.MethodHandle; public class ToolkitFuncs { static ToolkitFuncs instance; + public MethodHandle object_get_context; + public MethodHandle event_get_obj; public MethodHandle event_get_document; public MethodHandle event_get_windowdata; @@ -13,10 +15,30 @@ public class ToolkitFuncs { public MethodHandle event_get_int; public MethodHandle event_get_set; + public MethodHandle string_new; + public MethodHandle int_new; + public MethodHandle double_new; + public MethodHandle text_new; + public MethodHandle range_new; + public MethodHandle generic_new; + + public MethodHandle string_set; + public MethodHandle string_get; + public MethodHandle int_set; + public MethodHandle int_get; + public MethodHandle double_set; + public MethodHandle double_get; + public MethodHandle text_set; + public MethodHandle text_get; + private ToolkitFuncs(Linker linker, SymbolLookup lib) { // void* func(void*) FunctionDescriptor sigm_m = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS); FunctionDescriptor sigi_m = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); + FunctionDescriptor sigm_mm = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS); + FunctionDescriptor sigv_mm = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS); + + MemorySegment object_get_context_addr = lib.find("ui_object_get_context").orElseThrow(); MemorySegment event_get_obj_addr = lib.find("ui_event_get_obj").orElseThrow(); MemorySegment event_get_document_addr = lib.find("ui_event_get_document").orElseThrow(); @@ -25,12 +47,46 @@ public class ToolkitFuncs { MemorySegment event_get_int_addr = lib.find("ui_event_get_int").orElseThrow(); MemorySegment event_get_set_addr = lib.find("ui_event_get_set").orElseThrow(); + MemorySegment string_new_addr = lib.find("ui_string_new").orElseThrow(); + MemorySegment int_new_addr = lib.find("ui_int_new").orElseThrow(); + MemorySegment double_new_addr = lib.find("ui_double_new").orElseThrow(); + MemorySegment text_new_addr = lib.find("ui_text_new").orElseThrow(); + MemorySegment range_new_addr = lib.find("ui_range_new").orElseThrow(); + MemorySegment generic_new_addr = lib.find("ui_generic_new").orElseThrow(); + + MemorySegment string_set_addr = lib.find("ui_string_set").orElseThrow(); + MemorySegment string_get_addr = lib.find("ui_string_get").orElseThrow(); + MemorySegment int_set_addr = lib.find("ui_int_set").orElseThrow(); + MemorySegment int_get_addr = lib.find("ui_int_get").orElseThrow(); + MemorySegment double_set_addr = lib.find("ui_double_set").orElseThrow(); + MemorySegment double_get_addr = lib.find("ui_double_get").orElseThrow(); + MemorySegment text_set_addr = lib.find("ui_text_set").orElseThrow(); + MemorySegment text_get_addr = lib.find("ui_text_get").orElseThrow(); + + object_get_context = linker.downcallHandle(object_get_context_addr, sigm_m); + event_get_obj = linker.downcallHandle(event_get_obj_addr, sigm_m); event_get_document = linker.downcallHandle(event_get_document_addr, sigm_m); event_get_windowdata = linker.downcallHandle(event_get_windowdata_addr, sigm_m); event_get_eventdata = linker.downcallHandle(event_get_eventdata_addr, sigm_m); event_get_int = linker.downcallHandle(event_get_int_addr, sigi_m); event_get_set = linker.downcallHandle(event_get_set_addr, sigi_m); + + string_new = linker.downcallHandle(string_new_addr, sigm_mm); + int_new = linker.downcallHandle(int_new_addr, sigm_mm); + double_new = linker.downcallHandle(double_new_addr, sigm_mm); + text_new = linker.downcallHandle(text_new_addr, sigm_mm); + range_new = linker.downcallHandle(range_new_addr, sigm_mm); + generic_new = linker.downcallHandle(generic_new_addr, sigm_mm); + + string_set = linker.downcallHandle(string_set_addr, sigv_mm); + string_get = linker.downcallHandle(string_get_addr, sigm_m); + int_set = linker.downcallHandle(int_set_addr, FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_LONG)); + int_get = linker.downcallHandle(int_get_addr, FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)); + double_set = linker.downcallHandle(double_set_addr, FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_DOUBLE)); + double_get = linker.downcallHandle(double_get_addr, FunctionDescriptor.of(ValueLayout.JAVA_DOUBLE, ValueLayout.ADDRESS)); + text_set = linker.downcallHandle(text_set_addr, sigv_mm); + text_get = linker.downcallHandle(text_get_addr, sigm_m); } static ToolkitFuncs getInstance() { diff --git a/ui-java/src/main/java/de/unixwork/ui/UiContext.java b/ui-java/src/main/java/de/unixwork/ui/UiContext.java deleted file mode 100644 index d6bde18..0000000 --- a/ui-java/src/main/java/de/unixwork/ui/UiContext.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.unixwork.ui; - -import java.lang.foreign.MemorySegment; - -public class UiContext { - public MemorySegment ctxptr; - - - -} 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 503ab46..36364f6 100644 --- a/ui-java/src/main/java/de/unixwork/ui/UiObject.java +++ b/ui-java/src/main/java/de/unixwork/ui/UiObject.java @@ -7,7 +7,7 @@ import java.lang.invoke.MethodHandle; import java.util.ArrayList; import java.util.function.Function; -public class UiObject { +public class UiObject extends Context { MemorySegment ptr; private ArrayList eventHandlers = new ArrayList<>(); @@ -18,10 +18,20 @@ public class UiObject { public UiObject(MemorySegment ptr) { this.ptr = ptr; + + ToolkitFuncs ui = ToolkitFuncs.getInstance(); + // 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 + setCtx((MemorySegment) ui.object_get_context.invoke(ptr)); + } catch (Throwable e) { + throw new RuntimeException(e); + } } public static UiObject createWindow(String title) { diff --git a/ui-java/src/main/java/de/unixwork/ui/UiString.java b/ui-java/src/main/java/de/unixwork/ui/UiString.java new file mode 100644 index 0000000..3fd5d69 --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/UiString.java @@ -0,0 +1,46 @@ +package de.unixwork.ui; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + +public class UiString { + private MemorySegment valuePtr; + + protected UiString(Context ctx, String name) { + ToolkitFuncs ui = ToolkitFuncs.getInstance(); + + MemorySegment nameCStr = MemorySegment.NULL; + try (Arena arena = Arena.ofConfined()) { + if(name != null) { + nameCStr = arena.allocateFrom(name); + } + + valuePtr = (MemorySegment) ui.string_new.invoke(ctx.getCtx(), nameCStr); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + public String toString() { + ToolkitFuncs ui = ToolkitFuncs.getInstance(); + try { + MemorySegment cstr = (MemorySegment) ui.string_get.invoke(valuePtr); + if (cstr != null && cstr.address() != 0) { + return cstr.getString(0); + } + } catch (Throwable e) { + throw new RuntimeException(e); + } + return null; + } + + public void setString(String string) { + ToolkitFuncs ui = ToolkitFuncs.getInstance(); + try (Arena arena = Arena.ofConfined()) { + MemorySegment cstr = arena.allocateFrom(string); + ui.string_set.invoke(valuePtr, cstr); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } +}