rive_rs/bones/
bone.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::bones::SkeletalComponent;
6use crate::component::Component;
7use crate::core::{Core, CoreContext, Object, ObjectRef, OnAdded, Property};
8use crate::dyn_vec::{DynVec, DynVecIter};
9use crate::status_code::StatusCode;
10use crate::TransformComponent;
11
12#[derive(Debug, Default)]
13pub struct Bone {
14    skeletal_component: SkeletalComponent,
15    length: Property<f32>,
16    child_bones: DynVec<Object<Self>>,
17}
18
19impl ObjectRef<'_, Bone> {
20    pub fn length(&self) -> f32 {
21        self.length.get()
22    }
23
24    pub fn set_length(&self, length: f32) {
25        if self.length() == length {
26            return;
27        }
28
29        self.length.set(length);
30
31        for bone in self.child_bones.iter() {
32            bone.cast::<TransformComponent>().as_ref().mark_transform_dirty();
33        }
34    }
35}
36
37impl ObjectRef<'_, Bone> {
38    pub fn child_bones(&self) -> DynVecIter<'_, Object<Bone>> {
39        self.child_bones.iter()
40    }
41
42    pub fn push_child_bone(&self, child_bone: Object<Bone>) {
43        self.child_bones.push(child_bone);
44    }
45
46    pub(crate) fn x(&self) -> f32 {
47        let parent = self.cast::<Component>().parent().expect("Bone does not have a parent");
48        parent.cast::<Bone>().as_ref().length()
49    }
50
51    pub(crate) fn y(&self) -> f32 {
52        0.0
53    }
54}
55
56impl Core for Bone {
57    parent_types![(skeletal_component, SkeletalComponent)];
58
59    properties![(89, length, set_length), skeletal_component];
60}
61
62impl OnAdded for ObjectRef<'_, Bone> {
63    on_added!([on_added_dirty, import], SkeletalComponent);
64
65    fn on_added_clean(&self, context: &dyn CoreContext) -> StatusCode {
66        self.cast::<SkeletalComponent>().on_added_clean(context);
67
68        if let Some(parent) = self.try_cast::<Component>().and_then(|component| component.parent())
69        {
70            parent.cast::<Bone>().as_ref().push_child_bone(self.as_object());
71        } else {
72            return StatusCode::MissingObject;
73        }
74
75        StatusCode::Ok
76    }
77}