consolidate remote & local source into one
This commit is contained in:
+60
-34
@@ -2,6 +2,7 @@ use device_query::{DeviceEvents, DeviceEventsHandler};
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::RwLock;
|
||||
use std::time::Duration;
|
||||
@@ -27,18 +28,23 @@ pub struct CursorPositions {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CursorPositionChanged {
|
||||
pub positions: CursorPositions,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FriendCursorPositionChanged {
|
||||
pub friend_id: String,
|
||||
pub positions: CursorPositions,
|
||||
pub positions: HashMap<String, CursorPositions>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CursorState(RwLock<CursorPositions>);
|
||||
pub struct CursorState(RwLock<HashMap<String, CursorPositions>>);
|
||||
|
||||
impl CursorState {
|
||||
fn update(
|
||||
&self,
|
||||
user_id: String,
|
||||
positions: CursorPositions,
|
||||
) -> Result<HashMap<String, CursorPositions>, String> {
|
||||
let mut positions_by_user = self.0.write().map_err(|error| error.to_string())?;
|
||||
positions_by_user.insert(user_id, positions);
|
||||
Ok(positions_by_user.clone())
|
||||
}
|
||||
}
|
||||
|
||||
// Was private, but for some reason LSP
|
||||
// complains even when there's no external references.
|
||||
@@ -92,37 +98,28 @@ pub fn init(app: &AppHandle) {
|
||||
|
||||
#[inline]
|
||||
fn update_cursor_position(handle: &AppHandle, positions: CursorPositions) {
|
||||
let state = handle.state::<CursorState>();
|
||||
let mut guard = state.0.write().expect("Cursor Position lock failed");
|
||||
|
||||
*guard = positions.clone();
|
||||
drop(guard);
|
||||
|
||||
if let Err(error) = (CursorPositionChanged {
|
||||
positions: positions.clone(),
|
||||
})
|
||||
.emit(handle)
|
||||
{
|
||||
eprintln!("Failed to emit cursor position change: {error}");
|
||||
}
|
||||
let user_id = handle
|
||||
.state::<crate::keypair::AppKeypair>()
|
||||
.public_key()
|
||||
.to_owned();
|
||||
emit_position(handle, user_id, positions.clone());
|
||||
|
||||
handle
|
||||
.state::<crate::network::Network>()
|
||||
.send_live_data(crate::live_data::LiveData::Cursor { positions });
|
||||
}
|
||||
|
||||
pub(crate) fn emit_friend_position(
|
||||
handle: &AppHandle,
|
||||
friend_id: String,
|
||||
positions: CursorPositions,
|
||||
) {
|
||||
if let Err(error) = (FriendCursorPositionChanged {
|
||||
friend_id,
|
||||
positions,
|
||||
})
|
||||
.emit(handle)
|
||||
{
|
||||
eprintln!("Failed to emit friend cursor position change: {error}");
|
||||
pub(crate) fn emit_position(handle: &AppHandle, user_id: String, positions: CursorPositions) {
|
||||
let positions = match handle.state::<CursorState>().update(user_id, positions) {
|
||||
Ok(positions) => positions,
|
||||
Err(error) => {
|
||||
eprintln!("Failed to update cursor positions: {error}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(error) = (CursorPositionChanged { positions }).emit(handle) {
|
||||
eprintln!("Failed to emit cursor position change: {error}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +153,35 @@ fn transform_coords(pos: &CursorPosition, to_normalized: bool, w: f64, h: f64) -
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn positions(x: f64) -> CursorPositions {
|
||||
CursorPositions {
|
||||
raw: CursorPosition { x, y: x },
|
||||
mapped: CursorPosition { x, y: x },
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cursor_state_tracks_and_replaces_positions_by_user_id() {
|
||||
let state = CursorState::default();
|
||||
|
||||
let snapshot = state.update("local".to_owned(), positions(1.0)).unwrap();
|
||||
assert_eq!(snapshot.len(), 1);
|
||||
assert_eq!(snapshot["local"].raw.x, 1.0);
|
||||
|
||||
let snapshot = state.update("friend".to_owned(), positions(2.0)).unwrap();
|
||||
assert_eq!(snapshot.len(), 2);
|
||||
assert_eq!(snapshot["friend"].raw.x, 2.0);
|
||||
|
||||
let snapshot = state.update("local".to_owned(), positions(3.0)).unwrap();
|
||||
assert_eq!(snapshot.len(), 2);
|
||||
assert_eq!(snapshot["local"].raw.x, 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop cursor tracking and unregister all listeners.
|
||||
#[allow(dead_code)] // TODO: get rid of this when app teardown sequence is introduced.
|
||||
pub async fn stop_cursor_tracking() {
|
||||
|
||||
@@ -9,7 +9,6 @@ mod remotes;
|
||||
mod ufa;
|
||||
mod ui;
|
||||
mod user;
|
||||
mod windowing;
|
||||
|
||||
use tauri::Manager;
|
||||
|
||||
@@ -22,7 +21,6 @@ async fn launch_app(app: &tauri::App) -> Result<(), Box<dyn std::error::Error>>
|
||||
app.manage(cursor::CursorState::default());
|
||||
ufa::init(handle);
|
||||
cursor::init(handle);
|
||||
// windowing::init(handle);
|
||||
ui::init(handle);
|
||||
Ok(())
|
||||
}
|
||||
@@ -76,7 +74,6 @@ fn specta_builder() -> tauri_specta::Builder<tauri::Wry> {
|
||||
profile::ProfileChanged,
|
||||
network::NetworkStatusChanged,
|
||||
cursor::CursorPositionChanged,
|
||||
cursor::FriendCursorPositionChanged,
|
||||
ufa::ForegroundAppChanged,
|
||||
ufa::FriendForegroundAppChanged,
|
||||
])
|
||||
|
||||
@@ -327,7 +327,7 @@ async fn connect(
|
||||
ServerMessage::FriendLiveData { friend_id, payload } => {
|
||||
match serde_json::from_str(&payload) {
|
||||
Ok(LiveData::Cursor { positions }) => {
|
||||
crate::cursor::emit_friend_position(handle, friend_id, positions);
|
||||
crate::cursor::emit_position(handle, friend_id, positions);
|
||||
}
|
||||
Ok(LiveData::ForegroundApp { meta }) => {
|
||||
crate::ufa::emit_friend_app(handle, friend_id, meta);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use tauri::{AppHandle, Manager, WebviewUrl};
|
||||
|
||||
const WINDOW_LABEL: &str = "main";
|
||||
const WINDOW_LABEL: &str = "debug";
|
||||
|
||||
pub fn init(handle: &AppHandle) {
|
||||
if let Some(window) = handle.get_webview_window(WINDOW_LABEL) {
|
||||
@@ -14,7 +14,7 @@ pub fn init(handle: &AppHandle) {
|
||||
|
||||
let builder =
|
||||
tauri::WebviewWindowBuilder::new(handle, WINDOW_LABEL, WebviewUrl::App("/".into()))
|
||||
.title("Wyd")
|
||||
.title("Wyd Debug")
|
||||
.inner_size(800.0, 600.0)
|
||||
.min_inner_size(500.0, 400.0)
|
||||
.visible(true);
|
||||
@@ -1,7 +1,11 @@
|
||||
use tauri::AppHandle;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
mod debug;
|
||||
mod scene;
|
||||
|
||||
pub fn init(app_handle: &AppHandle) {
|
||||
#[cfg(debug_assertions)]
|
||||
debug::init(app_handle);
|
||||
scene::init(app_handle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user