1use whence::WhenceExt;
5
6use crate::{Server, ServerContext, SimpleMemoryMessage};
7
8pub trait MoveHandler<M: Move>
10where
11 Self: Server,
12{
13 const LEAK_MESSAGE: bool;
14 fn handle(&mut self, msg: M, sender: xous::PID, context: &mut ServerContext<Self>);
15}
16
17pub trait Move: crate::MessageId + From<SimpleMemoryMessage> + Into<SimpleMemoryMessage> {}
19
20pub fn handle_move<M: Move, S: MoveHandler<M>>(
22 handler: &mut S,
23 raw: xous::MessageEnvelope,
24 context: &mut ServerContext<S>,
25) {
26 let sender = raw.sender.pid().unwrap();
27 let msg = if S::LEAK_MESSAGE {
28 let message = raw.take_message();
29 let xous::Message::Move(mem) = message else {
30 log::warn!("invalid message: {message:?}");
31 return;
32 };
33 M::from(SimpleMemoryMessage::from(&mem))
34 } else {
35 let xous::Message::Move(mem) = &raw.body else {
36 log::warn!("invalid message: {raw:?}");
37 return;
38 };
39 M::from(SimpleMemoryMessage::from(mem))
40 };
41
42 handler.handle(msg, sender, context);
43}
44
45pub fn send_move<M: Move>(cid: xous::CID, msg: M) { try_send_move(cid, msg).unwrap(); }
47
48pub fn try_send_move<M: Move>(cid: xous::CID, msg: M) -> whence::Result<(), xous::Error> {
50 let msg: SimpleMemoryMessage = msg.into();
51 xous::send_message(
52 cid,
53 xous::Message::Move(xous::MemoryMessage {
54 id: M::ID,
55 buf: msg.buf,
56 offset: xous::MemoryAddress::new(msg.arg1),
57 valid: xous::MemoryAddress::new(msg.arg2),
58 }),
59 )
60 .whence()?;
61 Ok(())
62}
63
64pub fn send_move_nowait<M>(cid: xous::CID, msg: M) -> whence::Result<(), xous::Error>
67where
68 M: Move,
69{
70 let msg: SimpleMemoryMessage = msg.into();
71 xous::try_send_message(
72 cid,
73 xous::Message::Move(xous::MemoryMessage {
74 id: M::ID,
75 buf: msg.buf,
76 offset: xous::MemoryAddress::new(msg.arg1),
77 valid: xous::MemoryAddress::new(msg.arg2),
78 }),
79 )
80 .whence()?;
81 Ok(())
82}