diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs index 408bfed..6312cf7 100644 --- a/TNode/Editor/BaseViews/DataGraphView.cs +++ b/TNode/Editor/BaseViews/DataGraphView.cs @@ -116,7 +116,8 @@ namespace TNode.Editor.BaseViews{ private NodeInspector _nodeInspector; public GraphEditor Owner; private Dictionary _nodeDict = new(); - + private Blackboard _blackboard; + public T Data{ get{ return _data; } set{ @@ -234,7 +235,7 @@ namespace TNode.Editor.BaseViews{ } public void CreateBlackboard(){ - var blackboard = new Blackboard(); + _blackboard = new Blackboard(); //Blackboard add "Add Node" button // blackboard.Add(new BlackboardSection(){ // title = "Hello World", @@ -245,40 +246,60 @@ namespace TNode.Editor.BaseViews{ // }; // //Set black board to left side of the view - blackboard.SetPosition(new Rect(0,0,200,600)); - Add(blackboard); + _blackboard.SetPosition(new Rect(0,0,200,600)); + Add(_blackboard); //Check the type of the blackboard - OnDataChanged+= (sender, e) => { - - if (_data.blackboardData==null||_data.blackboardData.GetType()==typeof(BlackboardData)){ - _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); - - if(_data.blackboardData==null) return; - - } - Debug.Log(_data.blackboardData); - //Iterate field of the blackboard and add a button for each field - foreach (var field in _data.blackboardData.GetType() - .GetFields(BindingFlags.Public|BindingFlags.NonPublic | BindingFlags.Instance)){ - Debug.Log(field); - //if the field is MonoBehaviour,add a property field for blackboard - if(typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType)){ - var propertyField = new BlackboardField(null,field.Name,null){ - - }; - blackboard.Add(propertyField); - } - if(typeof(string).IsAssignableFrom(field.FieldType)){ - var propertyField = new BlackboardField(null,field.Name,null){ - - }; - blackboard.Add(propertyField); - } + OnDataChanged+= (sender, e) => { BlackboardUpdate(); }; + + } + + private void BlackboardUpdate(){ + if (_data.blackboardData == null || _data.blackboardData.GetType() == typeof(BlackboardData)){ + _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); + + if (_data.blackboardData == null) return; + } + + Debug.Log(_data.blackboardData); + //Iterate field of the blackboard and add a button for each field + foreach (var field in _data.blackboardData.GetType() + .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ + Debug.Log(field); + //if the field is MonoBehaviour,add a property field for blackboard + if (typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType)){ + var propertyField = new BlackboardField(null, field.Name, null){ + }; + _blackboard.Add(propertyField); + //register a drag event for the property field to drag the object from blackboard to the graph + + propertyField.RegisterCallback(evt => { + if (evt.target is GraphView graphView){ + var type = field.FieldType; + //Get Generic Constructor of the BlackDragNodeData<> + var genericConstructor = typeof(BlackDragNodeData<>).MakeGenericType(type).GetConstructor( + BindingFlags.Instance | BindingFlags.NonPublic, + null, + new Type[]{typeof(string), typeof(object)}, + null); + if (genericConstructor != null){ + NodeData nodeData = null; + nodeData = + genericConstructor.Invoke(null, new object[]{field.Name, _data.blackboardData}) as NodeData; + this.AddTNode(nodeData, new Rect(evt.localMousePosition, new Vector2(200, 200))); + } + } + }); } - }; + if (typeof(string).IsAssignableFrom(field.FieldType)){ + var propertyField = new BlackboardField(null, field.Name, null){ + }; + _blackboard.Add(propertyField); + } + } } + public virtual void DestroyInspector(){ if(_nodeInspector!=null){ this.Remove(_nodeInspector); diff --git a/TNode/Models/BlackDragNodeData.cs b/TNode/Models/BlackDragNodeData.cs index 19eb282..4876f25 100644 --- a/TNode/Models/BlackDragNodeData.cs +++ b/TNode/Models/BlackDragNodeData.cs @@ -1,16 +1,18 @@ using System.Runtime.InteropServices; using Newtonsoft.Json; using TNode.Attribute.Ports; +using TNode.RuntimeCache; namespace TNode.Models{ - public class BlackDragNodeData:NodeData{ + public class BlackDragNodeData:NodeData where T:BlackboardData{ [JsonIgnore] private string _blackDragData; [JsonIgnore] - private BlackboardData _blackboardData; + private T _blackboardData; - [Output] public T value => _blackboardData.GetValue(_blackDragData); - public BlackDragNodeData(string blackDragData,BlackboardData blackboardData){ + [Output] + public T Value => _blackboardData.GetValue(_blackDragData); + public BlackDragNodeData(string blackDragData,T blackboardData){ _blackDragData = blackDragData; _blackboardData = blackboardData; } diff --git a/TNode/Models/BlackboardData.cs b/TNode/Models/BlackboardData.cs index 4b2c2e7..fc0b66a 100644 --- a/TNode/Models/BlackboardData.cs +++ b/TNode/Models/BlackboardData.cs @@ -1,8 +1,6 @@ namespace TNode.Models{ public class BlackboardData:IModel{ - public T GetValue(string key){ - return default(T); - } + } } \ No newline at end of file diff --git a/TNode/Runtime/Runtimeblackboard.cs b/TNode/Runtime/Runtimeblackboard.cs new file mode 100644 index 0000000..1a91406 --- /dev/null +++ b/TNode/Runtime/Runtimeblackboard.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using TNode.Models; + +namespace TNode.Runtime{ + public class RuntimeBlackboard where T:BlackboardData{ + + public T Data { get; set; } + + } +} \ No newline at end of file diff --git a/TNode/Runtime/Runtimeblackboard.cs.meta b/TNode/Runtime/Runtimeblackboard.cs.meta new file mode 100644 index 0000000..02868cd --- /dev/null +++ b/TNode/Runtime/Runtimeblackboard.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6b69b2dedba24e35bf04bc9112da6b12 +timeCreated: 1656958407 \ No newline at end of file diff --git a/TNode/RuntimeCache/RuntimeCache.cs b/TNode/RuntimeCache/RuntimeCache.cs index 13e82e4..11bc35b 100644 --- a/TNode/RuntimeCache/RuntimeCache.cs +++ b/TNode/RuntimeCache/RuntimeCache.cs @@ -16,38 +16,13 @@ namespace TNode.RuntimeCache{ //delegate return a value from a nodedata public delegate object GetValueDelegate(IModel nodeData); - public readonly Dictionary> CachedDelegatesForGettingValue = + public readonly Dictionary> CachedDelegatesForGettingValue = new (); - public void ExecuteOutput(T nodeData) where T:NodeData{ - var type = typeof(T); - if(!CachedDelegatesForGettingValue.ContainsKey(type)){ - return; - } - var delegates = CachedDelegatesForGettingValue[type]; - foreach(var delegateInstance in delegates){ - var value = delegateInstance(nodeData); - } - } private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; - public void RegisterRuntimeNode() where T:NodeData{ - var type = typeof(T); - if(!CachedDelegatesForGettingValue.ContainsKey(type)){ - CachedDelegatesForGettingValue.Add(type, new List()); - var properties = type.GetProperties(); - foreach(var property in properties){ - var getValueDelegate = GetValueDelegateForProperty(property); - CachedDelegatesForGettingValue[type].Add(getValueDelegate); - } - } - else{ - //Cache already exists for this type - - } - } public void RegisterRuntimeBlackboard(Type type){ if(!CachedDelegatesForGettingValue.ContainsKey(type)){ - CachedDelegatesForGettingValue.Add(type, new List()); + CachedDelegatesForGettingValue.Add(type, new Dictionary()); var properties = type.GetProperties(); foreach(var property in properties){ //if the property only has a setter ,skip @@ -55,14 +30,41 @@ namespace TNode.RuntimeCache{ continue; } var getValueDelegate = GetValueDelegateForProperty(property); - CachedDelegatesForGettingValue[type].Add(getValueDelegate); + CachedDelegatesForGettingValue[type].Add(property.Name,getValueDelegate); + } + //register the fields + var fields = type.GetFields(); + foreach(var field in fields){ + var getValueDelegate = GetValueDelegateForField(field); + CachedDelegatesForGettingValue[type].Add(field.Name,getValueDelegate); } } } + private GetValueDelegate GetValueDelegateForField(FieldInfo field){ + return field.GetValue; + } + + private GetValueDelegate GetValueDelegateForProperty(PropertyInfo property){ var getValueDelegate = (GetValueDelegate)Delegate.CreateDelegate(typeof(GetValueDelegate), property.GetGetMethod()); return getValueDelegate; } + + + + } + public static class RuntimeExtension{ + + //todo latter on i will try some way caching reflection more efficiently + public static T GetValue(this BlackboardData blackboardData,string path){ + var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; + return (T) method.Invoke(blackboardData); + } + public static RuntimeCache.GetValueDelegate GetValueDelegate(this BlackboardData blackboardData,string path){ + var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; + return method; + } + } } \ No newline at end of file