Просмотр исходного кода

wallet: connect the tubez with LocalEventGraph. now we recv msgs from the backend.

darkfi 1 год назад
Родитель
Сommit
29ba9e43a8

+ 2 - 5
bin/darkwallet/src/app/node.rs

@@ -21,7 +21,7 @@ use crate::{
     expr::Op,
     gfx::{GraphicsEventPublisherPtr, RenderApiPtr, Vertex},
     prop::{Property, PropertyBool, PropertyStr, PropertySubType, PropertyType, Role},
-    scene::{CallArgType, MethodResponseFn, SceneNode, SceneNodeType, Slot},
+    scene::{CallArgType, SceneNode, SceneNodeType, Slot},
     text::TextShaperPtr,
     ExecutorPtr,
 };
@@ -258,7 +258,6 @@ pub fn create_chatview(name: &str) -> SceneNode {
     prop.set_defaults_f32(vec![1000.]).unwrap();
     node.add_property(prop).unwrap();
 
-    /*
     node.add_method(
         "insert_line",
         vec![
@@ -267,11 +266,9 @@ pub fn create_chatview(name: &str) -> SceneNode {
             ("nick", "Nickname", CallArgType::Str),
             ("text", "Text", CallArgType::Str),
         ],
-        vec![],
-        Box::new(method),
+        None,
     )
     .unwrap();
-    */
 
     node
 }

+ 2 - 4
bin/darkwallet/src/darkirc2.rs

@@ -109,18 +109,16 @@ pub async fn receive_msgs(sg_root: SceneNodePtr, ex: ExecutorPtr) -> Result<()>
 
         debug!(target: "darkirc", "privmsg: {privmsg:?}");
 
-        if privmsg.channel != "random" {
+        if privmsg.channel != "#random" {
             continue
         }
 
-        let response_fn = Box::new(|_| {});
-
         let mut arg_data = vec![];
         ev.timestamp.encode(&mut arg_data).unwrap();
         ev.id().as_bytes().encode(&mut arg_data).unwrap();
         privmsg.nick.encode(&mut arg_data).unwrap();
         privmsg.msg.encode(&mut arg_data).unwrap();
 
-        chatview_node.call_method("insert_line", arg_data, response_fn).unwrap();
+        chatview_node.call_method("insert_line", arg_data).await.unwrap();
     }
 }

+ 58 - 20
bin/darkwallet/src/scene.rs

@@ -31,6 +31,7 @@ use std::{
 use crate::{
     error::{Error, Result},
     prop::{Property, PropertyPtr, Role},
+    pubsub::{Publisher, PublisherPtr, Subscription},
     ui,
 };
 
@@ -271,8 +272,7 @@ impl SceneNode {
         &mut self,
         name: S,
         args: Vec<(S, S, CallArgType)>,
-        result: Vec<(S, S, CallArgType)>,
-        method_fn: MethodRequestFn,
+        result: Option<Vec<(S, S, CallArgType)>>,
     ) -> Result<()> {
         let name = name.into();
         if self.has_method(&name) {
@@ -282,11 +282,16 @@ impl SceneNode {
             .into_iter()
             .map(|(n, d, t)| CallArg { name: n.into(), desc: d.into(), typ: t })
             .collect();
-        let result = result
-            .into_iter()
-            .map(|(n, d, t)| CallArg { name: n.into(), desc: d.into(), typ: t })
-            .collect();
-        self.methods.push(Method { name: name.into(), args, result, method_fn });
+        let result = match result {
+            Some(result) => Some(
+                result
+                    .into_iter()
+                    .map(|(n, d, t)| CallArg { name: n.into(), desc: d.into(), typ: t })
+                    .collect(),
+            ),
+            None => None,
+        };
+        self.methods.push(Method::new(name.into(), args, result));
         Ok(())
     }
 
@@ -298,15 +303,15 @@ impl SceneNode {
         self.methods.iter().find(|method| method.name == name)
     }
 
-    pub fn call_method(
-        &self,
-        name: &str,
-        arg_data: Vec<u8>,
-        response_fn: MethodResponseFn,
-    ) -> Result<()> {
+    pub async fn call_method(&self, name: &str, arg_data: CallData) -> Result<Option<CallData>> {
         let method = self.get_method(name).ok_or(Error::MethodNotFound)?;
-        (method.method_fn)(arg_data, response_fn);
-        Ok(())
+        Ok(method.call(arg_data).await)
+    }
+
+    pub fn subscribe_method_call(&self, name: &str) -> Result<MethodCallSub> {
+        let method = self.get_method(name).ok_or(Error::MethodNotFound)?;
+        let method_sub = method.pubsub.clone().subscribe();
+        Ok(method_sub)
     }
 }
 
@@ -332,11 +337,13 @@ pub struct CallArg {
     pub typ: CallArgType,
 }
 
+pub type CallData = Vec<u8>;
+
 pub type SlotId = u32;
 
 pub struct Slot {
     pub name: String,
-    pub notify: Sender<Vec<u8>>,
+    pub notify: Sender<CallData>,
 }
 
 pub struct Signal {
@@ -349,14 +356,45 @@ pub struct Signal {
     freed: Vec<SlotId>,
 }
 
-type MethodRequestFn = Box<dyn Fn(Vec<u8>, MethodResponseFn) + Send + Sync>;
-pub type MethodResponseFn = Box<dyn Fn(Result<Vec<u8>>) + Send + Sync>;
+#[derive(Clone, Debug)]
+pub struct MethodCall {
+    pub data: CallData,
+    pub send_res: Option<Sender<CallData>>,
+}
+
+impl MethodCall {
+    fn new(data: CallData, send_res: Option<Sender<CallData>>) -> Self {
+        Self { data, send_res }
+    }
+}
+
+pub type MethodCallSub = Subscription<MethodCall>;
 
 pub struct Method {
     pub name: String,
     pub args: Vec<CallArg>,
-    pub result: Vec<CallArg>,
-    method_fn: MethodRequestFn,
+    pub result: Option<Vec<CallArg>>,
+    pub pubsub: PublisherPtr<MethodCall>,
+}
+
+impl Method {
+    fn new(name: String, args: Vec<CallArg>, result: Option<Vec<CallArg>>) -> Self {
+        Self { name, args, result, pubsub: Publisher::new() }
+    }
+
+    async fn call(&self, data: CallData) -> Option<CallData> {
+        match &self.result {
+            Some(_) => {
+                let (send_res, recv_res) = async_channel::bounded(1);
+                self.pubsub.notify(MethodCall::new(data, Some(send_res)));
+                Some(recv_res.recv().await.unwrap())
+            }
+            None => {
+                self.pubsub.notify(MethodCall::new(data, None));
+                None
+            }
+        }
+    }
 }
 
 pub enum Pimpl {

+ 12 - 14
bin/darkwallet/src/ui/chatview/mod.rs

@@ -49,7 +49,7 @@ use crate::{
         Role,
     },
     pubsub::Subscription,
-    scene::{Pimpl, SceneNodeWeak},
+    scene::{MethodCallSub, Pimpl, SceneNodeWeak},
     text::{self, Glyph, GlyphPositionIter, TextShaperPtr},
     util::{enumerate, is_whitespace},
     ExecutorPtr,
@@ -215,13 +215,11 @@ impl ChatView {
         let node_id = node_ref.id;
 
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
-            /*
+            let method_sub = node_ref.subscribe_method_call("insert_line").unwrap();
             let me2 = me.clone();
-            let insert_line_method_task =
-                ex.spawn(
-                    async move { while Self::process_insert_line_method(&me2, &recvr).await {} },
-                );
-            */
+            let insert_line_method_task = ex.spawn(async move {
+                while Self::process_insert_line_method(&me2, &method_sub).await {}
+            });
 
             let me2 = me.clone();
             let motion_cv = Arc::new(CondVar::new());
@@ -266,7 +264,7 @@ impl ChatView {
             //on_modify.when_change(rect.clone(), redraw);
             //on_modify.when_change(debug.prop(), redraw);
 
-            let mut tasks = vec![/*insert_line_method_task,*/ motion_task, bgload_task];
+            let mut tasks = vec![insert_line_method_task, motion_task, bgload_task];
             tasks.append(&mut on_modify.tasks);
 
             Self {
@@ -324,15 +322,15 @@ impl ChatView {
         Pimpl::ChatView(self_)
     }
 
-    async fn process_insert_line_method(
-        me: &Weak<Self>,
-        recvr: &async_channel::Receiver<Vec<u8>>,
-    ) -> bool {
-        let Ok(data) = recvr.recv().await else {
+    async fn process_insert_line_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
+        let Ok(method_call) = sub.receive().await else {
             debug!(target: "ui::chatview", "Event relayer closed");
             return false
         };
 
+        debug!(target: "ui::chatview", "method called: insert_line({method_call:?})");
+        assert!(method_call.send_res.is_none());
+
         fn decode_data(data: &[u8]) -> std::io::Result<(Timestamp, MessageId, String, String)> {
             let mut cur = Cursor::new(&data);
             let timestamp = Timestamp::decode(&mut cur)?;
@@ -342,7 +340,7 @@ impl ChatView {
             Ok((timestamp, message_id, nick, text))
         }
 
-        let Ok((timestamp, message_id, nick, text)) = decode_data(&data) else {
+        let Ok((timestamp, message_id, nick, text)) = decode_data(&method_call.data) else {
             error!(target: "ui::chatview", "insert_line() method invalid arg data");
             return true
         };