using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using TNodeCore.Runtime.Attributes.Ports; using TNodeCore.Runtime.Models; using TNodeCore.Runtime.RuntimeCache; namespace TNodeCore.Runtime{ public class RuntimeNode{ public NodeData NodeData { get; set; } //the link connect to node's in port public List InputLink = new List(); //the link connect to node's out port public List OutputLink = new List(); //Cache node data type for fast access private readonly Type _type; public Type NodeType => _type; public void SetInput(string portName,object value){ var valueType = value.GetType(); var portPath = portName.Split(':'); if (portPath.Length ==2){ portName = portPath[0]; int index = int.Parse(portPath[1]); if(_portAccessors[portName].Type.IsArray){ if (_portAccessors[portName].GetValue(NodeData) is Array array) array.SetValue(value, index); } if (_portAccessors[portName].Type.IsGenericType){ if (_portAccessors[portName].GetValue(NodeData) is IList list) list[index] = value; } } else{ var portType = _portAccessors[portName].Type; if(portType!=valueType && !portType.IsAssignableFrom(valueType)){ var res =RuntimeCache.RuntimeCache.Instance.GetConvertedValue(valueType, portType, value); _portAccessors[portName].SetValue(NodeData, res); } else{ _portAccessors[portName].SetValue(NodeData,value); } } } public object GetOutput(string portName){ var portPath = portName.Split(':'); if (portPath.Length == 2){ portName = portPath[0]; int index = int.Parse(portPath[1]); if(_portAccessors[portName].Type.IsArray){ if (_portAccessors[portName].GetValue(NodeData) is Array array) return array.GetValue(index); } if (_portAccessors[portName].Type.IsGenericType){ if (_portAccessors[portName].GetValue(NodeData) is IList list) return list[index]; } } return _portAccessors[portName].GetValue(NodeData); } public string[] GetPortsOfType (){ var ports = new List(); foreach (var port in _portAccessors.Keys){ if(_portAccessors[port].Type==typeof(T)){ ports.Add(port); } } return ports.ToArray(); } /// /// Call it carefully to cache /// /// /// public Direction GetPortDirection(string portName){ var attribute = NodeData.GetType().GetField(portName).GetCustomAttribute(); if (attribute is InputAttribute){ return Direction.Input; } return Direction.Output; } private readonly Dictionary _portAccessors; public Action Process; public RuntimeNode(NodeData nodeData){ NodeData = nodeData; //Caching the type of the node _type = nodeData.GetType(); var info = nodeData.GetType().GetProperties(); _portAccessors = RuntimeCache.RuntimeCache.Instance.CachedPropertyAccessors[_type]; } public List GetInputNodesId(){ List dependencies = new List(); foreach (NodeLink link in InputLink) { dependencies.Add(link.outPort.nodeDataId); } return dependencies; } } public enum Direction{ Input, Output } }