Partially on the way to receiving an incoming message

This is getting really ugly, but let's run with it for now.
This commit is contained in:
2020-05-17 03:01:21 +01:00
parent 49362a6606
commit b814a9aab0
5 changed files with 77 additions and 33 deletions

View File

@@ -9,6 +9,7 @@ mod type_text;
pub use type_text::*; pub use type_text::*;
use crate::telepathy; use crate::telepathy;
use std::sync::Arc;
// FIXME: I'm assuming that all channels will be of type text and 1-1 for now. // FIXME: I'm assuming that all channels will be of type text and 1-1 for now.
#[derive(Debug)] #[derive(Debug)]
@@ -24,29 +25,24 @@ pub fn channel_interfaces() -> Vec<String> {
type Result<T> = std::result::Result<T, dbus::tree::MethodErr>; type Result<T> = std::result::Result<T, dbus::tree::MethodErr>;
impl Channel { impl Channel {
fn build_tree(self) -> dbus::tree::Tree<dbus::tree::MTFn, ()> { pub fn build_object_path(
let c_rc = std::rc::Rc::new(self); channel: Arc<Channel>,
) -> dbus::tree::ObjectPath<dbus::tree::MTFn, ()> {
let f = dbus::tree::Factory::new_fn::<()>(); let f = dbus::tree::Factory::new_fn::<()>();
let mut tree = f.tree(());
let c_rc1 = c_rc.clone(); let c_rc1 = channel.clone();
let chan_iface = telepathy::channel_server(&f, (), move |_| c_rc1.clone()); let chan_iface = telepathy::channel_server(&f, (), move |_| c_rc1.clone());
let c_rc2 = c_rc.clone(); let c_rc2 = channel.clone();
let messages_iface = let messages_iface =
telepathy::channel_interface_messages_server(&f, (), move |_| c_rc2.clone()); telepathy::channel_interface_messages_server(&f, (), move |_| c_rc2.clone());
let type_text_iface = telepathy::channel_type_text_server(&f, (), move |_| c_rc.clone()); let type_text_iface = telepathy::channel_type_text_server(&f, (), move |_| channel.clone());
tree = tree.add( f.object_path("", ())
f.object_path("", ()) .introspectable()
.introspectable() .add(chan_iface)
.add(chan_iface) .add(messages_iface)
.add(messages_iface) .add(type_text_iface)
.add(type_text_iface),
);
tree = tree.add(f.object_path("/", ()).introspectable());
tree
} }
} }

View File

@@ -4,7 +4,7 @@ use dbus::tree::MethodErr;
use super::{Channel, Result}; use super::{Channel, Result};
impl AsRef<dyn telepathy::Channel + 'static> for std::rc::Rc<Channel> { impl AsRef<dyn telepathy::Channel + 'static> for std::sync::Arc<Channel> {
fn as_ref(&self) -> &(dyn telepathy::Channel + 'static) { fn as_ref(&self) -> &(dyn telepathy::Channel + 'static) {
&**self &**self
} }

View File

@@ -6,7 +6,7 @@ use std::collections::HashMap;
use super::{Channel, Result}; use super::{Channel, Result};
impl AsRef<dyn telepathy::ChannelInterfaceMessages + 'static> for std::rc::Rc<Channel> { impl AsRef<dyn telepathy::ChannelInterfaceMessages + 'static> for std::sync::Arc<Channel> {
fn as_ref(&self) -> &(dyn telepathy::ChannelInterfaceMessages + 'static) { fn as_ref(&self) -> &(dyn telepathy::ChannelInterfaceMessages + 'static) {
&**self &**self
} }

View File

@@ -3,7 +3,7 @@ use dbus::tree::MethodErr;
use super::{Channel, Result}; use super::{Channel, Result};
impl AsRef<dyn telepathy::ChannelTypeText + 'static> for std::rc::Rc<Channel> { impl AsRef<dyn telepathy::ChannelTypeText + 'static> for std::sync::Arc<Channel> {
fn as_ref(&self) -> &(dyn telepathy::ChannelTypeText + 'static) { fn as_ref(&self) -> &(dyn telepathy::ChannelTypeText + 'static) {
&**self &**self
} }

View File

@@ -24,7 +24,7 @@ use crate::padfoot::{Channel, VarArg};
use crate::telepathy; use crate::telepathy;
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection}; use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
use dbus::channel::Sender; use dbus::channel::{MatchingReceiver, Sender};
use dbus::tree::MethodErr; use dbus::tree::MethodErr;
use dc::config::Config; use dc::config::Config;
@@ -43,9 +43,12 @@ pub const CONN_OBJECT_PATH: &str = "/org/freedesktop/Telepathy/Connection/padfoo
// outside of method return values requires one of these to be added to actq // outside of method return values requires one of these to be added to actq
#[derive(Debug)] #[derive(Debug)]
enum DbusAction { enum DbusAction {
Signal(dbus::Message), // Generic signal to send Signal(dbus::Message), // Generic signal to send
NewChannel(Channel), // Add this channel NewChannel(Channel), // Add this channel
CloseChannel(dbus::Path<'static>), // Close this channel CloseChannel(dbus::Path<'static>), // Close this channel
IncomingMessage(dc::chat::ChatId, dc::message::MsgId), // Look at this \o/
} }
#[derive(Debug)] #[derive(Debug)]
@@ -55,7 +58,7 @@ pub struct Connection {
actq: Arc<Mutex<VecDeque<DbusAction>>>, actq: Arc<Mutex<VecDeque<DbusAction>>>,
// Channels we own // Channels we own
channels: Arc<RwLock<HashMap<dbus::Path<'static>, Channel>>>, channels: Arc<RwLock<HashMap<dbus::Path<'static>, Arc<Channel>>>>,
// Owned by the CM. Remove ourselves from this when done // Owned by the CM. Remove ourselves from this when done
conns: Arc<Mutex<HashSet<String>>>, conns: Arc<Mutex<HashSet<String>>>,
@@ -131,7 +134,7 @@ impl Connection {
let id = settings.id(); let id = settings.id();
// Use this if we need to send messages in response to DC events: // Use this if we need to send messages in response to DC events:
// let acqt2 = actq.clone(); let queue = actq.clone();
let f = move |_c: &Context, e: Event| { let f = move |_c: &Context, e: Event| {
match e { match e {
Event::Info(msg) => println!("Connection<{}>: INFO: {}", id, msg), Event::Info(msg) => println!("Connection<{}>: INFO: {}", id, msg),
@@ -145,15 +148,33 @@ impl Connection {
Event::ImapConnected(msg) | Event::SmtpConnected(msg) => { Event::ImapConnected(msg) | Event::SmtpConnected(msg) => {
println!("Connection<{}>: Network: {}", id, msg); println!("Connection<{}>: Network: {}", id, msg);
} }
Event::MsgsChanged { chat_id, msg_id } => {
println!(
"Connection<{}>: Messages changed for {}: {}",
id, chat_id, msg_id
);
let q = queue.clone();
q.lock()
.unwrap()
.push_back(DbusAction::IncomingMessage(chat_id, msg_id));
}
Event::IncomingMsg { chat_id, msg_id } => {
println!(
"Connection<{}>: Incoming message for {}: {}",
id, chat_id, msg_id
);
let q = queue.clone();
q.lock()
.unwrap()
.push_back(DbusAction::IncomingMessage(chat_id, msg_id));
}
/* Unhandled messages: /* Unhandled messages:
SmtpMessageSent(String), SmtpMessageSent(String),
ImapMessageDeleted(String), ImapMessageDeleted(String),
ImapMessageMoved(String),
ImapFolderEmptied(String), ImapFolderEmptied(String),
NewBlobFile(String), NewBlobFile(String),
DeletedBlobFile(String), DeletedBlobFile(String),
MsgsChanged
IncomingMsg
MsgDelivered MsgDelivered
MsgFailed MsgFailed
MsgRead MsgRead
@@ -165,6 +186,7 @@ impl Connection {
SecurejoinInviterProgress SecurejoinInviterProgress
SecurejoinJoinerProgress SecurejoinJoinerProgress
*/ */
Event::ImapMessageMoved(_) | Event::ImapMessageDeleted(_) => {}
_ => println!("Connection<{}>: unhandled event received: {:?}", id, e), _ => println!("Connection<{}>: unhandled event received: {:?}", id, e),
}; };
}; };
@@ -194,7 +216,9 @@ impl Connection {
conns, conns,
settings, settings,
actq, actq,
channels: Arc::new(RwLock::new(HashMap::<dbus::Path<'static>, Channel>::new())), channels: Arc::new(RwLock::new(
HashMap::<dbus::Path<'static>, Arc<Channel>>::new(),
)),
ctx: Arc::new(RwLock::new(ctx)), ctx: Arc::new(RwLock::new(ctx)),
state: Arc::new(RwLock::new(ConnState::Initial)), state: Arc::new(RwLock::new(ConnState::Initial)),
}) })
@@ -225,7 +249,19 @@ impl Connection {
} }
}; };
tree.start_receive(&c); let tc = tree.clone();
c.start_receive(
dbus::message::MatchRule::new_method_call(),
Box::new(move |msg, c| {
let tree = tc.lock().unwrap();
if let Some(replies) = tree.handle(&msg) {
for r in replies {
let _ = c.send(r);
}
}
true
}),
);
match c.request_name(bus.clone(), false, false, true) { match c.request_name(bus.clone(), false, false, true) {
Ok(RequestNameReply::Exists) => { Ok(RequestNameReply::Exists) => {
@@ -267,20 +303,32 @@ impl Connection {
} }
} }
DbusAction::NewChannel(channel) => { DbusAction::NewChannel(channel) => {
let path = channel.path.clone();
let rc_channel = Arc::new(channel);
Arc::clone(&chans) Arc::clone(&chans)
.write() .write()
.unwrap() .unwrap()
.insert(channel.path.clone(), channel); .insert(path.clone(), rc_channel.clone());
// TODO: add channel to tree let t2 = tree.clone();
let op = Channel::build_object_path(rc_channel);
t2.lock().unwrap().insert(op);
// TODO: emit signals // TODO: emit signals
} }
DbusAction::CloseChannel(path) => { DbusAction::CloseChannel(path) => {
let _chan = Arc::clone(&chans).write().unwrap().remove(&path); let _chan = Arc::clone(&chans).write().unwrap().remove(&path);
let t2 = tree.clone();
// TODO: add channel to tree t2.lock().unwrap().remove(&path);
// TODO: emit signals // TODO: emit signals
} }
DbusAction::IncomingMessage(_chat_id, _msg_id) => {
// TODO: check if we have a channel for the chat
// If not, create one
// If we do, send the message down it
}
} }
} }
} }
@@ -303,7 +351,7 @@ impl Connection {
self.settings.path() self.settings.path()
} }
fn build_tree(self) -> dbus::tree::Tree<dbus::tree::MTFn, ()> { fn build_tree(self) -> Arc<Mutex<dbus::tree::Tree<dbus::tree::MTFn, ()>>> {
let path = self.path(); let path = self.path();
let c_rc = std::rc::Rc::new(self); let c_rc = std::rc::Rc::new(self);
let f = dbus::tree::Factory::new_fn::<()>(); let f = dbus::tree::Factory::new_fn::<()>();
@@ -343,6 +391,6 @@ impl Connection {
); );
tree = tree.add(f.object_path("/", ()).introspectable()); tree = tree.add(f.object_path("/", ()).introspectable());
tree Arc::new(Mutex::new(tree))
} }
} }