Skip to content

Commit

Permalink
Feature/cycle event limit (#21)
Browse files Browse the repository at this point in the history
* limit the number of events

* only count single events

* handle event limit errors from Cycle in event iters

- panic in the plain rust cycle event iter
- set a lua callback error in the scripted cycle event iter

* add new 'with_seed' and 'with_event_limit' configure functions to Cycle

-  to ease constructing it and to add a constant for the event limit default
- to avoid passing "None" for seeds all the time

---------

Co-authored-by: Eduard Müller <[email protected]>
  • Loading branch information
unlessgames and emuell authored Jun 14, 2024
1 parent 5a6f8bc commit 685ebe4
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 87 deletions.
6 changes: 4 additions & 2 deletions src/bindings/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ pub struct CycleUserData {

impl CycleUserData {
pub fn from(arg: LuaString, seed: Option<[u8; 32]>) -> LuaResult<Self> {
// a single value, probably a sequence
let cycle = Cycle::from(&arg.to_string_lossy(), seed).map_err(LuaError::runtime)?;
let mut cycle = Cycle::from(&arg.to_string_lossy()).map_err(LuaError::runtime)?;
if let Some(seed) = seed {
cycle = cycle.with_seed(seed);
}
let mappings = Vec::new();
let mapping_function = None;
Ok(CycleUserData {
Expand Down
20 changes: 15 additions & 5 deletions src/event/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ impl CycleEventIter {
///
/// Returns error when the cycle string failed to parse.
pub fn from_mini(input: &str) -> Result<Self, String> {
Ok(Self::new(Cycle::from(input, None)?))
Ok(Self::new(Cycle::from(input)?))
}

/// Try creating a new cycle event iter from the given mini notation string
/// and the given seed for the cycle's random number generator.
///
/// Returns error when the cycle string failed to parse.
pub fn from_mini_with_seed(input: &str, seed: Option<[u8; 32]>) -> Result<Self, String> {
Ok(Self::new(Cycle::from(input, seed)?))
pub fn from_mini_with_seed(input: &str, seed: [u8; 32]) -> Result<Self, String> {
Ok(Self::new(Cycle::from(input)?.with_seed(seed)))
}

/// Return a new cycle with the given value mappings applied.
Expand Down Expand Up @@ -163,9 +163,19 @@ impl CycleEventIter {
/// Generate next batch of events from the next cycle run.
/// Converts cycle events to note events and flattens channels into note columns.
fn generate_events(&mut self) -> Vec<EventIterItem> {
// run the cycle event generator
let events = {
match self.cycle.generate() {
Ok(events) => events,
Err(err) => {
// NB: only expected error here is exceeding the event limit
panic!("Cycle runtime error: {err}");
}
}
};
let mut timed_note_events = CycleNoteEvents::new();
// convert possibly mapped cycle channel items to a list of note events
for (channel_index, channel_events) in self.cycle.generate().into_iter().enumerate() {
for (channel_index, channel_events) in events.into_iter().enumerate() {
for event in channel_events.into_iter() {
let start = event.span().start();
let length = event.span().length();
Expand Down Expand Up @@ -213,7 +223,7 @@ pub fn new_cycle_event(input: &str) -> Result<CycleEventIter, String> {

pub fn new_cycle_event_with_seed(
input: &str,
seed: Option<[u8; 32]>,
seed: [u8; 32],
) -> Result<CycleEventIter, String> {
CycleEventIter::from_mini_with_seed(input, seed)
}
13 changes: 12 additions & 1 deletion src/event/scripted_cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,24 @@ impl ScriptedCycleEventIter {
/// Generate next batch of events from the next cycle run.
/// Converts cycle events to note events and flattens channels into note columns.
fn generate_events(&mut self) -> Vec<EventIterItem> {
// run the cycle event generator
let events = {
match self.cycle.generate() {
Ok(events) => events,
Err(err) => {
add_lua_callback_error("cycle", &LuaError::RuntimeError(err));
// skip processing events
return vec![];
}
}
};
// reset timeout hook for mapping functions
if let Some(timeout_hook) = &mut self.timeout_hook {
timeout_hook.reset();
}
// convert possibly mapped cycle channel items to a list of note events
let mut timed_note_events = CycleNoteEvents::new();
for (channel_index, channel_events) in self.cycle.generate().into_iter().enumerate() {
for (channel_index, channel_events) in events.into_iter().enumerate() {
for (event_index, event) in channel_events.into_iter().enumerate() {
let start = event.span().start();
let length = event.span().length();
Expand Down
Loading

0 comments on commit 685ebe4

Please sign in to comment.