commonlibsse_ng\re\b/
BSAnimationGraphManager.rs

1//! # BSAnimationGraph
2use crate::re::BSAnimationCache;
3use crate::re::BSAnimationGraphChannel::BSAnimationGraphChannel;
4use crate::re::BSAnimationGraphEvent::BSAnimationGraphEvent;
5use crate::re::BSAnimationGraphManagerPtr;
6use crate::re::BSAtomic::BSSpinLock;
7use crate::re::BSFixedString::BSFixedString;
8use crate::re::BSIntrusiveRefCounted::BSIntrusiveRefCounted;
9use crate::re::BSIntrusiveRefCounted::BSIntrusiveRefCountedTrait;
10use crate::re::BSTArray::BSTArray;
11use crate::re::BSTEvent::BSTEventSink;
12use crate::re::BSTSmartPointer::BSTSmartPointer;
13use crate::re::BShkbAnimationGraph::BShkbAnimationGraph;
14use crate::re::offsets_rtti::RTTI_BSAnimationGraphManager;
15use crate::re::offsets_vtable::VTABLE_BSAnimationGraphManager;
16use crate::rel::id::VariantID;
17use crate::rel::module::ModuleState;
18use crate::rel::relocation::{
19    PhantomMember, RelocationError, relocate_member_if_newer, relocate_member_mut,
20};
21use crate::skse::version::RUNTIME_SSE_1_6_629;
22
23#[repr(C)]
24#[derive(Debug)]
25pub struct BSAnimationGraphManager {
26    pub __base: BSTEventSink<BSAnimationGraphEvent>,
27    pub __base1: BSIntrusiveRefCounted,
28    pub pad0C: u32,
29    pub boundChannels: BSTArray<BSTSmartPointer<BSAnimationGraphChannel>>,
30    pub bumpedChannels: BSTArray<BSTSmartPointer<BSAnimationGraphChannel>>,
31    pub graphs: BSTArray<BSTSmartPointer<BShkbAnimationGraph>>,
32    pub subManagers: BSTArray<BSAnimationGraphManagerPtr>,
33    pub variableCache: BSAnimationCache,
34
35    //////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
36    // runtime data
37    //
38    /// Lock for updating data.
39    /// Offset: `0x98` (SE), `0xA0` (AE)
40    pub updateLock: PhantomMember<BSSpinLock, 0x98, 0xa0>,
41
42    /// Lock for dependent manager.
43    /// Offset: `0xA0`
44    pub dependentManagerLock: PhantomMember<BSSpinLock, 0xa0, 0xa8>,
45
46    /// Active graph index.
47    /// Offset: `0xA8`
48    pub activeGraph: PhantomMember<u32, 0xa8, 0xb0>,
49
50    /// Graph generation depth.
51    /// Offset: `0xAC`
52    pub generateDepth: PhantomMember<u32, 0xac, 0xb4>,
53}
54const _: () = {
55    assert!(core::mem::offset_of!(BSAnimationGraphManager, __base) == 0x0);
56    assert!(core::mem::offset_of!(BSAnimationGraphManager, __base1) == 0x8);
57    assert!(core::mem::offset_of!(BSAnimationGraphManager, pad0C) == 0x0C);
58    assert!(core::mem::offset_of!(BSAnimationGraphManager, boundChannels) == 0x10);
59    assert!(core::mem::offset_of!(BSAnimationGraphManager, bumpedChannels) == 0x28);
60    assert!(core::mem::offset_of!(BSAnimationGraphManager, graphs) == 0x40);
61    assert!(core::mem::offset_of!(BSAnimationGraphManager, subManagers) == 0x58);
62    assert!(core::mem::offset_of!(BSAnimationGraphManager, variableCache) == 0x70);
63    assert!(core::mem::size_of::<BSAnimationGraphManager>() == 0x70);
64};
65
66impl BSAnimationGraphManager {
67    /// Address & offset of the runtime type information (RTTI) identifier.
68    pub const RTTI: VariantID = RTTI_BSAnimationGraphManager;
69
70    /// Address & offset of the virtual function table.
71    pub const VTABLE: [VariantID; 1] = VTABLE_BSAnimationGraphManager;
72}
73
74impl BSIntrusiveRefCountedTrait for BSAnimationGraphManager {
75    #[inline]
76    fn inc_ref(&self) -> u32 {
77        self.__base1.inc_ref()
78    }
79
80    #[inline]
81    fn dec_ref(&self) -> u32 {
82        self.__base1.dec_ref()
83    }
84}
85
86#[repr(C)]
87// #[derive(Debug, Clone, Copy, PartialEq)]
88pub union HkbVariableValue {
89    pub b: bool,
90    pub i: i32,
91    pub f: f32,
92}
93
94const _: () = {
95    assert!(std::mem::size_of::<HkbVariableValue>() == 0x4);
96};
97
98#[repr(C)]
99#[derive(Debug)]
100pub struct AnimVariableCacheInfo {
101    /// Variable name.
102    /// Offset: `0x00`
103    pub variable_name: BSFixedString,
104
105    /// Pointer to the variable value.
106    /// Offset: `0x08`
107    pub variable: *mut HkbVariableValue,
108}
109
110const _: () = {
111    assert!(std::mem::size_of::<AnimVariableCacheInfo>() == 0x10);
112};
113
114#[repr(C)]
115#[derive(Debug)]
116pub struct BSAnimationGraphVariableCache {
117    /// Cache of animation variables.
118    /// Offset: `0x00`
119    pub variable_cache: BSTArray<AnimVariableCacheInfo>,
120
121    /// Lock for updating cache.
122    /// Offset: `0x18`
123    pub update_lock: BSSpinLock,
124
125    /// Smart pointer to the animation graph (SE only).
126    /// Offset: `0x20` (SE), `0x28` (AE)
127    pub animation_graph: BSTSmartPointer<BShkbAnimationGraph>,
128}
129
130const _: () = {
131    assert!(std::mem::size_of::<BSAnimationGraphVariableCache>() == 0x28);
132};
133
134impl BSAnimationGraphVariableCache {
135    /// Gets the graph lock (Skyrim AE only).
136    #[inline]
137    pub fn get_graph_lock(&mut self) -> Option<&mut BSSpinLock> {
138        let is_ae_1_6_629 =
139            ModuleState::map_or_init(|module| module.version >= RUNTIME_SSE_1_6_629).ok()?;
140        if is_ae_1_6_629 {
141            return relocate_member_mut(self, 0x20, 0x20).ok();
142        }
143
144        None
145    }
146
147    /// Gets the animation graph (SE only).
148    ///
149    /// # Errors
150    #[inline]
151    pub fn get_animation_graph(
152        &self,
153    ) -> Result<&BSTSmartPointer<BShkbAnimationGraph>, RelocationError> {
154        unsafe { relocate_member_if_newer(RUNTIME_SSE_1_6_629, self, 0x20, 0x28) }
155    }
156}