using UnityEngine; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using System; using Octopus.Simulator; #region class public interface IStatusUpdateStatistics { long current_length { get; } long capacity { get; } } public class StoreStatusUpdateData { public StoreStatusUpdateDatastatistics statistics; } public class StoreStatusUpdateDatastatistics : IStatusUpdateStatistics { public long current_length; public long capacity; long IStatusUpdateStatistics.current_length => current_length; long IStatusUpdateStatistics.capacity => capacity; } public class QueueStatusUpdateData { public QueueStatusUpdateDatastatistics statistics; } public class QueueStatusUpdateDatastatistics : IStatusUpdateStatistics { public long current_length; public long capacity; long IStatusUpdateStatistics.current_length => current_length; long IStatusUpdateStatistics.capacity => capacity; } public enum StoreBehavior { FIFO, LIFO } #endregion public class SimulationModelStore : SimulationModel { [Header("Configuration")] public List storePositions = new List(); public List transporterPositions = new List(); public List storedProducts = new List(); public int maxCapacity; public StoreBehavior storeType = StoreBehavior.FIFO; protected override void init() { base.init(); maxCapacity = storePositions.Count; } public void StoreProduct(GameObject product) { if (product == null) return; product.transform.parent = transform; Transform emptySlot = storePositions.FirstOrDefault(slot => slot.childCount == 0); if (emptySlot != null) { product.transform.SetParent(emptySlot, false); } product.transform.localPosition = Vector3.zero; product.transform.localRotation = Quaternion.identity; storedProducts.Add(product); } public GameObject GetProduct() { if (storedProducts.Count == 0) return null; GameObject product = storeType == StoreBehavior.FIFO ? storedProducts[0] : storedProducts[storedProducts.Count - 1]; if (storeType == StoreBehavior.FIFO) storedProducts.RemoveAt(0); else storedProducts.RemoveAt(storedProducts.Count - 1); return product; } public Transform GetTransporterPosition() { if (transporterPositions == null || transporterPositions.Count == 0) return null; int idx = UnityEngine.Random.Range(0, transporterPositions.Count); return transporterPositions[idx]; } private void AdjustToTarget(IStatusUpdateStatistics status) { if (status == null) return; int current = storedProducts.Count; long target = status.current_length; int capacity = storePositions.Count; if (capacity <= 0) return; if (current < target) { int availableSlots = capacity - current; int spawnCount = (int)Mathf.Min(target - current, availableSlots); for (int i = 0; i < spawnCount; i++) { Transform emptySlot = storePositions.FirstOrDefault(slot => slot.childCount == 0); if (emptySlot == null) break; GameObject prod = ProductManager.Instance.SpawnProduct(); prod.transform.SetParent(emptySlot, false); storedProducts.Add(prod); } } else if (current > target) { int removeCount = (int)(current - target); for (int i = 0; i < removeCount; i++) { GameObject prod = storeType == StoreBehavior.FIFO ? storedProducts.FirstOrDefault() : storedProducts.LastOrDefault(); if (prod == null) continue; if (storeType == StoreBehavior.FIFO) storedProducts.RemoveAt(0); else storedProducts.RemoveAt(storedProducts.Count - 1); Destroy(prod); } } } public override void GetData(string data) { var wrapclass = JsonConvert.DeserializeObject(data); switch (wrapclass._event) { case "store_status_update": var storeStatus = JsonConvert.DeserializeObject(wrapclass.data.ToString()); AdjustToTarget(storeStatus?.statistics); SetBubble(storeStatus.statistics.current_length); SetBubbleDetail_Store(storeStatus.statistics); break; case "queue_status_update": var queueStatus = JsonConvert.DeserializeObject(wrapclass.data.ToString()); AdjustToTarget(queueStatus?.statistics); SetBubble(queueStatus.statistics.current_length); SetBubbleDetail_Queue(queueStatus.statistics); break; default: break; } } public override void SetBubble(object data) { string msg = data.ToString(); if (currentBubble == null) { // »ý¼º currentBubble = Instantiate(bubbleUIPrefab, FindAnyObjectByType().transform); currentBubble.target = DataBubbleSocket; currentBubble.worldOffset = new Vector3(0, 0, 0); // Çʿ信 µû¶ó Á¶Àý currentBubble.GetComponent().SetAsFirstSibling(); } // ÅØ½ºÆ® °»½Å currentBubble.SetMessage(msg); } public void SetBubbleDetail_Store(object data) { if (currentBubble != null) { currentBubble.SetDetail(data, logicType.store, LogicUIManager.instance.GetItemLabelByID(nodeID)); } } public void SetBubbleDetail_Queue(object data) { if (currentBubble != null) { currentBubble.SetDetail(data, logicType.queue, LogicUIManager.instance.GetItemLabelByID(nodeID)); } } }