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>()
}