using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Dm.net.buffer.ByteArrayBuffer;
namespace Serein.Flow
{
///
/// 显式参数
///
public class ExplicitData
{
///
/// 索引
///
public int Index { get; set; }
///
/// 是否为显式参数
///
public bool IsExplicitData { get; set; }
///
/// 显式类型
///
public Type? ExplicitType { get; set; }
///
/// 显示类型编号>
///
public string ExplicitTypeName { get; set; }
///
/// 方法需要的类型
///
public Type DataType { get; set; }
///
/// 方法入参参数名称
///
public string ParameterName { get; set; }
///
/// 入参值
///
public string DataValue { get; set; }
public string[] Items { get; set; }
public ExplicitData Clone() => new()
{
Index = Index,
IsExplicitData = IsExplicitData,
ExplicitType = ExplicitType,
DataType = DataType,
ParameterName = ParameterName,
ExplicitTypeName = ExplicitTypeName,
DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue,
Items = [.. Items],
};
}
public class MethodDetails
{
public MethodDetails Clone()
{
return new MethodDetails
{
ActingInstance = ActingInstance,
ActingInstanceType = ActingInstanceType,
MethodDelegate = MethodDelegate,
MethodDynamicType = MethodDynamicType,
MethodGuid = Guid.NewGuid().ToString(),
MethodTips = MethodTips ,
ReturnType = ReturnType,
MethodName = MethodName,
MethodLockName = MethodLockName,
ExplicitDatas = ExplicitDatas.Select(it => it.Clone()).ToArray(),
};
}
///
/// 作用实例
///
public Type ActingInstanceType { get; set; }
///
/// 作用实例
///
public object ActingInstance { get; set; }
///
/// 方法GUID
///
public string MethodGuid { get; set; }
///
/// 方法名称
///
public string MethodName { get; set; }
///
/// 方法委托
///
public Delegate MethodDelegate { get; set; }
///
/// 节点类型
///
public DynamicNodeType MethodDynamicType { get; set; }
///
/// 锁名称
///
public string MethodLockName { get; set; }
///
/// 方法说明
///
public string MethodTips { get; set; }
///
/// 参数内容
///
public ExplicitData[] ExplicitDatas { get; set; }
///
/// 出参类型
///
public Type ReturnType { get; set; }
public bool IsCanConnect(Type returnType)
{
if (ExplicitDatas.Length == 0)
{
// 目标不需要传参,可以舍弃结果?
return true;
}
var types = ExplicitDatas.Select(it => it.DataType).ToArray();
// 检查返回类型是否是元组类型
if (returnType.IsGenericType && IsValueTuple(returnType))
{
return CompareGenericArguments(returnType, types);
}
else
{
int index = 0;
if (types[index] == typeof(DynamicContext))
{
index++;
if (types.Length == 1)
{
return true;
}
}
// 被连接节点检查自己需要的参数类型,与发起连接的节点比较返回值类型
if (returnType == types[index])
{
return true;
}
}
return false;
}
///
/// 检查元组类型
///
///
///
private bool IsValueTuple(Type type)
{
if (!type.IsGenericType) return false;
var genericTypeDef = type.GetGenericTypeDefinition();
return genericTypeDef == typeof(ValueTuple<>) ||
genericTypeDef == typeof(ValueTuple<,>) ||
genericTypeDef == typeof(ValueTuple<,,>) ||
genericTypeDef == typeof(ValueTuple<,,,>) ||
genericTypeDef == typeof(ValueTuple<,,,,>) ||
genericTypeDef == typeof(ValueTuple<,,,,,>) ||
genericTypeDef == typeof(ValueTuple<,,,,,,>) ||
genericTypeDef == typeof(ValueTuple<,,,,,,,>);
}
private bool CompareGenericArguments(Type returnType, Type[] parameterTypes)
{
var genericArguments = returnType.GetGenericArguments();
var length = parameterTypes.Length;
for (int i = 0; i < genericArguments.Length; i++)
{
if (i >= length) return false;
if (IsValueTuple(genericArguments[i]))
{
// 如果当前参数也是 ValueTuple,递归检查嵌套的泛型参数
if (!CompareGenericArguments(genericArguments[i], parameterTypes.Skip(i).ToArray()))
{
return false;
}
}
else if (genericArguments[i] != parameterTypes[i])
{
return false;
}
}
return true;
}
}
}