diff --git a/Dialogue.meta b/Dialogue.meta deleted file mode 100644 index 3fc8b1a..0000000 --- a/Dialogue.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 95903e6a18543fb46ba6bd05887b9e85 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Sample/Editor/HelloEditor.cs b/Sample/Editor/HelloEditor.cs index 84da187..d342d59 100644 --- a/Sample/Editor/HelloEditor.cs +++ b/Sample/Editor/HelloEditor.cs @@ -18,5 +18,9 @@ namespace Sample.Editor{ } return false; } + + public HelloEditor(){ + + } } } \ No newline at end of file diff --git a/Sample/Editor/HelloGraphView.cs b/Sample/Editor/HelloGraphView.cs index 7bb5ef4..4185407 100644 --- a/Sample/Editor/HelloGraphView.cs +++ b/Sample/Editor/HelloGraphView.cs @@ -9,5 +9,7 @@ namespace Sample.Editor{ public override void OnGraphViewCreate(){ CreateInspector(); } + + } } \ No newline at end of file diff --git a/Sample/HelloComponent.cs b/Sample/HelloComponent.cs new file mode 100644 index 0000000..f4b3f03 --- /dev/null +++ b/Sample/HelloComponent.cs @@ -0,0 +1,13 @@ +using System; +using UnityEngine; + +namespace Sample{ + public class HelloComponent:MonoBehaviour{ + public void Update(){ + var trans1 = gameObject.transform; + var trans2 = gameObject.GetComponent(); + var tran3 = GetComponent(); + var tran4 = transform; + } + } +} \ No newline at end of file diff --git a/Sample/HelloComponent.cs.meta b/Sample/HelloComponent.cs.meta new file mode 100644 index 0000000..3ebdb9e --- /dev/null +++ b/Sample/HelloComponent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aba7d5b338ab470aa820882d309d1f7c +timeCreated: 1656587766 \ No newline at end of file diff --git a/Sample/HelloGraph.cs b/Sample/HelloGraph.cs index 89b4857..fe9ed6b 100644 --- a/Sample/HelloGraph.cs +++ b/Sample/HelloGraph.cs @@ -2,7 +2,7 @@ using System; using TNode.Models; using UnityEngine; -namespace Sample.Editor{ +namespace Sample{ [CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] [Serializable] public class HelloGraph : GraphData{ diff --git a/Sample/HelloNode.cs b/Sample/HelloNode.cs index b8dd3d0..b30dda3 100644 --- a/Sample/HelloNode.cs +++ b/Sample/HelloNode.cs @@ -1,10 +1,11 @@ -using Sample.Editor; -using TNode.Attribute; +using TNode.Attribute; using TNode.Models; +using UnityEngine; namespace Sample{ [GraphUsage(typeof(HelloGraph))] public class HelloNode:NodeData{ - + [ShowInNodeView] + public string SayHelloText = ""; } } \ No newline at end of file diff --git a/TNode/Attribute/ShowInNodeViewAttribute.cs b/TNode/Attribute/ShowInNodeViewAttribute.cs new file mode 100644 index 0000000..f2ffde9 --- /dev/null +++ b/TNode/Attribute/ShowInNodeViewAttribute.cs @@ -0,0 +1,8 @@ +using System; + +namespace TNode.Attribute{ + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] + public class ShowInNodeViewAttribute:System.Attribute{ + + } +} \ No newline at end of file diff --git a/TNode/Attribute/ShowInNodeViewAttribute.cs.meta b/TNode/Attribute/ShowInNodeViewAttribute.cs.meta new file mode 100644 index 0000000..810a289 --- /dev/null +++ b/TNode/Attribute/ShowInNodeViewAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3486b937bc1e4a95aa03e842a23fdf72 +timeCreated: 1656584304 \ No newline at end of file diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs index 4ff7ffa..e82d897 100644 --- a/TNode/Editor/BaseViews/DataGraphView.cs +++ b/TNode/Editor/BaseViews/DataGraphView.cs @@ -178,12 +178,24 @@ namespace TNode.Editor.BaseViews{ public virtual void CreateInspector(){ NodeInspector nodeInspector = new NodeInspector(); - nodeInspector.SetPosition(new Rect(200,200,200,600)); this.Add(nodeInspector); _nodeInspector = nodeInspector; _isInspectorOn = true; } + public virtual void DestroyInspector(){ + if(_nodeInspector!=null){ + this.Remove(_nodeInspector); + _nodeInspector = null; + } + _isInspectorOn = false; + } + public virtual void SetInspector(NodeInspector nodeInspector){ + _nodeInspector = nodeInspector; + if (!_isInspectorOn){ + _isInspectorOn = true; + } + } public virtual void OnGraphViewCreate(){ @@ -206,17 +218,25 @@ namespace TNode.Editor.BaseViews{ if (evt.clickCount == 1){ if (_isInspectorOn){ _nodeInspector.Data = nodeData; + _nodeInspector.NodeView = nodeView as INodeView; } } }); + if(nodeView is INodeView nodeViewInterface){ + nodeViewInterface.SetNodeData(nodeData); + } } } + public void RemoveTNode(NodeData nodeData){ + throw new NotImplementedException(); + } } public interface IDataGraphView{ public void AddTNode(NodeData nodeData, Rect rect); + public void RemoveTNode(NodeData nodeData); } public class DataChangedEventArgs{ diff --git a/TNode/Editor/BaseViews/NodeView.cs b/TNode/Editor/BaseViews/NodeView.cs index 60777c4..e456f0b 100644 --- a/TNode/Editor/BaseViews/NodeView.cs +++ b/TNode/Editor/BaseViews/NodeView.cs @@ -1,28 +1,80 @@ -using Dialogue; +using TNode.Editor.Inspector; using TNode.Models; +using UnityEditor; using UnityEditor.Experimental.GraphView; +using UnityEditor.UIElements; +using UnityEngine; -namespace TNode.BaseViews{ +namespace TNode.Editor.BaseViews{ //A NodeAttribute monitor some type of node in the graph - public abstract class NodeView : Node where T:NodeData,new(){ + public abstract class NodeView : Node,INodeView where T:NodeData,new(){ protected T _data; + private readonly NodeInspectorInNode _nodeInspectorInNode; + public T Data{ get => _data; set{ + if(_data!=null) + ((NodeDataWrapper)_data).OnValueChanged -= OnDataValueChanged; _data = value; OnDataChanged?.Invoke(value); + if(_data!=null) + ((NodeDataWrapper)_data).OnValueChanged += OnDataValueChanged; + } } + + private void OnDataValueChanged(NodeDataWrapper obj){ + Refresh(); + } + public sealed override string title{ get => base.title; set => base.title = value; } public event System.Action OnDataChanged; - - public NodeView(){ - + + protected NodeView(){ + OnDataChanged+=OnDataChangedHandler; + _nodeInspectorInNode = new NodeInspectorInNode(){ + name = "nodeInspectorInNode" + }; + this.extensionContainer.Add(_nodeInspectorInNode); + } + private void OnDataChangedHandler(T obj){ + this.title = _data.nodeName; + if (_nodeInspectorInNode != null){ + _nodeInspectorInNode.Data = obj; + this.RefreshExpandedState(); + this.expanded = true; + } + } + + 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(); + } } \ No newline at end of file diff --git a/TNode/Editor/Cache/NodeEditorExtensions.cs b/TNode/Editor/Cache/NodeEditorExtensions.cs index 9df7c55..def3bc3 100644 --- a/TNode/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/Editor/Cache/NodeEditorExtensions.cs @@ -5,6 +5,7 @@ using TNode.Attribute; using TNode.BaseViews; using TNode.Editor; using TNode.Editor.BaseViews; +using TNode.Editor.Inspector; using TNode.Models; using UnityEditor.Experimental.GraphView; using UnityEngine; @@ -57,17 +58,15 @@ namespace TNode.Cache{ } } } - + private readonly Type[] _acceptedTypesForGenericToSpecific = new Type[]{typeof(NodeView<>),typeof(DataGraphView<>),typeof(InspectorItem<>)}; private void SetNodeComponentAttribute(Type type){ foreach (var attribute in type.GetCustomAttributes(typeof(NodeComponentAttribute), false)){ //fetch this type 's parent class var parent = type.BaseType; //Check if this type is a generic type and is a generic type of NodeView or DataGraphView - if (parent is{IsGenericType: true} && (parent.GetGenericTypeDefinition() == typeof(NodeView<>) || - parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){ + if (parent is{IsGenericType: true} && _acceptedTypesForGenericToSpecific.Contains(parent.GetGenericTypeDefinition())){ //Get the generic type of this type //Add this type to the dictionary - Debug.Log($"Find a component named {type} and its parent is {parent}"); 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. diff --git a/TNode/Editor/DefaultNodeView.cs b/TNode/Editor/DefaultNodeView.cs index 999938a..10f4713 100644 --- a/TNode/Editor/DefaultNodeView.cs +++ b/TNode/Editor/DefaultNodeView.cs @@ -1,7 +1,10 @@ using TNode.BaseViews; +using TNode.Editor.BaseViews; using TNode.Models; namespace TNode.Editor{ + + public class DefaultNodeView:NodeView{ } diff --git a/TNode/Editor/GraphEditor.cs b/TNode/Editor/GraphEditor.cs index f80078d..4e7edae 100644 --- a/TNode/Editor/GraphEditor.cs +++ b/TNode/Editor/GraphEditor.cs @@ -2,6 +2,7 @@ using Codice.CM.Common; using TNode.BaseViews; using TNode.Cache; using TNode.Editor.BaseViews; +using TNode.Editor.Inspector; using TNode.Editor.Model; using TNode.Models; using UnityEditor; @@ -35,20 +36,16 @@ namespace TNode.Editor{ DefineGraphEditorActions(); OnCreate(); } + private void BuildGraphView(){ _graphView = NodeEditorExtensions.CreateInstance>(); rootVisualElement.Add(_graphView); _graphView.StretchToParentSize(); - - _graphView.ConstructViewContextualMenu(evt => { - //Current issue is that the search window don't show up at the exact position of the mouse click by dma.eventInfo.mousePosition //So I have to manually set the position of the search window to fit the mouse click position by add an offset driven by Editor's position //Maybe a better way exists to fix this issue Vector2 editorPosition = this.position.position; - - evt.menu.AppendAction("Create Node", dma => { var dmaPos = dma.eventInfo.mousePosition+editorPosition; SearchWindowContext searchWindowContext = new SearchWindowContext(dmaPos,200,200); diff --git a/TNode/Editor/Inspector/INodeDataBinding.cs b/TNode/Editor/Inspector/INodeDataBinding.cs index 1fe044b..d6f9613 100644 --- a/TNode/Editor/Inspector/INodeDataBinding.cs +++ b/TNode/Editor/Inspector/INodeDataBinding.cs @@ -3,20 +3,8 @@ using UnityEngine; namespace TNode.Editor.Inspector{ public interface INodeDataBinding: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(){ diff --git a/TNode/Editor/Inspector/InspectorImplementation/DefaultInspectorItem.cs b/TNode/Editor/Inspector/InspectorImplementation/DefaultInspectorItem.cs deleted file mode 100644 index 2dd72c2..0000000 --- a/TNode/Editor/Inspector/InspectorImplementation/DefaultInspectorItem.cs +++ /dev/null @@ -1,16 +0,0 @@ -using UnityEngine.UIElements; - -namespace TNode.Editor.Inspector.InspectorImplementation{ - public class DefaultInspectorItem:InspectorItem{ - public readonly Foldout foldOut; - public DefaultInspectorItem(){ - foldOut = new Foldout{ - text = "" - }; - this.Add(foldOut); - OnValueChanged += () => { - foldOut.text = this.BindingPath; - }; - } - } -} \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs b/TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs new file mode 100644 index 0000000..fbabbb0 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs @@ -0,0 +1,12 @@ +using System; +using TNode.Attribute; +using UnityEngine.UIElements; + +namespace TNode.Editor.Inspector.InspectorImplementation{ + [NodeComponent] + public class FloatFieldItem:InspectorItem{ + public FloatFieldItem():base(){ + CreateBindable(new FloatField()); + } + } +} \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs.meta b/TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs.meta new file mode 100644 index 0000000..170c2d3 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/FloatFieldItem.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 932de5e7a487475aa764dd819cc33aa0 +timeCreated: 1656583186 \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs b/TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs new file mode 100644 index 0000000..65d9ed9 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs @@ -0,0 +1,14 @@ +using TNode.Attribute; +using UnityEngine.UIElements; + +namespace TNode.Editor.Inspector.InspectorImplementation{ + /// + /// Force these element to bind native c# property + /// + [NodeComponent] + public class StringFieldItem:InspectorItem{ + public StringFieldItem():base(){ + CreateBindable(new TextField()); + } + } +} \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorImplementation/DefaultInspectorItem.cs.meta b/TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs.meta similarity index 100% rename from TNode/Editor/Inspector/InspectorImplementation/DefaultInspectorItem.cs.meta rename to TNode/Editor/Inspector/InspectorImplementation/StringFieldItem.cs.meta diff --git a/TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs b/TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs new file mode 100644 index 0000000..ce0e540 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs @@ -0,0 +1,12 @@ +using TNode.Attribute; +using UnityEngine.UIElements; + +namespace TNode.Editor.Inspector.InspectorImplementation{ + [NodeComponent] + public class ToggleFieldItem:InspectorItem{ + public ToggleFieldItem(){ + CreateBindable(new Toggle()); + } + + } +} \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs.meta b/TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs.meta new file mode 100644 index 0000000..7ab36a8 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/ToggleFieldItem.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d009d4819d604971976932b1d8f40bad +timeCreated: 1656580623 \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorItem.cs b/TNode/Editor/Inspector/InspectorItem.cs index 09de53f..a3b2569 100644 --- a/TNode/Editor/Inspector/InspectorItem.cs +++ b/TNode/Editor/Inspector/InspectorItem.cs @@ -1,19 +1,22 @@ -using TNode.Models; +using System; +using TNode.BaseViews; +using TNode.Models; using UnityEngine; using UnityEngine.UIElements; namespace TNode.Editor.Inspector{ - public abstract class InspectorItem:VisualElement,INodeDataBinding{ + public abstract class InspectorItem:VisualElement,INodeDataBinding { private NodeData _bindingNodeData; private string _bindingFieldName; - protected event System.Action OnValueChanged; + protected BaseField Bindable; + protected event System.Action OnDataChanged; public string BindingPath{ get => _bindingFieldName; set{ _bindingFieldName = value; if(_bindingFieldName!=null&&_bindingNodeData!=null){ - OnValueChanged?.Invoke(); + OnDataChanged?.Invoke(); } } } @@ -21,24 +24,78 @@ namespace TNode.Editor.Inspector{ public NodeData BindingNodeData{ get => _bindingNodeData; set{ + var oldWrapper = ((NodeDataWrapper) _bindingNodeData); + if(oldWrapper!=null){ + oldWrapper.OnValueChanged -= OnNodeDataValueChanged; + } _bindingNodeData = value; if(_bindingFieldName!=null&&_bindingNodeData!=null){ - OnValueChanged?.Invoke(); + OnDataChanged?.Invoke(); } - + if(_bindingNodeData!=null) + ((NodeDataWrapper) _bindingNodeData).OnValueChanged += OnNodeDataValueChanged; } } - public InspectorItem(){ - OnValueChanged+= OnValueChangedHandler; + private T GetValue(){ + + var fieldInfo = _bindingNodeData.GetType().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; } - private void OnValueChangedHandler(){ + protected T Value => GetValue(); + + protected void SetValue(T value){ + NodeDataWrapper wrapper = _bindingNodeData; + Debug.Log(wrapper); + wrapper.SetValue(BindingPath,value); + } + public InspectorItem(){ + + OnDataChanged+= OnDataChangedHandler; + } + /* + * e => { + SetValue(e.newValue); + } + */ + private void OnInspectorItemValueChanged(ChangeEvent e){ + SetValue(e.newValue); + } + public void CreateBindable(BaseField bindable){ + if (Bindable != null){ + Bindable.Clear(); + Bindable.UnregisterValueChangedCallback(OnInspectorItemValueChanged); + } + Bindable = bindable; + this.Add(Bindable); + Bindable?.RegisterValueChangedCallback(OnInspectorItemValueChanged); + } + private void OnDataChangedHandler(){ + Bindable = this.Q>(); + 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(){ - OnValueChanged-= OnValueChangedHandler; + OnDataChanged-= OnDataChangedHandler; } } } \ No newline at end of file diff --git a/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs b/TNode/Editor/Inspector/InspectorItemFactory.cs similarity index 51% rename from TNode/Editor/Inspector/DefaultInspectorItemFactory.cs rename to TNode/Editor/Inspector/InspectorItemFactory.cs index 0f90d97..be99391 100644 --- a/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs +++ b/TNode/Editor/Inspector/InspectorItemFactory.cs @@ -1,11 +1,13 @@ 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 DefaultInspectorItemFactory{ + public class InspectorItemFactory{ public InspectorItem Create(){ //Check type of GraphDataType @@ -13,22 +15,9 @@ namespace TNode.Editor.Inspector{ if (hasSpecificType){ return NodeEditorExtensions.CreateInstance>(); } - else{ - return DefaultInspectorItem(); - } + return null; } - public static InspectorItem DefaultInspectorItem(){ - DefaultInspectorItem item = new DefaultInspectorItem(); - if (typeof(string) == typeof(T)){ - item.foldOut.Add(new TextField(){ - name = "StringTextField" - }); - } - - return item; - - } } } \ No newline at end of file diff --git a/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs.meta b/TNode/Editor/Inspector/InspectorItemFactory.cs.meta similarity index 100% rename from TNode/Editor/Inspector/DefaultInspectorItemFactory.cs.meta rename to TNode/Editor/Inspector/InspectorItemFactory.cs.meta diff --git a/TNode/Editor/Inspector/NodeInspector.cs b/TNode/Editor/Inspector/NodeInspector.cs index 902d761..ca101db 100644 --- a/TNode/Editor/Inspector/NodeInspector.cs +++ b/TNode/Editor/Inspector/NodeInspector.cs @@ -1,13 +1,19 @@ -using System.Reflection; +using System; +using System.Collections.Generic; +using System.Reflection; using TNode.BaseViews; +using TNode.Editor.BaseViews; using TNode.Models; +using Unity.VisualScripting; +using UnityEditor; +using UnityEditor.Experimental.GraphView; +using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; namespace TNode.Editor.Inspector{ public class NodeInspector:SimpleGraphSubWindow{ private NodeData _data; - public NodeData Data{ get => _data; set{ @@ -17,6 +23,7 @@ namespace TNode.Editor.Inspector{ } } + public INodeView NodeView; private void UpdateData(){ Debug.Log(_data); if (_data != null){ @@ -24,6 +31,7 @@ namespace TNode.Editor.Inspector{ } } public NodeInspector(){ + this.capabilities |= Capabilities.Resizable; style.position = new StyleEnum(Position.Absolute); var visualTreeAsset = Resources.Load("NodeInspector"); Debug.Log(visualTreeAsset); @@ -31,28 +39,29 @@ namespace TNode.Editor.Inspector{ BuildWindow(visualTreeAsset); } + 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 - this.Q("InspectorBody").Clear(); + var body = this.Q("InspectorBody"); + body.Clear(); + body.StretchToParentSize(); foreach (var field in _data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)){ var bindingPath = field.Name; - var type = field.FieldType; - DefaultInspectorItemFactory defaultInspectorItemFactory = new DefaultInspectorItemFactory(); + InspectorItemFactory inspectorItemFactory = new InspectorItemFactory(); //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 = inspectorItemFactory.GetType().GetMethod("Create", BindingFlags.Instance | BindingFlags.Public); if (methodInfo != null){ var genericMethod = methodInfo.MakeGenericMethod(type); - var createdInspector = genericMethod.Invoke(defaultInspectorItemFactory,null) as VisualElement; - this.Q("InspectorBody").Add(createdInspector); - if (createdInspector is INodeDataBindingBase castedInspector){ - castedInspector.BindingNodeData = _data; - castedInspector.BindingPath = bindingPath; + var createdItem = genericMethod.Invoke(inspectorItemFactory,null) as VisualElement; + + body.Add(createdItem); + if (createdItem is INodeDataBindingBase castedItem){ + castedItem.BindingNodeData = _data; + castedItem.BindingPath = bindingPath; } } } - } - } } \ No newline at end of file diff --git a/TNode/Editor/Inspector/NodeInspectorInNode.cs b/TNode/Editor/Inspector/NodeInspectorInNode.cs new file mode 100644 index 0000000..15770de --- /dev/null +++ b/TNode/Editor/Inspector/NodeInspectorInNode.cs @@ -0,0 +1,51 @@ +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(){ + Debug.Log(_data); + if (_data != null){ + RefreshInspector(); + } + } + + private void RefreshInspector(){ + Clear(); + Debug.Log("In Node node inspector refresh for new data " + _data); + 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()!=null; + if(!showInNodeViewAttribute) + continue; + //Invoke generic function Create<> of default inspector item factory to create an inspector item of appropriate type by reflection + MethodInfo methodInfo = inspectorItemFactory.GetType().GetMethod("Create", BindingFlags.Instance | BindingFlags.Public); + if (methodInfo != null){ + var genericMethod = methodInfo.MakeGenericMethod(type); + var createdItem = genericMethod.Invoke(inspectorItemFactory,null) as VisualElement; + Add(createdItem); + if (createdItem is INodeDataBindingBase castedItem){ + castedItem.BindingNodeData = _data; + castedItem.BindingPath = bindingPath; + } + } + } + } + } +} \ No newline at end of file diff --git a/TNode/Editor/Inspector/NodeInspectorInNode.cs.meta b/TNode/Editor/Inspector/NodeInspectorInNode.cs.meta new file mode 100644 index 0000000..e96818d --- /dev/null +++ b/TNode/Editor/Inspector/NodeInspectorInNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0ab3baa9312e4beaa12e5f2131f09969 +timeCreated: 1656584377 \ No newline at end of file diff --git a/TNode/Editor/NodeDataWrapper.cs b/TNode/Editor/NodeDataWrapper.cs new file mode 100644 index 0000000..f951a18 --- /dev/null +++ b/TNode/Editor/NodeDataWrapper.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using TNode.Models; + +namespace TNode.Editor{ + public class NodeDataWrapper{ + private readonly NodeData _data; + private static readonly Dictionary Cache = new (); + public event Action OnValueChanged; + public static NodeDataWrapper Get(NodeData data){ + if(Cache.ContainsKey(data)){ + return Cache[data]; + } + var wrapper = new NodeDataWrapper(data); + Cache.Add(data,wrapper); + return wrapper; + } + public NodeDataWrapper(NodeData 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 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); + } + + } +} \ No newline at end of file diff --git a/TNode/Editor/NodeDataWrapper.cs.meta b/TNode/Editor/NodeDataWrapper.cs.meta new file mode 100644 index 0000000..a4baeaa --- /dev/null +++ b/TNode/Editor/NodeDataWrapper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 70538db48fe1494882ba207e1b3be19d +timeCreated: 1656585993 \ No newline at end of file diff --git a/TNode/Editor/Resources/NodeInspector.uxml b/TNode/Editor/Resources/NodeInspector.uxml index 1d0f297..70d1bab 100644 --- a/TNode/Editor/Resources/NodeInspector.uxml +++ b/TNode/Editor/Resources/NodeInspector.uxml @@ -1,3 +1,3 @@ - - + + diff --git a/TNode/Editor/SearchWindowProvider.cs b/TNode/Editor/SearchWindowProvider.cs index 8278c97..8a273bd 100644 --- a/TNode/Editor/SearchWindowProvider.cs +++ b/TNode/Editor/SearchWindowProvider.cs @@ -47,11 +47,11 @@ namespace TNode.Editor{ //Check if type is derived from NodeData if (typeof(NodeData).IsAssignableFrom(type)){ //Make an instance of the type - var nodeData = (NodeData) Activator.CreateInstance(type); - nodeData.nodeName = "New Node"; - ((IDataGraphView)_graphView).AddTNode(nodeData,new Rect(localPos.x,localPos.y,100,100)); + if (Activator.CreateInstance(type) is NodeData nodeData){ + nodeData.nodeName = "New Node"; + ((IDataGraphView) _graphView).AddTNode(nodeData, new Rect(localPos.x, localPos.y, 100, 100)); + } } - return true; } return false; diff --git a/TNode/Models/GraphData.cs b/TNode/Models/GraphData.cs index cc26096..ad25295 100644 --- a/TNode/Models/GraphData.cs +++ b/TNode/Models/GraphData.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using Dialogue; -using UnityEditor.Experimental.GraphView; using UnityEngine; namespace TNode.Models{ diff --git a/TNode/Models/NodeData.cs b/TNode/Models/NodeData.cs index b7b8fb2..c89b557 100644 --- a/TNode/Models/NodeData.cs +++ b/TNode/Models/NodeData.cs @@ -1,4 +1,5 @@ using System; +using TNode.Attribute; using TNode.BaseModels; using UnityEngine; @@ -17,6 +18,7 @@ namespace TNode.Models{ //Object Registration } public string nodeName; + [ShowInNodeView] public bool entryPoint; // #if UNITY_EDITOR // public Rect rect; diff --git a/TNode/Models/NodeLink.cs b/TNode/Models/NodeLink.cs index 810f3d9..451988d 100644 --- a/TNode/Models/NodeLink.cs +++ b/TNode/Models/NodeLink.cs @@ -1,30 +1,11 @@ using System; -using Dialogue; + namespace TNode.Models{ //NodeAttribute links are stored in output side of the two node port. [Serializable] public class NodeLink{ // public DialogueNodePortData From{ get; } - public bool ConditionEdge = false; - public DialogueNodePortData To{ get; } - public NodeLink(DialogueNodePortData to){ - // From = from; - To = to; - } - public delegate bool Condition(DialogueNodePortData to); - public Condition ConditionFunction; - - public bool Accessible{ - get{ - if (To == null) return false; - if(ConditionFunction == null) - return true; - return ConditionFunction(To); - } - } - public void SetCondition(Condition condition){ - ConditionFunction = condition; - } + } } \ No newline at end of file