using Newtonsoft.Json.Linq; using UnityEngine; using System; using System.Collections.Concurrent; using System.Collections.Generic; using UnityEngine.Events; using Octopus.Simulator.Networks; using Newtonsoft.Json; using Cysharp.Threading.Tasks; using Octopus.Simulator; [Serializable] public class ProcessDataClass_start { public string processor_id; public string processor_label; public int processing_time; public List input_queues; public List input_stores; public string output_queue; } [Serializable] public class ProcessInputQueue { public string queue_name; public int required_items; } [Serializable] public class ProcessInputStore { public string store_name; public int required_items; } [Serializable] public class ProcessDataClass_using_queue { public string processor_id; public string processor_label; public string queue_name; public int queue_length; public int required_items; public int priority_order; public string queue_type; } [Serializable] public class ProcessDataClass_using_store { public string processor_id; public string processor_label; public string store_name; public int store_length; public int required_items; public int priority_order; public string queue_type; } [Serializable] public class ProcessDataClass_checking_inputs { public string processor_id; public List queues; public List stores; } [Serializable] public class ProcessDataClass_defects_detected { public string processor_id; public int defect_count; public string queue_name; public int queue_length; } [Serializable] public class ProcessDataClass_requesting_resource { public string processor_id; public string resource_name; } [Serializable] public class ProcessDataClass_resource_acquired { public string processor_id; public string resource_name; } [Serializable] public class ProcessDataClass_speed_factor_applied { public string processor_id; public string resource_name; public float original_time; public float adjusted_time; public float speed_factor; } [Serializable] public class ProcessDataClass_batch_started { public string processor_id; public int product_count; public int processing_time; } [Serializable] public class ProcessDataClass_batch_completed { public string processor_id; public int product_count; } [Serializable] public class ProcessDataClass_output_queue { public string processor_id; public string queue_name; public int queue_length_before; public int products_to_add; } [Serializable] public class ProcessDataClass_output_store { public string processor_id; public string store_name; public int store_length; public int products_added; } [Serializable] public class ProcessDataClass_waiting { public string processor_id; public int missing; } [Serializable] public class ProcessDataClass_ResourceAcquired { public string processor_id; public string resource_name; } [Serializable] public class ProcessDataClass_statistics { public StatisticsProcess statistics; } [Serializable] public class StatisticsProcess { public int total_input; public int total_processed; } public class SimulationModelProcess : SimulationModel { public string eventUsingQueue = "processor_using_queue"; public string eventUsingStore = "processor_using_store"; public string eventStartBatch = "processor_batch_started"; public string eventOutputQueue = "processor_output_queue"; [Header("Transported Products")] public List listProducts = new List(); public Transform productPos; [Header("Process Events")] public UnityEvent onProcessStart; public UnityEvent onProcessEnd; public SimulationModelResource resource; int productCount = 0; float processTime = 0; float elapsedTime = 0; Action AnimationAction_Start; Action AnimationAction_End; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { var animator = GetComponentInChildren(); if ( animator != null) { AnimationAction_Start += animator.AnimationStart; AnimationAction_End += animator.AnimationEnd; } } private void LoadingCargo(ProcessDataClass_using_queue data) { string queueID = data.queue_name; int loadCount = data.required_items; SimulationModel model = DataManager.I.GetModel(queueID); SimulationModelStore storeModel = model.GetComponent(); for (int i = 0; i < loadCount; i++) { GameObject product = null; product = ProductManager.Instance.SpawnProduct(); product.GetComponent().SetParent(this.nodeID); product.transform.parent = productPos; product.transform.localPosition = Vector3.zero; product.transform.localRotation = Quaternion.identity; listProducts.Add(product); } return; } private void SetUsingQueue(ProcessDataClass_using_queue data) { string queueID = data.queue_name; int loadCount = data.required_items; SimulationModel model = DataManager.I.GetModel(queueID); SimulationModelStore storeModel = model.GetComponent(); for (int i = 0; i < loadCount; i++) { GameObject product = null; product = ProductManager.Instance.SpawnProduct(); product.GetComponent().SetParent(this.nodeID); product.transform.parent = productPos; product.transform.localPosition = Vector3.zero; product.transform.localRotation = Quaternion.identity; listProducts.Add(product); } } private void SetUsingStore(ProcessDataClass_using_store data) { string queueID = data.store_name; int loadCount = data.required_items; SimulationModel model = DataManager.I.GetModel(queueID); SimulationModelStore storeModel = model.GetComponent(); for (int i = 0; i < loadCount; i++) { GameObject product = null; product = ProductManager.Instance.SpawnProduct(); product.GetComponent().SetParent(this.nodeID); product.transform.parent = productPos; product.transform.localPosition = Vector3.zero; product.transform.localRotation = Quaternion.identity; listProducts.Add(product); } } private void BatchStarted(ProcessDataClass_batch_started data) { int productCount = data.product_count; processTime = data.processing_time; elapsedTime = 0; onProcessStart?.Invoke(); AnimationAction_Start?.Invoke(); } private void OutputToQueue(ProcessDataClass_output_queue data) { string queueID = data.queue_name; int productCount = data.products_to_add; SimulationModel model = DataManager.I.GetModel(queueID); SimulationModelStore storeModel = model.GetComponent(); for (int i = 0; i < productCount; i++) { if (listProducts.Count > 0) { GameObject product = listProducts[0]; //storeModel.StoreProduct(product); listProducts.Remove(product); Destroy(product); } else { //Debug.LogWarning("Trying to unload from empty transporter : " + nodeID); } } AnimationAction_End?.Invoke(); } private void DefectToQueue(ProcessDataClass_defects_detected data) { string queueID = data.queue_name; int productCount = data.defect_count; SimulationModel model = DataManager.I.GetModel(queueID); SimulationModelStore storeModel = model.GetComponent(); for (int i = 0; i < productCount; i++) { if (listProducts.Count > 0) { GameObject product = listProducts[0]; //storeModel.StoreProduct(product); listProducts.Remove(product); Destroy(product); } else { Debug.LogWarning("Trying to unload from empty transporter : " + nodeID); } } AnimationAction_End?.Invoke(); } private void OutputToStore(ProcessDataClass_output_store data) { string queueID = data.store_name; int productCount = data.products_added; SimulationModel model = DataManager.I.GetModel(queueID); SimulationModelStore storeModel = model.GetComponent(); for (int i = 0; i < productCount; i++) { if (listProducts.Count > 0) { GameObject product = listProducts[0]; //storeModel.StoreProduct(product); listProducts.Remove(product); Destroy(product); } else { Debug.LogWarning("Trying to unload from empty transporter : " + nodeID); } } AnimationAction_End?.Invoke(); } private void ResourceAcquired(ProcessDataClass_ResourceAcquired data) { resource = DataManager.I.GetModel(data.resource_name) as SimulationModelResource; //resource.gameObject.SetActive(true); AnimationAction_Start?.Invoke(); } private void ResourceReleased() { if (resource) { //resource.gameObject.SetActive(false); resource = null; } AnimationAction_End?.Invoke(); } public override void GetData(string data) { var message = JsonConvert.DeserializeObject(data); switch (message._event) { case "processor_using_queue": SetUsingQueue(message.data.ToObject()); //Debug.Log($"{this.nodeID}"); return; case "processor_using_store": SetUsingStore(message.data.ToObject()); return; case "processor_batch_started": BatchStarted(message.data.ToObject()); //Debug.Log($"{this.nodeID} started batch"); return; case "processor_output_queue": OutputToQueue(message.data.ToObject()); return; case "processor_output_store": OutputToStore(message.data.ToObject()); return; case "processor_defects_detected": DefectToQueue(message.data.ToObject()); return; case "processor_output_defect_store": OutputToStore(message.data.ToObject()); return; case "processor_resource_acquired": ResourceAcquired(message.data.ToObject()); return; case "processor_resource_released": ResourceReleased(); return; case "processor_statistics_update": SetBubble(message.data.ToObject().statistics); break; default: //Debug.Log($"{message._event} does not match any case!!!"); return; } } public override void SetBubble(object data) { var processStatistics = data as StatisticsProcess; string msg = $"{processStatistics.total_input}/{processStatistics.total_processed}"; if (currentBubble == null) { // »ý¼º currentBubble = Instantiate(bubbleUIPrefab, FindAnyObjectByType().transform); currentBubble.target = DataBubbleSocket; currentBubble.worldOffset = new Vector3(0, 0, 0); // Çʿ信 µû¶ó Á¶Àý currentBubble.GetComponent().SetAsFirstSibling(); } // ÅØ½ºÆ® °»½Å currentBubble.SetMessage(msg); currentBubble.SetDetail(processStatistics,logicType.processor, LogicUIManager.instance.GetItemLabelByID(nodeID)); } }