]> uap-core.de Git - rssreader.git/commitdiff
add invokeMainThread
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 18 Jul 2025 18:53:15 +0000 (20:53 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 18 Jul 2025 18:53:15 +0000 (20:53 +0200)
ui-java/src/main/java/de/unixwork/ui/ThreadCallback.java [new file with mode: 0644]
ui-java/src/main/java/de/unixwork/ui/Toolkit.java
ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.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 (file)
index 0000000..d8c7512
--- /dev/null
@@ -0,0 +1,6 @@
+package de.unixwork.ui;
+
+@FunctionalInterface
+public interface ThreadCallback {
+    public void callback();
+}
index 6f7fee714a70af375190d6e00994fc4e1ec28430..90d2a5d31f831f99dd2e1505e5d9d932a9a42156 100644 (file)
@@ -40,6 +40,10 @@ public class Toolkit {
     protected MemorySegment getValue;
     protected MemorySegment sourceListGetValue;
 
+    protected MemorySegment threadFuncPtr;
+
+    private HashMap<Integer, ThreadCallback> 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);
+        }
+    }
 }
index cab31f3caea16d62a604431d3e1c5f1fc9a141be..4d6655e8c3a63c01fece39f514021987cce8b5f1 100644 (file)
@@ -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);
     }