gwr_models/registers/
register.rs1use std::rc::Rc;
6
7use gwr_engine::traits::Resolver;
8
9pub trait Register {
11 fn write(&self, resolver: &impl Resolver, value: u64);
17
18 fn set(&self, resolver: &impl Resolver, value: u64);
24
25 fn read(&self) -> u64;
27
28 fn value(&self) -> u64;
30
31 fn reset_sync(&self, resolver: &impl Resolver);
37
38 fn reset_async(&self);
40}
41
42pub trait Written {
43 fn written(&self, old_value: u64, value_written: u64, new_value: u64);
44}
45
46pub trait Read {
47 fn read(&self, value_read: u64);
48}
49
50pub type WrittenCallback = Rc<dyn Written + 'static>;
51pub type ReadCallback = Rc<dyn Read + 'static>;
52
53#[macro_export]
54macro_rules! build_register_view {
55 (
56 $(#[$($reg_attrs:tt)*])*
57 $reg:ident, $state:path, $state_perms:path, $priority:ident ;
58 $(
59 $(#[$($field_attrs:tt)*])*
60 $field:ident : $perms:expr
61 ),+ $(,)*
62 ) => {
63 $crate::registers::paste! {
64 $(#[$($reg_attrs)*])*
65 #[doc=concat!("\n\nFor field details, see [`", stringify!($reg), "`](", stringify!($state), ").")]
66 #[doc=concat!("\n\nThis view has the following permissions for each field:\n")]
67 $(
68 #[doc=concat!(" - ", stringify!($field), ": [`", stringify!($perms), "`](crate::registers::Permission).")]
69 )+
70 pub struct [< $reg Reg >] {
71 state: std::rc::Rc<$state>,
72 perms: $state_perms,
73 write_callbacks: Vec<$crate::registers::register::WrittenCallback>,
74 read_callbacks: Vec<$crate::registers::register::ReadCallback>,
75 priority: $crate::registers::state::UpdatePriority,
76 }
77
78 impl [< $reg Reg >] {
79 pub fn new(state: std::rc::Rc<$state>) -> Self {
80 let perms = $state_perms {
81 $(
82 $field: $crate::registers::Permission::$perms,
83 )+
84 };
85 Self {
86 state,
87 perms,
88 write_callbacks: Vec::new(),
89 read_callbacks: Vec::new(),
90 priority: $crate::registers::state::UpdatePriority::$priority,
91 }
92 }
93
94 #[allow(dead_code)]
96 pub fn install_write_cb(&mut self, cb: $crate::registers::register::WrittenCallback) {
97 self.write_callbacks.push(cb);
98 }
99
100 #[allow(dead_code)]
102 pub fn install_read_cb(&mut self, cb: $crate::registers::register::ReadCallback) {
103 self.read_callbacks.push(cb);
104 }
105 }
106
107 impl $crate::registers::register::Register for [< $reg Reg >] {
108 fn write(&self, resolver: &impl gwr_engine::traits::Resolver, value: u64) {
109 let old_value = self.state.value();
110 let new_value = self.state.write(self.priority, &self.perms, value);
111
112 for cb in &self.write_callbacks {
113 cb.written(old_value, value, new_value);
114 }
115 resolver.add_resolve(self.state.clone());
116 }
117
118 fn set(&self, resolver: &impl gwr_engine::traits::Resolver, value: u64) {
119 self.state.set(self.priority, &self.perms, value);
120 resolver.add_resolve(self.state.clone());
121 }
122
123 fn read(&self) -> u64 {
124 let value = self.state.read(&self.perms);
125 for cb in &self.read_callbacks {
126 cb.read(value);
127 }
128 value
129 }
130
131 fn value(&self) -> u64 {
132 let value = self.state.value();
133 value
134 }
135
136 fn reset_sync(&self, resolver: &impl gwr_engine::traits::Resolver) {
137 self.state.reset_sync();
138 resolver.add_resolve(self.state.clone());
139 }
140
141 fn reset_async(&self) {
142 self.state.reset_async();
143 }
144 }
145 }}
146}