feat:so now different type could connected if a Converter is given

main
taoria 3 years ago
parent b95b47dfd8
commit 4858dfdbd6
  1. 4
      TNodeCore/Attribute/InternalUsageAttribute.cs
  2. 0
      TNodeCore/Attribute/InternalUsageAttribute.cs.meta
  3. 3
      TNodeCore/Attribute/PortTypeConversion.cs
  4. 3
      TNodeCore/Attribute/PortTypeConversion.cs.meta
  5. 2
      TNodeCore/Models/BlackboardDragNodeData.cs
  6. 3
      TNodeCore/Runtime/Interfaces.meta
  7. 7
      TNodeCore/Runtime/Interfaces/IPortTypeConversion.cs
  8. 3
      TNodeCore/Runtime/Interfaces/IPortTypeConversion.cs.meta
  9. 91
      TNodeCore/RuntimeCache/RuntimeCache.cs
  10. 6
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs

@ -2,8 +2,8 @@
/// <summary> /// <summary>
/// Internal use only. so that Editor Cache and Runtime cache could register it globally. /// Internal use only. so that Editor Cache and Runtime cache could register it globally.
/// </summary> /// </summary>
public class InternalModel:System.Attribute{ public class InternalUsageAttribute:System.Attribute{
public InternalModel(){ public InternalUsageAttribute(){
} }
} }

@ -0,0 +1,3 @@
namespace TNodeCore.Attribute{
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fb41beebff2a41efb7a3f76d58af6179
timeCreated: 1658306360

@ -6,7 +6,7 @@ using UnityEngine;
namespace TNodeCore.Models{ namespace TNodeCore.Models{
[Serializable] [Serializable]
[InternalModel] [InternalUsage]
public class BlackboardDragNodeData:RuntimeNodeData{ public class BlackboardDragNodeData:RuntimeNodeData{
public string blackDragData; public string blackDragData;

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 69f4e5ae5bcf45caa656a36173eeded3
timeCreated: 1658306474

@ -0,0 +1,7 @@
namespace TNodeCore.Runtime.Interfaces{
public interface IPortTypeConversion<in TFrom, out TTo>{
public TTo Convert(TFrom tFrom);
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4e8bdf96ae104472a12f010f37ff1190
timeCreated: 1658306486

@ -5,6 +5,7 @@ using System.Reflection;
using PlasticPipe.PlasticProtocol.Messages; using PlasticPipe.PlasticProtocol.Messages;
using TNodeCore.Attribute; using TNodeCore.Attribute;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeCore.Runtime.Interfaces;
using UnityEngine; using UnityEngine;
namespace TNodeCore.RuntimeCache{ namespace TNodeCore.RuntimeCache{
@ -32,6 +33,22 @@ namespace TNodeCore.RuntimeCache{
Set((T1)model,(T2)value); Set((T1)model,(T2)value);
} }
} }
internal class PortConverterHelper<T1,T2> : IPortConverterHelper{
private readonly IPortTypeConversion<T1, T2> _converter;
public PortConverterHelper(Type type){
_converter = Activator.CreateInstance(type) as IPortTypeConversion<T1, T2>;
}
public object Convert(object value){
return _converter.Convert((T1)value);
}
}
internal interface IPortConverterHelper{
public object Convert(object value);
}
public class PropertyNotFoundException : Exception{ public class PropertyNotFoundException : Exception{
public PropertyNotFoundException(string path):base("Property not found :"+path){ public PropertyNotFoundException(string path):base("Property not found :"+path){
@ -55,6 +72,11 @@ namespace TNodeCore.RuntimeCache{
new (); new ();
public readonly Dictionary<Type,Dictionary<string,IModelPropertyAccessor>> CachedPropertyAccessors = public readonly Dictionary<Type,Dictionary<string,IModelPropertyAccessor>> CachedPropertyAccessors =
new (); new ();
/// <summary>
/// TODO: Converters now work globally, but it should be possible to specify a converter for a specific graph.but it will be too nested.so in current implementation, we will use a global converter.
/// </summary>
private readonly Dictionary<Type,Dictionary<Type,IPortConverterHelper>> CachedPortConverters =
new ();
private readonly Dictionary<Type, Type> _graphBlackboardDictionary = new Dictionary<Type, Type>(); private readonly Dictionary<Type, Type> _graphBlackboardDictionary = new Dictionary<Type, Type>();
@ -75,8 +97,8 @@ namespace TNodeCore.RuntimeCache{
AddTypeToCache(type,attribute as GraphUsageAttribute); AddTypeToCache(type,attribute as GraphUsageAttribute);
} }
if (attribute is InternalModel){ if (attribute is InternalUsageAttribute usageAttribute){
AddTypeToCache(type,attribute as InternalModel); AddTypeToCache(type,usageAttribute);
} }
} }
} }
@ -93,9 +115,53 @@ namespace TNodeCore.RuntimeCache{
//if it is, add it to the cache //if it is, add it to the cache
CacheRuntimeNodeData(type); CacheRuntimeNodeData(type);
} }
//Check if the type is implementing IPortTypeConversion<T1,T2>
if(typeof(IPortTypeConversion<,>).IsAssignableFrom(type)){
//if it is, add it to the cache
CacheRuntimePortTypeConversion(type);
}
}
private void CacheRuntimePortTypeConversion(Type type){
if (type.IsGenericType == false){
return;
}
var genericType = type.GetGenericTypeDefinition();
if (genericType != typeof(IPortTypeConversion<,>)){
return;
}
var type1 = type.GetGenericArguments()[0];
var type2 = type.GetGenericArguments()[1];
var specificType = typeof(PortConverterHelper<,>).MakeGenericType(type1, type2);
var instance = Activator.CreateInstance(specificType, type) as IPortConverterHelper;
if (instance == null){
return;
}
if (!CachedPortConverters.ContainsKey(type1)){
CachedPortConverters.Add(type1,new Dictionary<Type,IPortConverterHelper>());
}
CachedPortConverters[type1].Add(type2,instance);
}
public object GetConvertedValue(Type from,Type to,object value){
if(!CachedPortConverters.ContainsKey(from)){
throw new ConversionFailedException("No converter found for type "+from);
return value;
}
if(!CachedPortConverters[from].ContainsKey(to)){
return value;
}
return CachedPortConverters[from][to].Convert(value);
}
public List<Type> GetSupportedTypes(Type type){
if(!CachedPortConverters.ContainsKey(type)){
return null;
}
return CachedPortConverters[type].Keys.ToList();
} }
private void AddBlackboardDataTypeToCache(Type type,GraphUsageAttribute attribute){ private void AddBlackboardDataTypeToCache(Type type,GraphUsageAttribute attribute){
var graphData = attribute.GraphDataType; var graphData = attribute.GraphDataType;
_graphBlackboardDictionary.Add(graphData,type); _graphBlackboardDictionary.Add(graphData,type);
@ -121,18 +187,6 @@ namespace TNodeCore.RuntimeCache{
if(!CachedDelegatesForGettingValue.ContainsKey(type)){ if(!CachedDelegatesForGettingValue.ContainsKey(type)){
CachedDelegatesForGettingValue.Add(type, new Dictionary<string, GetValueDelegate>()); CachedDelegatesForGettingValue.Add(type, new Dictionary<string, GetValueDelegate>());
CachedDelegatesForSettingValue.Add(type,new Dictionary<string, SetValueDelegate>()); CachedDelegatesForSettingValue.Add(type,new Dictionary<string, SetValueDelegate>());
// var properties = type.GetProperties();
// foreach(var property in properties){
// //if the property only has a setter ,skip
//
// var getValueDelegate = GetValueDelegateForProperty(property);
// CachedDelegatesForGettingValue[type].Add(property.Name,getValueDelegate);
//
// var setValueDelegate = SetValueDelegateForProperty(property);
// CachedDelegatesForSettingValue[type].Add(property.Name,setValueDelegate);
// }
//register the fields
var fields = type.GetFields(); var fields = type.GetFields();
foreach(var field in fields){ foreach(var field in fields){
var getValueDelegate = GetValueDelegateForField(field); var getValueDelegate = GetValueDelegateForField(field);
@ -185,6 +239,14 @@ namespace TNodeCore.RuntimeCache{
return field.SetValue; return field.SetValue;
} }
}
public class ConversionFailedException : Exception{
public ConversionFailedException(string noConverterFoundForType):base(noConverterFoundForType){
}
} }
public static class RuntimeExtension{ public static class RuntimeExtension{
@ -208,4 +270,5 @@ namespace TNodeCore.RuntimeCache{
method.Invoke(data,value); method.Invoke(data,value);
} }
} }
} }

@ -10,6 +10,7 @@ using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Editor.Tools.NodeCreator; using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeCore.Runtime; using TNodeCore.Runtime;
using TNodeCore.RuntimeCache;
using TNodeGraphViewImpl.Editor.Cache; using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.GraphBlackboard; using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.NodeViews; using TNodeGraphViewImpl.Editor.NodeViews;
@ -411,7 +412,10 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
} }
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){ public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){
return ports.Where(x => startPort!=x && (x.portType == startPort.portType || x.portType.IsAssignableFrom(startPort.portType))).ToList(); return ports.Where(x => startPort!=x &&
(x.portType == startPort.portType ||
x.portType.IsAssignableFrom(startPort.portType) ||
RuntimeCache.Instance.GetSupportedTypes(startPort.portType).Contains(x.portType))).ToList();
} }

Loading…
Cancel
Save