rive_rs/shapes/
points_path.rs

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
89
90
91
92
93
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::bones::{Skin, Skinnable};
use crate::component::Component;
use crate::component_dirt::ComponentDirt;
use crate::core::{Core, Object, ObjectRef, OnAdded, Property};
use crate::math::Mat;
use crate::option_cell::OptionCell;
use crate::shapes::path::Path;
use crate::transform_component::TransformComponent;

#[derive(Debug, Default)]
pub struct PointsPath {
    path: Path,
    is_closed: Property<bool>,
    skin: OptionCell<Object<Skin>>,
}

impl ObjectRef<'_, PointsPath> {
    pub fn is_closed(&self) -> bool {
        self.is_closed.get()
    }

    pub fn set_is_closed(&self, is_closed: bool) {
        self.is_closed.set(is_closed);
    }
}

impl ObjectRef<'_, PointsPath> {
    pub fn transform(&self) -> Mat {
        if self.skin.get().is_some() {
            Mat::default()
        } else {
            self.cast::<TransformComponent>().world_transform()
        }
    }

    pub fn mark_path_dirty(&self) {
        if let Some(skin) = self.skin.get() {
            skin.as_ref().cast::<Component>().add_dirt(ComponentDirt::PATH, false);
        }
    }

    pub fn is_path_closed(&self) -> bool {
        self.is_closed()
    }

    pub fn build_dependencies(&self) {
        self.cast::<Path>().build_dependencies();

        if let Some(skin) = self.skin.get() {
            skin.as_ref().cast::<Component>().push_dependent(self.as_object().cast());
        }
    }

    pub fn update(&self, value: ComponentDirt) {
        let path = self.cast::<Path>();

        if Component::value_has_dirt(value, ComponentDirt::PATH) {
            if let Some(skin) = self.skin.get() {
                skin.as_ref().deform(path.vertices());
            }
        }

        path.update(value);
    }
}

impl Skinnable for ObjectRef<'_, PointsPath> {
    fn skin(&self) -> Option<Object<Skin>> {
        self.skin.get()
    }

    fn set_skin(&self, skin: Object<Skin>) {
        self.skin.set(Some(skin));
    }

    fn mark_skin_dirty(&self) {
        self.cast::<Path>().mark_path_dirty();
    }
}

impl Core for PointsPath {
    parent_types![(path, Path)];

    properties![(32, is_closed, set_is_closed), path];
}

impl OnAdded for ObjectRef<'_, PointsPath> {
    on_added!(Path);
}