notation_model/
bar_lane.rs1use std::fmt::Display;
2use std::sync::{Arc, Weak};
3
4use notation_proto::prelude::Units;
5
6use crate::prelude::{LaneEntry, LaneKind, Slice, Tab, TabBar, TabBarProps, Track, TrackProps, LaneEntryProps};
7
8#[derive(Copy, Clone, Debug, Default)]
9pub struct BarLaneProps {
10 pub index: usize,
11 pub track: TrackProps,
12}
13
14#[derive(Clone, Debug)]
15pub struct BarLane {
16 pub bar: Weak<TabBar>,
17 pub kind: LaneKind,
18 pub track: Arc<Track>,
19 pub entries: Vec<Arc<LaneEntry>>,
20 pub props: BarLaneProps,
21}
22impl Display for BarLane {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 write!(
25 f,
26 "<BarLane>({} E:{})",
27 self.id(),
28 self.entries.len()
29 )
30 }
31}
32
33impl BarLane {
34 pub fn id(&self) -> String {
35 self.kind_id(self.kind)
36 }
37 pub fn kind_id(&self, kind: LaneKind) -> String {
38 format!("{}:{}", self.track.id, kind)
39 }
40 pub fn order(&self) -> (usize, LaneKind) {
41 (self.track.props.index, self.kind)
42 }
43 pub fn try_new_arc(
44 bar: Weak<TabBar>,
45 index: usize,
46 track: &Arc<Track>,
47 slice: Slice,
48 ) -> Option<Arc<Self>> {
49 let model_entries = track.get_entries(&slice.begin, &slice.end);
50 let kind = LaneKind::of_entries(&track.kind, &model_entries);
51 if !kind.is_none() {
52 Some(Arc::<Self>::new_cyclic(|weak_self| {
53 let props = BarLaneProps {
54 index,
55 track: track.props,
56 };
57 let entries = LaneEntry::new_entries(model_entries, weak_self, slice);
58 Self {
59 bar,
60 kind,
61 track: track.clone(),
62 entries,
63 props,
64 }
65 }))
66 } else {
67 None
68 }
69 }
70 pub fn merge_lane(&self, lane: &BarLane) -> Arc<Self> {
71 Arc::<Self>::new_cyclic(|weak_self| {
72 let mut entries = Vec::new();
73 for entry in self.entries.iter() {
74 entries.push(entry.clone());
75 }
76 for entry in lane.entries.iter() {
77 entries.push(entry.clone());
78 }
79 entries.sort_by(|a, b| {
80 a.props.in_bar_pos.cmp(&b.props.in_bar_pos)
81 });
82 let entries = entries.iter().enumerate().map(|(index, entry)| {
83 let merged_entry = LaneEntry {
84 props: LaneEntryProps {
85 slice: entry.props.slice.clone(),
86 index,
87 ..entry.props
88 },
89 lane: weak_self.clone(),
90 model: entry.model.clone(),
91 };
92 Arc::new(merged_entry)
93 }).collect();
94 Self {
95 bar: self.bar.clone(),
96 kind: self.kind,
97 track: self.track.clone(),
98 entries,
99 props: self.props,
100 }
101 })
102 }
103 pub fn bar(&self) -> Option<Arc<TabBar>> {
104 self.bar.upgrade().map(|x| x.clone())
105 }
106 pub fn tab(&self) -> Option<Arc<Tab>> {
107 self.bar().and_then(|x| x.tab())
108 }
109 pub fn bar_props(&self) -> TabBarProps {
110 self.bar().map(|x| x.props).unwrap_or_default()
111 }
112 pub fn get_entry_at<T, F: Fn(&LaneEntry) -> Option<T>>(
113 &self,
114 in_bar_pos: Units,
115 predicate: &F,
116 ) -> Option<T> {
117 for entry in self.entries.iter() {
118 if in_bar_pos < entry.props.in_bar_pos {
119 break;
120 } else {
121 if in_bar_pos < entry.props.in_bar_pos + entry.model().props.tied_units {
122 if let Some(result) = predicate(entry.as_ref()) {
123 return Some(result);
124 }
125 }
126 }
127 }
128 None
129 }
130 pub fn get_next_entry<T, F: Fn(&LaneEntry) -> Option<T>>(
131 &self,
132 in_bar_pos: Units,
133 predicate: &F,
134 ) -> Option<T> {
135 self.get_entry(&|x: &LaneEntry| {
136 if x.props.in_bar_pos.is_bigger_than(&in_bar_pos) {
137 predicate(x)
138 } else {
139 None
140 }
141 })
142 }
143}