mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 11:35:25 +00:00
wip: solved the preview performance regression
This commit is contained in:
parent
fc3f24fd89
commit
07ad8d760b
@ -1,6 +1,5 @@
|
||||
use crate::channels::cable::prototypes::CableChannelPrototype;
|
||||
use crate::preview::{Preview, PreviewContent};
|
||||
use crate::utils::cache::RingSet;
|
||||
use crate::utils::command::shell_command;
|
||||
use crate::{
|
||||
channels::{entry::Entry, preview::PreviewCommand},
|
||||
@ -16,34 +15,25 @@ use tracing::debug;
|
||||
#[derive(Debug)]
|
||||
pub struct Previewer {
|
||||
cache: Arc<Mutex<PreviewCache>>,
|
||||
requests: RingSet<Entry>,
|
||||
concurrent_preview_tasks: Arc<AtomicU8>,
|
||||
in_flight_previews: Arc<Mutex<FxHashSet<String>>>,
|
||||
command: PreviewCommand,
|
||||
}
|
||||
|
||||
const REQUEST_STACK_SIZE: usize = 10;
|
||||
|
||||
impl Previewer {
|
||||
// we could use a target scroll here to make the previewer
|
||||
// faster, but since it's already running in the background and quite
|
||||
// fast for most standard file sizes, plus we're caching the previews,
|
||||
// I'm not sure the extra complexity is worth it.
|
||||
pub fn handle_request(&mut self, entry: &Entry) -> Option<Arc<Preview>> {
|
||||
pub fn request(&mut self, entry: &Entry) -> Option<Arc<Preview>> {
|
||||
// check if we have a preview in cache for the current request
|
||||
if let Some(preview) = self.cached(entry) {
|
||||
return Some(preview);
|
||||
}
|
||||
|
||||
// otherwise, if we haven't acknowledged the request yet, acknowledge it
|
||||
self.requests.push(entry.clone());
|
||||
// start a background task to compute the preview
|
||||
self.preview(entry);
|
||||
|
||||
// lookup request stack and return the most recent preview available
|
||||
for entry in self.requests.back_to_front() {
|
||||
if let Some(preview) = self.preview(&entry) {
|
||||
return Some(preview);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -54,7 +44,6 @@ impl Previewer {
|
||||
pub fn new(command: PreviewCommand) -> Self {
|
||||
Previewer {
|
||||
cache: Arc::new(Mutex::new(PreviewCache::default())),
|
||||
requests: RingSet::with_capacity(REQUEST_STACK_SIZE),
|
||||
concurrent_preview_tasks: Arc::new(AtomicU8::new(0)),
|
||||
in_flight_previews: Arc::new(Mutex::new(FxHashSet::default())),
|
||||
command,
|
||||
@ -65,18 +54,7 @@ impl Previewer {
|
||||
self.cache.lock().get(&entry.name)
|
||||
}
|
||||
|
||||
pub fn preview(&mut self, entry: &Entry) -> Option<Arc<Preview>> {
|
||||
if let Some(preview) = self.cached(entry) {
|
||||
Some(preview)
|
||||
} else {
|
||||
// preview is not in cache, spawn a task to compute the preview
|
||||
debug!("Preview cache miss for {:?}", entry.name);
|
||||
self.handle_preview_request(entry);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_preview_request(&mut self, entry: &Entry) {
|
||||
pub fn preview(&mut self, entry: &Entry) {
|
||||
if self.in_flight_previews.lock().contains(&entry.name) {
|
||||
debug!("Preview already in flight for {:?}", entry.name);
|
||||
return;
|
||||
|
@ -8,9 +8,7 @@ use crate::{
|
||||
},
|
||||
entry::Entry,
|
||||
remote_control::RemoteControl,
|
||||
// stdin::Channel as StdinChannel,
|
||||
OnAir,
|
||||
TelevisionChannel,
|
||||
OnAir, TelevisionChannel,
|
||||
},
|
||||
config::{Config, Theme},
|
||||
draw::{ChannelState, Ctx, TvState},
|
||||
@ -391,15 +389,11 @@ impl Television {
|
||||
// FIXME: this is probably redundant with the channel supporting previews
|
||||
&& self.previewer.is_some()
|
||||
{
|
||||
// preview content
|
||||
if let Some(preview) = self
|
||||
.previewer
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.handle_request(selected_entry)
|
||||
// avoid sending unnecessary requests to the previewer
|
||||
if self.preview_state.preview.title != selected_entry.name {
|
||||
if let Some(preview) =
|
||||
self.previewer.as_mut().unwrap().request(selected_entry)
|
||||
{
|
||||
// only update if the preview content has changed
|
||||
if self.preview_state.preview.title != preview.title {
|
||||
self.preview_state.update(
|
||||
preview,
|
||||
// scroll to center the selected entry
|
||||
@ -576,15 +570,12 @@ impl Television {
|
||||
self.handle_input_action(action);
|
||||
}
|
||||
Action::SelectNextEntry => {
|
||||
self.preview_state.reset();
|
||||
self.select_next_entry(1);
|
||||
}
|
||||
Action::SelectPrevEntry => {
|
||||
self.preview_state.reset();
|
||||
self.select_prev_entry(1);
|
||||
}
|
||||
Action::SelectNextPage => {
|
||||
self.preview_state.reset();
|
||||
self.select_next_entry(
|
||||
self.ui_state
|
||||
.layout
|
||||
@ -595,7 +586,6 @@ impl Television {
|
||||
);
|
||||
}
|
||||
Action::SelectPrevPage => {
|
||||
self.preview_state.reset();
|
||||
self.select_prev_entry(
|
||||
self.ui_state
|
||||
.layout
|
||||
|
Loading…
x
Reference in New Issue
Block a user