1.try script object type node data

main
taoria 3 years ago
parent a26dfb0ac5
commit 7cc59a6636
  1. 2
      Sample/HelloGraph.cs
  2. 3
      Sample/HelloNode.cs
  3. 4
      TNode/Editor/BaseViews/DataGraphView.cs
  4. 41
      TNode/Editor/BaseViews/NodeView.cs
  5. 1
      TNode/Editor/Cache/NodeEditorExtensions.cs
  6. 3
      TNode/Editor/DefaultNodeView.cs
  7. 16
      TNode/Editor/Inspector/DefaultInspectorItemFactory.cs
  8. 12
      TNode/Editor/Inspector/INodeDataBinding.cs
  9. 6
      TNode/Editor/Inspector/InspectorImplementation/DefaultInspectorItem.cs
  10. 21
      TNode/Editor/Inspector/InspectorItem.cs
  11. 18
      TNode/Editor/Inspector/NodeInspector.cs
  12. 5
      TNode/Editor/SearchWindowProvider.cs
  13. 2
      TNode/Models/NodeData.cs

@ -2,7 +2,7 @@ using System;
using TNode.Models; using TNode.Models;
using UnityEngine; using UnityEngine;
namespace Sample.Editor{ namespace Sample{
[CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] [CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")]
[Serializable] [Serializable]
public class HelloGraph : GraphData{ public class HelloGraph : GraphData{

@ -1,5 +1,4 @@
using Sample.Editor; using TNode.Attribute;
using TNode.Attribute;
using TNode.Models; using TNode.Models;
namespace Sample{ namespace Sample{

@ -206,10 +206,14 @@ 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;
} }
} }
}); });
if(nodeView is INodeView nodeViewInterface){
nodeViewInterface.SetNodeData(nodeData);
}
} }
} }

@ -1,12 +1,13 @@
using Dialogue; using TNode.Models;
using TNode.Models; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
namespace TNode.BaseViews{ namespace TNode.Editor.BaseViews{
//A NodeAttribute monitor some type of node in the graph //A NodeAttribute monitor some type of node in the graph
public abstract class NodeView<T> : Node where T:NodeData,new(){ public abstract class NodeView<T> : Node,INodeView where T:NodeData,new(){
protected T _data; protected T _data;
public T Data{ public T Data{
get => _data; get => _data;
@ -21,8 +22,38 @@ namespace TNode.BaseViews{
} }
public event System.Action<T> OnDataChanged; public event System.Action<T> OnDataChanged;
public NodeView(){ protected NodeView(){
OnDataChanged+=OnDataChangedHandler;
}
private void OnDataChangedHandler(T obj){
this.title = _data.nodeName;
}
public void SetNodeData(NodeData nodeData){
Data = (T)nodeData;
}
public NodeData GetNodeData(){
return _data;
}
public void OnDataModified(){
Refresh();
} }
public void Refresh(){
title = _data.nodeName;
}
}
public interface INodeView{
public void SetNodeData(NodeData nodeData);
public NodeData GetNodeData();
public void OnDataModified();
} }
} }

@ -67,7 +67,6 @@ namespace TNode.Cache{
parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){ parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){
//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($"Find a component named {type} and its parent is {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.

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

@ -1,7 +1,9 @@
using System; using System;
using TNode.Cache; using TNode.Cache;
using TNode.Editor.Inspector.InspectorImplementation; using TNode.Editor.Inspector.InspectorImplementation;
using Unity.VisualScripting;
using UnityEditor; using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNode.Editor.Inspector{ namespace TNode.Editor.Inspector{
@ -21,11 +23,21 @@ namespace TNode.Editor.Inspector{
public static InspectorItem<T> DefaultInspectorItem<T>(){ public static InspectorItem<T> DefaultInspectorItem<T>(){
DefaultInspectorItem<T> item = new DefaultInspectorItem<T>(); DefaultInspectorItem<T> item = new DefaultInspectorItem<T>();
if (typeof(string) == typeof(T)){ if (typeof(string) == typeof(T)){
item.foldOut.Add(new TextField(){ var textField = new TextField(){
name = "StringTextField" name = "StringTextField"
}); };
item.foldOut.Add(textField);
textField.RegisterCallback<ChangeEvent<string>>(e => {
Debug.Log(item.BindingNodeData);
Debug.Log(item.BindingPath);
item.BindingNodeData.GetType().GetField(item.BindingPath).SetValue(item.BindingNodeData, e.newValue);
if (item.parent.parent is NodeInspector nodeInspector){
Debug.Log("item 's parent 's parent is exactly a node inspector");
nodeInspector.NodeView.OnDataModified();
} }
});
}
return item; return item;
} }

@ -3,20 +3,8 @@ using UnityEngine;
namespace TNode.Editor.Inspector{ namespace TNode.Editor.Inspector{
public interface INodeDataBinding<out T>:INodeDataBindingBase{ public interface INodeDataBinding<out T>:INodeDataBindingBase{
protected T GetValue(){
var fieldInfo = typeof(T).GetField(BindingPath, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
//check field type
if (fieldInfo != null && fieldInfo.FieldType == typeof(T)){
return (T)fieldInfo.GetValue(BindingNodeData);
}
else{
Debug.LogError("Wrong Type for current node data");
}
return default;
}
public T Value => GetValue();
public void OnBindingDataUpdate(){ public void OnBindingDataUpdate(){

@ -3,13 +3,17 @@
namespace TNode.Editor.Inspector.InspectorImplementation{ namespace TNode.Editor.Inspector.InspectorImplementation{
public class DefaultInspectorItem<T>:InspectorItem<T>{ public class DefaultInspectorItem<T>:InspectorItem<T>{
public readonly Foldout foldOut; public readonly Foldout foldOut;
public DefaultInspectorItem(){ public DefaultInspectorItem():base(){
foldOut = new Foldout{ foldOut = new Foldout{
text = "" text = ""
}; };
this.Add(foldOut); this.Add(foldOut);
OnValueChanged += () => { OnValueChanged += () => {
foldOut.text = this.BindingPath; foldOut.text = this.BindingPath;
var textField = this.Q<TextField>();
if(textField != null){
textField.value = this.Value.ToString();
}
}; };
} }
} }

@ -1,4 +1,5 @@
using TNode.Models; using TNode.BaseViews;
using TNode.Models;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
@ -29,13 +30,29 @@ namespace TNode.Editor.Inspector{
} }
} }
private T GetValue(){
var fieldInfo = _bindingNodeData.GetType().GetField(BindingPath, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
Debug.Log(fieldInfo);
Debug.Log(fieldInfo?.FieldType );
//check field type
if (fieldInfo != null && fieldInfo.FieldType == typeof(T)){
return (T)fieldInfo.GetValue(BindingNodeData);
}
else{
Debug.LogError("Wrong Type for current node data");
}
return default;
}
protected T Value => GetValue();
public InspectorItem(){ public InspectorItem(){
OnValueChanged+= OnValueChangedHandler; OnValueChanged+= OnValueChangedHandler;
} }
private void OnValueChangedHandler(){ private void OnValueChangedHandler(){
} }
~InspectorItem(){ ~InspectorItem(){
OnValueChanged-= OnValueChangedHandler; OnValueChanged-= OnValueChangedHandler;

@ -1,5 +1,6 @@
using System.Reflection; using System.Reflection;
using TNode.BaseViews; using TNode.BaseViews;
using TNode.Editor.BaseViews;
using TNode.Models; using TNode.Models;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
@ -17,6 +18,7 @@ namespace TNode.Editor.Inspector{
} }
} }
public INodeView NodeView;
private void UpdateData(){ private void UpdateData(){
Debug.Log(_data); Debug.Log(_data);
if (_data != null){ if (_data != null){
@ -33,21 +35,23 @@ namespace TNode.Editor.Inspector{
private void RefreshInspector(){ private void RefreshInspector(){
//iterate field of data and get name of every fields,create a new inspector item of appropriate type and add it to the inspector for each field //iterate field of data and get name of every fields,create a new inspector item of appropriate type and add it to the inspector for each field
this.Q("InspectorBody").Clear(); var body = this.Q("InspectorBody");
body.Clear();
body.Add(new Label(_data.nodeName));
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;
DefaultInspectorItemFactory defaultInspectorItemFactory = new DefaultInspectorItemFactory(); DefaultInspectorItemFactory defaultInspectorItemFactory = new DefaultInspectorItemFactory();
//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
MethodInfo methodInfo = defaultInspectorItemFactory.GetType().GetMethod("Create", BindingFlags.Instance | BindingFlags.Public); MethodInfo methodInfo = defaultInspectorItemFactory.GetType().GetMethod("Create", BindingFlags.Instance | BindingFlags.Public);
if (methodInfo != null){ if (methodInfo != null){
var genericMethod = methodInfo.MakeGenericMethod(type); var genericMethod = methodInfo.MakeGenericMethod(type);
var createdInspector = genericMethod.Invoke(defaultInspectorItemFactory,null) as VisualElement; var createdItem = genericMethod.Invoke(defaultInspectorItemFactory,null) as VisualElement;
this.Q("InspectorBody").Add(createdInspector);
if (createdInspector is INodeDataBindingBase castedInspector){ body.Add(createdItem);
castedInspector.BindingNodeData = _data; if (createdItem is INodeDataBindingBase castedItem){
castedInspector.BindingPath = bindingPath; castedItem.BindingNodeData = _data;
castedItem.BindingPath = bindingPath;
} }
} }
} }

@ -47,11 +47,12 @@ namespace TNode.Editor{
//Check if type is derived from NodeData //Check if type is derived from NodeData
if (typeof(NodeData).IsAssignableFrom(type)){ if (typeof(NodeData).IsAssignableFrom(type)){
//Make an instance of the type //Make an instance of the type
var nodeData = (NodeData) Activator.CreateInstance(type); var nodeData = CreateInstance(type) as NodeData;
if (nodeData != null){
nodeData.nodeName = "New Node"; nodeData.nodeName = "New Node";
((IDataGraphView) _graphView).AddTNode(nodeData, new Rect(localPos.x, localPos.y, 100, 100)); ((IDataGraphView) _graphView).AddTNode(nodeData, new Rect(localPos.x, localPos.y, 100, 100));
} }
}
return true; return true;
} }
return false; return false;

@ -11,7 +11,7 @@ namespace TNode.Models{
/// ///
/// </summary> /// </summary>
[Serializable] [Serializable]
public class NodeData:IModel{ public class NodeData:ScriptableObject,IModel{
public NodeData() : base(){ public NodeData() : base(){
//Object Registration //Object Registration

Loading…
Cancel
Save