diff --git a/rumcake-macros/src/via.rs b/rumcake-macros/src/via.rs index 8492c52..c897d21 100644 --- a/rumcake-macros/src/via.rs +++ b/rumcake-macros/src/via.rs @@ -18,14 +18,16 @@ pub fn setup_macro_buffer(args: Punctuated) -> TokenStream { const DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE: u16 = #buffer_size; const DYNAMIC_KEYMAP_MACRO_COUNT: u8 = #macro_count; - fn get_macro_buffer() -> &'static mut ::rumcake::via::MacroBuffer< - 'static, - { Self::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE as usize }, - { Self::DYNAMIC_KEYMAP_MACRO_COUNT as usize }, + fn get_macro_buffer() -> Option< + &'static mut ::rumcake::via::MacroBuffer< + 'static, + { Self::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE as usize }, + { Self::DYNAMIC_KEYMAP_MACRO_COUNT as usize }, + >, > { static mut MACRO_BUFFER: ::rumcake::via::MacroBuffer<'static, #buffer_size, #macro_count> = ::rumcake::via::MacroBuffer::new(); - unsafe { &mut MACRO_BUFFER } + Some(unsafe { &mut MACRO_BUFFER }) } } } diff --git a/rumcake/src/via/handlers.rs b/rumcake/src/via/handlers.rs index e47c8f9..8e936e9 100644 --- a/rumcake/src/via/handlers.rs +++ b/rumcake/src/via/handlers.rs @@ -92,7 +92,9 @@ where [(); K::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE as usize]:, [(); K::DYNAMIC_KEYMAP_MACRO_COUNT as usize]:, { - K::get_macro_buffer().buffer.fill(0); + if let Some(macro_data) = K::get_macro_buffer() { + macro_data.buffer.fill(0) + }; } pub fn dynamic_keymap_macro_get_buffer_size(data: &mut [u8]) { @@ -113,9 +115,9 @@ pub async fn dynamic_keymap_macro_get_buffer( size as usize }; - let buf = K::get_macro_buffer().buffer; - - data[..len].copy_from_slice(&buf[(offset as usize)..(offset as usize + len)]); + if let Some(macro_data) = K::get_macro_buffer() { + data[..len].copy_from_slice(¯o_data.buffer[(offset as usize)..(offset as usize + len)]); + }; } pub async fn dynamic_keymap_macro_set_buffer( @@ -132,7 +134,9 @@ pub async fn dynamic_keymap_macro_set_buffer( size as usize }; - K::get_macro_buffer().update_buffer(offset as usize, &data[..len]); + if let Some(macro_data) = K::get_macro_buffer() { + macro_data.update_buffer(offset as usize, &data[..len]); + } #[cfg(feature = "storage")] super::storage::update_data( diff --git a/rumcake/src/via/mod.rs b/rumcake/src/via/mod.rs index 29d9a1e..46b5ab4 100644 --- a/rumcake/src/via/mod.rs +++ b/rumcake/src/via/mod.rs @@ -75,23 +75,31 @@ pub trait ViaKeyboard: Keyboard + KeyboardLayout { // const DYNAMIC_KEYMAP_LAYER_COUNT: usize = 4; // This is the default if this variable isn't defined in QMK /// The number of macros that your keyboard can store. You should use [`setup_macro_buffer`] to - /// implement this. + /// implement this. If you plan on using macros, this should be non-zero. const DYNAMIC_KEYMAP_MACRO_COUNT: u8 = 0; // This is the default if this variable isn't defined in QMK - /// The total amount of bytes that can be used to store macros assigned by Via. - const DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE: u16; + /// The total amount of bytes that can be used to store macros assigned by Via. You should use + /// [`setup_macro_buffer`] to implement this. If you plan on using macros, this should be + /// non-zero. + const DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE: u16 = 0; /// Determines how QK_BACKLIGHT keycodes should be converted to a [`crate::keyboard::Keycode`] /// and vice versa. If this is `None`, then backlighting keycodes will not be converted. const BACKLIGHT_TYPE: Option = None; /// Obtain a reference to macro data created by Via. You should use [`setup_macro_buffer`] to - /// implement this. - fn get_macro_buffer() -> &'static mut MacroBuffer< - 'static, - { Self::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE as usize }, - { Self::DYNAMIC_KEYMAP_MACRO_COUNT as usize }, - >; + /// implement this. If this returns `Some`, then [`ViaKeyboard::DYNAMIC_KEYMAP_MACRO_COUNT`] + /// and [`ViaKeyboard::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE`] should be non-zero. Otherwise, + /// [`ViaKeyboard::DYNAMIC_KEYMAP_MACRO_COUNT`] should be 0. + fn get_macro_buffer() -> Option< + &'static mut MacroBuffer< + 'static, + { Self::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE as usize }, + { Self::DYNAMIC_KEYMAP_MACRO_COUNT as usize }, + >, + > { + None + } /// Override for handling a Via/Vial protocol packet. /// @@ -162,6 +170,21 @@ where { assert!(K::DYNAMIC_KEYMAP_LAYER_COUNT <= K::LAYERS); assert!(K::DYNAMIC_KEYMAP_LAYER_COUNT <= 16); + if K::get_macro_buffer().is_some() { + assert!( + K::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE > 0, + "Macro buffer size must be greater than 0 if you are using Via macros." + ); + assert!( + K::DYNAMIC_KEYMAP_MACRO_COUNT > 0, + "Macro count must be greater than 0 if you are using Via macros." + ); + } else { + assert!( + K::DYNAMIC_KEYMAP_MACRO_COUNT == 0, + "Macro count should be 0 if you are not using Via macros." + ); + } let via_state: Mutex> = Mutex::new(Default::default()); @@ -368,7 +391,9 @@ pub mod storage { ) .await { - K::get_macro_buffer().update_buffer(0, &stored_data[..stored_len]) + if let Some(macro_data) = K::get_macro_buffer() { + macro_data.update_buffer(0, &stored_data[..stored_len]) + } }; } diff --git a/rumcake/src/via/protocol_12/keycodes.rs b/rumcake/src/via/protocol_12/keycodes.rs index 5e9320c..99bc1b5 100644 --- a/rumcake/src/via/protocol_12/keycodes.rs +++ b/rumcake/src/via/protocol_12/keycodes.rs @@ -953,17 +953,15 @@ where UNKNOWN_KEYCODE } } - Action::Sequence(sequence) => { - if let Some(macro_number) = K::get_macro_buffer() + Action::Sequence(sequence) => K::get_macro_buffer().map_or(UNKNOWN_KEYCODE, |macro_data| { + macro_data .sequences .iter() .position(|s| core::ptr::eq(s as *const _, sequence as *const _)) - { - QMKKeycodeRanges::QK_MACRO as u16 + macro_number as u16 - } else { - UNKNOWN_KEYCODE - } - } + .map_or(UNKNOWN_KEYCODE, |macro_number| { + QMKKeycodeRanges::QK_MACRO as u16 + macro_number as u16 + }) + }), Action::Custom(key) => match key { Keycode::Custom(id) => { if id as u16 <= 31 { @@ -1432,10 +1430,12 @@ where && keycode <= QMKKeycodeRanges::QK_MACRO_MAX as u16 { let sequence_number = (keycode - QMKKeycodeRanges::QK_MACRO as u16) as usize; - return K::get_macro_buffer() - .sequences - .get(sequence_number) - .map(Action::Sequence); + return K::get_macro_buffer().and_then(|macro_data| { + macro_data + .sequences + .get(sequence_number) + .map(Action::Sequence) + }); } if QMKKeycodeRanges::QK_LIGHTING as u16 <= keycode diff --git a/rumcake/src/vial/mod.rs b/rumcake/src/vial/mod.rs index b8cd6c0..310a238 100644 --- a/rumcake/src/vial/mod.rs +++ b/rumcake/src/vial/mod.rs @@ -3,6 +3,7 @@ //! To use Vial, you will need to implement [`ViaKeyboard`] and [`VialKeyboard`]. use crate::backlight::{BacklightMatrixDevice, EmptyBacklightMatrix}; +use defmt::assert; use embassy_futures::join; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; @@ -77,6 +78,21 @@ where assert!(K::DYNAMIC_KEYMAP_LAYER_COUNT <= K::LAYERS); assert!(K::DYNAMIC_KEYMAP_LAYER_COUNT <= 16); assert!(K::VIAL_UNLOCK_COMBO.len() < 15); + if K::get_macro_buffer().is_some() { + assert!( + K::DYNAMIC_KEYMAP_MACRO_BUFFER_SIZE > 0, + "Macro buffer size must be greater than 0 if you are using Via macros." + ); + assert!( + K::DYNAMIC_KEYMAP_MACRO_COUNT > 0, + "Macro count must be greater than 0 if you are using Via macros." + ); + } else { + assert!( + K::DYNAMIC_KEYMAP_MACRO_COUNT == 0, + "Macro count should be 0 if you are not using Via macros." + ); + } let vial_state: Mutex = Mutex::new(Default::default()); let via_state: Mutex> =