Skip to content

Commit

Permalink
feat: Prediction
Browse files Browse the repository at this point in the history
  • Loading branch information
jcs090218 committed Jul 4, 2024
1 parent 98a4156 commit 0cee411
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 82 deletions.
2 changes: 1 addition & 1 deletion src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Client {
if user.is_none() {
return None;
}
let path = user.unwrap().path();
let path = user.unwrap().path;
if path.is_none() {
return None;
}
Expand Down
5 changes: 4 additions & 1 deletion src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ impl File {
self.save();
}

pub fn update(&mut self, add_or_delete: &String, beg: usize, end: usize, contents: &String) {
pub fn update(&mut self, add_or_delete: &String, beg: isize, end: isize, contents: &String) {
let view = self.view.as_mut().unwrap();

let beg = beg as usize;
let end = end as usize;

match add_or_delete.clone().as_str() {
"add" => {
view.insert(beg, &contents);
Expand Down
71 changes: 67 additions & 4 deletions src/handler/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,93 @@
* limitations under the License.
*/
pub use crate::handler::room::*;
pub use std::net::SocketAddr;

/// Addition and Deletion to the buffer.
pub mod update {
use crate::handler::buffer::*;

const METHOD: &str = "buffer::update";

fn predict_delta(add_or_delete: &String, beg: isize, end: isize) -> isize {
if add_or_delete == "delete" {
return beg - end;
}
end - beg
}

fn predict_movement(
addr: &SocketAddr,
room: &mut Room,
add_or_delete: &String,
beg: isize,
end: isize,
) {
let pt = beg;
let delta = predict_delta(&add_or_delete, beg, end);

let clients = room.get_clients_mut();

for (_addr, _client) in clients.iter_mut() {
// Skip for the request client.
if _addr == addr {
continue;
}

let user = _client.user_mut();

if user.is_none() {
continue;
}

let user = user.unwrap();
let point = user.point;

if point.is_none() {
continue;
}

let point = point.unwrap();

if pt <= point {
user.point = Some(point + delta);

if !user.region_beg.is_none() {
user.region_beg = Some(user.region_beg.unwrap() + delta);
user.region_end = Some(user.region_end.unwrap() + delta);
}
}
}
}

pub async fn handle(channel: &mut Channel, room: &Arc<Mutex<Room>>, json: &Value) {
let addr = &channel.get_connection().addr;
let mut room = room.lock().await;

let path = data_str(json, "path").unwrap();
let add_or_delete = data_str(json, "add_or_delete").unwrap();
let beg = data_usize(json, "beg").unwrap();
let end = data_usize(json, "end").unwrap();
let beg = data_isize(json, "beg").unwrap();
let end = data_isize(json, "end").unwrap();
let contents = data_str(json, "contents").unwrap();

// Update the buffer view.
{
let file = room.get_file_create_mut(&addr, &path, None);
let file = file.unwrap();

let rel_file = file.relative_path();

file.update(&add_or_delete, beg, end, &contents);
}

// Predict mouse movement.
predict_movement(addr, &mut room, &add_or_delete, beg, end);

let file = room.get_file_create_mut(&addr, &path, None);
let file = file.unwrap();

let rel_file = file.relative_path();

file.update(&add_or_delete, beg, end, &contents);

// Get the peers that are in the file.
let peers = room.peers_by_file(&room, &rel_file);

Expand Down
8 changes: 4 additions & 4 deletions src/handler/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ pub mod info {
let this_user = client.user().unwrap();

// If user is not in the file, ignore it.
if this_user.path().is_none() {
if this_user.path.is_none() {
return users;
}

for _client in room.get_clients().iter() {
for _client in room.get_clients_vec().iter() {
let user = _client.user();

// User not entered yet.
Expand All @@ -100,7 +100,7 @@ pub mod info {
}

// Ignore when user not visiting any project files.
if user.path().is_none() {
if user.path.is_none() {
continue;
}

Expand Down Expand Up @@ -152,7 +152,7 @@ pub mod say {
return;
}

let username = client.user().unwrap().username();
let username = client.user().unwrap().username.clone();

let file = data_str(json, "file").unwrap();
let file = no_room_path(&room, &file);
Expand Down
53 changes: 27 additions & 26 deletions src/handler/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub mod exit {
}

let user = client.user();
let username = user.unwrap().username();
let username = user.unwrap().username.clone();

// Leave the room
client.exit_room();
Expand Down Expand Up @@ -328,7 +328,7 @@ pub mod kick {
return;
}

let admin_name = client.user().unwrap().username();
let admin_name = client.user().unwrap().username.clone();
// target user to kick out
let target_name = data_str(json, "username").unwrap();

Expand Down Expand Up @@ -370,7 +370,7 @@ pub mod broadcast {
let room = room.lock().await;
let client = room.get_client(addr).unwrap();

let username = client.user().unwrap().username();
let username = client.user().unwrap().username.clone();

if !check_entered(channel, client, METHOD).await {
return;
Expand Down Expand Up @@ -407,9 +407,9 @@ pub mod update_client {
}

let path = data_str(json, "path");
let point = data_u64(json, "point");
let region_beg = data_u64(json, "region_beg");
let region_end = data_u64(json, "region_end");
let point = data_isize(json, "point");
let region_beg = data_isize(json, "region_beg");
let region_end = data_isize(json, "region_end");
let color_cursor = data_str(json, "color_cursor");
let color_region = data_str(json, "color_region");

Expand All @@ -420,29 +420,30 @@ pub mod update_client {
let client = room.get_client(addr).unwrap();
let rel_path = no_client_path(&client, &path);

let abs_path = to_room_path(addr, &room, path.unwrap());
let file = room.get_file(addr, &abs_path);
if !path.is_none() {
let abs_path = to_room_path(addr, &room, path.unwrap());
let file = room.get_file(addr, &abs_path);

if !file.is_none() {
let buffer = file.unwrap().buffer();
let buffer_md5 = md5::compute(buffer);
if !file.is_none() {
let buffer = file.unwrap().buffer();
let buffer_md5 = md5::compute(buffer);

// `md5_contents` is only optional.
if !md5_contents.is_none() {
let md5_contents = md5_contents.unwrap();
// `md5_contents` is only optional.
if !md5_contents.is_none() {
let md5_contents = md5_contents.unwrap();

if format!("{:x}", buffer_md5) != md5_contents.as_str() {
return;
if format!("{:x}", buffer_md5) != md5_contents.as_str() {
return;
}
}
}

// `contents` is only optional.
if !contents.is_none() {
let contents = contents.unwrap();
// `contents` is only optional.
if !contents.is_none() {
let contents = contents.unwrap();

if buffer_md5 != md5::compute(contents) {
println!("ret");
return;
if buffer_md5 != md5::compute(contents) {
return;
}
}
}
}
Expand Down Expand Up @@ -472,7 +473,7 @@ pub mod info {
fn get_users(room: &Room) -> Vec<User> {
let mut users = Vec::new();

for client in room.get_clients().iter() {
for client in room.get_clients_vec().iter() {
let user = client.user();

// User not entered yet.
Expand Down Expand Up @@ -578,8 +579,8 @@ pub mod find_user {

let user = client.user().unwrap();

let path = user.path().unwrap();
let point = user.point().unwrap();
let path = user.path.clone().unwrap();
let point = user.point.unwrap();

channel
.send_json(&serde_json::json!({
Expand Down
22 changes: 14 additions & 8 deletions src/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ impl Room {
continue;
}

if _client.user().unwrap().username() == *username {
if _client.user().unwrap().username == *username {
return true;
}
}
Expand Down Expand Up @@ -337,13 +337,19 @@ impl Room {
return (true, "");
}

/// Return a list of client.
pub fn get_clients(&self) -> Vec<&Client> {
self.clients.values().collect::<Vec<&Client>>()
/// Return the clients as the HashMap.
pub fn get_clients(&self) -> &HashMap<SocketAddr, Client> {
&self.clients
}
pub fn get_clients_mut(&mut self) -> &mut HashMap<SocketAddr, Client> {
&mut self.clients
}

/// Return a list of client.
pub fn get_clients_mut(&mut self) -> Vec<&mut Client> {
/// Return the clients as the Vec.
pub fn get_clients_vec(&self) -> Vec<&Client> {
self.clients.values().collect::<Vec<&Client>>()
}
pub fn get_clients_vec_mut(&mut self) -> Vec<&mut Client> {
self.clients.values_mut().collect::<Vec<&mut Client>>()
}

Expand Down Expand Up @@ -382,7 +388,7 @@ impl Room {
/// * `username` - The client username.
pub fn get_client_by_name(&self, username: &str) -> Option<&Client> {
for (_addr, client) in self.clients.iter() {
if client.user().unwrap().username() == username {
if client.user().unwrap().username == username {
return Some(client);
}
}
Expand All @@ -396,7 +402,7 @@ impl Room {
/// * `username` - The client username.
pub fn get_client_mut_by_name(&mut self, username: &str) -> Option<&mut Client> {
for (_addr, client) in self.clients.iter_mut() {
if client.user().unwrap().username() == username {
if client.user().unwrap().username == username {
return Some(client);
}
}
Expand Down
48 changes: 10 additions & 38 deletions src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub struct User {
username: String,
path: Option<String>, // the user's location
point: Option<u64>,
region_beg: Option<u64>,
region_end: Option<u64>,
pub username: String,
pub path: Option<String>, // the user's location
pub point: Option<isize>,
pub region_beg: Option<isize>,
pub region_end: Option<isize>,
// Color definition
color_cursor: Option<String>, // hex
color_region: Option<String>, // hex
pub color_cursor: Option<String>, // hex
pub color_region: Option<String>, // hex
}

impl User {
Expand All @@ -40,40 +40,12 @@ impl User {
}
}

pub fn username(&self) -> String {
self.username.clone()
}

pub fn path(&self) -> Option<String> {
self.path.clone()
}

pub fn point(&self) -> Option<u64> {
self.point
}

pub fn region_beg(&self) -> Option<u64> {
self.region_beg
}

pub fn region_end(&self) -> Option<u64> {
self.region_end
}

pub fn color_cursor(&self) -> Option<String> {
self.color_cursor.clone()
}

pub fn color_region(&self) -> Option<String> {
self.color_region.clone()
}

pub fn update(
&mut self,
path: Option<String>,
point: Option<u64>,
region_beg: Option<u64>,
region_end: Option<u64>,
point: Option<isize>,
region_beg: Option<isize>,
region_end: Option<isize>,
color_cursor: Option<String>,
color_region: Option<String>,
) {
Expand Down
13 changes: 13 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ pub fn data_usize(json: &Value, key: &str) -> Option<usize> {
Some(json[key].to_string().parse::<usize>().unwrap())
}

/// Get data as isize.
///
/// # Arguments
///
/// * `json` - JSON object.
/// * `key` - Key to the data.
pub fn data_isize(json: &Value, key: &str) -> Option<isize> {
if json[key].is_null() {
return None;
}
Some(json[key].to_string().parse::<isize>().unwrap())
}

/// Parse data to u64.
///
/// # Arguments
Expand Down

0 comments on commit 0cee411

Please sign in to comment.