1

I have two arrays:

struct Data {
    all_objects: Vec<Rc<dyn Drawable>>;
    selected_objects: Vec<Rc<dyn Drawable>>;
}

selected_objects is guarenteed to be a subset of all_objects. I want to be able to somehow be able to add or remove mutable references to selected objects.

I can add the objects easily enough to selected_objects:

Rc::get_mut(selected_object).unwrap().select(true);
self.selected_objects.push(selected_object.clone());

However, if I later try:

for obj in self.selected_objects.iter_mut() {
    Rc::get_mut(obj).unwrap().select(false);
}

This gives a runtime error, which matches the documentation for get_mut: "Returns None otherwise, because it is not safe to mutate a shared value."

However, I really want to be able to access and call arbitrary methods on both arrays, so I can efficiently perform operations on the selection, while also being able to still perform operations for all objects.

It seems Rc does not support this, it seems RefMut is missing a Clone() that alows me to put it into multiple arrays, plus not actually supporting dyn types. Box is also missing a Clone(). So my question is, how do you store writable pointers in multiple arrays? Is there another type of smart pointer for this purpose? Do I need to nest them? Is there some other data structure more suitable? Is there a way to give up the writable reference?

mousetail
  • 7,009
  • 4
  • 25
  • 45
  • `elected_objects is guarenteed to be a subset of all_objects` - so it's a [`slice`](https://doc.rust-lang.org/std/primitive.slice.html)? – KamilCuk Feb 29 '20 at 20:23
  • I don't think, they are not guaranteed to be continuous or evenly spaced. It's just an arbitrary subset – mousetail Feb 29 '20 at 20:26
  • Does this answer your question? [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct) – Stargateur Feb 29 '20 at 22:10

1 Answers1

1

Ok, it took me a bit of trial and error, but I have a ugly solution:

struct Data {
    all_objects: Vec<Rc<RefCell<dyn Drawable>>>;
    selected_objects: Vec<Rc<RefCell<dyn Drawable>>>;
}

The Rc allows you to store multiple references to an object. RefCell makes these references mutable. Now the only thing I have to do is call .borrow() every time I use a object.

While this seems to work and be reasonably versitle, I'm still open for cleaner solutions.

mousetail
  • 7,009
  • 4
  • 25
  • 45