Merge pull request #16 from taoria/working-in-process

Working in process
main
taoria 3 years ago committed by GitHub
commit 93e540bcc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      TNode/Attribute/BlackboardSection.cs
  2. 3
      TNode/Attribute/BlackboardSection.cs.meta
  3. 2
      TNode/Attribute/Ports/InputAttribute.cs
  4. 4
      TNode/Attribute/Ports/OutputAttribute.cs
  5. 13
      TNode/Attribute/Ports/PortAttribute.cs
  6. 3
      TNode/Editor/Blackboard.meta
  7. 19
      TNode/Editor/Blackboard/IBlackboardView.cs
  8. 3
      TNode/Editor/Blackboard/IBlackboardView.cs.meta
  9. 5
      TNode/Editor/EditorPersistence/GraphEditorData.cs
  10. 4
      TNode/Editor/EditorPersistence/GraphElementEditorData.cs
  11. 4
      TNode/Editor/NodeGraphView/IBaseDataGraphView.cs
  12. 2
      TNode/Editor/NodeGraphView/IDataGraphView.cs
  13. 3
      TNode/Editor/Serialization.meta
  14. 10
      TNode/Editor/Serialization/BlackboardDataWrapper.cs
  15. 3
      TNode/Editor/Serialization/BlackboardDataWrapper.cs.meta
  16. 53
      TNode/Editor/Serialization/DataWrapper.cs
  17. 3
      TNode/Editor/Serialization/DataWrapper.cs.meta
  18. 110
      TNode/Editor/Serialization/NodeDataWrapper.cs
  19. 0
      TNode/Editor/Serialization/NodeDataWrapper.cs.meta
  20. 2
      TNode/Editor/Tools/GraphEditorCreator/GraphEditorCreator.cs
  21. 7
      TNode/Editor/Tools/GraphEditorCreator/SourceGeneratorForGraphEditor.cs
  22. 3
      TNode/JsonSerialize.meta
  23. 36
      TNode/JsonSerialize/JsonSerializeTool.cs
  24. 3
      TNode/JsonSerialize/JsonSerializeTool.cs.meta
  25. 42
      TNode/JsonSerialize/NodeDataConverter.cs
  26. 3
      TNode/JsonSerialize/NodeDataConverter.cs.meta
  27. 28
      TNode/JsonSerialize/Vector3Converter.cs
  28. 3
      TNode/JsonSerialize/Vector3Converter.cs.meta
  29. 4
      TNode/Models/BlackboardData.cs
  30. 15
      TNode/Models/BlackboardDragNodeData.cs
  31. 51
      TNode/Models/GraphData.cs
  32. 5
      TNode/RuntimeCache/RuntimeCache.cs
  33. 3
      TNode/Tools.meta
  34. 90
      TNode/Tools/NodeDataWrapper.cs
  35. 0
      TNodeGraphViewImpl/Editor/Cache.meta
  36. 17
      TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
  37. 0
      TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs.meta
  38. 53
      TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
  39. 45
      TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardView.cs
  40. 4
      TNodeGraphViewImpl/Editor/GraphEditor.cs
  41. 0
      TNodeGraphViewImpl/Editor/GraphEditor.cs.meta
  42. 1
      TNodeGraphViewImpl/Editor/Inspector/NodeInspector.cs
  43. 7
      TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
  44. 93
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  45. 1
      TNodeGraphViewImpl/Editor/NodeViews/DefaultNodeView.cs
  46. 5
      TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs
  47. 23
      TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
  48. 3
      TNodeGraphViewImpl/Editor/Resources.meta
  49. 5
      TNodeGraphViewImpl/Editor/Resources/GraphViewPropertyField.uss
  50. 3
      TNodeGraphViewImpl/Editor/Resources/GraphViewPropertyField.uss.meta
  51. 2
      TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace TNode.Attribute{
/// <summary>
/// Use this attribute to declare a blackboard section ,a blackboard section is a group of variables with same types
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[BaseTypeRequired(typeof(List<>))]
public class BlackboardSection:System.Attribute{
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 773d073006dc4dd488e18b38165efd5a
timeCreated: 1656942977

@ -5,7 +5,7 @@ namespace TNode.Attribute.Ports{
[MeansImplicitUse] [MeansImplicitUse]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class InputAttribute : PortAttribute{ public class InputAttribute : PortAttribute{
public InputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto) : base(name, nameHandling){ public InputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared) : base(name, nameHandling,typeHandling){
} }
} }
} }

@ -1,6 +1,8 @@
namespace TNode.Attribute.Ports{ namespace TNode.Attribute.Ports{
public class OutputAttribute:PortAttribute{ public class OutputAttribute:PortAttribute{
public OutputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto) : base(name, nameHandling){
public OutputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling = TypeHandling.Declared) : base(name, nameHandling,typeHandling){
} }
} }
} }

@ -9,17 +9,26 @@ namespace TNode.Attribute.Ports{
Manual, Manual,
Format, Format,
MemberType MemberType
}
public enum TypeHandling{
Declared,
Implemented,
Specified
} }
[MeansImplicitUse] [MeansImplicitUse]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class PortAttribute:System.Attribute{ public class PortAttribute:System.Attribute{
public readonly string Name; public readonly string Name;
public readonly PortNameHandling NameHandling; public readonly PortNameHandling NameHandling;
public Type HandledType;
public PortAttribute(string name,PortNameHandling nameHandling=PortNameHandling.Auto){ public TypeHandling TypeHandling{ get; set; }
public PortAttribute(string name,PortNameHandling nameHandling=PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared){
this.Name = name; this.Name = name;
this.NameHandling = nameHandling; this.NameHandling = nameHandling;
this.TypeHandling = typeHandling;
} }
} }
} }

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bf3b6f6e73b647e2a5421f482a0b0e8f
timeCreated: 1657686050

@ -0,0 +1,19 @@
using TNode.Editor.NodeGraphView;
using TNode.Models;
using UnityEditor;
using UnityEngine;
namespace TNode.Editor.Blackboard{
public interface IBlackboardView{
public BlackboardData GetBlackboardData();
public void SetBlackboardData(BlackboardData data);
public void AddItem();
void Setup(IBaseDataGraphView graphView,EditorWindow ownerWindow);
}
public interface IBlackboardView<T> : IBlackboardView where T : BlackboardData{
public T Data{ get; set; }
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9c618ca8a5b0444284489b8a1942af91
timeCreated: 1657686059

@ -1,10 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using TNode.Editor.EditorPersistence;
using TNode.Editor.Model;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
namespace TNode.Editor{ namespace TNode.Editor.EditorPersistence{
[CreateAssetMenu(fileName = "Graph Editor Data", menuName = "TNode/Graph Editor Data")] [CreateAssetMenu(fileName = "Graph Editor Data", menuName = "TNode/Graph Editor Data")]
public class GraphEditorData:ScriptableObject{ public class GraphEditorData:ScriptableObject{

@ -1,9 +1,7 @@
using System; using System;
using TNode.Models;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
namespace TNode.Editor.Model{ namespace TNode.Editor.EditorPersistence{
[Serializable] [Serializable]
public class GraphElementEditorData{ public class GraphElementEditorData{

@ -6,6 +6,10 @@ namespace TNode.Editor.NodeGraphView{
public void AddTNode(NodeData nodeData, Rect rect); public void AddTNode(NodeData nodeData, Rect rect);
public void RemoveTNode(NodeData nodeData); public void RemoveTNode(NodeData nodeData);
public void CreateBlackboard();
public GraphData GetGraphData();
public BlackboardData GetBlackboardData(); public BlackboardData GetBlackboardData();
} }
} }

@ -2,6 +2,6 @@
namespace TNode.Editor.NodeGraphView{ namespace TNode.Editor.NodeGraphView{
public interface IDataGraphView<T> : IBaseDataGraphView where T:GraphData{ public interface IDataGraphView<T> : IBaseDataGraphView where T:GraphData{
public T Data{ get; set; }
} }
} }

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4c1e0017367a4d448a68ed34b7540782
timeCreated: 1657690936

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using TNode.Models;
using UnityEngine;
namespace TNode.Editor.Serialization{
public class BlackboardDataWrapper:DataWrapper<BlackboardDataWrapper,BlackboardData>{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ac3fada821244e69b6b9a27a7b94eeee
timeCreated: 1657691334

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using TNode.Models;
using UnityEngine;
namespace TNode.Editor.Serialization{
[Serializable]
public class DataWrapper<TWrapper,TData>:ScriptableObject where TWrapper:DataWrapper<TWrapper,TData> where TData:IModel,new(){
[SerializeReference]
public TData data;
private static readonly Dictionary<TData,TWrapper> Cache = new ();
public static TWrapper Get(TData data){
if (data.GetType().IsGenericType){
return CreateInstance<TWrapper>();
}
if(Cache.ContainsKey(data)){
return Cache[data];
}
var wrapper = CreateInstance<TWrapper>();
wrapper.data = data;
Cache.Add(data,wrapper);
return wrapper;
}
public event Action<DataWrapper<TWrapper,TData>> OnValueChanged;
public void SetValue(string path, object value){
var fieldInfo = data.GetType().GetField(path);
fieldInfo.SetValue(data,value);
OnValueChanged?.Invoke(this);
}
public object GetValue(string path){
var fieldInfo = data.GetType().GetField(path);
return fieldInfo.GetValue(data);
}
public static implicit operator TData(DataWrapper<TWrapper,TData> wrapper){
if (wrapper == null)
return default(TData);
return wrapper.data;
}
/// <summary>
/// Use this to get the wrapped data directly.
/// </summary>
/// <param name="unWrapper"></param>
/// <returns></returns>
public static implicit operator DataWrapper<TWrapper,TData>(TData unWrapper){
if (unWrapper == null)
return null;
return Get(unWrapper);
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3b4407f1670d4359b807377900c83583
timeCreated: 1657693507

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using TNode.Models;
using UnityEngine;
using UnityEngine.Serialization;
namespace TNode.Editor.Serialization{
[Obsolete]
public class NodeDataWrapper<T> : ScriptableObject where T : NodeData{
public T Data;
private static readonly Dictionary<T,NodeDataWrapper<T>> Cache = new ();
public event Action<NodeDataWrapper<T>> OnValueChanged;
public static NodeDataWrapper<T> Get(T data){
if(Cache.ContainsKey(data)){
return Cache[data];
}
var wrapper = ScriptableObject.CreateInstance<NodeDataWrapper<T>>();
Cache.Add(data,wrapper);
return wrapper;
}
public NodeDataWrapper(T data){
this.Data = data;
}
public void SetValue(string path, object value){
var fieldInfo = Data.GetType().GetField(path);
fieldInfo.SetValue(Data,value);
OnValueChanged?.Invoke(this);
}
public object GetValue(string path){
var fieldInfo = Data.GetType().GetField(path);
return fieldInfo.GetValue(Data);
}
public static implicit operator T(NodeDataWrapper<T> wrapper){
if (wrapper == null)
return null;
return wrapper.Data;
}
public static implicit operator NodeDataWrapper<T>(T unWrapper){
if (unWrapper == null)
return null;
return Get(unWrapper);
}
}
public class NodeDataWrapper:DataWrapper<NodeDataWrapper,NodeData>{
}
/// <summary>
/// Scriptable object wrapper enable property drawer for t-node
/// instance create automatically when using get function,generic node data is not support yet because of unity serialization system.
/// TODO : support generic node data
/// </summary>
// public class NodeDataWrapper:ScriptableObject{
// [SerializeReference]
// public NodeData data;
// private static readonly Dictionary<NodeData,NodeDataWrapper> Cache = new ();
// public event Action<NodeDataWrapper> OnValueChanged;
// /// <summary>
// /// Create a new wrapper or get a cached wrapper for the given data
// /// </summary>
// /// <param name="data">node data,an implemented type is acceptable</param>
// /// <returns></returns>
// public static NodeDataWrapper Get(NodeData data){
// if (data.GetType().IsGenericType){
// return CreateInstance<NodeDataWrapper>();
// }
// if(Cache.ContainsKey(data)){
// return Cache[data];
// }
// var wrapper = CreateInstance<NodeDataWrapper>();
// wrapper.data = data;
// Cache.Add(data,wrapper);
// return wrapper;
// }
//
//
// public void SetValue(string path, object value){
// var fieldInfo = data.GetType().GetField(path);
// fieldInfo.SetValue(data,value);
// OnValueChanged?.Invoke(this);
// }
//
// public object GetValue(string path){
// var fieldInfo = data.GetType().GetField(path);
// return fieldInfo.GetValue(data);
// }
// public static implicit operator NodeData(NodeDataWrapper wrapper){
// if (wrapper == null)
// return null;
// return wrapper.data;
//
// }
// /// <summary>
// /// Use this to get the wrapped data directly.
// /// </summary>
// /// <param name="unWrapper"></param>
// /// <returns></returns>
// public static implicit operator NodeDataWrapper(NodeData unWrapper){
// if (unWrapper == null)
// return null;
// return Get(unWrapper);
// }
// }
}

@ -1,6 +1,6 @@
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using TNode.Editor.Model; using TNode.Editor.EditorPersistence;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;

@ -1,9 +1,4 @@
using System; using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using UnityEngine; using UnityEngine;
namespace TNode.Editor.Tools.GraphEditorCreator{ namespace TNode.Editor.Tools.GraphEditorCreator{

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: ec6119d082a947f58ed6402290b65596
timeCreated: 1656817965

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace TNode.JsonSerialize{
public static class JsonSerializeTool{
class WritablePropertiesOnlyResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
return props.Where(p => p.Writable).ToList();
}
}
public static JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings(){
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
DateFormatString = "yyyy-MM-dd HH:mm:ss",
Converters = new List<JsonConverter> { new Vector3Converter() },
TypeNameHandling = TypeNameHandling.Auto,
ContractResolver = new WritablePropertiesOnlyResolver(),
Formatting = Formatting.Indented
};
public static JsonSerializerSettings InternalJsonSerializerSettings = new JsonSerializerSettings(){
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented
};
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 14067671fe28434e9ae2e67a34074c52
timeCreated: 1656819161

@ -1,42 +0,0 @@
using System;
using Newtonsoft.Json;
using TNode.Models;
using UnityEngine;
namespace TNode.JsonSerialize{
public class NodeDataConverter:JsonConverter<NodeData>{
public override void WriteJson(JsonWriter writer, NodeData value, JsonSerializer serializer){
//Write node data with type information
writer.WriteStartObject();
writer.WritePropertyName("type");
Debug.Log(value.GetType().ToString());
writer.WriteValue(value.GetType().Name);
writer.WritePropertyName("data");
serializer.Serialize(writer, value, value.GetType());
writer.WriteEndObject();
}
public override NodeData ReadJson(JsonReader reader, Type objectType, NodeData existingValue, bool hasExistingValue,
JsonSerializer serializer){
//Load type info
reader.Read();
if (reader.Value != null){
var type = reader.Value.ToString();
if (type.Trim().Length==0){
Debug.LogError(type);
throw new JsonSerializationException("Type name is empty");
}
reader.Read();
//Load data
var data = serializer.Deserialize(reader, Type.GetType(type));
return (NodeData) data;
}
return null;
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6f960539f2744729b35ff3011677d8ba
timeCreated: 1656857829

@ -1,28 +0,0 @@
using System;
using System.Numerics;
using Newtonsoft.Json;
namespace TNode.JsonSerialize{
public class Vector3Converter:JsonConverter<Vector3>{
public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer){
writer.WriteStartArray();
writer.WriteValue(value.X);
writer.WriteValue(value.Y);
writer.WriteValue(value.Z);
writer.WriteEndArray();
}
public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer){
if (reader.TokenType == JsonToken.Null){
return default(Vector3);
}
else{
var array = serializer.Deserialize<float[]>(reader);
if (array != null) return new Vector3(array[0], array[1], array[2]);
}
return default(Vector3);
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: fecb77054ad348239341a58c50549879
timeCreated: 1656817975

@ -1,5 +1,7 @@
namespace TNode.Models{ using System;
namespace TNode.Models{
[Serializable]
public class BlackboardData:IModel{ public class BlackboardData:IModel{
} }

@ -4,15 +4,18 @@ using Newtonsoft.Json;
using TNode.Attribute; using TNode.Attribute;
using TNode.Attribute.Ports; using TNode.Attribute.Ports;
using TNode.RuntimeCache; using TNode.RuntimeCache;
using UnityEngine;
using UnityEngine.Serialization;
namespace TNode.Models{ namespace TNode.Models{
public class BlackboardDragNodeData<T>:NodeData{ [Serializable]
private string _blackDragData; public class BlackboardDragNodeData:NodeData{
[JsonIgnore] public string blackDragData;
private BlackboardData _blackboardData; [SerializeReference]
public BlackboardData blackboardData;
[Output("",PortNameHandling.MemberType)] [Output("",PortNameHandling.MemberType,TypeHandling.Implemented)]
public T Value => _blackboardData.GetValue<T>(_blackDragData); public object Value => blackboardData.GetValue(blackDragData);
public BlackboardDragNodeData(){ public BlackboardDragNodeData(){

@ -1,38 +1,45 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json; using Newtonsoft.Json;
using TNode.Editor; using UnityEngine;
using TNode.JsonSerialize;
using UnityEditor.Experimental.GraphView;
using UnityEngine.Serialization; using UnityEngine.Serialization;
namespace TNode.Models{ namespace TNode.Models{
[Serializable] [Serializable]
public class GraphData:ScriptableObject,ISerializationCallbackReceiver{ public class GraphData:ScriptableObject,ISerializationCallbackReceiver{
[SerializeField]
public Dictionary<string,NodeData> NodeDictionary = new Dictionary<string,NodeData>(); public Dictionary<string,NodeData> NodeDictionary = new Dictionary<string,NodeData>();
public List<NodeLink> nodeLinks = new();
public BlackboardData blackboardData = new(); [SerializeReference]
[TextArea(1,10)] public List<NodeData> nodeList = new List<NodeData>();
[SerializeField]
//[HideInInspector]
private string jsonObject;
[TextArea(1,10)]
[SerializeField] [SerializeField]
private string jsonBlackboard; protected List<NodeLink> nodeLinks;
[SerializeReference]
public BlackboardData blackboardData;
public List<NodeLink> NodeLinks{
get{
return nodeLinks ??= new List<NodeLink>();
}
set => nodeLinks = value;
}
public void OnBeforeSerialize(){ public void OnBeforeSerialize(){
jsonObject = JsonConvert.SerializeObject(NodeDictionary,JsonSerializeTool.JsonSerializerSettings);
jsonBlackboard = JsonConvert.SerializeObject(blackboardData,JsonSerializeTool.JsonSerializerSettings);
nodeList.Clear();
foreach(var node in NodeDictionary.Values){
nodeList.Add(node);
}
} }
public void OnAfterDeserialize(){ public void OnAfterDeserialize(){
//Deserialize node dictionary NodeDictionary.Clear();
var deserializedData = JsonConvert.DeserializeObject<Dictionary<string,NodeData>>(jsonObject,JsonSerializeTool.JsonSerializerSettings); foreach(var node in nodeList){
NodeDictionary = deserializedData; NodeDictionary.Add(node.id,node);
//Deserialize blackboard data
var deserializedBlackboard = JsonConvert.DeserializeObject<BlackboardData>(jsonBlackboard,JsonSerializeTool.JsonSerializerSettings);
blackboardData = deserializedBlackboard;
} }
} }
}
} }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using EasyRandomGenerator.Blackboard;
using JetBrains.Annotations; using JetBrains.Annotations;
using TNode.Models; using TNode.Models;
using Unity.VisualScripting; using Unity.VisualScripting;
@ -21,6 +22,10 @@ namespace TNode.RuntimeCache{
new (); new ();
private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"};
public RuntimeCache(){
RegisterRuntimeBlackboard(typeof(EasyBlackboardData));
}
public void RegisterRuntimeBlackboard(Type type){ public void RegisterRuntimeBlackboard(Type type){
if(!CachedDelegatesForGettingValue.ContainsKey(type)){ if(!CachedDelegatesForGettingValue.ContainsKey(type)){
CachedDelegatesForGettingValue.Add(type, new Dictionary<string, GetValueDelegate>()); CachedDelegatesForGettingValue.Add(type, new Dictionary<string, GetValueDelegate>());

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 206b9a7ba6b54706b02c6aa2cb9a18b0
timeCreated: 1656762017

@ -1,90 +0,0 @@
using System;
using System.Collections.Generic;
using TNode.Models;
using UnityEngine;
namespace TNode.Editor{
/// <summary>
/// Scriptable object wrapper enable property drawer for t-node
/// </summary>
public class NodeDataWrapper<T> : ScriptableObject where T : NodeData{
public T Data;
private static readonly Dictionary<T,NodeDataWrapper<T>> Cache = new ();
public event Action<NodeDataWrapper<T>> OnValueChanged;
public static NodeDataWrapper<T> Get(T data){
if(Cache.ContainsKey(data)){
return Cache[data];
}
var wrapper = ScriptableObject.CreateInstance<NodeDataWrapper<T>>();
Cache.Add(data,wrapper);
return wrapper;
}
public NodeDataWrapper(T data){
this.Data = data;
}
public void SetValue(string path, object value){
var fieldInfo = Data.GetType().GetField(path);
fieldInfo.SetValue(Data,value);
OnValueChanged?.Invoke(this);
}
public object GetValue(string path){
var fieldInfo = Data.GetType().GetField(path);
return fieldInfo.GetValue(Data);
}
public static implicit operator T(NodeDataWrapper<T> wrapper){
if (wrapper == null)
return null;
return wrapper.Data;
}
public static implicit operator NodeDataWrapper<T>(T unWrapper){
if (unWrapper == null)
return null;
return Get(unWrapper);
}
}
public class NodeDataWrapper:ScriptableObject{
[SerializeReference]
public NodeData Data;
private static readonly Dictionary<NodeData,NodeDataWrapper> Cache = new ();
public event Action<NodeDataWrapper> OnValueChanged;
public static NodeDataWrapper Get(NodeData data){
if (data.GetType().IsGenericType){
return ScriptableObject.CreateInstance<NodeDataWrapper>();
}
if(Cache.ContainsKey(data)){
return Cache[data];
}
var wrapper = ScriptableObject.CreateInstance<NodeDataWrapper>();
wrapper.Data = data;
Cache.Add(data,wrapper);
return wrapper;
}
public void SetValue(string path, object value){
var fieldInfo = Data.GetType().GetField(path);
fieldInfo.SetValue(Data,value);
OnValueChanged?.Invoke(this);
}
public object GetValue(string path){
var fieldInfo = Data.GetType().GetField(path);
return fieldInfo.GetValue(Data);
}
public static implicit operator NodeData(NodeDataWrapper wrapper){
if (wrapper == null)
return null;
return wrapper.Data;
}
public static implicit operator NodeDataWrapper(NodeData unWrapper){
if (unWrapper == null)
return null;
return Get(unWrapper);
}
}
}

@ -3,16 +3,16 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using TNode.Attribute; using TNode.Attribute;
using TNode.Editor; using TNode.Editor;
using TNode.Editor.Inspector; using TNode.Editor.Blackboard;
using TNode.Editor.NodeViews; using TNode.Editor.NodeViews;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.GraphBlackboard; using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.NodeGraphView; using TNodeGraphViewImpl.Editor.NodeGraphView;
using TNodeGraphViewImpl.Editor.NodeViews;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
using UnityEngine.TestTools.Utils;
namespace TNode.Cache{ namespace TNodeGraphViewImpl.Editor.Cache{
/// <summary> /// <summary>
/// Internal singleton class for caching TNode reflection Data. /// Internal singleton class for caching TNode reflection Data.
/// </summary> /// </summary>
@ -153,14 +153,14 @@ namespace TNode.Cache{
return null; return null;
} }
public static Blackboard CreateBlackboardDataFromBlackboardDataType(Type t){ public static IBlackboardView CreateBlackboardDataFromBlackboardDataType(Type t){
var type = typeof(GraphBlackboardView<>).MakeGenericType(t); var type = typeof(GraphBlackboardView<>).MakeGenericType(t);
var res = CreateViewComponentFromBaseType(type) as Blackboard; var res = CreateViewComponentFromBaseType(type) as IBlackboardView;
return res ?? new DefaultGraphBlackboardView(); return res ?? new DefaultGraphBlackboardView();
} }
public static Blackboard CreateBlackboardWithGraphData(GraphData graphData){ public static IBlackboardView CreateBlackboardWithGraphData(GraphData graphData){
var graphType = graphData.GetType(); var graphType = graphData.GetType();
if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(graphType)){ if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(graphType)){
var type = NodeEditorSingleton.Instance.GraphBlackboard[graphType]; var type = NodeEditorSingleton.Instance.GraphBlackboard[graphType];
@ -169,7 +169,7 @@ namespace TNode.Cache{
} }
return null; return null;
} }
public static Blackboard CreateBlackboardWithGraphData(Type graphType){ public static IBlackboardView CreateBlackboardWithGraphData(Type graphType){
if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(graphType)){ if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(graphType)){
var type = NodeEditorSingleton.Instance.GraphBlackboard[graphType]; var type = NodeEditorSingleton.Instance.GraphBlackboard[graphType];
return CreateBlackboardDataFromBlackboardDataType(type); return CreateBlackboardDataFromBlackboardDataType(type);
@ -201,7 +201,6 @@ namespace TNode.Cache{
//Check the generic type of BaseNodeView by t //Check the generic type of BaseNodeView by t
if (t.IsGenericType){ if (t.IsGenericType){
Debug.Log($"A generic type {t} is detected");
//AKA if BlackboardDragNodeData<Camera> is pulled //AKA if BlackboardDragNodeData<Camera> is pulled
//Get BlackboardDragNodeData<T> as generic type //Get BlackboardDragNodeData<T> as generic type
@ -210,14 +209,12 @@ namespace TNode.Cache{
//What you want is a BaseNodeView<BlackboardDragNodeData<T>> to be created //What you want is a BaseNodeView<BlackboardDragNodeData<T>> to be created
var genericViewType = typeof(BaseNodeView<>).MakeGenericType(genericTypeDefinition); var genericViewType = typeof(BaseNodeView<>).MakeGenericType(genericTypeDefinition);
Debug.Log($"The generic view type is {genericViewType}");
//search for the specific type of genericViewType in the dictionary //search for the specific type of genericViewType in the dictionary
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(genericViewType)){ if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(genericViewType)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[genericViewType]; var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[genericViewType];
//The implementedType is still a generic type ,so we make it a specific type by using MakeGenericType //The implementedType is still a generic type ,so we make it a specific type by using MakeGenericType
Debug.Log($"{implementedType}");
//Get argument type of t //Get argument type of t
var argumentType = t.GetGenericArguments()[0]; var argumentType = t.GetGenericArguments()[0];
var instance = Activator.CreateInstance(implementedType.MakeGenericType(argumentType)); var instance = Activator.CreateInstance(implementedType.MakeGenericType(argumentType));

@ -1,17 +1,62 @@
using TNode.Attribute; using System.Collections;
using System.Reflection;
using TNode.Attribute;
using TNode.Editor.NodeGraphView;
using TNode.Editor.Search;
using TNode.Editor.Serialization;
using TNode.Models; using TNode.Models;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNodeGraphViewImpl.Editor.GraphBlackboard{ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
[ViewComponent] [ViewComponent]
public class DefaultGraphBlackboardView:GraphBlackboardView<BlackboardData>{ public class DefaultGraphBlackboardView:GraphBlackboardView<BlackboardData>{
public DefaultGraphBlackboardView(){ public DefaultGraphBlackboardView():base(){
//the label and the field gap smaller
styleSheets.Add( Resources.Load<StyleSheet>("GraphViewPropertyField"));
} }
public void ConstructView(){ protected override void UpdateBlackboard(BlackboardData data){
var serializedObject = new SerializedObject((BlackboardDataWrapper)data);
foreach (var field in data.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){
//if the field is MonoBehaviour,add a property field for blackboard
//skip if the field is a list or Ilist
if (!typeof(IList).IsAssignableFrom(field.FieldType)){
VisualElement visualElement = new VisualElement();
var propertyField = new BlackboardPropertyField(new BlackboardProperty.BlackboardProperty(field.Name,field.FieldType));
var foldoutData = new Foldout{
text = field.Name
};
var drawer = new PropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name);
drawer.Bind(serializedObject);
foldoutData.Add(drawer);
visualElement.Add(propertyField);
visualElement.Add(foldoutData);
this.Add(visualElement);
} }
public void AddParameter(){ else{
var blackboardList = new BlackboardSection{
title = field.Name
};
this.Add(blackboardList);
}
}
addItemRequested = (sender) => {
var res = ScriptableObject.CreateInstance<BlackboardSearchWindowProvider>();
//Get right top corner of the blackboard
var blackboardPos = GetPosition().position+OwnerWindow.position.position;
var searchWindowContext = new SearchWindowContext(blackboardPos,200,200);
//Call search window
res.Setup(Owner.GetGraphData().GetType(),Owner,OwnerWindow);
SearchWindow.Open(searchWindowContext, res);
};
} }
} }
} }

@ -1,14 +1,51 @@
using TNode.Models; using TNode.Editor.Blackboard;
using TNode.Editor.NodeGraphView;
using TNode.Editor.Search;
using TNode.Models;
using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine;
namespace TNodeGraphViewImpl.Editor.GraphBlackboard{ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
/// <summary> /// <summary>
/// Implement this class to create graph black board for specified graph /// Implement this class to create graph black board for specified graph
/// </summary> /// </summary>
public class GraphBlackboardView<T>:Blackboard where T:BlackboardData{ public class GraphBlackboardView<T>:Blackboard,IBlackboardView<T> where T:BlackboardData{
public T BlackboardData; protected IBaseDataGraphView Owner;
protected EditorWindow OwnerWindow;
private T _data;
public GraphBlackboardView() : base(){ public void Setup(IBaseDataGraphView graphView,EditorWindow ownerWindow){
Owner = graphView;
OwnerWindow = ownerWindow;
}
public new void SetPosition(Rect rect){
}
protected virtual void UpdateBlackboard(BlackboardData data){
}
public T Data{
get => (T) _data;
set{
_data = value;
UpdateBlackboard(value);
}
}
public BlackboardData GetBlackboardData(){
return _data;
}
public void SetBlackboardData(BlackboardData data){
Data = (T) data;
}
public void AddItem(){
} }
} }

@ -1,8 +1,8 @@
using Codice.CM.Common; using Codice.CM.Common;
using TNode.Cache; using TNode.Editor.EditorPersistence;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.Model;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.NodeGraphView; using TNodeGraphViewImpl.Editor.NodeGraphView;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;

@ -5,6 +5,7 @@ using TNode.Attribute;
using TNode.Editor.NodeViews; using TNode.Editor.NodeViews;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.NodeGraphView; using TNodeGraphViewImpl.Editor.NodeGraphView;
using TNodeGraphViewImpl.Editor.NodeViews;
using Unity.VisualScripting; using Unity.VisualScripting;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;

@ -1,5 +1,6 @@
using System.Reflection; using System.Reflection;
using TNode.Attribute; using TNode.Attribute;
using TNode.Editor.Serialization;
using TNode.Models; using TNode.Models;
using UnityEditor; using UnityEditor;
using UnityEditor.UIElements; using UnityEditor.UIElements;
@ -37,7 +38,7 @@ namespace TNode.Editor.Inspector{
private void RefreshPropertyDrawer(){ private void RefreshPropertyDrawer(){
//Check if the data's type is a generic type of BlackboardDragNodeData<> //Check if the data's type is a generic type of BlackboardDragNodeData<>
if (_data.GetType().IsSubclassOf(typeof(BlackboardDragNodeData<>))){ if (_data.GetType().IsSubclassOf(typeof(BlackboardDragNodeData))){
return; return;
} }
var serializedObject = new SerializedObject((NodeDataWrapper)_data); var serializedObject = new SerializedObject((NodeDataWrapper)_data);
@ -47,11 +48,11 @@ namespace TNode.Editor.Inspector{
var showInNodeViewAttribute = field.GetCustomAttribute<ShowInNodeViewAttribute>() != null; var showInNodeViewAttribute = field.GetCustomAttribute<ShowInNodeViewAttribute>() != null;
if (!showInNodeViewAttribute) if (!showInNodeViewAttribute)
continue; continue;
var drawer = new PropertyField(serializedObject.FindProperty("Data").FindPropertyRelative(field.Name),field.Name); var drawer = new PropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name);
Debug.Log(serializedObject.FindProperty("Data"));
drawer.Bind(serializedObject); drawer.Bind(serializedObject);
Add(drawer); Add(drawer);
} }
} }
} }
} }

@ -3,17 +3,19 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using TNode.Cache;
using TNode.Editor; using TNode.Editor;
using TNode.Editor.Blackboard;
using TNode.Editor.EditorPersistence;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.Model;
using TNode.Editor.NodeGraphView; using TNode.Editor.NodeGraphView;
using TNode.Editor.NodeViews; using TNode.Editor.NodeViews;
using TNode.Editor.Search; using TNode.Editor.Search;
using TNode.Editor.Tools.NodeCreator; using TNode.Editor.Tools.NodeCreator;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.GraphBlackboard; using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardProperty; using TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardProperty;
using TNodeGraphViewImpl.Editor.NodeViews;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
@ -21,7 +23,7 @@ using UnityEngine.UIElements;
using Edge = UnityEditor.Experimental.GraphView.Edge; using Edge = UnityEditor.Experimental.GraphView.Edge;
namespace TNodeGraphViewImpl.Editor.NodeGraphView{ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public abstract class BaseDataGraphView<T>:GraphView,IBaseDataGraphView where T:GraphData{ public abstract class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{
#region variables and properties #region variables and properties
private T _data; private T _data;
private bool _isInspectorOn; private bool _isInspectorOn;
@ -29,7 +31,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
private NodeInspector _nodeInspector; private NodeInspector _nodeInspector;
public GraphEditor<T> Owner; public GraphEditor<T> Owner;
private Dictionary<string,Node> _nodeDict = new(); private Dictionary<string,Node> _nodeDict = new();
private Blackboard _blackboard; private IBlackboardView _blackboard;
public T Data{ public T Data{
get{ return _data; } get{ return _data; }
set{ set{
@ -103,11 +105,10 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
foreach (var selectable in blackboardFields){ foreach (var selectable in blackboardFields){
if(selectable is { } field) { if(selectable is { } field) {
//Make a constructor of BlackboardDragNodeData<field.PropertyType > by reflection //Make a constructor of BlackboardDragNodeData<field.PropertyType > by reflection
var specifiedType = var dragNodeData = NodeCreator.InstantiateNodeData<BlackboardDragNodeData>();
typeof(BlackboardDragNodeData<>).MakeGenericType(field.BlackboardProperty.PropertyType); dragNodeData.blackboardData = _data.blackboardData;
//Create a new instance of specified type dragNodeData.blackDragData = field.BlackboardProperty.PropertyName;
var dragNodeData = NodeCreator.InstantiateNodeData(specifiedType); AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200)));
this.AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200)));
} }
} }
@ -155,7 +156,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
AddTNode(dataNode,nodePos); AddTNode(dataNode,nodePos);
} }
foreach (var edge in _data.nodeLinks){ foreach (var edge in _data.NodeLinks){
var inputNode = _data.NodeDictionary[edge.inPort.nodeDataId]; var inputNode = _data.NodeDictionary[edge.inPort.nodeDataId];
var outputNode = _data.NodeDictionary[edge.outPort.nodeDataId]; var outputNode = _data.NodeDictionary[edge.outPort.nodeDataId];
var inputNodeView = _nodeDict[inputNode.id]; var inputNodeView = _nodeDict[inputNode.id];
@ -191,47 +192,15 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
miniMap.SetPosition(rect); miniMap.SetPosition(rect);
} }
public virtual void CreateBlackboard(){
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));
_blackboard.SetPosition(new Rect(0,0,200,600));
Add(_blackboard);
OnDataChanged+= (sender, e) => { BlackboardUpdate(); };
}
private void BlackboardUpdate(){ private void BlackboardUpdate(){
if (_data.blackboardData == null || _data.blackboardData.GetType() == typeof(BlackboardData)){ if (_data.blackboardData == null || _data.blackboardData.GetType()==(typeof(BlackboardData))){
_data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType());
if (_data.blackboardData == null) return; if (_data.blackboardData == null) return;
}
//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)){
//if the field is MonoBehaviour,add a property field for blackboard
//skip if the field is a list or Ilist
if (!typeof(IList).IsAssignableFrom(field.FieldType)){
var propertyField = new BlackboardPropertyField(new BlackboardProperty(field.Name,field.FieldType));
_blackboard.Add(propertyField);
} }
_blackboard.SetBlackboardData(_data.blackboardData);
}
_blackboard.addItemRequested = (sender) => {
var res = ScriptableObject.CreateInstance<BlackboardSearchWindowProvider>();
//Get right top corner of the blackboard
var blackboardPos = _blackboard.GetPosition().position;
var searchWindowContext = new SearchWindowContext(blackboardPos,200,200);
//Call search window
res.Setup(typeof(T),this,Owner);
SearchWindow.Open(searchWindowContext, res);
};
} }
public virtual void DestroyInspector(){ public virtual void DestroyInspector(){
@ -304,16 +273,22 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
} }
_data.nodeLinks = links; _data.NodeLinks = links;
} }
private void SaveGraphData(){ private void SaveGraphData(){
_data.NodeDictionary.Clear(); _data.NodeDictionary.Clear();
_data.nodeLinks.Clear(); _data.NodeLinks.Clear();
SaveNode(); SaveNode();
SaveEdge(); SaveEdge();
SaveBlackboard();
EditorUtility.SetDirty(_data); EditorUtility.SetDirty(_data);
} }
private void SaveBlackboard(){
if (_data.blackboardData == null){
_data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType());
}
}
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){ public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){
@ -330,10 +305,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
OnGraphViewDestroy(); OnGraphViewDestroy();
} }
public bool IsDroppable(){ #region implement interfaces
return true;
}
public void AddTNode(NodeData nodeData, Rect rect){ public void AddTNode(NodeData nodeData, Rect rect){
if (NodeEditorExtensions.CreateNodeViewFromNodeType(nodeData.GetType()) is Node nodeView){ if (NodeEditorExtensions.CreateNodeViewFromNodeType(nodeData.GetType()) is Node nodeView){
nodeView.SetPosition(rect); nodeView.SetPosition(rect);
@ -381,9 +353,30 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
Owner.graphEditorData.graphElementsData.RemoveAll(x => x.guid == nodeData.id); Owner.graphEditorData.graphElementsData.RemoveAll(x => x.guid == nodeData.id);
} }
public void CreateBlackboard(){
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));
_blackboard.Setup(this,Owner);
var castedBlackboard = _blackboard as Blackboard;
Add(castedBlackboard);
Rect blackboardPos = new Rect(0,0,300,700);
castedBlackboard?.SetPosition(blackboardPos);
OnDataChanged+= (sender, e) => { BlackboardUpdate(); };
}
public GraphData GetGraphData(){
return _data;
}
public BlackboardData GetBlackboardData(){ public BlackboardData GetBlackboardData(){
return this._data.blackboardData; return this._data.blackboardData;
} }
#endregion
} }

@ -1,5 +1,6 @@
using TNode.Editor.NodeViews; using TNode.Editor.NodeViews;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.NodeViews;
namespace TNode.Editor{ namespace TNode.Editor{

@ -1,12 +1,11 @@
using TNode.Attribute; using TNode.Attribute;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.NodeViews;
namespace TNode.Editor.NodeViews{ namespace TNode.Editor.NodeViews{
[ViewComponent] [ViewComponent]
public class DragBaseNodeView<T>:BaseNodeView<BlackboardDragNodeData<T>>{ public class DragBaseNodeView:BaseNodeView<BlackboardDragNodeData>{
public DragBaseNodeView() : base(){ public DragBaseNodeView() : base(){
//Make capsule like style
this.titleContainer.visible = false; this.titleContainer.visible = false;
this.titleContainer.RemoveFromHierarchy(); this.titleContainer.RemoveFromHierarchy();
} }

@ -1,15 +1,15 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using TNode.Attribute;
using TNode.Attribute.Ports; using TNode.Attribute.Ports;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.Serialization;
using TNode.Models; using TNode.Models;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNode.Editor.NodeViews{ namespace TNodeGraphViewImpl.Editor.NodeViews{
public abstract class BaseNodeView<T> : Node,INodeView<T> where T:NodeData,new(){ public abstract class BaseNodeView<T> : Node,INodeView<T> where T:NodeData,new(){
protected T _data; protected T _data;
@ -28,10 +28,9 @@ namespace TNode.Editor.NodeViews{
} }
} }
private void OnDataValueChanged(NodeDataWrapper obj){ private void OnDataValueChanged(DataWrapper<NodeDataWrapper, NodeData> obj){
Refresh(); Refresh();
} }
public sealed override string title{ public sealed override string title{
get => base.title; get => base.title;
set => base.title = value; set => base.title = value;
@ -77,6 +76,18 @@ namespace TNode.Editor.NodeViews{
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
protected virtual Type BuildPortType(PortAttribute portAttribute,PropertyInfo propertyInfo){
switch (portAttribute.TypeHandling){
case TypeHandling.Declared :
return propertyInfo.PropertyType;
case TypeHandling.Implemented:
return propertyInfo.GetValue(_data)?.GetType();
case TypeHandling.Specified:
return portAttribute.HandledType??typeof(object);
default:
throw new ArgumentOutOfRangeException();
}
}
/// <summary> /// <summary>
/// of course you can override this method to build your own port builder /// of course you can override this method to build your own port builder
/// </summary> /// </summary>
@ -85,7 +96,7 @@ namespace TNode.Editor.NodeViews{
foreach (var propertyInfo in propertyInfos){ foreach (var propertyInfo in propertyInfos){
if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){ if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){
Port port = InstantiatePort(Orientation.Horizontal, Direction.Output,Port.Capacity.Multi,propertyInfo.PropertyType); Port port = InstantiatePort(Orientation.Horizontal, Direction.Output,Port.Capacity.Multi,BuildPortType(attribute,propertyInfo));
this.outputContainer.Add(port); this.outputContainer.Add(port);
var portName = BuildPortName(attribute,propertyInfo); var portName = BuildPortName(attribute,propertyInfo);
port.portName = portName; port.portName = portName;
@ -94,7 +105,7 @@ namespace TNode.Editor.NodeViews{
} }
foreach (var propertyInfo in propertyInfos){ foreach (var propertyInfo in propertyInfos){
if(propertyInfo.GetCustomAttributes(typeof(InputAttribute),true).FirstOrDefault() is InputAttribute attribute){ if(propertyInfo.GetCustomAttributes(typeof(InputAttribute),true).FirstOrDefault() is InputAttribute attribute){
Port port = InstantiatePort(Orientation.Horizontal, Direction.Input,Port.Capacity.Single,propertyInfo.PropertyType); Port port = InstantiatePort(Orientation.Horizontal, Direction.Input,Port.Capacity.Single,BuildPortType(attribute,propertyInfo));
this.inputContainer.Add(port); this.inputContainer.Add(port);
var portName = BuildPortName(attribute,propertyInfo); var portName = BuildPortName(attribute,propertyInfo);
port.portName = portName; port.portName = portName;

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7d628735dd6d477c88ed608b684c50b4
timeCreated: 1657702172

@ -0,0 +1,5 @@
.unity-property-field__label {
width: 75px;
min-width: 100px;
max-width: 150px;
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2b84790a3a0445f894b9c496ad1e716b
timeCreated: 1657702197

@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using TNode.Cache;
using TNode.Editor.NodeGraphView; using TNode.Editor.NodeGraphView;
using TNode.Editor.Tools.NodeCreator; using TNode.Editor.Tools.NodeCreator;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.Cache;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;

Loading…
Cancel
Save