namespace ChickenGameTest; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; [Meta(typeof(IAutoNode))] public partial class ConveyorItemRender : Node { public override void _Notification(int what) => this.Notify(what); [Export] protected Path3D Path3D { get; set; } = default!; [Export] protected TestItemConveyor ItemConveyor { get; set; } = default!; [Chickensoft.AutoInject.Dependency] protected IItemRenderer Items => this.DependOn(); private Chickensoft.Sync.Primitives.AutoList.Binding binding = default!; public override async void _Ready() { base._Ready(); if (!ItemConveyor.IsNodeReady()) { await ToSignal(ItemConveyor, Node.SignalName.Ready); } binding = ItemConveyor.Items.Items.Bind(); // binding.OnRemove(callback => // { // Items.Remove(callback.Item); // // GD.PrintS(callback.Item, callback.BeltT); // // if (itemsRenders.TryGetValue(callback.Item, out var node)) // // { // // GD.PrintS(callback.Item, callback.BeltT,node); // // itemsRenders.Remove(callback.Item); // // node.QueueFree(); // // } // }); binding.OnAdd((i, v) => { // itemsRenders[i.Item] = new MeshInstance3D(){Mesh = new BoxMesh()}; // AddSibling(itemsRenders[i.Item]); // itemsRenders[i.Item].Transform = Path3D.Curve.SampleBakedWithRotation(i.BeltT); // GD.Print($"Item : {i},{v} added"); Items.UpdateTransform(i.Item,Path3D.GlobalTransform *Path3D.Curve.SampleBakedWithRotation(i.BeltT)); }); binding.OnUpdate((a,b) => { Items.UpdateTransform(a.Item, Path3D.GlobalTransform *Path3D.Curve.SampleBakedWithRotation(b.BeltT).Translated(-Path3D.Curve.SampleBakedWithRotation(b.BeltT).Basis.X*(b.LaneSpan.Start))); return; if (itemsRenders.TryGetValue(a.Item, out var node)) { if (tweens.TryGetValue(a.Item, out var t)) { t.Kill(); } tweens[a.Item] = t = CreateTween(); t.TweenProperty(node, "transform",Path3D.Curve.SampleBakedWithRotation(b.BeltT), .25f); // node.Transform = Path3D.Curve.SampleBakedWithRotation(b.BeltT); } }); } private Dictionary itemsRenders = [];//This would be an item server for reuse via depency private Dictionary tweens = [];//This would be an item server for reuse via depency protected override void Dispose(bool disposing) { binding.Dispose(); base.Dispose(disposing); } } public interface IItemRenderer { // Node3D GetVisualNode(IBeltItem beltItem); void UpdateTransform(IBeltItem beltItem, Transform3D newTransform); void UpdateTransform(IBeltItem beltItem, Transform3D newTransform, float time); void Remove(IBeltItem beltItem); } public partial class TestItemRendered : Node3D, IItemRenderer { public Dictionary _items = []; private ConditionalWeakTable _tweens = []; public void Remove(IBeltItem beltItem) { if (_items.TryGetValue(beltItem, out var node)){ node.QueueFree(); } _items.Remove(beltItem); } public void UpdateTransform(IBeltItem beltItem, Transform3D newTransform, float time ){ if (!_items.TryGetValue(beltItem, out var node)) { _items.Add(beltItem,node = beltItem.CreateItemVisual()); AddChild(node); beltItem.Disposed += _ =>{node.QueueFree();_items.Remove(beltItem);}; node.Transform = newTransform; return; } if (_tweens.TryGetValue(beltItem, out var tween)) { tween.Kill(); _tweens.Remove(beltItem); } // GD.Print(newTransform); tween = GetTree().CreateTween().BindNode(node); tween.TweenProperty(node, "transform", newTransform, time); _tweens.Add(beltItem,tween); } public void UpdateTransform(IBeltItem beltItem, Transform3D newTransform) => UpdateTransform(beltItem,newTransform,.25f); }