Совместное использование слабых признаков объекта

Я пытаюсь предоставить "взгляды" на не принадлежащие ему структуры для разделения компонентов системы.

Предположим, набор черт с различными методами: Drawable, Modifiable и ряд структур, которые реализуют по крайней мере одну из черт - SimpleBox, Panel, Expression,

Различные компоненты системы должны будут часто получать доступ к последовательностям этих объектов, используя методы определенных черт; рассмотреть DrawingManager или ModifyManager:

struct DrawingManager {
    items: Vec<Weak<Drawable>>,
}

struct ModifyManager {
    items: Vec<Weak<Modifiable>>
}

В то время как на оба менеджера можно ссылаться на один объект, предположим, что существует отдельный владелец всех структур:

struct ObjectManager {
    boxes: Vec<Rc<Box>>,
    panels: Vec<Rc<Panel>>,
    expressions: Vec<Rc<Expression>>,
}

В идеале было бы полезно иметь возможность управлять удалением структур из одного места - т.е. просто удалять их из ObjectManager быть достаточным для аннулирования ссылок во всех других компонентах (следовательно, использование Weak).

  • Есть ли способ сделать это?
  • Это правильный путь для достижения этого?
  • Есть ли более идиоматический способ реализации этой функциональности?

Система содержит несколько черт, поэтому создание единой черты с использованием методов всех других черт кажется плохой идеей. Несколько признаков имеют более одного метода, поэтому заменить их замыканиями невозможно.

Что я пробовал

Как один объект может производить один или несколько Rc<Trait>мы могли бы представить реализацию этого с HashMap<ID, Vec<Rc<Any>>> в результате чего каждая структура имеет уникальный ID, который отображается на список всех Rc которые были сделаны для этого.

Когда мы хотим удалить объект, мы удаляем его из соответствующего списка и удаляем запись в hashmap, аннулируя все Weak Рекомендации.

Однако реализовать это не удается, так как вставить в HashMapнужно подбросить Rc<Trait> -> Rc<Any>Только чтобы удручить это позже.

1 ответ

Я не уверен, что это идиоматический способ сделать это, но с тех пор я разработал ящик, обеспечивающий эту функциональность - dependent_view,

Используя ящик, начальная проблема может быть решена с помощью DependentRc вместо простого Rc "S:

struct ObjectManager {
    boxes: Vec<DependentRc<Box>>,
    panels: Vec<DependentRc<Panel>>,
    expressions: Vec<DependentRc<Expression>>
}

let object_manager : ObjectManager = ObjectManager::new();

Затем с помощью макросов, предоставленных ящиком, мы можем получить Weak<> ссылки на эти структуры:

let box_view : Weak<Drawable> = to_view!(object_manager.boxes[0]);
let panel_view : Weak<Drawable> = to_view!(object_manager.panels[0]);
let expression_view : Weak<Drawable> = to_view!(object_manager.expressions[0]);

При этом сбросив соответствующий DependentRc<> лишит законной силы все Weak<> ссылки, которые были сделаны из него.

Другие вопросы по тегам