I'm trying to provide "views" of non-owned structs to separate components of a system.
Assume a set of traits with distinct methods: Drawable
, Modifiable
and a number of structs which implement at least one of the traits - SimpleBox
, Panel
, Expression
.
Different components of the system will need to frequently access sequences of these objects, using methods of specific traits; consider a DrawingManager
or a ModifyManager
:
struct DrawingManager {
items: Vec<Weak<Drawable>>,
}
struct ModifyManager {
items: Vec<Weak<Modifiable>>
}
While a single object may be referenced in both managers, assume that there is a separate single owner of all structs:
struct ObjectManager {
boxes: Vec<Rc<Box>>,
panels: Vec<Rc<Panel>>,
expressions: Vec<Rc<Expression>>,
}
Ideally, it would be useful to be able to manage deleting structs from one place - i.e simply removing it from the ObjectManager
being enough to invalidate references in all other components (hence the use of Weak
).
- Is there a way of doing this?
- Is this the correct way to achieve this?
- Is there a more idiomatic way of implementing this functionality?
The system contains several traits, so making a single trait using methods of all the other traits seems like a bad idea. Several traits have more than one method, so replacing them with closures is not possible.
What I have tried
As one object may produce one or more Rc<Trait>
, we might envision implementing this with a HashMap<ID, Vec<Rc<Any>>>
whereby we make each struct have a unique ID
, which maps to a list of all Rc
that have been made for it.
When we want to remove an object, we remove it from the corresponding list, and remove the entry in the hashmap, invalidating all Weak
references.
However, implementing this fails, as to insert into the HashMap
, one must upcast a Rc<Trait>
-> Rc<Any>
, only to downcast it later.
Rc<struct> -> Rc<Trait>
by cloning, and then convert a reference to that toWeak<Trait>
usingRc::downgrade
, I have not found a suitable way to first store theRc<Trait>
into a sequence of a supertype (for exampleVec<Rc<Any>>
, and then downcast the reference to the supertype back into a reference to the original type (&Rc<Any> -> &Rc<Trait>
) . - Kiran Gopinathanvec<Weak<Trait>>
, rather than several lists of each independent type. It just so happens that in my example I have an issue with downcasting (but only because I upcasted immediately prior). - Kiran Gopinathan