mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 17:08:21 +00:00
cleanup having two AsyncStatus
This commit is contained in:
parent
e271defc63
commit
572be62b5f
5 changed files with 82 additions and 199 deletions
|
|
@ -8,14 +8,12 @@ mod diff;
|
|||
mod error;
|
||||
mod revlog;
|
||||
mod status;
|
||||
mod status2;
|
||||
pub mod sync;
|
||||
|
||||
pub use crate::{
|
||||
diff::{AsyncDiff, DiffParams},
|
||||
revlog::AsyncLog,
|
||||
status::AsyncStatus,
|
||||
status2::{AsyncStatus2, StatusParams},
|
||||
status::{AsyncStatus, StatusParams},
|
||||
sync::{
|
||||
diff::{DiffLine, DiffLineType, FileDiff},
|
||||
status::{StatusItem, StatusItemType},
|
||||
|
|
@ -25,7 +23,6 @@ pub use crate::{
|
|||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
hash::{Hash, Hasher},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
/// this type is used to communicate events back through the channel
|
||||
|
|
@ -48,11 +45,3 @@ pub fn hash<T: Hash + ?Sized>(v: &T) -> u64 {
|
|||
v.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
/// helper function to return the current tick since unix epoch
|
||||
pub fn current_tick() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as u64
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use crate::{
|
||||
error::Result, hash, sync, sync::status::StatusType,
|
||||
AsyncNotification, StatusItem, CWD,
|
||||
error::Result, hash, sync, AsyncNotification, StatusItem, CWD,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use log::trace;
|
||||
|
|
@ -10,12 +9,42 @@ use std::{
|
|||
atomic::{AtomicUsize, Ordering},
|
||||
Arc, Mutex,
|
||||
},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
use sync::status::StatusType;
|
||||
|
||||
fn current_tick() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as u64
|
||||
}
|
||||
|
||||
#[derive(Default, Hash, Clone)]
|
||||
pub struct Status {
|
||||
pub work_dir: Vec<StatusItem>,
|
||||
pub stage: Vec<StatusItem>,
|
||||
pub items: Vec<StatusItem>,
|
||||
}
|
||||
|
||||
///
|
||||
#[derive(Default, Hash, Clone, PartialEq)]
|
||||
pub struct StatusParams {
|
||||
tick: u64,
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
}
|
||||
|
||||
impl StatusParams {
|
||||
///
|
||||
pub fn new(
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
tick: current_tick(),
|
||||
status_type,
|
||||
include_untracked,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Request<R, A>(R, Option<A>);
|
||||
|
|
@ -51,10 +80,13 @@ impl AsyncStatus {
|
|||
}
|
||||
|
||||
///
|
||||
pub fn fetch(&mut self, request: u64) -> Result<Option<Status>> {
|
||||
let hash_request = hash(&request);
|
||||
pub fn fetch(
|
||||
&mut self,
|
||||
params: StatusParams,
|
||||
) -> Result<Option<Status>> {
|
||||
let hash_request = hash(¶ms);
|
||||
|
||||
trace!("request: {} [hash: {}]", request, hash_request);
|
||||
trace!("request: [hash: {}]", hash_request);
|
||||
|
||||
{
|
||||
let mut current = self.current.lock()?;
|
||||
|
|
@ -71,10 +103,14 @@ impl AsyncStatus {
|
|||
let arc_last = Arc::clone(&self.last);
|
||||
let sender = self.sender.clone();
|
||||
let arc_pending = Arc::clone(&self.pending);
|
||||
let status_type = params.status_type;
|
||||
let include_untracked = params.include_untracked;
|
||||
rayon_core::spawn(move || {
|
||||
arc_pending.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
AsyncStatus::fetch_helper(
|
||||
Self::fetch_helper(
|
||||
status_type,
|
||||
include_untracked,
|
||||
hash_request,
|
||||
arc_current,
|
||||
arc_last,
|
||||
|
|
@ -92,11 +128,13 @@ impl AsyncStatus {
|
|||
}
|
||||
|
||||
fn fetch_helper(
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
hash_request: u64,
|
||||
arc_current: Arc<Mutex<Request<u64, Status>>>,
|
||||
arc_last: Arc<Mutex<Status>>,
|
||||
) -> Result<()> {
|
||||
let res = Self::get_status()?;
|
||||
let res = Self::get_status(status_type, include_untracked)?;
|
||||
trace!("status fetched: {}", hash(&res));
|
||||
|
||||
{
|
||||
|
|
@ -114,11 +152,16 @@ impl AsyncStatus {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn get_status() -> Result<Status> {
|
||||
let work_dir =
|
||||
sync::status::get_status(CWD, StatusType::WorkingDir)?;
|
||||
let stage = sync::status::get_status(CWD, StatusType::Stage)?;
|
||||
|
||||
Ok(Status { stage, work_dir })
|
||||
fn get_status(
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
) -> Result<Status> {
|
||||
Ok(Status {
|
||||
items: sync::status::get_status_new(
|
||||
CWD,
|
||||
status_type,
|
||||
include_untracked,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,160 +0,0 @@
|
|||
use crate::{
|
||||
current_tick, error::Result, hash, sync, AsyncNotification,
|
||||
StatusItem, CWD,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use log::trace;
|
||||
use std::{
|
||||
hash::Hash,
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc, Mutex,
|
||||
},
|
||||
};
|
||||
use sync::status::StatusType;
|
||||
|
||||
#[derive(Default, Hash, Clone)]
|
||||
pub struct Status2 {
|
||||
pub items: Vec<StatusItem>,
|
||||
}
|
||||
|
||||
///
|
||||
#[derive(Default, Hash, Clone, PartialEq)]
|
||||
pub struct StatusParams {
|
||||
tick: u64,
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
}
|
||||
|
||||
impl StatusParams {
|
||||
///
|
||||
pub fn new(
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
tick: current_tick(),
|
||||
status_type,
|
||||
include_untracked,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Request<R, A>(R, Option<A>);
|
||||
|
||||
///TODO: merge functionality with AsyncStatus
|
||||
pub struct AsyncStatus2 {
|
||||
current: Arc<Mutex<Request<u64, Status2>>>,
|
||||
last: Arc<Mutex<Status2>>,
|
||||
sender: Sender<AsyncNotification>,
|
||||
pending: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
impl AsyncStatus2 {
|
||||
///
|
||||
pub fn new(sender: Sender<AsyncNotification>) -> Self {
|
||||
Self {
|
||||
current: Arc::new(Mutex::new(Request(0, None))),
|
||||
last: Arc::new(Mutex::new(Status2::default())),
|
||||
sender,
|
||||
pending: Arc::new(AtomicUsize::new(0)),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn last(&mut self) -> Result<Status2> {
|
||||
let last = self.last.lock()?;
|
||||
Ok(last.clone())
|
||||
}
|
||||
|
||||
///
|
||||
pub fn is_pending(&self) -> bool {
|
||||
self.pending.load(Ordering::Relaxed) > 0
|
||||
}
|
||||
|
||||
///
|
||||
pub fn fetch(
|
||||
&mut self,
|
||||
params: StatusParams,
|
||||
) -> Result<Option<Status2>> {
|
||||
let hash_request = hash(¶ms);
|
||||
|
||||
trace!("request: [hash: {}]", hash_request);
|
||||
|
||||
{
|
||||
let mut current = self.current.lock()?;
|
||||
|
||||
if current.0 == hash_request {
|
||||
return Ok(current.1.clone());
|
||||
}
|
||||
|
||||
current.0 = hash_request;
|
||||
current.1 = None;
|
||||
}
|
||||
|
||||
let arc_current = Arc::clone(&self.current);
|
||||
let arc_last = Arc::clone(&self.last);
|
||||
let sender = self.sender.clone();
|
||||
let arc_pending = Arc::clone(&self.pending);
|
||||
let status_type = params.status_type;
|
||||
let include_untracked = params.include_untracked;
|
||||
rayon_core::spawn(move || {
|
||||
arc_pending.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
Self::fetch_helper(
|
||||
status_type,
|
||||
include_untracked,
|
||||
hash_request,
|
||||
arc_current,
|
||||
arc_last,
|
||||
)
|
||||
.expect("failed to fetch status");
|
||||
|
||||
arc_pending.fetch_sub(1, Ordering::Relaxed);
|
||||
|
||||
sender
|
||||
.send(AsyncNotification::Status)
|
||||
.expect("error sending status");
|
||||
});
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn fetch_helper(
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
hash_request: u64,
|
||||
arc_current: Arc<Mutex<Request<u64, Status2>>>,
|
||||
arc_last: Arc<Mutex<Status2>>,
|
||||
) -> Result<()> {
|
||||
let res = Self::get_status(status_type, include_untracked)?;
|
||||
trace!("status fetched: {}", hash(&res));
|
||||
|
||||
{
|
||||
let mut current = arc_current.lock()?;
|
||||
if current.0 == hash_request {
|
||||
current.1 = Some(res.clone());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let mut last = arc_last.lock()?;
|
||||
*last = res;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_status(
|
||||
status_type: StatusType,
|
||||
include_untracked: bool,
|
||||
) -> Result<Status2> {
|
||||
Ok(Status2 {
|
||||
items: sync::status::get_status_new(
|
||||
CWD,
|
||||
status_type,
|
||||
include_untracked,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
};
|
||||
use asyncgit::{
|
||||
sync::{self, status::StatusType},
|
||||
AsyncNotification, AsyncStatus2, StatusParams, CWD,
|
||||
AsyncNotification, AsyncStatus, StatusParams, CWD,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use crossterm::event::Event;
|
||||
|
|
@ -31,7 +31,7 @@ pub struct Stashing {
|
|||
options: Options,
|
||||
index: FileTreeComponent,
|
||||
theme: Theme,
|
||||
git_status: AsyncStatus2,
|
||||
git_status: AsyncStatus,
|
||||
queue: Queue,
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ impl Stashing {
|
|||
theme,
|
||||
),
|
||||
theme: *theme,
|
||||
git_status: AsyncStatus2::new(sender.clone()),
|
||||
git_status: AsyncStatus::new(sender.clone()),
|
||||
queue: queue.clone(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ use crate::{
|
|||
ui::style::Theme,
|
||||
};
|
||||
use asyncgit::{
|
||||
current_tick, AsyncDiff, AsyncNotification, AsyncStatus,
|
||||
DiffParams,
|
||||
sync::status::StatusType, AsyncDiff, AsyncNotification,
|
||||
AsyncStatus, DiffParams, StatusParams,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use crossterm::event::Event;
|
||||
|
|
@ -42,7 +42,8 @@ pub struct Status {
|
|||
index_wd: ChangesComponent,
|
||||
diff: DiffComponent,
|
||||
git_diff: AsyncDiff,
|
||||
git_status: AsyncStatus,
|
||||
git_status_workdir: AsyncStatus,
|
||||
git_status_stage: AsyncStatus,
|
||||
}
|
||||
|
||||
impl DrawableComponent for Status {
|
||||
|
|
@ -122,7 +123,8 @@ impl Status {
|
|||
),
|
||||
diff: DiffComponent::new(queue.clone(), theme),
|
||||
git_diff: AsyncDiff::new(sender.clone()),
|
||||
git_status: AsyncStatus::new(sender.clone()),
|
||||
git_status_workdir: AsyncStatus::new(sender.clone()),
|
||||
git_status_stage: AsyncStatus::new(sender.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,12 +190,19 @@ impl Status {
|
|||
///
|
||||
pub fn update(&mut self) {
|
||||
self.git_diff.refresh().unwrap();
|
||||
self.git_status.fetch(current_tick()).unwrap();
|
||||
self.git_status_workdir
|
||||
.fetch(StatusParams::new(StatusType::WorkingDir, true))
|
||||
.unwrap();
|
||||
self.git_status_stage
|
||||
.fetch(StatusParams::new(StatusType::Stage, true))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
///
|
||||
pub fn anything_pending(&self) -> bool {
|
||||
self.git_diff.is_pending() || self.git_status.is_pending()
|
||||
self.git_diff.is_pending()
|
||||
|| self.git_status_stage.is_pending()
|
||||
|| self.git_status_workdir.is_pending()
|
||||
}
|
||||
|
||||
///
|
||||
|
|
@ -206,9 +215,11 @@ impl Status {
|
|||
}
|
||||
|
||||
fn update_status(&mut self) {
|
||||
let status = self.git_status.last().unwrap();
|
||||
self.index.update(&status.stage);
|
||||
self.index_wd.update(&status.work_dir);
|
||||
let status = self.git_status_stage.last().unwrap();
|
||||
self.index.update(&status.items);
|
||||
|
||||
let status = self.git_status_workdir.last().unwrap();
|
||||
self.index_wd.update(&status.items);
|
||||
|
||||
self.update_diff();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue