GregoryConrad / rearch-rs

Re-imagined approach to application design and architecture
https://crates.io/crates/rearch
MIT License
81 stars 4 forks source link

Consider "multi-effect" side effect to avoid needing tuples of effects #50

Closed GregoryConrad closed 5 months ago

GregoryConrad commented 5 months ago

I still think I want to keep the default register api as-is, but I think a side effect (in rearch-effects) like the following would be a nice touch:

let register = register(effects::multi::<16>()); // 16 is const generic for size of backing array
let (count, set_count) = register(effects::state::<Cloned<_>>(0));
let mut num_builds = register(effects::value::<MutRef<_>>(0));
*num_builds += 1;

Note that in the above example, the backing array size could be 2. 16 is just chosen as a sane default.

This should be possible with 100% safe rust via split_first_mut:

curr_slice = &mut backing_array;
register:
  let (curr_element, rest_slice) = self.curr_slice.split_first_mut().unwrap_or(|| panic!(“you need to increase length passed into multi!”));
  *self.curr_slice = rest_slice;
  return curr_element.some_cast_and_transform();
GregoryConrad commented 5 months ago

As a note: the only way to do this safely without a set upper-bound size (16 above) is to use a linked list. That is both:

This is because each side effects needs to return a mut ref. Can't have multiple mutable borrows on the same object at the same time, unless you use something sneaky like split_at_mut