rusteal 0.9.0

Rust bindings for Unreal Engine 5.8.2
use bindings::core_ue::FTransform;
use bindings::engine::{
    Actor, ActorComponent, ActorExt, SubsystemBlueprintLibrary, WorldSubsystem,
};
use bindings::rusteal::RustealWorldSubsystem;
use rusteal_runtime::runtime::{RustealResult, SubclassOf, Transform, UObjectRef, UeClass};
use rusteal_runtime::{uclass, uclass_impl};

use crate::component::{{ plugin }}Component;

#[uclass(parent = RustealWorldSubsystem)]
pub struct {{ plugin }}Subsystem {}

#[uclass_impl]
impl {{ plugin }}Subsystem {
    #[ufunction]
    pub fn inventory_of(
        &mut self,
        actor: UObjectRef<Actor>,
        create: bool,
    ) -> UObjectRef<{{ plugin }}Component> {
        find_or_add(actor, create).unwrap_or_else(|_| UObjectRef::null())
    }
}

impl {{ plugin }}Subsystem {
    pub fn get(context: UObjectRef<bindings::core_ue::Object>) -> RustealResult<Self> {
        let class = SubclassOf::<Self>::base().upcast_to::<WorldSubsystem>();

        Self::from_obj(SubsystemBlueprintLibrary::get_world_subsystem(
            context, class,
        ))
    }
}

fn find_or_add(
    actor: UObjectRef<Actor>,
    create: bool,
) -> RustealResult<UObjectRef<{{ plugin }}Component>> {
    let actor = actor.checked()?;
    let class = SubclassOf::<{{ plugin }}Component>::base().upcast_to::<ActorComponent>();
    let mut component = actor.get_component_by_class(class);
    if !component.is_valid() && create {
        let identity = FTransform::from_transform(Transform::IDENTITY);
        component = actor.add_component_by_class(class, false, &identity, false);
    }
    component.cast::<{{ plugin }}Component>()
}