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
/*
* Copyright (c) godot-rust; Bromeon and contributors.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
use crate::builtin::NodePath;
use crate::classes::{Node, PackedScene};
use crate::obj::{Gd, Inherits};
/// Manual extensions for the `Node` class.
impl Node {
/// ⚠️ Retrieves the node at path `path`, panicking if not found or bad type.
///
/// # Panics
/// If the node is not found, or if it does not have type `T` or inherited.
pub fn get_node_as<T>(&self, path: impl Into<NodePath>) -> Gd<T>
where
T: Inherits<Node>,
{
let path = path.into();
let copy = path.clone(); // TODO avoid copy
self.try_get_node_as(path).unwrap_or_else(|| {
panic!(
"There is no node of type {ty} at path `{copy}`",
ty = T::class_name()
)
})
}
/// Retrieves the node at path `path` (fallible).
///
/// If the node is not found, or if it does not have type `T` or inherited,
/// `None` will be returned.
pub fn try_get_node_as<T>(&self, path: impl Into<NodePath>) -> Option<Gd<T>>
where
T: Inherits<Node>,
{
let path = path.into();
// TODO differentiate errors (not found, bad type) with Result
self.get_node_or_null(path)
.and_then(|node| node.try_cast::<T>().ok())
}
}
// ----------------------------------------------------------------------------------------------------------------------------------------------
/// Manual extensions for the `PackedScene` class.
impl PackedScene {
/// ⚠️ Instantiates the scene as type `T`, panicking if not found or bad type.
///
/// # Panics
/// If the scene is not type `T` or inherited.
pub fn instantiate_as<T>(&self) -> Gd<T>
where
T: Inherits<Node>,
{
self.try_instantiate_as::<T>()
.unwrap_or_else(|| panic!("Failed to instantiate {to}", to = T::class_name()))
}
/// Instantiates the scene as type `T` (fallible).
///
/// If the scene is not type `T` or inherited.
pub fn try_instantiate_as<T>(&self) -> Option<Gd<T>>
where
T: Inherits<Node>,
{
self.instantiate().and_then(|gd| gd.try_cast::<T>().ok())
}
}