diff --git a/TNode/Attribute/GraphUsageAttribute.cs b/TNode/Attribute/GraphUsageAttribute.cs
index 50c9c08..fd17135 100644
--- a/TNode/Attribute/GraphUsageAttribute.cs
+++ b/TNode/Attribute/GraphUsageAttribute.cs
@@ -5,21 +5,21 @@ using Unity.VisualScripting;
namespace TNode.Attribute{
///
- /// Use this attribute to claim the usage of a type of node on the derived NodeData class.
+ /// Use this attribute to claim the usage of a type derived IModel IModel
/// it can be applied to the same node multiple times.
///
/// [GraphUsage(DialogueGraph)]
///
///
[AttributeUsage(AttributeTargets.Class)]
- [BaseTypeRequired(typeof(NodeData))]
+ [BaseTypeRequired(typeof(IModel))]
public class GraphUsageAttribute:System.Attribute{
public readonly Type GraphDataType;
public string Category;
public GraphUsageAttribute(Type t,string category = null){
//check if the type t is graph
if(!typeof(GraphData).IsAssignableFrom(t)){
- throw new Exception("The type must be a graph");
+ throw new Exception("The type used on Graph Usage must be a graph");
}
GraphDataType = t;
if (category != null){
@@ -27,4 +27,6 @@ namespace TNode.Attribute{
}
}
}
+
+
}
\ No newline at end of file
diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs
index fc11fe7..408bfed 100644
--- a/TNode/Editor/BaseViews/DataGraphView.cs
+++ b/TNode/Editor/BaseViews/DataGraphView.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using TNode.BaseViews;
using TNode.Cache;
using TNode.Editor.Inspector;
@@ -152,7 +153,7 @@ namespace TNode.Editor.BaseViews{
//Rebuild the contextual menu
this.RegisterCallback(evt => {
- Vector2 editorPosition = Owner.position.position;
+ Vector2 editorPosition = Owner==null?Vector2.zero:Owner.position.position;
//Remove all the previous menu items
evt.menu.MenuItems().Clear();
evt.menu.AppendAction("Create Node", dma => {
@@ -232,21 +233,51 @@ namespace TNode.Editor.BaseViews{
miniMap.SetPosition(rect);
}
- public void CreateBlackBoard(){
+ public void CreateBlackboard(){
var blackboard = new Blackboard();
//Blackboard add "Add Node" button
- blackboard.Add(new BlackboardSection(){
- title = "Hello World",
- });
- blackboard.addItemRequested = (item) => {
- //Create a sub window for the blackboard to show the selection
- var subWindow = ScriptableObject.CreateInstance();
- };
-
+ // blackboard.Add(new BlackboardSection(){
+ // title = "Hello World",
+ // });
+ // blackboard.addItemRequested = (item) => {
+ // //Create a sub window for the blackboard to show the selection
+ // var subWindow = ScriptableObject.CreateInstance();
+ // };
+ //
//Set black board to left side of the view
blackboard.SetPosition(new Rect(0,0,200,600));
- this.Add(blackboard);
+ Add(blackboard);
+ //Check the type of the blackboard
+ OnDataChanged+= (sender, e) => {
+
+ if (_data.blackboardData==null||_data.blackboardData.GetType()==typeof(BlackboardData)){
+ _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType());
+
+ if(_data.blackboardData==null) return;
+
+ }
+ Debug.Log(_data.blackboardData);
+ //Iterate field of the blackboard and add a button for each field
+ foreach (var field in _data.blackboardData.GetType()
+ .GetFields(BindingFlags.Public|BindingFlags.NonPublic | BindingFlags.Instance)){
+ Debug.Log(field);
+ //if the field is MonoBehaviour,add a property field for blackboard
+ if(typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType)){
+ var propertyField = new BlackboardField(null,field.Name,null){
+
+ };
+ blackboard.Add(propertyField);
+ }
+ if(typeof(string).IsAssignableFrom(field.FieldType)){
+ var propertyField = new BlackboardField(null,field.Name,null){
+
+ };
+ blackboard.Add(propertyField);
+ }
+ }
+ };
+
}
public virtual void DestroyInspector(){
if(_nodeInspector!=null){
diff --git a/TNode/Editor/BaseViews/NodeView.cs b/TNode/Editor/BaseViews/NodeView.cs
index b5aca22..15c6636 100644
--- a/TNode/Editor/BaseViews/NodeView.cs
+++ b/TNode/Editor/BaseViews/NodeView.cs
@@ -63,7 +63,6 @@ namespace TNode.Editor.BaseViews{
var propertyInfos = _data.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos){
- Debug.Log(propertyInfos);
var attribute = propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true);
if (attribute.Length > 0){
Port port = InstantiatePort(Orientation.Horizontal, Direction.Output,Port.Capacity.Multi,propertyInfo.PropertyType);
diff --git a/TNode/Editor/Cache/NodeEditorExtensions.cs b/TNode/Editor/Cache/NodeEditorExtensions.cs
index 813d68a..6338d97 100644
--- a/TNode/Editor/Cache/NodeEditorExtensions.cs
+++ b/TNode/Editor/Cache/NodeEditorExtensions.cs
@@ -18,6 +18,7 @@ namespace TNode.Cache{
private static NodeEditorSingleton _instance;
public readonly Dictionary FromGenericToSpecific = new Dictionary();
public readonly Dictionary> GraphDataUsage = new Dictionary>();
+ public Dictionary GraphBlackboard = new();
public static NodeEditorSingleton Instance{
get{ return _instance ??= new NodeEditorSingleton(); }
}
@@ -45,14 +46,30 @@ namespace TNode.Cache{
private void SetGraphUsageAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){
var parent = type.BaseType;
- if (typeof(NodeData).IsAssignableFrom(type.BaseType)){
+ if (typeof(IModel).IsAssignableFrom(type.BaseType)){
//Check if GraphDataUsage dictionary has GraphDataType of attribute
- if (attribute is GraphUsageAttribute attributeCasted){
- if (GraphDataUsage.ContainsKey(attributeCasted.GraphDataType)){
- GraphDataUsage[attributeCasted.GraphDataType].Add(type);
+
+ if (typeof(NodeData).IsAssignableFrom(type)){
+ if (attribute is GraphUsageAttribute attributeCasted){
+ if (GraphDataUsage.ContainsKey(attributeCasted.GraphDataType)){
+ GraphDataUsage[attributeCasted.GraphDataType].Add(type);
+ }
+ else{
+ GraphDataUsage.Add(attributeCasted.GraphDataType, new List{type});
+ }
}
- else{
- GraphDataUsage.Add(attributeCasted.GraphDataType, new List{type});
+ }
+
+ if (typeof(BlackboardData).IsAssignableFrom(type)){
+ if (attribute is GraphUsageAttribute attributeCasted){
+ if (GraphBlackboard.ContainsKey(attributeCasted.GraphDataType)){
+ GraphBlackboard[attributeCasted.GraphDataType] = type;
+
+ }
+ else{
+ GraphBlackboard.Add(attributeCasted.GraphDataType, type);
+ }
+
}
}
}
@@ -107,6 +124,12 @@ namespace TNode.Cache{
}
return new List();
}
+ public static BlackboardData GetAppropriateBlackboardData(Type t){
+ if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(t)){
+ return (BlackboardData)Activator.CreateInstance(NodeEditorSingleton.Instance.GraphBlackboard[t]);
+ }
+ return null;
+ }
public static object CreateNodeViewFromNodeType() where T:NodeData,new(){
//Check specific derived type exists or not.
var type = typeof(NodeView);
diff --git a/TNode/Editor/Inspector/NodeInspectorInNode.cs b/TNode/Editor/Inspector/NodeInspectorInNode.cs
index 61a1b70..0268d98 100644
--- a/TNode/Editor/Inspector/NodeInspectorInNode.cs
+++ b/TNode/Editor/Inspector/NodeInspectorInNode.cs
@@ -17,7 +17,6 @@ namespace TNode.Editor.Inspector{
}
private void UpdateData(){
- Debug.Log(_data);
if (_data != null){
RefreshInspector();
}
diff --git a/TNode/Editor/Model.meta b/TNode/Editor/Model.meta
deleted file mode 100644
index 505afc9..0000000
--- a/TNode/Editor/Model.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: e3bc969c46434a308e20796dede95f3b
-timeCreated: 1655969991
\ No newline at end of file
diff --git a/TNode/Models/BlackDragNodeData.cs b/TNode/Models/BlackDragNodeData.cs
index 6038a6f..19eb282 100644
--- a/TNode/Models/BlackDragNodeData.cs
+++ b/TNode/Models/BlackDragNodeData.cs
@@ -1,4 +1,5 @@
-using Newtonsoft.Json;
+using System.Runtime.InteropServices;
+using Newtonsoft.Json;
using TNode.Attribute.Ports;
namespace TNode.Models{
@@ -7,6 +8,12 @@ namespace TNode.Models{
private string _blackDragData;
[JsonIgnore]
private BlackboardData _blackboardData;
+
+ [Output] public T value => _blackboardData.GetValue(_blackDragData);
+ public BlackDragNodeData(string blackDragData,BlackboardData blackboardData){
+ _blackDragData = blackDragData;
+ _blackboardData = blackboardData;
+ }
}
}
\ No newline at end of file
diff --git a/TNode/Models/BlackboardData.cs b/TNode/Models/BlackboardData.cs
index 5d60568..4b2c2e7 100644
--- a/TNode/Models/BlackboardData.cs
+++ b/TNode/Models/BlackboardData.cs
@@ -1,6 +1,8 @@
namespace TNode.Models{
- public class BlackboardData{
-
+ public class BlackboardData:IModel{
+ public T GetValue(string key){
+ return default(T);
+ }
}
}
\ No newline at end of file
diff --git a/TNode/Models/IModel.cs b/TNode/Models/IModel.cs
new file mode 100644
index 0000000..0328c7d
--- /dev/null
+++ b/TNode/Models/IModel.cs
@@ -0,0 +1,5 @@
+namespace TNode.Models{
+ public interface IModel{
+
+ }
+}
\ No newline at end of file
diff --git a/TNode/Models/IModel.cs.meta b/TNode/Models/IModel.cs.meta
new file mode 100644
index 0000000..6656fdf
--- /dev/null
+++ b/TNode/Models/IModel.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 7d60da1ee3e9447a9a2f764a6655536f
+timeCreated: 1656953115
\ No newline at end of file
diff --git a/TNode/Models/NodeData.cs b/TNode/Models/NodeData.cs
index d9c6bf9..a9fc49b 100644
--- a/TNode/Models/NodeData.cs
+++ b/TNode/Models/NodeData.cs
@@ -11,7 +11,7 @@ namespace TNode.Models{
///
///
[Serializable]
- public class NodeData{
+ public class NodeData:IModel{
public NodeData() : base(){
//Object Registration
diff --git a/TNode/RuntimeCache/RuntimeCache.cs b/TNode/RuntimeCache/RuntimeCache.cs
index 4ec50ce..13e82e4 100644
--- a/TNode/RuntimeCache/RuntimeCache.cs
+++ b/TNode/RuntimeCache/RuntimeCache.cs
@@ -14,11 +14,11 @@ namespace TNode.RuntimeCache{
get{ return _instance ??= new RuntimeCache(); }
}
//delegate return a value from a nodedata
- public delegate object GetValueDelegate(NodeData nodeData);
+ public delegate object GetValueDelegate(IModel nodeData);
public readonly Dictionary> CachedDelegatesForGettingValue =
new ();
-
+
public void ExecuteOutput(T nodeData) where T:NodeData{
var type = typeof(T);
if(!CachedDelegatesForGettingValue.ContainsKey(type)){
@@ -29,7 +29,7 @@ namespace TNode.RuntimeCache{
var value = delegateInstance(nodeData);
}
}
-
+ private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"};
public void RegisterRuntimeNode() where T:NodeData{
var type = typeof(T);
if(!CachedDelegatesForGettingValue.ContainsKey(type)){
@@ -44,9 +44,20 @@ namespace TNode.RuntimeCache{
//Cache already exists for this type
}
-
-
-
+ }
+ public void RegisterRuntimeBlackboard(Type type){
+ if(!CachedDelegatesForGettingValue.ContainsKey(type)){
+ CachedDelegatesForGettingValue.Add(type, new List());
+ var properties = type.GetProperties();
+ foreach(var property in properties){
+ //if the property only has a setter ,skip
+ if(property.GetMethod == null){
+ continue;
+ }
+ var getValueDelegate = GetValueDelegateForProperty(property);
+ CachedDelegatesForGettingValue[type].Add(getValueDelegate);
+ }
+ }
}
private GetValueDelegate GetValueDelegateForProperty(PropertyInfo property){