]> uap-core.de Git - rssreader.git/commitdiff
reduce EventWrapper allocations
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Tue, 5 Aug 2025 19:45:26 +0000 (21:45 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Tue, 5 Aug 2025 19:45:26 +0000 (21:45 +0200)
ui-java/src/main/java/de/unixwork/ui/EventWrapper.java
ui-java/src/main/java/de/unixwork/ui/Toolkit.java
ui-java/src/main/java/de/unixwork/ui/UiObjectFuncs.java

index b018454328e0e3f471f9e35403322abdddac7028..e6310bacd92d04de46e283a9cb4c254eeb72d0d8 100644 (file)
@@ -20,41 +20,22 @@ public class EventWrapper {
         // EventHandler object
 
         Arena objArena = obj.getArena(); // very important to use the obj arena
-        initCallback(objArena, "eventHandler");
+        callback = Toolkit.getInstance().eventHandler;
 
         long index = obj.addEventHandler(handler);
         // use index as callback userdata, like casting it to intptr_t/void*
         userdata = MemorySegment.ofAddress(index);
     }
 
-    public EventWrapper(EventHandler handler) {
+    public EventWrapper(EventHandler handler, boolean oneshot) {
         Toolkit toolkit = Toolkit.getInstance();
-        initCallback(toolkit.getStaticArena(), "globalEventHandler");
+        callback = oneshot ? toolkit.oneshotEventHandler : toolkit.globalEventHandler;
         long index = toolkit.addEventHandler(handler);
         userdata = MemorySegment.ofAddress(index);
     }
 
-    private void initCallback(Arena arena, String methodName) {
-        Toolkit toolkit = Toolkit.getInstance();
-        // void callback(UiEvent *event, void *userdata)
-        FunctionDescriptor handlerSig = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS);
-
-        MethodHandle callbackMethod = null;
-        try {
-            callbackMethod = MethodHandles.lookup().findStatic(
-                    EventWrapper.class,
-                    methodName,
-                    MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class));
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException(e);
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-
-        callback = toolkit.getLinker().upcallStub(
-                callbackMethod,
-                handlerSig,
-                arena);
+    public EventWrapper(EventHandler handler) {
+        this(handler, false);
     }
 
     public MemorySegment getCallback() {
@@ -86,4 +67,8 @@ public class EventWrapper {
             handler.callback(e);
         } // else: error?
     }
+
+    public static void oneshotEventHandler(MemorySegment event, MemorySegment userdata) {
+
+    }
 }
index b2c7f9fbcfb272fb56f7126a50dc9f4db512aeaf..21c53427c29a2dbaef3864c39d7d54165e58e93d 100644 (file)
@@ -31,6 +31,7 @@ public class Toolkit {
     private MethodHandle mainFunc;
 
     private ArrayList<EventHandler> eventHandlers = new ArrayList<>();
+    private HashMap<Long, EventHandler> onshotEventHandlers = new HashMap<>();
 
     protected MemorySegment listFirst;
     protected MemorySegment listNext;
@@ -42,6 +43,10 @@ public class Toolkit {
 
     protected MemorySegment threadFuncPtr;
 
+    protected MemorySegment eventHandler;
+    protected MemorySegment globalEventHandler;
+    protected MemorySegment oneshotEventHandler;
+
     private HashMap<Integer, ThreadCallback> threadCallbacks = new HashMap<>();
 
     private Toolkit(String appName) {
@@ -196,6 +201,45 @@ public class Toolkit {
         } catch (IllegalAccessException e) {
             throw new RuntimeException(e);
         }
+
+        // ui_callback wrapper
+        // void callback(UiEvent *event, void *userdata)
+        FunctionDescriptor handlerSig = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+
+        MethodHandle objCallbackMethod = null;
+        MethodHandle globalCallbackMethod = null;
+        MethodHandle oneshotCallbackMethod = null;
+        try {
+            objCallbackMethod = MethodHandles.lookup().findStatic(
+                    EventWrapper.class,
+                    "eventHandler",
+                    MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class));
+            globalCallbackMethod = MethodHandles.lookup().findStatic(
+                    EventWrapper.class,
+                    "globalEventHandler",
+                    MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class));
+            oneshotCallbackMethod = MethodHandles.lookup().findStatic(
+                    EventWrapper.class,
+                    "oneshotEventHandler",
+                    MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class));
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+
+        eventHandler = linker.upcallStub(
+                objCallbackMethod,
+                handlerSig,
+                staticArena);
+        globalEventHandler = linker.upcallStub(
+                globalCallbackMethod,
+                handlerSig,
+                staticArena);
+        oneshotEventHandler = linker.upcallStub(
+                oneshotCallbackMethod,
+                handlerSig,
+                staticArena);
     }
 
     public static Toolkit getInstance() {
index efe702c80af01705bd5dc316da329dca8605a3d8..220a61d6a4517a47113b17165f9cda130c781c80 100644 (file)
@@ -12,6 +12,8 @@ class UiObjectFuncs {
     public MethodHandle ui_simple_window;
     public MethodHandle ui_dialog_window_create;
     public MethodHandle ui_dialog_create;
+    public MethodHandle ui_openfiledialog;
+    public MethodHandle ui_savefiledialog;
 
 
     private UiObjectFuncs(Linker linker, SymbolLookup lib) {
@@ -21,6 +23,8 @@ class UiObjectFuncs {
         FunctionDescriptor sigv_m = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
         // void func(void*, void*)
         FunctionDescriptor sigv_mm = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+        FunctionDescriptor sigv_mimm = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+        FunctionDescriptor sigv_mmmm = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
 
         MemorySegment ui_show_addr = lib.find("ui_show").orElseThrow();
         MemorySegment ui_window_addr = lib.find("ui_window").orElseThrow();
@@ -28,6 +32,8 @@ class UiObjectFuncs {
         MemorySegment ui_simple_window_addr = lib.find("ui_simple_window").orElseThrow();
         MemorySegment ui_dialog_window_create_addr = lib.find("ui_dialog_window_create").orElseThrow();
         MemorySegment ui_dialog_create_addr = lib.find("ui_dialog_create").orElseThrow();
+        MemorySegment ui_openfiledialog_addr = lib.find("ui_openfiledialog").orElseThrow();
+        MemorySegment ui_savefiledialog_addr = lib.find("ui_savefiledialog").orElseThrow();
 
         ui_show = linker.downcallHandle(ui_show_addr, sigv_m);
         ui_window = linker.downcallHandle(ui_window_addr, sigm_mm);
@@ -35,6 +41,8 @@ class UiObjectFuncs {
         ui_simple_window = linker.downcallHandle(ui_simple_window_addr, sigm_mm);
         ui_dialog_window_create = linker.downcallHandle(ui_dialog_window_create_addr, sigm_mm);
         ui_dialog_create = linker.downcallHandle(ui_dialog_create_addr, sigv_mm);
+        ui_openfiledialog = linker.downcallHandle(ui_openfiledialog_addr, sigv_mimm);
+        ui_savefiledialog = linker.downcallHandle(ui_savefiledialog_addr, sigv_mmmm);
     }
 
     // must be called by the Toolkit constructor
@@ -97,4 +105,12 @@ class UiObjectFuncs {
             throw new RuntimeException(e);
         }
     }
+
+    public void openFileDialog(UiObject obj, int mode, EventHandler callback) {
+        EventWrapper ew = new EventWrapper(callback);
+    }
+
+    public void saveFileDialog(UiObject obj, String name, EventHandler callback) {
+
+    }
 }