use crate::{input_sequence::InputSequence, KeyChord};
use bevy::prelude::Resource;
use trie_rs::{
inc_search::{IncSearch, Position},
map::{Trie, TrieBuilder},
};
#[derive(Resource, Default)]
pub struct KeySequenceCache {
trie: Option<Trie<KeyChord, InputSequence<KeyChord, ()>>>,
position: Option<Position>,
}
impl KeySequenceCache {
pub fn trie<'a>(
&mut self,
sequences: impl Iterator<Item = &'a InputSequence<KeyChord, ()>>,
) -> &Trie<KeyChord, InputSequence<KeyChord, ()>> {
self.trie.get_or_insert_with(|| {
let mut builder: TrieBuilder<KeyChord, InputSequence<KeyChord, ()>> =
TrieBuilder::new();
for sequence in sequences {
builder.insert(sequence.acts.clone(), sequence.clone());
}
builder.build()
})
}
pub fn store(&mut self, position: Position) {
self.position = Some(position)
}
pub fn recall<'a, 'b>(
&'b mut self,
sequences: impl Iterator<Item = &'a InputSequence<KeyChord, ()>>,
) -> IncSearch<'a, KeyChord, InputSequence<KeyChord, ()>>
where
'b: 'a,
{
let position = self.position;
let trie = self.trie(sequences);
position
.map(move |p| IncSearch::resume(trie, p))
.unwrap_or_else(move || trie.inc_search())
}
pub fn reset(&mut self) {
self.trie = None;
self.position = None;
}
}