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

Working in process
main
taoria 3 years ago committed by GitHub
commit b17720b572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      README.md
  2. 27
      TNodeCore/Editor/EditorPersistence/GraphEditorData.cs
  3. 6
      TNodeCore/Editor/NodeGraphView/IDataGraphView.cs
  4. 15
      TNodeCore/GraphEditor.cs
  5. 0
      TNodeCore/GraphEditor.cs.meta
  6. 1
      TNodeCore/RuntimeCache/RuntimeCache.cs
  7. 65
      TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
  8. 8
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs

@ -1,24 +1,38 @@
# T-Node # T-Node
Simple wrapper for unity experimental graphview and if possible latter,GTF. Node graph creation tool based on unity experimental graphview and if possible latter,GTF.
the main goal of the repo is to make graph creation easier and more intuitive. the main goal of the repo is to make graph creation easier and more intuitive.
Note **it's not usable and productive on current stage** and need a better Note **it's not usable and productive on current stage** and need a better
development . development .
and it's mainly for my own use now. and it's mainly for my own use now.
The tool separate its graph editor implementation and the graph creation logic.
# Install # Install
currently under development currently under development
# Features # Main Features
* Create graph script by the creator tool
* Node creation based on specified type of graph
* Easy port creation via attribute
* Runtime graph
* Blackboard for runtime graph as exposed parameters
* Runtime graph execution
* An easy test mode (Runtime graph only)
1. Create graph script by the creator tool # Some To-dos
2. Node creation based on specified type of graph * Caching runtime state for faster execution
3. Easy port creation via attribute * Undo redo support
4. Runtime graph * Function as port
5. Blackboard for runtime graph as exposed parameters * Better blackboard support
6. Runtime graph execution
7. Test Mode (Runtime graph only)
# Usage # Usage
No ,It's better not to use TNode at current stage until it's stable.
### Convention

@ -1,10 +1,35 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Models;
using UnityEngine; using UnityEngine;
namespace TNodeCore.Editor.EditorPersistence{ namespace TNodeCore.Editor.EditorPersistence{
[CreateAssetMenu(fileName = "Graph Editor Data", menuName = "TNode/Graph Editor Data")] [CreateAssetMenu(fileName = "Graph Editor Data", menuName = "TNode/Graph Editor Data")]
public class GraphEditorData:ScriptableObject{ public class GraphEditorData:ScriptableObject{
[HideInInspector]
public List<GraphElementEditorData> graphElementsData; public List<GraphElementEditorData> graphElementsData;
public GraphImplType graphImplType = GraphImplType.GraphViewImpl;
public static Func<Type,IBaseDataGraphView> GraphViewImplCreator;
public static Func<Type,IBaseDataGraphView> GtfImplCreator;
public IDataGraphView<T> GetGraphView<T> () where T:GraphData{
switch (graphImplType){
case GraphImplType.GraphViewImpl:
return (IDataGraphView<T>)GraphViewImplCreator.Invoke(typeof(T));
case GraphImplType.GraphToolsFoundationImpl:
throw new NotImplementedException();
default:
throw new NotImplementedException();
}
}
}
public enum GraphImplType{
GraphViewImpl,
GraphToolsFoundationImpl
} }
} }

@ -1,7 +1,11 @@
using TNodeCore.Models; using TNodeCore.Editor.EditorPersistence;
using TNodeCore.Models;
using TNodeEditor.Editor;
namespace TNodeCore.Editor.NodeGraphView{ namespace TNodeCore.Editor.NodeGraphView{
public interface IDataGraphView<T> : IBaseDataGraphView where T:GraphData{ public interface IDataGraphView<T> : IBaseDataGraphView where T:GraphData{
public T Data{ get; set; } public T Data{ get; set; }
GraphEditor<T> Owner{ get; set; }
void SaveWithEditorData(GraphEditorData graphEditorData);
} }
} }

@ -1,16 +1,13 @@
using System;
using TNodeCore.Editor; using TNodeCore.Editor;
using TNodeCore.Editor.EditorPersistence; using TNodeCore.Editor.EditorPersistence;
using TNodeCore.Editor.NodeGraphView; using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.NodeGraphView;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNodeGraphViewImpl.Editor{ namespace TNodeEditor.Editor{
// public class SelectGraphWindow : EditorWindow{ // public class SelectGraphWindow : EditorWindow{
// public EditorWindow parent; // public EditorWindow parent;
@ -48,7 +45,7 @@ namespace TNodeGraphViewImpl.Editor{
// } // }
// } // }
public abstract class GraphEditor<T> : EditorWindow,IGraphEditor where T:GraphData{ public abstract class GraphEditor<T> : EditorWindow,IGraphEditor where T:GraphData{
protected BaseDataGraphView<T> GraphView; protected IDataGraphView<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
@ -84,9 +81,9 @@ namespace TNodeGraphViewImpl.Editor{
GraphView.IsRuntimeGraph = false; GraphView.IsRuntimeGraph = false;
} }
private void BuildGraphView(){ private void BuildGraphView(){
GraphView = NodeEditorExtensions.CreateViewComponentFromBaseType<BaseDataGraphView<T>>(); GraphView = graphEditorData.GetGraphView<T>();
rootVisualElement.Add(GraphView); rootVisualElement.Add((VisualElement)GraphView);
GraphView.StretchToParentSize(); ((VisualElement)GraphView).StretchToParentSize();
} }
private void DefineGraphEditorActions(){ private void DefineGraphEditorActions(){
@ -126,7 +123,7 @@ namespace TNodeGraphViewImpl.Editor{
} }
public void SetGraphView(IBaseDataGraphView graphView){ public void SetGraphView(IBaseDataGraphView graphView){
GraphView = graphView as BaseDataGraphView<T>; GraphView = (IDataGraphView<T>)graphView;
} }
public IBaseDataGraphView GetGraphView(){ public IBaseDataGraphView GetGraphView(){

@ -147,7 +147,6 @@ namespace TNodeCore.RuntimeCache{
public object GetConvertedValue(Type from,Type to,object value){ public object GetConvertedValue(Type from,Type to,object value){
if(!CachedPortConverters.ContainsKey(from)){ if(!CachedPortConverters.ContainsKey(from)){
throw new ConversionFailedException("No converter found for type "+from); throw new ConversionFailedException("No converter found for type "+from);
return value;
} }
if(!CachedPortConverters[from].ContainsKey(to)){ if(!CachedPortConverters[from].ContainsKey(to)){
return value; return value;

@ -3,14 +3,15 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using TNode.Editor; using TNode.Editor;
using TNode.Editor.NodeViews;
using TNodeCore.Attribute; using TNodeCore.Attribute;
using TNodeCore.Editor.Blackboard; using TNodeCore.Editor.Blackboard;
using TNodeCore.Editor.EditorPersistence;
using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeGraphViewImpl.Editor.GraphBlackboard; using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.NodeGraphView; using TNodeGraphViewImpl.Editor.NodeGraphView;
using TNodeGraphViewImpl.Editor.NodeViews; using TNodeGraphViewImpl.Editor.NodeViews;
using UnityEditor.Experimental.GraphView; using UnityEditor;
using UnityEngine; using UnityEngine;
namespace TNodeGraphViewImpl.Editor.Cache{ namespace TNodeGraphViewImpl.Editor.Cache{
@ -42,6 +43,25 @@ namespace TNodeGraphViewImpl.Editor.Cache{
} }
private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"};
public static T CreateViewComponentFromBaseType<T>(){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)];
var instance = (T)Activator.CreateInstance(implementedType);
return instance;
}
public static object CreateViewComponentFromBaseType(Type t){
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(t)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[t];
var instance = Activator.CreateInstance(implementedType);
return instance;
}
//check if t is a generic type node view
if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(BaseNodeView<>)){
var instance = Activator.CreateInstance(typeof(BaseNodeView<NodeData>));
return instance;
}
return null;
}
private NodeEditorSingleton(){ private NodeEditorSingleton(){
//exclude unity ,system ,and microsoft types //exclude unity ,system ,and microsoft types
@ -60,9 +80,14 @@ namespace TNodeGraphViewImpl.Editor.Cache{
} }
} }
} }
GraphEditorData.GraphViewImplCreator+=GraphViewImplCreator;
} }
private IBaseDataGraphView GraphViewImplCreator(Type arg){
var genericType = typeof(BaseDataGraphView<>).MakeGenericType(arg);
var instance = CreateViewComponentFromBaseType(genericType) as IBaseDataGraphView;
return instance;
}
private void SetGraphUsageAttribute(Type type){ private void SetGraphUsageAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){ foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){
var parent = type.BaseType; var parent = type.BaseType;
@ -116,6 +141,11 @@ namespace TNodeGraphViewImpl.Editor.Cache{
//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.
} }
} }
public void Initialize(){
//Do nothing indeed
Debug.Log("Hello");
}
} }
//Outer wrapper for the singleton class //Outer wrapper for the singleton class
public static class NodeEditorExtensions{ public static class NodeEditorExtensions{
@ -124,11 +154,7 @@ namespace TNodeGraphViewImpl.Editor.Cache{
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static T CreateViewComponentFromBaseType<T>(){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)];
var instance = (T)Activator.CreateInstance(implementedType);
return instance;
}
public static string GetTypeCategory(Type type){ public static string GetTypeCategory(Type type){
var category = type.GetCustomAttribute<GraphUsageAttribute>(); var category = type.GetCustomAttribute<GraphUsageAttribute>();
return category?.Category ?? ""; return category?.Category ?? "";
@ -138,26 +164,11 @@ namespace TNodeGraphViewImpl.Editor.Cache{
/// by given a generic type t,return the implementation instance of the generic type /// by given a generic type t,return the implementation instance of the generic type
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static object CreateViewComponentFromBaseType(Type t){
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(t)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[t];
var instance = Activator.CreateInstance(implementedType);
return instance;
}
//check if t is a generic type node view
if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(BaseNodeView<>)){
var instance = Activator.CreateInstance(typeof(BaseNodeView<NodeData>));
return instance;
}
return null;
}
public static IBlackboardView CreateBlackboardDataFromBlackboardDataType(Type t){ public static IBlackboardView CreateBlackboardDataFromBlackboardDataType(Type t){
var type = typeof(GraphBlackboardView<>).MakeGenericType(t); var type = typeof(GraphBlackboardView<>).MakeGenericType(t);
var res = CreateViewComponentFromBaseType(type) as IBlackboardView; var res = NodeEditorSingleton.CreateViewComponentFromBaseType(type) as IBlackboardView;
return res ?? new DefaultGraphBlackboardView(); return res ?? new DefaultGraphBlackboardView();
} }
public static IBlackboardView CreateBlackboardWithGraphData(GraphData graphData){ public static IBlackboardView CreateBlackboardWithGraphData(GraphData graphData){
@ -248,4 +259,10 @@ namespace TNodeGraphViewImpl.Editor.Cache{
} }
} }
[InitializeOnLoad]
public class Launcher{
static Launcher(){
NodeEditorSingleton.Instance.Initialize();
}
}
} }

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.Search;
using TNodeCore.Editor.Blackboard; using TNodeCore.Editor.Blackboard;
using TNodeCore.Editor.EditorPersistence; using TNodeCore.Editor.EditorPersistence;
using TNodeCore.Editor.NodeGraphView; using TNodeCore.Editor.NodeGraphView;
@ -11,8 +10,8 @@ using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeCore.Runtime; using TNodeCore.Runtime;
using TNodeCore.RuntimeCache; using TNodeCore.RuntimeCache;
using TNodeEditor.Editor;
using TNodeGraphViewImpl.Editor.Cache; using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.NodeViews; using TNodeGraphViewImpl.Editor.NodeViews;
using TNodeGraphViewImpl.Editor.Search; using TNodeGraphViewImpl.Editor.Search;
using UnityEditor; using UnityEditor;
@ -23,7 +22,7 @@ using BlackboardField = TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardFiel
using Edge = UnityEditor.Experimental.GraphView.Edge; using Edge = UnityEditor.Experimental.GraphView.Edge;
namespace TNodeGraphViewImpl.Editor.NodeGraphView{ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public abstract class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{ public class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{
#region variables and properties #region variables and properties
private T _data; private T _data;
private RuntimeGraph _runtimeGraph; private RuntimeGraph _runtimeGraph;
@ -31,7 +30,6 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
private bool _isInspectorOn; private bool _isInspectorOn;
private NodeSearchWindowProvider _nodeSearchWindowProvider; private NodeSearchWindowProvider _nodeSearchWindowProvider;
private NodeInspector _nodeInspector; private NodeInspector _nodeInspector;
public GraphEditor<T> Owner;
private Dictionary<string,Node> _nodeDict = new(); private Dictionary<string,Node> _nodeDict = new();
private IBlackboardView _blackboard; private IBlackboardView _blackboard;
public T Data{ public T Data{
@ -44,6 +42,8 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
ResetGraphView(); ResetGraphView();
} }
} }
public GraphEditor<T> Owner{ get; set; }
public event DataChangedEventHandler OnDataChanged; public event DataChangedEventHandler OnDataChanged;
#endregion #endregion
#region event declarations #region event declarations

Loading…
Cancel
Save