From 7452eb2e65105cbfd7f8fe911a0e063533307b6e Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Fri, 18 Jul 2025 20:53:15 +0200 Subject: [PATCH] add invokeMainThread --- .../java/de/unixwork/ui/ThreadCallback.java | 6 +++ .../src/main/java/de/unixwork/ui/Toolkit.java | 46 +++++++++++++++++++ .../java/de/unixwork/ui/ToolkitFuncs.java | 6 +++ 3 files changed, 58 insertions(+) create mode 100644 ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java diff --git a/ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java b/ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java new file mode 100644 index 0000000..d8c7512 --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java @@ -0,0 +1,6 @@ +package de.unixwork.ui; + +@FunctionalInterface +public interface ThreadCallback { + public void callback(); +} 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 6f7fee7..90d2a5d 100644 --- a/ui-java/src/main/java/de/unixwork/ui/Toolkit.java +++ b/ui-java/src/main/java/de/unixwork/ui/Toolkit.java @@ -40,6 +40,10 @@ public class Toolkit { protected MemorySegment getValue; protected MemorySegment sourceListGetValue; + protected MemorySegment threadFuncPtr; + + private HashMap threadCallbacks = new HashMap<>(); + private Toolkit(String appName) { // load shared library System.loadLibrary("uitk"); @@ -175,6 +179,23 @@ public class Toolkit { } catch (IllegalAccessException e) { throw new RuntimeException(e); } + + // threadfunc wrapper + try { + MethodHandle threadFuncCallback = MethodHandles.lookup().findStatic( + Thread.class, + "threadFunc", + MethodType.methodType(int.class, MemorySegment.class)); + FunctionDescriptor threadFuncDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); + threadFuncPtr = linker.upcallStub( + threadFuncCallback, + threadFuncDescriptor, + staticArena); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } } public static Toolkit getInstance() { @@ -470,4 +491,29 @@ public class Toolkit { Context listCtx = Toolkit.getInstance().getContext(listCtxPtr); return listCtx.getList((int)listIndex); } + + private static int threadFunc(MemorySegment ptr) { + int key = (int)ptr.address(); + Toolkit toolkit = Toolkit.getInstance(); + ThreadCallback callback = toolkit.threadCallbacks.get(key); + if(callback != null) { + callback.callback(); + } + return 0; + } + + private synchronized ThreadCallback getThreadCallback(int key) { + return threadCallbacks.remove(key); + } + + public synchronized void invokeMainThread(ThreadCallback callback) { + int key = threadCallbacks.size(); + threadCallbacks.put(key, callback); + MemorySegment ckey = MemorySegment.ofAddress((long)key); + try { + ToolkitFuncs.getInstance().call_mainthread.invoke(threadFuncPtr, ckey); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } } 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 cab31f3..4d6655e 100644 --- a/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java +++ b/ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java @@ -60,6 +60,8 @@ public class ToolkitFuncs { public MethodHandle text_set; public MethodHandle text_get; + public MethodHandle call_mainthread; + // some libc stuff public MethodHandle malloc; public MethodHandle free; @@ -128,6 +130,8 @@ public class ToolkitFuncs { MemorySegment text_set_addr = lib.find("ui_text_set").orElseThrow(); MemorySegment text_get_addr = lib.find("ui_text_get").orElseThrow(); + MemorySegment call_mainthread_addr = lib.find("ui_call_mainthread").orElseThrow(); + MemorySegment malloc_addr = lib.find("malloc").orElseThrow(); MemorySegment free_addr = lib.find("free").orElseThrow(); @@ -186,6 +190,8 @@ public class ToolkitFuncs { text_set = linker.downcallHandle(text_set_addr, sigv_mm); text_get = linker.downcallHandle(text_get_addr, sigm_m); + call_mainthread = linker.downcallHandle(call_mainthread_addr, sigv_mm); + malloc = linker.downcallHandle(malloc_addr, sigm_l); free = linker.downcallHandle(free_addr, sigv_m); } -- 2.47.3