Files
AetherBags/KamiToolKit/Nodes/Component/ComponentNode.cs
T
KnackAtNite 8db4ce6094
Debug Build and Test / Build against Latest Dalamud (push) Has been cancelled
Debug Build and Test / Build against Staging Dalamud (push) Has been cancelled
Initial commit: AetherBags + KamiToolKit for FC Gitea
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 14:46:31 -05:00

113 lines
4.2 KiB
C#

using System;
using FFXIVClientStructs.FFXIV.Client.System.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
using KamiToolKit.Classes;
namespace KamiToolKit.Nodes;
public abstract unsafe class ComponentNode(NodeType nodeType) : NodeBase<AtkComponentNode>(nodeType) {
public abstract CollisionNode CollisionNode { get; }
public abstract AtkComponentBase* ComponentBase { get; }
public abstract AtkUldComponentDataBase* DataBase { get; }
}
public abstract unsafe class ComponentNode<T, TU> : ComponentNode where T : unmanaged, ICreatable where TU : unmanaged {
public sealed override CollisionNode CollisionNode { get; }
public sealed override AtkComponentBase* ComponentBase => Node->Component;
public sealed override AtkUldComponentDataBase* DataBase => Node->Component->UldManager.ComponentData;
protected ComponentNode() : base(NodeType.Component) {
Node->Component = (AtkComponentBase*) NativeMemoryHelper.Create<T>();
Node->Component->UldManager.ComponentData = (AtkUldComponentDataBase*)NativeMemoryHelper.UiAlloc<TU>();
ComponentBase->Initialize();
CollisionNode = new CollisionNode {
NodeId = 1,
LinkedComponent = ComponentBase,
NodeFlags = NodeFlags.Visible | NodeFlags.Enabled | NodeFlags.HasCollision |
NodeFlags.RespondToMouse | NodeFlags.Focusable | NodeFlags.EmitsEvents | NodeFlags.Fill,
};
CollisionNode.ResNode->ParentNode = ResNode;
CollisionNode.ParentUldManager = &((AtkComponentBase*)Component)->UldManager;
ChildNodes.Add(CollisionNode);
ComponentBase->OwnerNode = Node;
ComponentBase->ComponentFlags = 1;
ref var uldManager = ref ComponentBase->UldManager;
uldManager.Objects = (AtkUldObjectInfo*)NativeMemoryHelper.UiAlloc<AtkUldComponentInfo>();
ref var objects = ref uldManager.Objects;
uldManager.ObjectCount = 1;
SetInternalComponentType(ComponentType.Base);
objects->NodeList = (AtkResNode**)NativeMemoryHelper.Malloc(8);
objects->NodeList[0] = CollisionNode;
objects->NodeCount = 1;
objects->Id = 1000;
uldManager.InitializeResourceRendererManager();
uldManager.RootNode = CollisionNode;
uldManager.UpdateDrawNodeList();
uldManager.ResourceFlags = AtkUldManagerResourceFlag.Initialized | AtkUldManagerResourceFlag.ArraysAllocated;
uldManager.LoadedState = AtkLoadState.Loaded;
}
protected override void Dispose(bool disposing, bool isNativeDestructor) {
if (disposing) {
try {
if (!isNativeDestructor) {
Node->Component->Deinitialize();
Node->Component->Dtor(1);
Node->Component = null;
}
}
catch (Exception e) {
Log.Exception(e);
} finally {
base.Dispose(disposing, isNativeDestructor);
}
}
}
public static implicit operator AtkEventListener*(ComponentNode<T, TU> node) => &node.ComponentBase->AtkEventListener;
public static implicit operator T*(ComponentNode<T, TU> node) => node.Component;
public static implicit operator TU*(ComponentNode<T, TU> node) => node.Data;
protected void SetInternalComponentType(ComponentType type) {
var componentInfo = (AtkUldComponentInfo*)ComponentBase->UldManager.Objects;
componentInfo->ComponentType = type;
}
protected void InitializeComponentEvents() {
ComponentBase->InitializeFromComponentData(DataBase);
ComponentBase->Setup();
ComponentBase->SetEnabledState(true);
}
protected override void OnSizeChanged() {
base.OnSizeChanged();
CollisionNode.Size = Size;
ComponentBase->UldManager.RootNodeHeight = (ushort)Height;
ComponentBase->UldManager.RootNodeWidth = (ushort)Width;
}
public virtual bool IsEnabled {
get => NodeFlags.HasFlag(NodeFlags.Enabled);
set => ComponentBase->SetEnabledState(value);
}
public override int ChildCount => ComponentBase->UldManager.NodeListCount;
public T* Component => (T*)ComponentBase;
public TU* Data => (TU*)DataBase;
}