notation_model/
lane_entry.rs1use std::fmt::Display;
2use std::sync::{Arc, Weak};
3
4use crate::prelude::{BarLane, BarLaneProps, ModelEntry, Tab, TabBar, TabBarProps, Track};
5use notation_proto::prelude::{
6 BarPosition, Duration, Entry, EntryPassMode, ProtoEntry, TrackKind, Units, Slice,
7};
8
9#[derive(Clone, Debug, Default)]
10pub struct LaneEntryProps {
11 pub slice: Slice,
12 pub slice_index: usize,
13 pub index: usize,
14 pub in_bar_pos: Units,
15 pub tied_units: Units,
16 pub duration: Duration,
17}
18
19#[derive(Clone, Debug)]
20pub struct LaneEntry {
21 pub lane: Weak<BarLane>,
22 pub model: Arc<ModelEntry>,
23 pub props: LaneEntryProps,
24}
25impl Display for LaneEntry {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "<LaneEntry>({}: {})", self.props.index, self.model.proto)
28 }
29}
30impl LaneEntry {
31 pub fn new(
32 lane: Weak<BarLane>,
33 slice: Slice,
34 slice_index: usize,
35 index: usize,
36 model: Arc<ModelEntry>,
37 in_bar_pos: Units,
38 ) -> Self {
39 let props = LaneEntryProps {
40 slice,
41 slice_index,
42 index,
43 in_bar_pos,
44 tied_units: model.tied_units(),
45 duration: model.duration(),
46 };
47 Self { lane, model, props }
48 }
49}
50impl Entry for LaneEntry {
51 fn duration(&self) -> notation_proto::prelude::Duration {
52 self.model.duration()
53 }
54 fn prev_is_tie(&self) -> bool {
55 self.model.prev_is_tie()
56 }
57 fn next_is_tie(&self) -> bool {
58 self.model.next_is_tie()
59 }
60 fn tied_units(&self) -> Units {
61 self.model.tied_units()
62 }
63 fn pass_mode(&self) -> EntryPassMode {
64 self.model.pass_mode()
65 }
66}
67impl LaneEntry {
68 pub fn in_bar_pos(&self) -> Units {
69 self.props.in_bar_pos
70 }
71 pub fn bar_position(&self) -> BarPosition {
72 BarPosition::new(
73 self.bar_props().bar_units,
74 self.bar_props().bar_ordinal,
75 self.props.in_bar_pos,
76 )
77 }
78}
79impl LaneEntry {
80 pub fn lane(&self) -> Option<Arc<BarLane>> {
81 self.lane.upgrade().map(|x| x.clone())
82 }
83 pub fn track(&self) -> Option<Arc<Track>> {
84 self.lane().map(|x| x.track.clone())
85 }
86 pub fn bar(&self) -> Option<Arc<TabBar>> {
87 self.lane().and_then(|x| x.bar())
88 }
89 pub fn tab(&self) -> Option<Arc<Tab>> {
90 self.bar().and_then(|x| x.tab())
91 }
92 pub fn lane_props(&self) -> BarLaneProps {
93 self.lane().map(|x| x.props).unwrap_or_default()
94 }
95 pub fn bar_props(&self) -> TabBarProps {
96 self.bar().map(|x| x.props).unwrap_or_default()
97 }
98}
99impl LaneEntry {
100 pub fn model(&self) -> &ModelEntry {
101 self.model.as_ref()
102 }
103 pub fn proto(&self) -> &ProtoEntry {
104 self.model.proto.as_ref()
105 }
106 pub fn prev(&self) -> Option<Arc<LaneEntry>> {
107 if self.props.index == 0 {
108 None
109 } else if let Some(lane) = self.lane.upgrade() {
110 lane.entries.get(self.props.index - 1).map(|x| x.clone())
111 } else {
112 None
113 }
114 }
115 pub fn next(&self) -> Option<Arc<LaneEntry>> {
116 if let Some(lane) = self.lane.upgrade() {
117 lane.entries.get(self.props.index + 1).map(|x| x.clone())
118 } else {
119 None
120 }
121 }
122 pub fn prev_as_mark(&self) -> Option<String> {
123 if let Some(entry) = self.prev() {
124 entry.model.proto.as_mark().map(|x| x.clone())
125 } else {
126 None
127 }
128 }
129 pub fn track_id(&self) -> String {
130 self.model.track_id()
131 }
132 pub fn track_kind(&self) -> TrackKind {
133 self.model.track_kind()
134 }
135 pub fn track_index(&self) -> Option<usize> {
136 self.model.track_index()
137 }
138 pub fn get_lane_entry<T, F: Fn(&LaneEntry) -> Option<T>>(&self, predicate: &F) -> Option<T> {
139 if let Some(lane) = self.lane.upgrade() {
140 lane.get_entry(predicate)
141 } else {
142 None
143 }
144 }
145 pub fn get_track_entry<T, F: Fn(&ModelEntry) -> Option<T>>(&self, predicate: &F) -> Option<T> {
146 if let Some(lane) = self.lane.upgrade() {
147 lane.track.get_entry(predicate)
148 } else {
149 None
150 }
151 }
152}