feat(rmc): start implementing new rmc protocol abstraction

This commit is contained in:
DJMrTV 2025-02-19 23:30:15 +01:00
commit 6f02339464
6 changed files with 283 additions and 77 deletions

View file

@ -1,17 +1,109 @@
use std::sync::Arc;
use macros::method_id;
use std::collections::HashMap;
use std::ops::Add;
use std::sync::{Arc, Condvar};
use std::time::Duration;
use async_trait::async_trait;
use tokio::sync::Mutex;
use crate::prudp::socket::ExternalConnection;
use chrono::TimeDelta;
use macros::{rmc_proto, rmc_struct};
use paste::paste;
use tokio::sync::{Mutex, Notify};
use tokio::time::{sleep_until, Instant};
use crate::prudp::socket::{ExternalConnection, SendingConnection};
use crate::rmc::structures::connection_data::ConnectionData;
pub trait RmcCallable{
fn rmc_call(protocol_id: u8, method_id: u8, rest: Vec<u8>);
}
struct RmcConnection(SendingConnection, RmcResponseReceiver);
struct LocalRmcObjectWrapper<T: RmcCallable>(T);
impl<T: RmcCallable> LocalRmcObjectWrapper<T>{
pub fn new(object: T, conn: ExternalConnection) -> Self{
unimplemented!()
struct RmcResponseReceiver(Notify, Mutex<HashMap<(u16, u32), Vec<u8>>>);
impl RmcResponseReceiver{
// returns none if timed out
pub async fn get_response_data(&self, proto: u16, method: u32) -> Option<Vec<u8>>{
let mut end_wait_time = Instant::now();
end_wait_time += Duration::from_secs(5);
let sleep_fut = sleep_until(end_wait_time);
tokio::pin!(sleep_fut);
loop {
let mut locked = self.1.lock().await;
if let Some(v) = locked.remove(&(proto, method)){
return Some(v);
}
let notif_fut = self.0.notified();
drop(locked);
tokio::select! {
_ = &mut sleep_fut => {
return None;
}
_ = notif_fut => {
continue;
}
}
}
}
}
pub trait RmcCallable{
async fn rmc_call(&self, protocol_id: u16, method_id: u32, rest: Vec<u8>);
}
macro_rules! define_rmc_proto {
(proto $name:ident{
$($protocol:path),*
}) => {
paste!{
trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>])* {
async fn rmc_call(&self, protocol_id: u16, method_id: u32, rest: Vec<u8>){
match protocol_id{
$(
[<Raw $protocol Info>]::PROTOCOL_ID => <Self as [<Raw $protocol>]>::rmc_call_proto(self, method_id, rest).await,
)*
v => log::error!("invalid protocol called on rmc object {}", v)
}
}
}
}
};
}
trait RawNotif{
async fn rmc_call_proto(&self, method_id: u32, rest: Vec<u8>){
}
}
struct RawNotifInfo;
impl RawNotifInfo{
const PROTOCOL_ID: u16 = 10;
}
#[rmc_proto(1)]
pub trait Another{
#[method_id(1)]
async fn test();
}
define_rmc_proto!{
proto TestProto{
Notif,
Another
}
}
#[rmc_struct(TestProto)]
struct TestProtoImplementor{
}
impl RawNotif for TestProtoImplementor{
}