rewrite backend in rust #32
4 changed files with 72 additions and 31 deletions
73
src/main.rs
73
src/main.rs
|
@ -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
|
||||||
|
|
|
@ -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(icons[tracked.color]);
|
||||||
markers[i].setIcon(self_icons[tracked.color]);
|
|
||||||
markers[i].setZIndexOffset(1000);
|
|
||||||
} else {
|
|
||||||
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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in a new issue