Sfoglia il codice sorgente

wallet: split event streams into separate publishers to avoid waking sleeping tasks uncessarily

darkfi 2 anni fa
parent
commit
9565b6a390
3 ha cambiato i file con 48 aggiunte e 32 eliminazioni
  1. 6 10
      bin/darkwallet/src/app.rs
  2. 35 14
      bin/darkwallet/src/gfx2.rs
  3. 7 8
      bin/darkwallet/src/main.rs

+ 6 - 10
bin/darkwallet/src/app.rs

@@ -12,7 +12,7 @@ use crate::{
     error::{Error, Result},
     error::{Error, Result},
     expr::{Op, SExprMachine, SExprVal},
     expr::{Op, SExprMachine, SExprVal},
     gfx::Rectangle,
     gfx::Rectangle,
-    gfx2::{self, DrawCall, DrawInstruction, DrawMesh, GraphicsEvent, RenderApiPtr, Vertex},
+    gfx2::{self, DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, RenderApiPtr, Vertex},
     prop::{
     prop::{
         Property, PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr,
         Property, PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr,
         PropertySubType, PropertyType, PropertyUint32,
         PropertySubType, PropertyType, PropertyUint32,
@@ -103,7 +103,7 @@ pub struct App {
     sg: SceneGraphPtr2,
     sg: SceneGraphPtr2,
     ex: Arc<smol::Executor<'static>>,
     ex: Arc<smol::Executor<'static>>,
     render_api: RenderApiPtr,
     render_api: RenderApiPtr,
-    event_pub: PublisherPtr<GraphicsEvent>,
+    event_pub: GraphicsEventPublisherPtr,
 }
 }
 
 
 impl App {
 impl App {
@@ -111,7 +111,7 @@ impl App {
         sg: SceneGraphPtr2,
         sg: SceneGraphPtr2,
         ex: Arc<smol::Executor<'static>>,
         ex: Arc<smol::Executor<'static>>,
         render_api: RenderApiPtr,
         render_api: RenderApiPtr,
-        event_pub: PublisherPtr<GraphicsEvent>,
+        event_pub: GraphicsEventPublisherPtr,
     ) -> Arc<Self> {
     ) -> Arc<Self> {
         Arc::new(Self { sg, ex, render_api, event_pub })
         Arc::new(Self { sg, ex, render_api, event_pub })
     }
     }
@@ -467,7 +467,7 @@ impl Window {
         node_id: SceneNodeId,
         node_id: SceneNodeId,
         ex: Arc<smol::Executor<'static>>,
         ex: Arc<smol::Executor<'static>>,
         render_api: RenderApiPtr,
         render_api: RenderApiPtr,
-        event_pub: PublisherPtr<GraphicsEvent>,
+        event_pub: GraphicsEventPublisherPtr,
     ) -> Pimpl {
     ) -> Pimpl {
         debug!(target: "app", "Window::new()");
         debug!(target: "app", "Window::new()");
 
 
@@ -481,20 +481,16 @@ impl Window {
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
             // Start a task monitoring for window resize events
             // Start a task monitoring for window resize events
             // which updates screen_size
             // which updates screen_size
-            let ev_sub = event_pub.subscribe();
+            let ev_sub = event_pub.subscribe_resize();
             let screen_size_prop2 = screen_size_prop.clone();
             let screen_size_prop2 = screen_size_prop.clone();
             let me2 = me.clone();
             let me2 = me.clone();
             let sg2 = sg.clone();
             let sg2 = sg.clone();
             let resize_task = ex.spawn(async move {
             let resize_task = ex.spawn(async move {
                 loop {
                 loop {
-                    let Ok(ev) = ev_sub.receive().await else {
+                    let Ok((w, h)) = ev_sub.receive().await else {
                         debug!(target: "app", "Event relayer closed");
                         debug!(target: "app", "Event relayer closed");
                         break
                         break
                     };
                     };
-                    let (w, h) = match ev {
-                        GraphicsEvent::Resize((w, h)) => (w, h),
-                        _ => continue,
-                    };
 
 
                     debug!(target: "app", "Window resized ({w}, {h})");
                     debug!(target: "app", "Window resized ({w}, {h})");
                     // Now update the properties
                     // Now update the properties

+ 35 - 14
bin/darkwallet/src/gfx2.rs

@@ -24,7 +24,7 @@ use crate::{
     gfx::Rectangle,
     gfx::Rectangle,
     keysym::{KeyCodeAsStr, MouseButtonAsU8},
     keysym::{KeyCodeAsStr, MouseButtonAsU8},
     prop::{Property, PropertySubType, PropertyType},
     prop::{Property, PropertySubType, PropertyType},
-    pubsub::PublisherPtr,
+    pubsub::{Publisher, PublisherPtr, Subscription},
     res::{ResourceId, ResourceManager},
     res::{ResourceId, ResourceManager},
     scene::{
     scene::{
         MethodResponseFn, Pimpl, SceneGraph, SceneGraphPtr, SceneNode, SceneNodeId, SceneNodeInfo,
         MethodResponseFn, Pimpl, SceneGraph, SceneGraphPtr, SceneNode, SceneNodeId, SceneNodeInfo,
@@ -221,10 +221,34 @@ pub enum GraphicsMethod {
     ReplaceDrawCalls(Vec<(u64, DrawCall)>),
     ReplaceDrawCalls(Vec<(u64, DrawCall)>),
 }
 }
 
 
-#[derive(Debug, Clone)]
-pub enum GraphicsEvent {
-    KeyDown((KeyCode, KeyMods, bool)),
-    Resize((f32, f32)),
+pub type GraphicsEventPublisherPtr = Arc<GraphicsEventPublisher>;
+
+pub struct GraphicsEventPublisher {
+    key_down: PublisherPtr<(KeyCode, KeyMods, bool)>,
+    resize: PublisherPtr<(f32, f32)>,
+}
+
+impl GraphicsEventPublisher {
+    pub fn new() -> Arc<Self> {
+        Arc::new(Self {
+            key_down: Publisher::new(),
+            resize: Publisher::new(),
+        })
+    }
+
+    fn notify_key_down(&self, key: KeyCode, mods: KeyMods, repeat: bool) {
+        self.key_down.notify((key, mods, repeat));
+    }
+    fn notify_resize(&self, w: f32, h: f32) {
+        self.resize.notify((w, h));
+    }
+
+    pub fn subscribe_key_down(&self) -> Subscription<(KeyCode, KeyMods, bool)> {
+        self.key_down.clone().subscribe()
+    }
+    pub fn subscribe_resize(&self) -> Subscription<(f32, f32)> {
+        self.resize.clone().subscribe()
+    }
 }
 }
 
 
 struct Stage {
 struct Stage {
@@ -237,14 +261,14 @@ struct Stage {
     last_draw_time: Option<Instant>,
     last_draw_time: Option<Instant>,
 
 
     method_rep: mpsc::Receiver<GraphicsMethod>,
     method_rep: mpsc::Receiver<GraphicsMethod>,
-    event_pub: PublisherPtr<GraphicsEvent>,
+    event_pub: GraphicsEventPublisherPtr,
 }
 }
 
 
 impl Stage {
 impl Stage {
     pub fn new(
     pub fn new(
         async_runtime: AsyncRuntime,
         async_runtime: AsyncRuntime,
         method_rep: mpsc::Receiver<GraphicsMethod>,
         method_rep: mpsc::Receiver<GraphicsMethod>,
-        event_pub: PublisherPtr<GraphicsEvent>,
+        event_pub: GraphicsEventPublisherPtr,
     ) -> Self {
     ) -> Self {
         let mut ctx: Box<dyn RenderingBackend> = window::new_rendering_backend();
         let mut ctx: Box<dyn RenderingBackend> = window::new_rendering_backend();
 
 
@@ -253,8 +277,7 @@ impl Stage {
         #[cfg(target_os = "android")]
         #[cfg(target_os = "android")]
         {
         {
             let (screen_width, screen_height) = window::screen_size();
             let (screen_width, screen_height) = window::screen_size();
-            let event = GraphicsEvent::Resize((screen_width, screen_height));
-            event_pub.notify(event);
+            event_pub.notify_resize(screen_width, screen_height);
         }
         }
 
 
         let white_texture = ctx.new_texture_from_rgba8(1, 1, &[255, 255, 255, 255]);
         let white_texture = ctx.new_texture_from_rgba8(1, 1, &[255, 255, 255, 255]);
@@ -422,12 +445,10 @@ impl EventHandler for Stage {
     }
     }
 
 
     fn key_down_event(&mut self, keycode: KeyCode, mods: KeyMods, repeat: bool) {
     fn key_down_event(&mut self, keycode: KeyCode, mods: KeyMods, repeat: bool) {
-        let event = GraphicsEvent::KeyDown((keycode, mods, repeat));
-        self.event_pub.notify(event);
+        self.event_pub.notify_key_down(keycode, mods, repeat);
     }
     }
     fn resize_event(&mut self, width: f32, height: f32) {
     fn resize_event(&mut self, width: f32, height: f32) {
-        let event = GraphicsEvent::Resize((width, height));
-        self.event_pub.notify(event);
+        self.event_pub.notify_resize(width, height);
     }
     }
 
 
     fn quit_requested_event(&mut self) {
     fn quit_requested_event(&mut self) {
@@ -438,7 +459,7 @@ impl EventHandler for Stage {
 pub fn run_gui(
 pub fn run_gui(
     async_runtime: AsyncRuntime,
     async_runtime: AsyncRuntime,
     method_rep: mpsc::Receiver<GraphicsMethod>,
     method_rep: mpsc::Receiver<GraphicsMethod>,
-    event_pub: PublisherPtr<GraphicsEvent>,
+    event_pub: GraphicsEventPublisherPtr,
 ) {
 ) {
     let mut conf = miniquad::conf::Conf {
     let mut conf = miniquad::conf::Conf {
         high_dpi: true,
         high_dpi: true,

+ 7 - 8
bin/darkwallet/src/main.rs

@@ -79,7 +79,7 @@ fn main() {
     // The UI actually needs to be running for this to reply back.
     // The UI actually needs to be running for this to reply back.
     // Otherwise calls will just hang.
     // Otherwise calls will just hang.
     let render_api = gfx2::RenderApi::new(method_req);
     let render_api = gfx2::RenderApi::new(method_req);
-    let event_pub = pubsub::Publisher::new();
+    let event_pub = gfx2::GraphicsEventPublisher::new();
 
 
     let async_runtime = app::AsyncRuntime::new(ex.clone());
     let async_runtime = app::AsyncRuntime::new(ex.clone());
     async_runtime.start();
     async_runtime.start();
@@ -90,21 +90,20 @@ fn main() {
     //app.clone().start();
     //app.clone().start();
 
 
     // Nice to see which events exist
     // Nice to see which events exist
-    let ev_sub = event_pub.clone().subscribe();
+    let ev_sub = event_pub.subscribe_key_down();
     let ev_relay_task = ex.spawn(async move {
     let ev_relay_task = ex.spawn(async move {
         debug!(target: "main", "event relayer started");
         debug!(target: "main", "event relayer started");
         loop {
         loop {
-            let Ok(ev) = ev_sub.receive().await else {
+            let Ok((key, mods, repeat)) = ev_sub.receive().await else {
                 debug!(target: "main", "Event relayer closed");
                 debug!(target: "main", "Event relayer closed");
                 break
                 break
             };
             };
-            // Ignore keys which get stuck
-            match &ev {
-                gfx2::GraphicsEvent::KeyDown((miniquad::KeyCode::LeftShift, _, _)) |
-                gfx2::GraphicsEvent::KeyDown((miniquad::KeyCode::LeftSuper, _, _)) => continue,
+            // Ignore keys which get stuck repeating when switching windows
+            match key {
+                miniquad::KeyCode::LeftShift | miniquad::KeyCode::LeftSuper => continue,
                 _ => {}
                 _ => {}
             }
             }
-            debug!(target: "main", "event: {:?}", ev);
+            debug!(target: "main", "key_down event: {:?} {:?} {}", key, mods, repeat);
         }
         }
     });
     });
     async_runtime.push_task(ev_relay_task);
     async_runtime.push_task(ev_relay_task);