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
use anyhow::{format_err, Error};
use crate::v7400::object::{ObjectHandle, ObjectId};
#[derive(Debug, Clone, Copy)]
pub struct SceneHandle<'a> {
object: ObjectHandle<'a>,
}
impl<'a> SceneHandle<'a> {
pub(crate) fn new(object: ObjectHandle<'a>) -> Option<Self> {
let is_document_node = object
.document()
.objects_cache()
.document_nodes()
.contains(&object.object_node_id());
if !is_document_node {
return None;
}
Some(Self { object })
}
pub fn root_object_id(&self) -> Result<ObjectId, Error> {
self.object
.node()
.children_by_name("RootNode")
.next()
.ok_or_else(|| format_err!("`RootNode` not found for scene object node"))?
.attributes()
.get(0)
.ok_or_else(|| format_err!("Attributes not found for `RootNode`"))?
.get_i64_or_type()
.map(ObjectId::new)
.map_err(|ty| {
format_err!(
"Unexpected attribute type for `RootNode`: expected `i64` but got {:?}",
ty
)
})
}
pub fn root_object(&self) -> Result<ObjectHandle<'_>, Error> {
self.root_object_id()?
.to_object_handle(self.object.document())
.ok_or_else(|| {
format_err!(
"Root object of the scene has no corresponding node: object_id={:?}",
self.object.object_id()
)
})
}
}
impl<'a> std::ops::Deref for SceneHandle<'a> {
type Target = ObjectHandle<'a>;
fn deref(&self) -> &Self::Target {
&self.object
}
}