Firstly I'm aware this is not the best architecture, but project requires this.
I have a problem of multiple types/structs implementations requiring mutable access to each others. For example i have A, B and C where (this is just an example):
- A needs &mut B and &mut C
- B needs &mut A and &mut C
- C needs &mut A and &mut B
I don't want to use Arc/RefCell everywhere so I searched some more. Other forum posts recommend to use some kind of a pool, store only ids and get mutable reference by id:
struct Pool {
a: Vec<A>,
b: Vec<B>,
c: Vec<C>,
// many more
}
// what I would like is this:
impl A {
fn mutate(&self, pool: &mut Pool) {
pool.b.get_mut(self.b_id).mutate();
pool.c.get_mut(self.c_id).mutate();
}
}
But the problem with this is that I can't pass the Pool object via mutable reference to the A, because Pool contains that A and borrow checker doesn't like it. So instead I had to adapt:
struct ADependencies<'a> {
b: &'a mut Vec<B>,
c: &'a mut Vec<C>,
}
impl A {
fn mutate(&self, dependencies: ADependencies) {
dependencies.b.get_mut(self.b_id).mutate(BDependencies { ... });
dependencies.c.get_mut(self.c_id).mutate(CDependencies { ... });
}
}
a.mutate(ADependencies {
b: &mut pool.b,
c: &mut pool.c,
});
This works but the problem is that I now need to create all these XDependencies
structs for each object and it is a lot of boilerplate code. Moving all functions from objects to the level of the Pool object is not really feasible.
I also would like to avoid following (doesn't play well with nested calls):
a.mutate(pool.b.get_mut(a.b_id), pool.c.get_mut(a.c_id));
Is there any other way around it? Maybe I'm missing something?