#![allow( clippy::type_complexity, clippy::too_many_arguments, clippy::large_enum_variant )] use mpstthree::binary::struct_trait::end::End; use mpstthree::binary::struct_trait::session::Session; use mpstthree::binary_atmp::struct_trait::{recv::RecvTimed, send::SendTimed}; use mpstthree::generate_atmp; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use std::collections::HashMap; use std::error::Error; use std::time::Instant; // Create the new MeshedChannels for three participants and the close and fork functions generate_atmp!(MeshedChannels, Satellite, Sensor, Server); // Labels struct Stop {} struct GetData {} struct Data {} // Types // Satellite type OfferFromServertoSatellite = RecvTimed; type BinaryDataFromSensortoSatellite = SendTimed< GetData, 'a', 0, true, 10, true, ' ', RecvTimed, >; type BinaryDataFromServertoSatellite = RecvTimed< GetData, 'a', 0, true, 10, true, ' ', SendTimed, >; type BinaryStopFromSensortoSatellite = SendTimed; type BinaryStopFromServertoSatellite = RecvTimed; enum BranchingFromServertoSatellite { Data( MeshedChannels< BinaryDataFromSensortoSatellite, BinaryDataFromServertoSatellite, RoleServer>>>>, NameSatellite, >, ), Stop( MeshedChannels< BinaryStopFromSensortoSatellite, BinaryStopFromServertoSatellite, RoleServer>, NameSatellite, >, ), } // Sensor type OfferFromServertoSensor = RecvTimed; type BinaryDataFromSatellitetoSensor = ::Dual; type BinaryStopFromSatellitetoSensor = ::Dual; enum BranchingFromServertoSensor { Data( MeshedChannels< BinaryDataFromSatellitetoSensor, OfferFromServertoSensor, RoleSatellite>>, NameSensor, >, ), Stop(MeshedChannels, NameSensor>), } // Server type ChooseFromServertoSatellite = ::Dual; type ChooseFromServertoSensor = ::Dual; type BinaryDataFromSatellitetoServer = ::Dual; type BinaryStopFromSatellitetoServer = ::Dual; // Endpoints // Satellite type EndpointSatellite0 = MeshedChannels, NameSatellite>; // Sensor type EndpointSensor0 = MeshedChannels, NameSensor>; // Server type EndpointServer0 = MeshedChannels< ChooseFromServertoSatellite, ChooseFromServertoSensor, RoleBroadcast, NameServer, >; type EndpointServer1Data = MeshedChannels< BinaryDataFromSatellitetoServer, ChooseFromServertoSensor, RoleSatellite>, NameServer, >; type EndpointServer1Stop = MeshedChannels, NameServer>; // Functions // Satellite fn endpoint_satellite( s: EndpointSatellite0, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); recurs_satellite(s, all_clocks) } fn recurs_satellite( s: EndpointSatellite0, all_clocks: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s, all_clocks, { BranchingFromServertoSatellite::Stop(s) => { let (stop, s) = s.recv(all_clocks)?; let s = s.send(stop, all_clocks)?; s.close() }, BranchingFromServertoSatellite::Data(s) => { // Forward get_data signal let (get_data, s) = s.recv(all_clocks)?; let s = s.send(get_data, all_clocks)?; // Forward the data let (data, s) = s.recv(all_clocks)?; let s = s.send(data, all_clocks)?; recurs_satellite(s, all_clocks) }, }) } // Sensor fn endpoint_sensor( s: EndpointSensor0, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); recurs_sensor(s, all_clocks) } fn recurs_sensor( s: EndpointSensor0, all_clocks: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s, all_clocks, { BranchingFromServertoSensor::Stop(s) => { let (_stop, s) = s.recv(all_clocks)?; s.close() }, BranchingFromServertoSensor::Data(s) => { // Get get_data signal let (_get_data, s) = s.recv(all_clocks)?; // Send the data let s = s.send(Data {}, all_clocks)?; recurs_sensor(s, all_clocks) }, }) } // Server fn endpoint_server( s: EndpointServer0, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); recurs_server(s, 100, all_clocks) } fn recurs_server( s: EndpointServer0, loops: i32, all_clocks: &mut HashMap, ) -> Result<(), Box> { match loops { 0 => { let s: EndpointServer1Stop = choose_mpst_server_to_all!( s, all_clocks, BranchingFromServertoSatellite::Stop, BranchingFromServertoSensor::Stop, ); let s = s.send(Stop {}, all_clocks)?; s.close() } i => { let s: EndpointServer1Data = choose_mpst_server_to_all!( s, all_clocks, BranchingFromServertoSatellite::Data, BranchingFromServertoSensor::Data, ); let s = s.send(GetData {}, all_clocks)?; let (_data, s) = s.recv(all_clocks)?; recurs_server(s, i - 1, all_clocks) } } } fn main() { let (thread_satellite, thread_sensor, thread_server) = fork_mpst(endpoint_satellite, endpoint_sensor, endpoint_server); thread_satellite.join().unwrap(); thread_sensor.join().unwrap(); thread_server.join().unwrap(); }