rapid feedback

This commit is contained in:
catvayor 2024-06-02 16:14:44 +02:00
parent e289b8850b
commit 5728936d4d
4 changed files with 72 additions and 31 deletions

View file

@ -165,34 +165,46 @@ type TrackingEventQueue = Arc<RwLock<HashMap<String, RwLock<VecDeque<QueuedEvent
struct TrackedInfo { struct TrackedInfo {
name: String, name: String,
pos: (f32, f32), pos: (f32, f32),
me: bool,
color: u8, color: u8,
} }
#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct AdminTrackedInfo {
name: String,
pos: (f32, f32),
color: u8,
}
impl From<AdminTrackedInfo> for TrackedInfo {
fn from(admin_info: AdminTrackedInfo) -> TrackedInfo {
TrackedInfo {
name: admin_info.name,
pos: admin_info.pos,
color: admin_info.color,
}
}
}
fn base_view(team: &Tracked) -> TrackedInfo { fn base_view(team: &Tracked) -> TrackedInfo {
TrackedInfo { TrackedInfo {
name: team.name.clone(), name: team.name.clone(),
pos: team.pos, pos: team.pos,
me: false,
color: team.state.color(), color: team.state.color(),
} }
} }
fn admin_view(team: &Tracked) -> TrackedInfo { fn admin_view(team: &Tracked) -> AdminTrackedInfo {
TrackedInfo { AdminTrackedInfo {
name: team.name.clone(), name: team.name.clone(),
pos: team.pos, pos: team.pos,
me: false,
color: team.state.admin_color(), color: team.state.admin_color(),
} }
} }
fn apparent_info(watcher: &Tracked, team: &Tracked) -> Option<TrackedInfo> { fn apparent_info(watcher: &Tracked, team: &Tracked) -> Option<TrackedInfo> {
if watcher.id == team.id { if watcher.id == team.id {
Some(TrackedInfo { None
me: true,
..admin_view(team)
})
} else if let Conscrit { } else if let Conscrit {
captured, mallette, .. captured, mallette, ..
} = watcher.state } = watcher.state
@ -221,7 +233,7 @@ fn apparent_info(watcher: &Tracked, team: &Tracked) -> Option<TrackedInfo> {
} }
} }
} else { } else {
Some(admin_view(team)) Some(admin_view(team).into())
} }
} }
@ -264,16 +276,19 @@ fn evts_to_send(id: &str, evt_queue: &TrackingEventQueue) -> Vec<Event> {
#[get("/track/<id>/events")] #[get("/track/<id>/events")]
fn tracked_events<'a>( fn tracked_events<'a>(
id: &'a str, id: &'a str,
tracking: &State<Tracking>,
evt_queue: &'a State<TrackingEventQueue>, evt_queue: &'a State<TrackingEventQueue>,
mut shutdown: Shutdown, mut shutdown: Shutdown,
) -> Option<EventStream![Event + 'a]> { ) -> Option<EventStream![Event + 'a]> {
if evt_queue.read().unwrap().contains_key(&id.to_string()) { if evt_queue.read().unwrap().contains_key(&id.to_string()) {
state_update(&tracking.read().unwrap().get(&id.to_string()).unwrap().read().unwrap(), &evt_queue);
Some(EventStream! { Some(EventStream! {
let mut interval = time::interval(Duration::from_millis(100)); let mut interval = time::interval(Duration::from_millis(100));
loop { loop {
select!{ select!{
_ = interval.tick() =>{ _ = interval.tick() =>{
for evt in evts_to_send(id, evt_queue){ for evt in evts_to_send(id, evt_queue){
//println!("{:?}", evt);
yield evt; yield evt;
} }
}, },
@ -286,29 +301,49 @@ fn tracked_events<'a>(
} }
} }
fn state_update(tracked: &Tracked, evt_queues: &TrackingEventQueue) {
evt_queues
.read()
.unwrap()
.get(&tracked.id)
.unwrap()
.write()
.unwrap()
.push_back(Event::json(&admin_view(tracked)).event("self_info").into());
}
#[put("/track/<id>/pos?<lat>&<long>")] #[put("/track/<id>/pos?<lat>&<long>")]
fn store_pos(id: &str, lat: f32, long: f32, tracking: &State<Tracking>) { fn store_pos(
id: &str,
lat: f32,
long: f32,
tracking: &State<Tracking>,
evt_queues: &State<TrackingEventQueue>,
) {
if let Some(tracked) = tracking.read().unwrap().get(&id.to_string()) { if let Some(tracked) = tracking.read().unwrap().get(&id.to_string()) {
tracked.write().unwrap().pos = (lat, long); tracked.write().unwrap().pos = (lat, long);
state_update(&tracked.read().unwrap(), &evt_queues);
} }
} }
#[put("/track/<id>/state?<inv>&<col>")] #[put("/track/<id>/state?<inv>&<col>")]
fn set_state(id: &str, inv: bool, col: u8, tracking: &State<Tracking>) -> Option<()> { fn set_state(
id: &str,
inv: bool,
col: u8,
tracking: &State<Tracking>,
evt_queues: &State<TrackingEventQueue>,
) -> Option<()> {
let tracking_lock = tracking.read().unwrap(); let tracking_lock = tracking.read().unwrap();
let state = &mut tracking_lock let tracked = &mut tracking_lock.get(&id.to_string()).unwrap().write().unwrap();
.get(&id.to_string())
.unwrap()
.write()
.unwrap()
.state;
if let Vieux { if let Vieux {
ref mut invisible, ref mut invisible,
ref mut color, ref mut color,
} = state } = tracked.state
{ {
*invisible = inv; *invisible = inv;
*color = col; *color = col;
state_update(&tracked, &evt_queues);
Some(()) Some(())
} else { } else {
None None

View file

@ -1,5 +1,8 @@
var evtsource; var evtsource;
var markers = []; var markers = [];
var self_marker;
var name;
var id;
var CircleIcon = L.Icon.extend({ var CircleIcon = L.Icon.extend({
options: { options: {
@ -73,36 +76,39 @@ function setup_map(){
}).addTo(map); }).addTo(map);
L.polyline(map_border, {color: 'red'}).addTo(map); L.polyline(map_border, {color: 'red'}).addTo(map);
self_marker = L.marker([0,0], {"icon": icons[0] }).addTo(map);
self_marker.setZIndexOffset(1000);
self_marker.bindPopup(name);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// EVENT LISTENNING // EVENT LISTENNING
function setup_evtlisten_common(){ function setup_evtlisten_common(){
evtSource = new EventSource("/track/"+id+"/events");
evtSource.addEventListener("coords", (event) => { evtSource.addEventListener("coords", (event) => {
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
console.log(data);
var i = 0; var i = 0;
for (tracked of data) { for (tracked of data) {
if (i == markers.length) { if (i == markers.length) {
markers.push(L.marker([0,0], {"icon": icons[0] }).addTo(map)); markers.push(L.marker([0,0], {"icon": icons[0] }).addTo(map));
markers[i].bindPopup(""); markers[i].bindPopup("");
markers[i].setZIndexOffset(0);
} }
markers[i].setLatLng(tracked.pos); markers[i].setLatLng(tracked.pos);
markers[i].setPopupContent(tracked.name); markers[i].setPopupContent(tracked.name);
if (tracked.me) {
markers[i].setIcon(self_icons[tracked.color]);
markers[i].setZIndexOffset(1000);
} else {
markers[i].setIcon(icons[tracked.color]); markers[i].setIcon(icons[tracked.color]);
markers[i].setZIndexOffset(0);
}
++i; ++i;
} }
for (; i < markers.length; ++i) { for (; i < markers.length; ++i) {
markers[i].setLatLng([0,0]); markers[i].setLatLng([0,0]);
} }
}); });
evtSource.addEventListener("self_info", (event) => {
const data = JSON.parse(event.data);
self_marker.setLatLng(data.pos);
self_marker.setIcon(self_icons[data.color]);
});
//socket.on("popup", function(data){ //socket.on("popup", function(data){
// alert(data.content); // alert(data.content);

View file

@ -36,6 +36,8 @@
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
id = "{{id}}";
name = "{{name}}";
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// SETUP MAP // SETUP MAP
@ -44,8 +46,6 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// EVENT LISTENNING // EVENT LISTENNING
id = "{{id}}";
evtSource = new EventSource("/track/{{id}}/events");
setup_evtlisten_common(); setup_evtlisten_common();
// ////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////

View file

@ -62,6 +62,8 @@
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
id = "{{id}}";
name = "{{name}}";
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// SETUP MAP // SETUP MAP
@ -70,8 +72,6 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// EVENT LISTENNING // EVENT LISTENNING
id = "{{id}}";
evtSource = new EventSource("/track/{{id}}/events");
setup_evtlisten_common(); setup_evtlisten_common();
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////