bevy_input_sequence/cache/
button.rs1use crate::input_sequence::InputSequence;
3use bevy::prelude::{Entity, GamepadButton, In, Resource};
4use std::collections::HashMap;
5use trie_rs::{
6 inc_search::{IncSearch, Position},
7 map::{Trie, TrieBuilder},
8};
9
10#[derive(Resource, Default)]
12pub struct ButtonSequenceCache {
13 trie: Option<Trie<GamepadButton, InputSequence<GamepadButton, In<Entity>>>>,
14 position: HashMap<Entity, Position>,
15}
16
17impl ButtonSequenceCache {
18 pub fn trie<'a>(
22 &mut self,
23 sequences: impl Iterator<Item = &'a InputSequence<GamepadButton, In<Entity>>>,
24 ) -> &Trie<GamepadButton, InputSequence<GamepadButton, In<Entity>>> {
25 self.trie.get_or_insert_with(|| {
26 let mut builder: TrieBuilder<GamepadButton, InputSequence<GamepadButton, In<Entity>>> =
27 TrieBuilder::new();
28 for sequence in sequences {
29 builder.insert(sequence.acts.clone(), sequence.clone());
30 }
31 assert!(
36 self.position.is_empty(),
37 "Position should be none when rebuilding trie"
38 );
39 builder.build()
40 })
41 }
42
43 pub fn store(&mut self, key: Entity, position: Position) {
45 self.position.insert(key, position);
46 }
47
48 pub fn recall<'a, 'b>(
50 &'b mut self,
51 key: Entity,
52 sequences: impl Iterator<Item = &'a InputSequence<GamepadButton, In<Entity>>>,
53 ) -> IncSearch<'a, GamepadButton, InputSequence<GamepadButton, In<Entity>>>
54 where
55 'b: 'a,
56 {
57 let position = self.position.get(&key).cloned();
58 let trie = self.trie(sequences);
59 position
60 .map(move |p| IncSearch::resume(trie, p))
61 .unwrap_or_else(move || trie.inc_search())
62 }
63
64 pub fn reset(&mut self) {
66 self.trie = None;
67 self.position.clear();
68 }
69}