using Serein.Library;
using Serein.Library.Api;
using Serein.Library.Utils;
using Serein.NodeFlow.Env;
using Serein.NodeFlow.Model;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Reflection;
using System.Text;
namespace Serein.NodeFlow
{
///
/// 流程环境需要的扩展方法
///
public static class FlowNodeExtension
{
///
/// 判断是否为基础节点
///
///
public static bool IsBaseNode(this NodeControlType nodeControlType)
{
var nodeDesc = EnumHelper.GetAttribute(nodeControlType);
if("base".Equals(nodeDesc?.Description, StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
///
/// 是否为根节点
///
///
///
public static bool IsRoot(this IFlowNode node)
{
var cts = NodeStaticConfig.ConnectionTypes;
foreach (var ct in cts)
{
if (node.PreviousNodes[ct].Count > 0)
{
return false;
}
}
return true;
}
///
/// 创建节点
///
/// 运行环境使用的IOC
/// 节点类型
/// 方法描述
///
///
public static IFlowNode CreateNode(ISereinIOC envIOC, NodeControlType nodeControlType, MethodDetails? methodDetails = null)
{
// 尝试获取需要创建的节点类型
var flowEdit = envIOC.Get();
if (!flowEdit.NodeMVVMManagement.TryGetType(nodeControlType, out var nodeMVVM) || nodeMVVM.ModelType == null)
{
throw new Exception($"无法创建{nodeControlType}节点,节点类型尚未注册。");
}
// 生成实例
//var nodeObj = Activator.CreateInstance(nodeMVVM.ModelType, env);
var nodeObj = envIOC.CreateObject(nodeMVVM.ModelType);
if (nodeObj is not IFlowNode nodeModel)
{
throw new Exception($"无法创建目标节点类型的实例[{nodeControlType}]");
}
// 配置基础的属性
nodeModel.ControlType = nodeControlType;
if (methodDetails == null) // 不存在方法描述时,可能是基础节点(表达式节点、条件表达式节点)
{
methodDetails = new MethodDetails();
}
var md = methodDetails.CloneOfNode(nodeModel);
nodeModel.DisplayName = md.MethodAnotherName;
nodeModel.MethodDetails = md;
nodeModel.OnCreating();
return nodeModel;
}
///
/// 程序集封装依赖
///
///
///
public static FlowLibraryInfo ToLibrary(this FlowLibraryInfo libraryInfo)
{
return new FlowLibraryInfo
{
AssemblyName = libraryInfo.AssemblyName,
FileName = libraryInfo.FileName,
FilePath = libraryInfo.FilePath,
};
}
///
/// 触发器运行后状态转为对应的后继分支类别
///
///
///
///
public static ConnectionInvokeType ToContentType(this FlipflopStateType flowStateType)
{
return flowStateType switch
{
FlipflopStateType.Succeed => ConnectionInvokeType.IsSucceed,
FlipflopStateType.Fail => ConnectionInvokeType.IsFail,
FlipflopStateType.Error => ConnectionInvokeType.IsError,
FlipflopStateType.Cancel => ConnectionInvokeType.None,
_ => throw new NotImplementedException("未定义的流程状态")
};
}
///
/// 判断 触发器节点 是否存在上游分支
///
///
///
public static bool NotExitPreviousNode(this SingleFlipflopNode node)
{
ConnectionInvokeType[] ct = [ConnectionInvokeType.IsSucceed,
ConnectionInvokeType.IsFail,
ConnectionInvokeType.IsError,
ConnectionInvokeType.Upstream];
foreach (ConnectionInvokeType ctType in ct)
{
if (node.PreviousNodes[ctType].Count > 0)
{
return false;
}
}
return true;
}
///
/// 添加代码
///
/// 字符串构建器
/// 缩进次数(4个空格)
/// 要添加的代码
/// 字符串构建器本身
public static StringBuilder AppendCode(this StringBuilder sb,
int retractCount = 0,
string code = null,
bool isWrapping = true)
{
if (!string.IsNullOrWhiteSpace(code))
{
string retract = new string(' ', retractCount * 4);
sb.Append(retract);
if (isWrapping)
{
sb.AppendLine(code);
}
else
{
sb.Append(code);
}
}
return sb;
}
/////
///// 从节点类型枚举中转为对应的 Model 类型
/////
/////
/////
//public static Type? ControlTypeToModel(this NodeControlType nodeControlType)
//{
// // 确定创建的节点类型
// Type? nodeType = nodeControlType switch
// {
// NodeControlType.Action => typeof(SingleActionNode),
// NodeControlType.Flipflop => typeof(SingleFlipflopNode),
// NodeControlType.ExpOp => typeof(SingleExpOpNode),
// NodeControlType.ExpCondition => typeof(SingleConditionNode),
// NodeControlType.ConditionRegion => typeof(CompositeConditionNode),
// _ => null
// };
// return nodeType;
//}
//public static NodeControlType ModelToControlType(this NodeControlType nodeControlType)
//{
// var type = nodeControlType.GetType();
// NodeControlType controlType = type switch
// {
// Type when type == typeof(SingleActionNode) => NodeControlType.Action,
// Type when type == typeof(SingleFlipflopNode) => NodeControlType.Flipflop,
// Type when type == typeof(SingleExpOpNode) => NodeControlType.ExpOp,
// Type when type == typeof(SingleConditionNode) => NodeControlType.ExpCondition,
// Type when type == typeof(CompositeConditionNode) => NodeControlType.ConditionRegion,
// _ => NodeControlType.None,
// };
// return controlType;
//}
}
}