1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use crate::{ObjectType, Ref, Upcast, WeakRef};
use std::fmt;
/// A reference to an element that the holder does not own: the value type
/// of properties such as a placement target, the target of a label or the
/// element an adorner adorns.
///
/// Such a property points sideways or up the tree — often at an ancestor of
/// the element it is set on — so holding the element strongly would make
/// the two keep each other alive. An `ElementRef` holds it weakly and
/// compares by identity. Classes expose these properties with getters that
/// return `Option<Ref<T>>` and setters that take `impl Into<Nullable<T>>`;
/// untyped access and bindings convert to and from `Ref<T>` (see
/// `ValueTypes::register_element_ref`).
///
/// When the referenced element is dropped the reference reads as nothing;
/// no change notification is raised for that.
pub struct ElementRef<T: ObjectType>(WeakRef<T>);
impl<T: ObjectType> ElementRef<T> {
/// Creates a reference to `element`.
#[inline]
pub fn new<U: ObjectType + Upcast<T>>(element: &Ref<U>) -> Self {
ElementRef(element.downgrade().upcast())
}
/// Creates a reference to an element of exactly class `T`.
#[inline]
pub fn of(element: &Ref<T>) -> Self {
ElementRef(element.downgrade())
}
/// The property value for an optional element.
#[inline]
pub fn from_nullable(element: Option<Ref<T>>) -> Option<Self> {
element.map(|element| ElementRef(element.downgrade()))
}
/// The referenced element, if it is still alive.
#[inline]
pub fn get(&self) -> Option<Ref<T>> {
self.0.upgrade()
}
/// The element referenced by a property value.
#[inline]
pub fn resolve(value: &Option<Self>) -> Option<Ref<T>> {
value.as_ref().and_then(ElementRef::get)
}
/// Whether the reference points at `element`.
#[inline]
pub fn points_to<U: ObjectType>(&self, element: &Ref<U>) -> bool {
self.0.points_to(element)
}
}
impl<T: ObjectType> Clone for ElementRef<T> {
#[inline]
fn clone(&self) -> Self {
ElementRef(self.0.clone())
}
}
/// Identity: two references are equal when they point at the same element,
/// whether or not it is still alive.
impl<T: ObjectType> PartialEq for ElementRef<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0.ptr_eq(&other.0)
}
}
impl<T: ObjectType> fmt::Debug for ElementRef<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.get() {
Some(_) => write!(f, "ElementRef<{}>", T::TYPE.name()),
None => write!(f, "ElementRef<{}>(dropped)", T::TYPE.name()),
}
}
}
impl<T: ObjectType + Upcast<U>, U: ObjectType> From<&Ref<T>> for ElementRef<U> {
#[inline]
fn from(value: &Ref<T>) -> Self {
ElementRef::new(value)
}
}