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

Working in process
main
taoria 3 years ago committed by GitHub
commit ac21c1b27d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      Sample/MathGraph/Editor/MathEditor.cs
  2. 7
      Sample/MathGraph/Editor/MathGraphView.cs
  3. 4
      TNode/Attribute/Ports/InputAttribute.cs
  4. 3
      TNode/Attribute/Ports/PortAttribute.cs
  5. 2
      TNode/Attribute/ViewComponentAttribute.cs
  6. 0
      TNode/Attribute/ViewComponentAttribute.cs.meta
  7. 3
      TNode/Editor/BaseViews.meta
  8. 86
      TNode/Editor/Cache/NodeEditorExtensions.cs
  9. 12
      TNode/Editor/GraphBlackboard/BlackboardField.cs
  10. 15
      TNode/Editor/GraphEditor.cs
  11. 3
      TNode/Editor/Inspector/InspectorImplementation.meta
  12. 20
      TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs
  13. 3
      TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs.meta
  14. 12
      TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs
  15. 3
      TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs.meta
  16. 23
      TNode/Editor/Inspector/InspectorImplementation/PropertyFieldItem.cs
  17. 3
      TNode/Editor/Inspector/InspectorImplementation/PropertyFieldItem.cs.meta
  18. 14
      TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs
  19. 3
      TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs.meta
  20. 12
      TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs
  21. 3
      TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs.meta
  22. 104
      TNode/Editor/Inspector/InspectorItem.cs
  23. 3
      TNode/Editor/Inspector/InspectorItem.cs.meta
  24. 44
      TNode/Editor/Inspector/InspectorItemFactory.cs
  25. 3
      TNode/Editor/Inspector/InspectorItemFactory.cs.meta
  26. 16
      TNode/Editor/Inspector/MonoScriptInspector.cs
  27. 3
      TNode/Editor/Inspector/MonoScriptInspector.cs.meta
  28. 45
      TNode/Editor/Inspector/NodeInspectorInNode.cs
  29. 3
      TNode/Editor/Manipulators.meta
  30. 3
      TNode/Editor/NodeGraphView.meta
  31. 11
      TNode/Editor/NodeGraphView/IBaseDataGraphView.cs
  32. 3
      TNode/Editor/NodeGraphView/IBaseDataGraphView.cs.meta
  33. 7
      TNode/Editor/NodeGraphView/IDataGraphView.cs
  34. 3
      TNode/Editor/NodeGraphView/IDataGraphView.cs.meta
  35. 11
      TNode/Editor/NodeViews/DefaultNodeView.cs
  36. 1
      TNode/Editor/Resources/NodeInspector.uss
  37. 3
      TNode/Editor/Resources/NodeInspector.uss.meta
  38. 3
      TNode/Models/BlackboardDragNodeData.cs
  39. 68
      TNode/Tools/NodeDataWrapper.cs
  40. 3
      TNodeGraphViewImpl.meta
  41. 3
      TNodeGraphViewImpl/Editor.meta
  42. 0
      TNodeGraphViewImpl/Editor/GraphBlackboard.meta
  43. 12
      TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardField.cs
  44. 0
      TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardField.cs.meta
  45. 0
      TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardProperty.meta
  46. 2
      TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs
  47. 0
      TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs.meta
  48. 17
      TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
  49. 3
      TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs.meta
  50. 7
      TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardView.cs
  51. 0
      TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardView.cs.meta
  52. 3
      TNodeGraphViewImpl/Editor/Inspector.meta
  53. 30
      TNodeGraphViewImpl/Editor/Inspector/NodeInspector.cs
  54. 0
      TNodeGraphViewImpl/Editor/Inspector/NodeInspector.cs.meta
  55. 57
      TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
  56. 0
      TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs.meta
  57. 3
      TNodeGraphViewImpl/Editor/NodeGraphView.meta
  58. 164
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  59. 0
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs.meta
  60. 2
      TNodeGraphViewImpl/Editor/NodeGraphView/SimpleGraphSubWindow.cs
  61. 0
      TNodeGraphViewImpl/Editor/NodeGraphView/SimpleGraphSubWindow.cs.meta
  62. 0
      TNodeGraphViewImpl/Editor/NodeViews.meta
  63. 10
      TNodeGraphViewImpl/Editor/NodeViews/DefaultNodeView.cs
  64. 0
      TNodeGraphViewImpl/Editor/NodeViews/DefaultNodeView.cs.meta
  65. 7
      TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs
  66. 0
      TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs.meta
  67. 20
      TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
  68. 0
      TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs.meta
  69. 0
      TNodeGraphViewImpl/Editor/Search.meta
  70. 30
      TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs
  71. 0
      TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs.meta
  72. 8
      TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs
  73. 0
      TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs.meta

@ -14,7 +14,7 @@ public class MathEditor : GraphEditor<MathGraph>{
var wnd = GetWindow<MathEditor>(); var wnd = GetWindow<MathEditor>();
wnd.titleContent = new GUIContent("MathGraph Editor"); wnd.titleContent = new GUIContent("MathGraph Editor");
wnd.CreateGUI(); wnd.CreateGUI();
wnd._graphView.Data = graph; wnd.GraphView.Data = graph;
return true; return true;
} }
return false; return false;

@ -1,8 +1,9 @@
using TNode.Models; using TNode.Models;
using TNode.Attribute; using TNode.Attribute;
using TNode.Editor.BaseViews; using TNodeGraphViewImpl.Editor.NodeGraphView;
[NodeComponent]
public class MathGraphView : DataGraphView<MathGraph>{ [ViewComponent]
public class MathGraphView : BaseDataGraphView<MathGraph>{

@ -1,9 +1,7 @@
using System; using System;
using JetBrains.Annotations; using JetBrains.Annotations;
using TNode.Models;
using UnityEditor.Experimental.GraphView;
namespace TNode.Attribute{ namespace TNode.Attribute.Ports{
[MeansImplicitUse] [MeansImplicitUse]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class InputAttribute : PortAttribute{ public class InputAttribute : PortAttribute{

@ -1,8 +1,7 @@
using System; using System;
using JetBrains.Annotations; using JetBrains.Annotations;
using UnityEditor.Experimental.GraphView;
namespace TNode.Attribute{ namespace TNode.Attribute.Ports{
public enum PortNameHandling{ public enum PortNameHandling{
Auto, Auto,

@ -11,7 +11,7 @@ namespace TNode.Attribute{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MeansImplicitUse] [MeansImplicitUse]
public class NodeComponentAttribute:System.Attribute{ public class ViewComponentAttribute:System.Attribute{
public Type GenericType{ get; set; } public Type GenericType{ get; set; }

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: be6b702224dc40098aadadb3749d8c81
timeCreated: 1655394343

@ -2,11 +2,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using TNode.Attribute; using TNode.Attribute;
using TNode.BaseViews;
using TNode.Editor; using TNode.Editor;
using TNode.Editor.BaseViews;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.NodeViews;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.NodeGraphView;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
using UnityEngine.TestTools.Utils; using UnityEngine.TestTools.Utils;
@ -58,7 +59,7 @@ namespace TNode.Cache{
foreach(var type in assembly.GetTypes()){ foreach(var type in assembly.GetTypes()){
if(type.IsClass && !type.IsAbstract){ if(type.IsClass && !type.IsAbstract){
//Register Node View And Graph View via its parent class //Register Node View And Graph View via its parent class
SetNodeComponentAttribute(type); SetViewComponentAttribute(type);
//Register Node Data by GraphUsageAttribute. //Register Node Data by GraphUsageAttribute.
SetGraphUsageAttribute(type); SetGraphUsageAttribute(type);
} }
@ -98,12 +99,13 @@ namespace TNode.Cache{
} }
} }
} }
private readonly Type[] _acceptedTypesForGenericToSpecific = new Type[]{typeof(NodeView<>),typeof(DataGraphView<>),typeof(InspectorItem<>),typeof(NodeView<>)}; private readonly Type[] _acceptedTypesForGenericToSpecific = new Type[]{typeof(BaseNodeView<>),typeof(BaseDataGraphView<>),typeof(GraphBlackboardView<>)};
private void SetNodeComponentAttribute(Type type){ private readonly Type[] _defaultTypes = new []{typeof(DefaultBaseNodeView),typeof(DefaultGraphBlackboardView)};
foreach (var attribute in type.GetCustomAttributes(typeof(NodeComponentAttribute), false)){ private void SetViewComponentAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(ViewComponentAttribute), false)){
//fetch this type 's parent class //fetch this type 's parent class
var parent = type.BaseType; var parent = type.BaseType;
//Check if this type is a generic type and is a generic type of NodeView or DataGraphView, //Check if this type is a generic type and is a generic type of BaseNodeView or BaseDataGraphView,
//Two level generic definition is now supported by TNode //Two level generic definition is now supported by TNode
//Deeper nested generic definition is not supported by TNode //Deeper nested generic definition is not supported by TNode
if (parent is{IsGenericType: true} && if (parent is{IsGenericType: true} &&
@ -113,7 +115,6 @@ namespace TNode.Cache{
){ ){
//Get the generic type of this type //Get the generic type of this type
//Add this type to the dictionary //Add this type to the dictionary
Debug.Log($"type {type} is a registered as node component for {parent}");
FromGenericToSpecific.Add(parent, type); FromGenericToSpecific.Add(parent, type);
} }
//TODO Note that a node component only applied to a specific type of editor,so ,same GraphView could behave differently in different editor.it's a todo feature. //TODO Note that a node component only applied to a specific type of editor,so ,same GraphView could behave differently in different editor.it's a todo feature.
@ -122,24 +123,60 @@ namespace TNode.Cache{
} }
//Outer wrapper for the singleton class //Outer wrapper for the singleton class
public static class NodeEditorExtensions{ public static class NodeEditorExtensions{
public static T CreateNodeComponentFromGenericType<T>(){ /// <summary>
/// by given a generic type T,return the implementation instance of the generic type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T CreateViewComponentFromBaseType<T>(){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)]; var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)];
var instance = (T)Activator.CreateInstance(implementedType); var instance = (T)Activator.CreateInstance(implementedType);
return instance; return instance;
} }
public static object CreateNodeComponentFromGenericType(Type t){
/// <summary>
/// by given a generic type t,return the implementation instance of the generic type
/// </summary>
/// <returns></returns>
public static object CreateViewComponentFromBaseType(Type t){
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(t)){ if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(t)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[t]; var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[t];
var instance = Activator.CreateInstance(implementedType); var instance = Activator.CreateInstance(implementedType);
return instance; return instance;
} }
//check if t is a generic type node view //check if t is a generic type node view
if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(NodeView<>)){ if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(BaseNodeView<>)){
var instance = Activator.CreateInstance(typeof(NodeView<NodeData>)); var instance = Activator.CreateInstance(typeof(BaseNodeView<NodeData>));
return instance; return instance;
} }
return null; return null;
} }
public static Blackboard CreateBlackboardDataFromBlackboardDataType(Type t){
var type = typeof(GraphBlackboardView<>).MakeGenericType(t);
var res = CreateViewComponentFromBaseType(type) as Blackboard;
return res ?? new DefaultGraphBlackboardView();
}
public static Blackboard CreateBlackboardWithGraphData(GraphData graphData){
var graphType = graphData.GetType();
if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(graphType)){
var type = NodeEditorSingleton.Instance.GraphBlackboard[graphType];
return CreateBlackboardDataFromBlackboardDataType(type);
}
return null;
}
public static Blackboard CreateBlackboardWithGraphData(Type graphType){
if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(graphType)){
var type = NodeEditorSingleton.Instance.GraphBlackboard[graphType];
return CreateBlackboardDataFromBlackboardDataType(type);
}
return null;
}
public static bool HasSpecificTypeComponent<T>() where T : class{ public static bool HasSpecificTypeComponent<T>() where T : class{
return NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(typeof(T)); return NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(typeof(T));
@ -160,21 +197,8 @@ namespace TNode.Cache{
} }
return null; return null;
} }
public static object CreateNodeViewFromNodeType<T>() where T:NodeData,new(){
//Check specific derived type exists or not.
var type = typeof(NodeView<T>);
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type];
var instance = (NodeView<T>)Activator.CreateInstance(implementedType);
return instance;
}
else{
return new DefaultNodeView();
}
}
public static object CreateNodeViewFromNodeType(Type t){ public static object CreateNodeViewFromNodeType(Type t){
//Check the generic type of NodeView by t //Check the generic type of BaseNodeView by t
if (t.IsGenericType){ if (t.IsGenericType){
Debug.Log($"A generic type {t} is detected"); Debug.Log($"A generic type {t} is detected");
@ -184,8 +208,8 @@ namespace TNode.Cache{
var genericTypeDefinition = t.GetGenericTypeDefinition(); var genericTypeDefinition = t.GetGenericTypeDefinition();
//What you want is a NodeView<BlackboardDragNodeData<T>> to be created //What you want is a BaseNodeView<BlackboardDragNodeData<T>> to be created
var genericViewType = typeof(NodeView<>).MakeGenericType(genericTypeDefinition); var genericViewType = typeof(BaseNodeView<>).MakeGenericType(genericTypeDefinition);
Debug.Log($"The generic view type is {genericViewType}"); 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
@ -202,11 +226,11 @@ namespace TNode.Cache{
} }
else{ else{
return new DefaultNodeView(); return new DefaultBaseNodeView();
} }
} }
var type = typeof(NodeView<>).MakeGenericType(t); var type = typeof(BaseNodeView<>).MakeGenericType(t);
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){ if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type]; var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type];
@ -215,7 +239,7 @@ namespace TNode.Cache{
} }
else{ else{
return new DefaultNodeView(); return new DefaultBaseNodeView();
} }
} }

@ -1,12 +0,0 @@
using UnityEditor.Experimental.GraphView;
namespace TNode.Editor.GraphBlackboard{
public class BlackboardPropertyField:BlackboardField{
public BlackboardProperty BlackboardProperty;
public BlackboardPropertyField(BlackboardProperty blackboardProperty):base(null,blackboardProperty.PropertyName,null){
BlackboardProperty = blackboardProperty;
}
}
}

@ -1,10 +1,9 @@
using Codice.CM.Common; using Codice.CM.Common;
using TNode.BaseViews;
using TNode.Cache; using TNode.Cache;
using TNode.Editor.BaseViews;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.Model; using TNode.Editor.Model;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.NodeGraphView;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
@ -15,7 +14,7 @@ namespace TNode.Editor{
public abstract class GraphEditor<T> : EditorWindow where T:GraphData{ public abstract class GraphEditor<T> : EditorWindow where T:GraphData{
protected DataGraphView<T> _graphView; protected BaseDataGraphView<T> GraphView;
[SerializeField] [SerializeField]
private VisualTreeAsset mVisualTreeAsset = default; private VisualTreeAsset mVisualTreeAsset = default;
//Persist editor data ,such as node position,node size ,etc ,in this script object //Persist editor data ,such as node position,node size ,etc ,in this script object
@ -36,9 +35,9 @@ namespace TNode.Editor{
} }
private void BuildGraphView(){ private void BuildGraphView(){
_graphView = NodeEditorExtensions.CreateNodeComponentFromGenericType<DataGraphView<T>>(); GraphView = NodeEditorExtensions.CreateViewComponentFromBaseType<BaseDataGraphView<T>>();
rootVisualElement.Add(_graphView); rootVisualElement.Add(GraphView);
_graphView.StretchToParentSize(); GraphView.StretchToParentSize();
} }
private void DefineGraphEditorActions(){ private void DefineGraphEditorActions(){
@ -54,7 +53,7 @@ namespace TNode.Editor{
private void Save(){ private void Save(){
//if no graph is loaded ,create a file save dialogue //if no graph is loaded ,create a file save dialogue
if (_graphView.Data == null) if (GraphView.Data == null)
{ {
string path = EditorUtility.SaveFilePanel("Save Graph", "", "", "asset"); string path = EditorUtility.SaveFilePanel("Save Graph", "", "", "asset");
if (path.Length != 0){ if (path.Length != 0){
@ -66,7 +65,7 @@ namespace TNode.Editor{
} }
} }
else{ else{
_graphView.SaveWithEditorData(graphEditorData); GraphView.SaveWithEditorData(graphEditorData);
AssetDatabase.Refresh(); AssetDatabase.Refresh();
} }

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 4cdebd0430794d32918ba8c63d71d0cc
timeCreated: 1656142311

@ -1,20 +0,0 @@
using System;
using TNode.Attribute;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector.InspectorImplementation{
[NodeComponent]
public class EnumFieldItem:InspectorItem<Enum>{
public EnumFieldItem() : base(){
var field = new EnumField();
Debug.Log("An Enum Field is created");
CreateBindable(field);
OnDataChanged += () => {
field.Init(Value);
Debug.Log(Value.GetType());
};
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6eb83a1255d545e5998c7b3efd1b0d69
timeCreated: 1657193097

@ -1,12 +0,0 @@
using System;
using TNode.Attribute;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector.InspectorImplementation{
[NodeComponent]
public class FloatFieldItem:InspectorItem<float>{
public FloatFieldItem():base(){
CreateBindable(new FloatField());
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 932de5e7a487475aa764dd819cc33aa0
timeCreated: 1656583186

@ -1,23 +0,0 @@
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector.InspectorImplementation{
public class PropertyFieldItem:InspectorItem<Object>{
public PropertyFieldItem(){
OnDataChanged += () => {
var data = new SerializedObject(Value as Object);
var testProperty = data.GetIterator().GetArrayElementAtIndex(0);
PropertyField propertyField = new PropertyField(testProperty);
this.Q<PropertyField>()?.RemoveFromHierarchy();
this.Add(propertyField);
};
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 98769c8b285d438197820fa366568fee
timeCreated: 1657280625

@ -1,14 +0,0 @@
using TNode.Attribute;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector.InspectorImplementation{
/// <summary>
/// Force these element to bind native c# property
/// </summary>
[NodeComponent]
public class StringFieldItem:InspectorItem<string>{
public StringFieldItem():base(){
CreateBindable(new TextField());
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6b4f88e6c094449280ba5e38cb508287
timeCreated: 1656143219

@ -1,12 +0,0 @@
using TNode.Attribute;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector.InspectorImplementation{
[NodeComponent]
public class ToggleFieldItem:InspectorItem<bool>{
public ToggleFieldItem(){
CreateBindable(new Toggle());
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: d009d4819d604971976932b1d8f40bad
timeCreated: 1656580623

@ -1,104 +0,0 @@
using System;
using TNode.BaseViews;
using TNode.Models;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector{
public abstract class InspectorItem<T>:VisualElement,INodeDataBinding<T> {
protected NodeData _bindingNodeData;
protected string _bindingFieldName;
protected BaseField<T> Bindable;
protected event System.Action OnDataChanged;
public string BindingPath{
get => _bindingFieldName;
set{
_bindingFieldName = value;
if(_bindingFieldName!=null&&_bindingNodeData!=null){
OnDataChanged?.Invoke();
}
}
}
public NodeData BindingNodeData{
get => _bindingNodeData;
set{
var oldWrapper = ((NodeDataWrapper) _bindingNodeData);
if(oldWrapper!=null){
oldWrapper.OnValueChanged -= OnNodeDataValueChanged;
}
_bindingNodeData = value;
if(_bindingFieldName!=null&&_bindingNodeData!=null){
OnDataChanged?.Invoke();
}
if(_bindingNodeData!=null)
((NodeDataWrapper) _bindingNodeData).OnValueChanged += OnNodeDataValueChanged;
}
}
private T GetValue(){
var fieldInfo = _bindingNodeData.GetType().GetField(BindingPath, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (fieldInfo == null){
throw new Exception("Null field info");
}
if (fieldInfo.FieldType == typeof(T)){
return (T)fieldInfo.GetValue(BindingNodeData);
}
if (fieldInfo.FieldType.IsEnum){
return (T)fieldInfo.GetValue(BindingNodeData);
}
Debug.LogError("Wrong Type for current node data");
return default;
}
protected T Value => GetValue();
protected void SetValue(T value){
NodeDataWrapper wrapper = _bindingNodeData;
wrapper.SetValue(BindingPath,value);
}
public InspectorItem(){
OnDataChanged+= OnDataChangedHandler;
}
/*
* e => {
SetValue(e.newValue);
}
*/
private void OnInspectorItemValueChanged(ChangeEvent<T> e){
SetValue(e.newValue);
}
public void CreateBindable(BaseField<T> bindable){
if (Bindable != null){
Bindable.Clear();
Bindable.UnregisterValueChangedCallback(OnInspectorItemValueChanged);
}
Bindable = bindable;
Add(Bindable);
Bindable?.RegisterValueChangedCallback(OnInspectorItemValueChanged);
}
private void OnDataChangedHandler(){
Bindable = this.Q<BaseField<T>>();
if(Bindable!= null){
Bindable.value = Value;
Bindable.label = BindingPath;
}
}
private void OnNodeDataValueChanged(NodeDataWrapper wrapper){
var value = (T) wrapper.GetValue(BindingPath) ;
if(Bindable!=null){
Bindable.value = value;
}
}
~InspectorItem(){
OnDataChanged-= OnDataChangedHandler;
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 82902f281e4642f2be8b742866d38839
timeCreated: 1656126272

@ -1,44 +0,0 @@
using System;
using TNode.Cache;
using TNode.Editor.Inspector.InspectorImplementation;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector{
public class InspectorItemFactory{
public InspectorItem<T> Create<T>(){
//Check type of GraphDataType
var hasSpecificType = NodeEditorExtensions.HasSpecificTypeComponent<InspectorItem<T>>();
if (hasSpecificType){
return NodeEditorExtensions.CreateNodeComponentFromGenericType<InspectorItem<T>>();
}
if (typeof(T).IsEnum){
return NodeEditorExtensions.CreateNodeComponentFromGenericType(typeof(InspectorItem<Enum>)) as InspectorItem<T>;
}
return null;
}
public INodeDataBindingBase Create(Type t){
var genericType = typeof(InspectorItem<>).MakeGenericType(t);
var hasSpecificType = NodeEditorExtensions.HasSpecificTypeComponent(genericType);
if (hasSpecificType){
return NodeEditorExtensions.CreateNodeComponentFromGenericType(genericType) as INodeDataBindingBase;
}
if (t.IsEnum){
return NodeEditorExtensions.CreateNodeComponentFromGenericType(typeof(InspectorItem<Enum>)) as INodeDataBindingBase;
}
return null;
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 83b9e37f79cf4a18b265e3e22e7e3ced
timeCreated: 1656142463

@ -1,16 +0,0 @@
using UnityEditor;
using UnityEditor.AssetImporters;
using UnityEngine;
namespace TNode.Editor.Inspector{
// [CustomEditor(typeof(MonoImporter))]
// public class MonoScriptInspector:AssetImporterEditor{
// public override void OnInspectorGUI(){
// base.OnInspectorGUI();
// if(GUILayout.Button("Open")){
// EditorUtility.OpenWithDefaultApp(AssetDatabase.GetAssetPath(target));
// }
// }
// }
//
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 192a51f6578144c5bbddb5cf77685c71
timeCreated: 1656214219

@ -1,45 +0,0 @@
using System.Reflection;
using TNode.Attribute;
using TNode.Models;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector{
public class NodeInspectorInNode:VisualElement{
private NodeData _data;
public NodeData Data{
get => _data;
set{
_data = value;
UpdateData();
}
}
private void UpdateData(){
if (_data != null){
RefreshInspector();
}
}
private void RefreshInspector(){
Clear();
InspectorItemFactory inspectorItemFactory = new InspectorItemFactory();
foreach (var field in _data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)){
var bindingPath = field.Name;
var type = field.FieldType;
//check if the field has ShowInNodeView attribute
var showInNodeViewAttribute = field.GetCustomAttribute<ShowInNodeViewAttribute>()!=null;
if(!showInNodeViewAttribute)
continue;
var createdItem = inspectorItemFactory.Create(type);
if (createdItem is { } castedItem){
castedItem.BindingNodeData = _data;
castedItem.BindingPath = bindingPath;
}
Add((VisualElement)createdItem);
}
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 400542f3cec140e2b55e2bcf637b2d9b
timeCreated: 1657009018

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9e377285943b43278ea539231483fe6f
timeCreated: 1657683945

@ -0,0 +1,11 @@
using TNode.Models;
using UnityEngine;
namespace TNode.Editor.NodeGraphView{
public interface IBaseDataGraphView{
public void AddTNode(NodeData nodeData, Rect rect);
public void RemoveTNode(NodeData nodeData);
public BlackboardData GetBlackboardData();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9839105141d14b3aac3891bcaaa3fe50
timeCreated: 1657684189

@ -0,0 +1,7 @@
using TNode.Models;
namespace TNode.Editor.NodeGraphView{
public interface IDataGraphView<T> : IBaseDataGraphView where T:GraphData{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b0f8421124864a7d993bcbfb419987dd
timeCreated: 1657684182

@ -1,11 +0,0 @@
using TNode.BaseViews;
using TNode.Editor.BaseViews;
using TNode.Models;
namespace TNode.Editor{
public class DefaultNodeView:NodeView<NodeData>{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3180a0745e5144aea3d7ea3d43b5b073
timeCreated: 1657483260

@ -1,4 +1,5 @@
using System.Runtime.InteropServices; using System;
using System.Runtime.InteropServices;
using Newtonsoft.Json; using Newtonsoft.Json;
using TNode.Attribute; using TNode.Attribute;
using TNode.Attribute.Ports; using TNode.Attribute.Ports;

@ -4,36 +4,81 @@ using TNode.Models;
using UnityEngine; using UnityEngine;
namespace TNode.Editor{ namespace TNode.Editor{
public class NodeDataWrapper{ /// <summary>
private readonly NodeData _data; /// 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 (); private static readonly Dictionary<NodeData,NodeDataWrapper> Cache = new ();
public event Action<NodeDataWrapper> OnValueChanged; public event Action<NodeDataWrapper> OnValueChanged;
public static NodeDataWrapper Get(NodeData data){ public static NodeDataWrapper Get(NodeData data){
if (data.GetType().IsGenericType){
return ScriptableObject.CreateInstance<NodeDataWrapper>();
}
if(Cache.ContainsKey(data)){ if(Cache.ContainsKey(data)){
return Cache[data]; return Cache[data];
} }
var wrapper = new NodeDataWrapper(data); var wrapper = ScriptableObject.CreateInstance<NodeDataWrapper>();
wrapper.Data = data;
Cache.Add(data,wrapper); Cache.Add(data,wrapper);
return wrapper; return wrapper;
} }
public NodeDataWrapper(NodeData data){
this._data = data;
}
public void SetValue(string path, object value){ public void SetValue(string path, object value){
var fieldInfo = _data.GetType().GetField(path); var fieldInfo = Data.GetType().GetField(path);
fieldInfo.SetValue(_data,value); fieldInfo.SetValue(Data,value);
OnValueChanged?.Invoke(this); OnValueChanged?.Invoke(this);
} }
public object GetValue(string path){ public object GetValue(string path){
var fieldInfo = _data.GetType().GetField(path); var fieldInfo = Data.GetType().GetField(path);
return fieldInfo.GetValue(_data); return fieldInfo.GetValue(Data);
} }
public static implicit operator NodeData(NodeDataWrapper wrapper){ public static implicit operator NodeData(NodeDataWrapper wrapper){
if (wrapper == null) if (wrapper == null)
return null; return null;
return wrapper._data; return wrapper.Data;
} }
public static implicit operator NodeDataWrapper(NodeData unWrapper){ public static implicit operator NodeDataWrapper(NodeData unWrapper){
@ -41,6 +86,5 @@ namespace TNode.Editor{
return null; return null;
return Get(unWrapper); return Get(unWrapper);
} }
} }
} }

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 792d2c6b4dca441981787b922b385f0a
timeCreated: 1657684260

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1e6ee4cc74d84496a099ac0624bda536
timeCreated: 1657684324

@ -0,0 +1,12 @@
using UnityEditor.Experimental.GraphView;
namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
public class BlackboardPropertyField:BlackboardField{
public BlackboardProperty.BlackboardProperty BlackboardProperty;
public BlackboardPropertyField(BlackboardProperty.BlackboardProperty blackboardProperty):base(null,blackboardProperty.PropertyName,null){
BlackboardProperty = blackboardProperty;
}
}
}

@ -1,6 +1,6 @@
using System; using System;
namespace TNode.Editor.GraphBlackboard{ namespace TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardProperty{
public class BlackboardProperty{ public class BlackboardProperty{
public string PropertyName; public string PropertyName;
public Type PropertyType; public Type PropertyType;

@ -0,0 +1,17 @@
using TNode.Attribute;
using TNode.Models;
namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
[ViewComponent]
public class DefaultGraphBlackboardView:GraphBlackboardView<BlackboardData>{
public DefaultGraphBlackboardView(){
}
public void ConstructView(){
}
public void AddParameter(){
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 98e4de339ad84949ac2c50e61a108a96
timeCreated: 1657592333

@ -1,12 +1,15 @@
using TNode.Models; using TNode.Models;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
namespace TNode.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 GraphBlackboard<T>:Blackboard where T:BlackboardData{ public class GraphBlackboardView<T>:Blackboard where T:BlackboardData{
public T BlackboardData; public T BlackboardData;
public GraphBlackboardView() : base(){
}
} }
} }

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 152e46659fee4d2fb09bc06f18d54c98
timeCreated: 1657684641

@ -2,9 +2,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using TNode.Attribute; using TNode.Attribute;
using TNode.BaseViews; using TNode.Editor.NodeViews;
using TNode.Editor.BaseViews;
using TNode.Models; using TNode.Models;
using TNodeGraphViewImpl.Editor.NodeGraphView;
using Unity.VisualScripting; using Unity.VisualScripting;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
@ -24,7 +24,7 @@ namespace TNode.Editor.Inspector{
} }
} }
public INodeView NodeView; public IBaseNodeView BaseNodeView;
private void UpdateData(){ private void UpdateData(){
Debug.Log(_data); Debug.Log(_data);
if (_data != null){ if (_data != null){
@ -46,18 +46,18 @@ namespace TNode.Editor.Inspector{
var body = this.Q("InspectorBody"); var body = this.Q("InspectorBody");
body.Clear(); body.Clear();
body.StretchToParentSize(); body.StretchToParentSize();
foreach (var field in _data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)){ // foreach (var field in _data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)){
var bindingPath = field.Name; // var bindingPath = field.Name;
var type = field.FieldType; // var type = field.FieldType;
InspectorItemFactory inspectorItemFactory = new InspectorItemFactory(); // InspectorItemFactory inspectorItemFactory = new InspectorItemFactory();
//Invoke generic function Create<> of default inspector item factory to create an inspector item of appropriate type by reflection // //Invoke generic function Create<> of default inspector item factory to create an inspector item of appropriate type by reflection
var createdItem = inspectorItemFactory.Create(type); // var createdItem = inspectorItemFactory.Create(type);
if (createdItem is { } castedItem){ // if (createdItem is { } castedItem){
castedItem.BindingNodeData = _data; // castedItem.BindingNodeData = _data;
castedItem.BindingPath = bindingPath; // castedItem.BindingPath = bindingPath;
} // }
Add((VisualElement)createdItem); // Add((VisualElement)createdItem);
} // }
} }
} }
} }

@ -0,0 +1,57 @@
using System.Reflection;
using TNode.Attribute;
using TNode.Models;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor.Inspector{
public class NodeInspectorInNode:VisualElement{
private NodeData _data;
public NodeData Data{
get => _data;
set{
_data = value;
UpdateData();
}
}
public NodeInspectorInNode():base(){
}
private void UpdateData(){
if (_data != null){
RefreshInspector();
}
}
private void RefreshInspector(){
//Set size
Clear();
//RefreshItems();
RefreshPropertyDrawer();
}
private void RefreshPropertyDrawer(){
//Check if the data's type is a generic type of BlackboardDragNodeData<>
if (_data.GetType().IsSubclassOf(typeof(BlackboardDragNodeData<>))){
return;
}
var serializedObject = new SerializedObject((NodeDataWrapper)_data);
foreach (var field in _data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public|BindingFlags.NonPublic)){
//Create corresponding property field
//check if the field has ShowInNodeView attribute
var showInNodeViewAttribute = field.GetCustomAttribute<ShowInNodeViewAttribute>() != null;
if (!showInNodeViewAttribute)
continue;
var drawer = new PropertyField(serializedObject.FindProperty("Data").FindPropertyRelative(field.Name),field.Name);
Debug.Log(serializedObject.FindProperty("Data"));
drawer.Bind(serializedObject);
Add(drawer);
}
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 509019c594fa494dba98f9910092b63e
timeCreated: 1657684502

@ -1,116 +1,27 @@
using System; using System;
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.BaseViews;
using TNode.Cache; using TNode.Cache;
using TNode.Editor.GraphBlackboard; using TNode.Editor;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.Model; using TNode.Editor.Model;
using TNode.Editor.NodeGraphView;
using TNode.Editor.NodeViews;
using TNode.Editor.Search;
using TNode.Editor.Tools.NodeCreator; using TNode.Editor.Tools.NodeCreator;
using TNode.Models; using TNode.Models;
using Unity.VisualScripting; using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardProperty;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
using Edge = UnityEditor.Experimental.GraphView.Edge; using Edge = UnityEditor.Experimental.GraphView.Edge;
namespace TNode.Editor.BaseViews{ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
/* public abstract class BaseDataGraphView<T>:GraphView,IBaseDataGraphView where T:GraphData{
public class DialogueGraphView : DataGraphView<DialogueGraph>{
public Action<DialogueNodeView> onNodeAdded;
public Action<DialogueNodeView> onNodeSelected;
public Action<DialogueNodeView> onNodeRemoved;
public Action<DialogueNodeView> onNodeUnselected;
// public DialogueGraphView(DialogueGraph graph):base(){
// this.Data = graph;
//
// //Set background to a bit of darker
//
//
// //Register a data context change callback
//
// }
public override void OnGraphViewCreate(){
AddNode(GenerateEntryPoint());
RegisterCallback<ContextualMenuPopulateEvent>(evt => {
var pos = evt.mousePosition;
evt.menu.AppendAction("Add NodeAttribute", (dropMenuAction) => {
DialogueNodeView nodeView = new DialogueNodeView{
GUID = Guid.NewGuid().ToString(),
title = "New NodeAttribute"
};
// make it a 200x100 box
nodeView.SetPosition(new Rect(pos.x - 100, pos.y - 50, 200, 100));
AddNode(nodeView);
}, DropdownMenuAction.AlwaysEnabled);
});
this.OnDataChanged += OnOnDataChanged;
}
private void OnOnDataChanged(object sender, DataChangedEventArgs<DialogueGraph> e){
//clean all nodes from the graphview
foreach (var graphViewNode in nodes){
RemoveElement(graphViewNode);
}
foreach (var edge in edges){
RemoveElement(edge);
}
//add all nodes from the new graph
foreach (var node in e.NewData.nodes){
//AddNode(node);
}
}
public void AddNode(DialogueNodeData dialogueNodeData){
var res = InstantiateFromDialogueNodeData(dialogueNodeData);
AddNode(res);
}
public void AddNode(DialogueNodeView nodeView){
AddElement(nodeView);
onNodeAdded?.Invoke(nodeView);
//Register nodeView selection callback
nodeView.RegisterCallback<MouseDownEvent>(evt => {
if (evt.clickCount == 1){
onNodeSelected?.Invoke(nodeView);
}
});
nodeView.OnUnselect += () => { onNodeUnselected?.Invoke(nodeView); };
}
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter) => this.ports.ToList()
.Where(x => x != startPort &&
x.direction != startPort.direction).ToList();
public DialogueNodeView GenerateEntryPoint(){
var entryPoint = new DialogueNodeView{
title = "Entry Point",
GUID = Guid.NewGuid().ToString(),
EntryPoint = true
};
//Add output port to the nodeView
entryPoint.AddPort(Orientation.Horizontal, Direction.Output, "Next");
//Set nodeView position to top center side of screen
entryPoint.SetPosition(new Rect(this.layout.width / 2 - 100, 0, 200, 200));
return entryPoint;
}
protected DialogueNodeView InstantiateFromDialogueNodeData(DialogueNodeData dialogueNodeData){
var node = new DialogueNodeView();
node.title = dialogueNodeData.nodeName;
node.GUID = Guid.NewGuid().ToString();
//TODO:after completing the separation of the node data and the node editor data,this should be switch to the node editor data
//node.SetPosition(dialogueNodeData.rect);
this.AddNode(node);
return node;
}
}
*/
public abstract class DataGraphView<T>:GraphView,IDataGraphView where T:GraphData{
#region variables and properties #region variables and properties
private T _data; private T _data;
private bool _isInspectorOn; private bool _isInspectorOn;
@ -136,11 +47,11 @@ namespace TNode.Editor.BaseViews{
#endregion #endregion
//A Constructor for the DataGraphView ,never to override it //A Constructor for the BaseDataGraphView ,never to override it
#region construct default behaviour #region construct default behaviour
public DataGraphView(){ public BaseDataGraphView(){
styleSheets.Add(Resources.Load<StyleSheet>("GraphViewBackground")); styleSheets.Add(Resources.Load<StyleSheet>("GraphViewBackground"));
var grid = new GridBackground(); var grid = new GridBackground();
Insert(0,grid); Insert(0,grid);
@ -281,20 +192,11 @@ namespace TNode.Editor.BaseViews{
} }
public virtual void CreateBlackboard(){ public virtual void CreateBlackboard(){
_blackboard = new Blackboard();
//Blackboard add "Add Node" button _blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));
// blackboard.Add(new BlackboardSection(){
// title = "Hello World",
// });
// blackboard.addItemRequested = (item) => {
// //Create a sub window for the blackboard to show the selection
// var subWindow = ScriptableObject.CreateNodeComponentFromGenericType<NodeSearchWindowProvider>();
// };
//
//Set black board to left side of the view
_blackboard.SetPosition(new Rect(0,0,200,600)); _blackboard.SetPosition(new Rect(0,0,200,600));
Add(_blackboard); Add(_blackboard);
//Check the type of the blackboard
OnDataChanged+= (sender, e) => { BlackboardUpdate(); }; OnDataChanged+= (sender, e) => { BlackboardUpdate(); };
@ -311,9 +213,25 @@ namespace TNode.Editor.BaseViews{
foreach (var field in _data.blackboardData.GetType() foreach (var field in _data.blackboardData.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){
//if the field is MonoBehaviour,add a property field for blackboard //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)); var propertyField = new BlackboardPropertyField(new BlackboardProperty(field.Name,field.FieldType));
_blackboard.Add(propertyField); _blackboard.Add(propertyField);
} }
}
_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(){
@ -341,7 +259,7 @@ namespace TNode.Editor.BaseViews{
var nodeEditorData = new GraphElementEditorData{ var nodeEditorData = new GraphElementEditorData{
pos = node.GetPosition(), pos = node.GetPosition(),
}; };
if (node is INodeView nodeView){ if (node is IBaseNodeView nodeView){
nodeEditorData.guid = nodeView.GetNodeData().id; nodeEditorData.guid = nodeView.GetNodeData().id;
} }
graphEditorData.graphElementsData.Add(nodeEditorData); graphEditorData.graphElementsData.Add(nodeEditorData);
@ -357,7 +275,7 @@ namespace TNode.Editor.BaseViews{
private void SaveNode(){ private void SaveNode(){
foreach (var node in nodes){ foreach (var node in nodes){
if (node is INodeView nodeView){ if (node is IBaseNodeView nodeView){
var nodeData = nodeView.GetNodeData(); var nodeData = nodeView.GetNodeData();
if (!_data.NodeDictionary.ContainsKey(nodeData.id)){ if (!_data.NodeDictionary.ContainsKey(nodeData.id)){
_data.NodeDictionary.Add(nodeData.id, nodeData); _data.NodeDictionary.Add(nodeData.id, nodeData);
@ -368,8 +286,8 @@ namespace TNode.Editor.BaseViews{
private void SaveEdge(){ private void SaveEdge(){
var links = new List<NodeLink>(); var links = new List<NodeLink>();
foreach (var edge in edges){ foreach (var edge in edges){
var inputNode = edge.input.node as INodeView; var inputNode = edge.input.node as IBaseNodeView;
var outputNode = edge.output.node as INodeView; var outputNode = edge.output.node as IBaseNodeView;
if (inputNode != null && outputNode != null){ if (inputNode != null && outputNode != null){
var inputNodeData = inputNode.GetNodeData(); var inputNodeData = inputNode.GetNodeData();
var outputNodeData = outputNode.GetNodeData(); var outputNodeData = outputNode.GetNodeData();
@ -408,7 +326,7 @@ namespace TNode.Editor.BaseViews{
public virtual void OnGraphViewDestroy(){ public virtual void OnGraphViewDestroy(){
} }
~DataGraphView(){ ~BaseDataGraphView(){
OnGraphViewDestroy(); OnGraphViewDestroy();
} }
@ -425,11 +343,11 @@ namespace TNode.Editor.BaseViews{
if (evt.clickCount == 1){ if (evt.clickCount == 1){
if (_isInspectorOn){ if (_isInspectorOn){
_nodeInspector.Data = nodeData; _nodeInspector.Data = nodeData;
_nodeInspector.NodeView = nodeView as INodeView; _nodeInspector.BaseNodeView = nodeView as IBaseNodeView;
} }
} }
}); });
if(nodeView is INodeView nodeViewInterface){ if(nodeView is IBaseNodeView nodeViewInterface){
nodeViewInterface.SetNodeData(nodeData); nodeViewInterface.SetNodeData(nodeData);
} }
_nodeDict.Add(nodeData.id, nodeView); _nodeDict.Add(nodeData.id, nodeView);
@ -439,7 +357,7 @@ namespace TNode.Editor.BaseViews{
var menu = new GenericMenu(); var menu = new GenericMenu();
menu.AddItem(new GUIContent("Delete"), false, () => { menu.AddItem(new GUIContent("Delete"), false, () => {
RemoveElement(nodeView); RemoveElement(nodeView);
if (nodeView is INodeView tNodeView){ if (nodeView is IBaseNodeView tNodeView){
RemoveTNode(tNodeView.GetNodeData()); RemoveTNode(tNodeView.GetNodeData());
} }
}); });
@ -468,12 +386,6 @@ namespace TNode.Editor.BaseViews{
} }
} }
public interface IDataGraphView{
public void AddTNode(NodeData nodeData, Rect rect);
public void RemoveTNode(NodeData nodeData);
public BlackboardData GetBlackboardData();
}
public class DataChangedEventArgs<T>{ public class DataChangedEventArgs<T>{
public DataChangedEventArgs(T data){ public DataChangedEventArgs(T data){

@ -5,7 +5,7 @@ using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNode.BaseViews{ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public class SimpleGraphSubWindow:GraphElement,IGraphViewPersistence{ public class SimpleGraphSubWindow:GraphElement,IGraphViewPersistence{
private readonly Dragger _dragger = new Dragger(); private readonly Dragger _dragger = new Dragger();

@ -0,0 +1,10 @@
using TNode.Editor.NodeViews;
using TNode.Models;
namespace TNode.Editor{
public class DefaultBaseNodeView:BaseNodeView<NodeData>{
}
}

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

@ -5,17 +5,13 @@ using TNode.Attribute;
using TNode.Attribute.Ports; using TNode.Attribute.Ports;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Models; using TNode.Models;
using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNode.Editor.BaseViews{ namespace TNode.Editor.NodeViews{
//A NodeAttribute monitor some type of node in the graph public abstract class BaseNodeView<T> : Node,INodeView<T> where T:NodeData,new(){
public abstract class NodeView<T> : Node,INodeView where T:NodeData,new(){
protected T _data; protected T _data;
private readonly NodeInspectorInNode _nodeInspectorInNode; private readonly NodeInspectorInNode _nodeInspectorInNode;
@ -42,7 +38,7 @@ namespace TNode.Editor.BaseViews{
} }
public event System.Action<T> OnDataChanged; public event System.Action<T> OnDataChanged;
protected NodeView(){ protected BaseNodeView(){
OnDataChanged+=OnDataChangedHandler; OnDataChanged+=OnDataChangedHandler;
_nodeInspectorInNode = new NodeInspectorInNode(){ _nodeInspectorInNode = new NodeInspectorInNode(){
@ -69,10 +65,8 @@ namespace TNode.Editor.BaseViews{
switch (portAttribute.NameHandling){ switch (portAttribute.NameHandling){
case PortNameHandling.Auto: case PortNameHandling.Auto:
return portAttribute.Name.Trim(' ').Length>0?portAttribute.Name:propertyInfo.Name; return portAttribute.Name.Trim(' ').Length>0?portAttribute.Name:propertyInfo.Name;
break;
case PortNameHandling.Manual: case PortNameHandling.Manual:
return portAttribute.Name; return portAttribute.Name;
break;
case PortNameHandling.MemberName: case PortNameHandling.MemberName:
return propertyInfo.Name; return propertyInfo.Name;
case PortNameHandling.Format: case PortNameHandling.Format:
@ -169,11 +163,15 @@ namespace TNode.Editor.BaseViews{
} }
} }
public interface INodeView{ public interface IBaseNodeView{
public void SetNodeData(NodeData nodeData); public void SetNodeData(NodeData nodeData);
public NodeData GetNodeData(); public NodeData GetNodeData();
public void OnDataModified(); public void OnDataModified();
} }
public interface INodeView<T>:IBaseNodeView where T:NodeData,new(){
public T Data{ get; set; }
}
} }

@ -1,15 +1,15 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using TNode.Editor.BaseViews; using TNode.Editor.NodeGraphView;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
namespace TNode.Editor{ namespace TNode.Editor.Search{
public class BlackboardSearchWindowProvider:ISearchWindowProvider{ public class BlackboardSearchWindowProvider:ScriptableObject,ISearchWindowProvider{
private Type _graphType; private Type _graphType;
private IDataGraphView _graphView; private IBaseDataGraphView _graphView;
private EditorWindow _editor; private EditorWindow _editor;
private struct InternalSearchTreeUserData{ private struct InternalSearchTreeUserData{
@ -20,15 +20,19 @@ namespace TNode.Editor{
public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context){ public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context){
var blackboardData = _graphView.GetBlackboardData(); var blackboardData = _graphView.GetBlackboardData();
var type = blackboardData.GetType(); var type = blackboardData.GetType();
var entries = new List<SearchTreeEntry>(); var list = new List<SearchTreeEntry>(){
if (entries == null) throw new ArgumentNullException(nameof(entries)); new SearchTreeGroupEntry(new GUIContent("Add New Blackboard Data"), 0),
};
if (list == null) throw new ArgumentNullException(nameof(list));
//search fields with List type //search fields with List type
Texture2D icon = new Texture2D(2,2); Texture2D icon = new Texture2D(2,2);
foreach (var field in type.GetFields()){ foreach (var field in type.GetFields()){
if (field.FieldType.IsGenericType){ if (field.FieldType.IsGenericType){
var genericType = field.FieldType.GetGenericTypeDefinition(); var genericType = field.FieldType.GetGenericTypeDefinition();
if (genericType == typeof(List<>)){ if (genericType == typeof(List<>)){
entries.Add(new SearchTreeEntry(new GUIContent(field.Name,icon)){ list.Add(new SearchTreeEntry(new GUIContent(field.Name,icon)){
level = 1, level = 1,
userData = new InternalSearchTreeUserData(){ userData = new InternalSearchTreeUserData(){
List = field.GetValue(blackboardData) as IList, List = field.GetValue(blackboardData) as IList,
@ -39,28 +43,24 @@ namespace TNode.Editor{
} }
} }
} }
Debug.Log($"{list.Count}");
return entries; return list;
} }
public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){ public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){
var userData = SearchTreeEntry.userData; var userData = SearchTreeEntry.userData;
var relativePos = context.screenMousePosition - _editor.position.position;
var blackboardData = _graphView.GetBlackboardData();
if (userData is InternalSearchTreeUserData){ if (userData is InternalSearchTreeUserData){
var list = ((InternalSearchTreeUserData) userData).List; var list = ((InternalSearchTreeUserData) userData).List;
var type = ((InternalSearchTreeUserData) userData).Type; var type = ((InternalSearchTreeUserData) userData).Type;
var newItem = Activator.CreateInstance(type); var newItem = Activator.CreateInstance(type);
list.Add(newItem); list?.Add(newItem);
return true; return true;
} }
return false; return false;
} }
public void Setup(Type graph,IDataGraphView graphView,EditorWindow editor){ public void Setup(Type graph,IBaseDataGraphView graphView,EditorWindow editor){
_graphType = graph; _graphType = graph;
_graphView = graphView; _graphView = graphView;
_editor = editor; _editor = editor;

@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using TNode.BaseViews;
using TNode.Cache; using TNode.Cache;
using TNode.Editor.BaseViews; using TNode.Editor.NodeGraphView;
using TNode.Editor.Tools.NodeCreator; using TNode.Editor.Tools.NodeCreator;
using TNode.Models; using TNode.Models;
using UnityEditor; using UnityEditor;
@ -11,7 +9,7 @@ using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNode.Editor{ namespace TNode.Editor.Search{
public class NodeSearchWindowProvider:ScriptableObject,ISearchWindowProvider{ public class NodeSearchWindowProvider:ScriptableObject,ISearchWindowProvider{
private Type _graphType; private Type _graphType;
private GraphView _graphView; private GraphView _graphView;
@ -50,7 +48,7 @@ namespace TNode.Editor{
//Make an instance of the type //Make an instance of the type
if (NodeCreator.InstantiateNodeData(type) is { } nodeData){ if (NodeCreator.InstantiateNodeData(type) is { } nodeData){
nodeData.nodeName = $"New {type.Name}"; nodeData.nodeName = $"New {type.Name}";
((IDataGraphView) _graphView).AddTNode(nodeData, new Rect(localPos.x, localPos.y, 100, 100)); ((IBaseDataGraphView) _graphView).AddTNode(nodeData, new Rect(localPos.x, localPos.y, 100, 100));
} }
} }
return true; return true;
Loading…
Cancel
Save