List <Action> Navigate(IActivity activity, object results, IUser dealer, Context context) { // 已处理,且状态有变化的才能开始寻找下一步 if (this.Status != ActivityStates.Dealed || !this.statesChanged || results == null) { return; } if (this.Graph.Nexts == null || this.Graph.Nexts.Count == 0) { return; } var nextActions = new List <Action>(); var nextEntities = new List <ActivityEntity>(); var navEntities = new List <NavigationEntity>(); foreach (var arrow in this.Graph.Nexts) { // 每条线路只能进入一次 if (this.Nexts.ContainsKey(arrow.Name)) { continue; } var navResults = activity.Navigate(arrow, this, context); //检查没通过,不会走该线路 if (navResults == null) { continue; } // 执行导航 var nextAction = this.DoNavigate(arrow, navResults, context); nextEntities.Add(nextAction.entity); nextActions.Add(nextAction); navEntities.Add(new NavigationEntity() { FromActionId = this.Id, ToActionId = nextAction.Id, OwnActionId = parent.Id, FlowId = parent.entity.FlowId, NavigationType = arrow.InstanceType, NextDealerId = navResults.NextDealer?.Id, NextDealerName = navResults.NextDealer?.Name, NextInputs = JSON.Stringify(navResults.NextInputs), CreateTime = DateTime.Now, CreatorId = context.Dealer.Id, CreatorName = context.Dealer.Name }); this.AddNexts(arrow.Name, nextAction.entity.Id); } if (nextEntities.Count > 0) { this.Engine.FlowRepository.Inserts(nextEntities); this.Engine.FlowRepository.InsertNavigations(navEntities); } this.SaveChanges(); return(nextActions); }
static void ImportStates(Activity activity, object inputs, Context context) { var node = activity.Graph; activity.Entity.Inputs = JSON.Stringify(inputs); if (node.Imports != null && node.Imports.Count > 0 && context.Inputs != null) { var inputDic = JSON.ToDict(inputs); if (inputDic != null && inputDic.Count > 0) { var states = new Dictionary <string, string>(); foreach (var pair in node.Imports) { inputDic.TryGetValue(pair.Key, out string stat); states.Add(pair.Value, stat); } activity.Entity.States = JSON.Stringify(states); } } }
NavigationEntity CreateNavigation(Activity toActivity, IAssociation assoc, NavigateResults navResults, ProcessContext processContext) { var entity = new NavigationEntity() { FromActivityId = this.FromActivity.Id, ToActivityId = toActivity.Id, ParentActivityId = this.FromActivity.ParentId.Value, FlowId = toActivity.FlowId, NavigatorType = assoc.InstanceType, NextDealerId = navResults.NextDealer?.Id, NextDealerName = navResults.NextDealer?.Name, NextInputs = JSON.Stringify(navResults.NextInputs), CreateTime = DateTime.Now, CreatorId = processContext.Dealer.Id, CreatorName = processContext.Dealer.Name }; this.NavigationEntities.Add(entity); this.FromActivity.AddNexts(assoc.Name, toActivity.Id); return(entity); }
static Activity CreateActivityInstance(Node node, string version, IUser creator, Engine engine) { Guid id = Guid.NewGuid(); var entity = new ActivityEntity() { Id = id, NodeName = node.Name, Status = ActivityStates.Initializing, Version = version, Domain = engine.Name, InstanceType = node.InstanceType ?? engine.DefaultActivityInstanceType, Graph = JSON.Stringify(node), HasChildren = node.Nodes != null && node.Nodes.Count > 0, CreateTime = DateTime.Now, CreatorId = creator.Id, CreatorName = creator.Name }; return(CreateActivityInstance(entity, engine)); }
public Activity(Engine engine, Activity parent, INode node, string version, object inputs, IUser creator, IUser owner, ProcessContext processContext) { this.Engine = engine; this.graph = node; this.parent = parent; #region init entity var entity = new ActivityEntity() { Id = Guid.NewGuid(), NodeName = node.Name, NodePath = parent == null ? node.Name : parent.NodePath + "/" + node.Name, Status = ActivityStates.Creating, Version = version ?? parent?.Version, Domain = engine.Name, ActionType = node.InstanceType ?? engine.DefaultActionType, Graph = JSON.Stringify(node), HasChildren = node.Nodes != null && node.Nodes.Count > 0, Inputs = JSON.Stringify(inputs), CreateTime = DateTime.Now, CreatorId = creator.Id, CreatorName = creator.Name }; this.entity = entity; this.Owner = owner; #endregion if (parent != null) { this.FlowRepository = parent.FlowRepository; this.AddChild(this); } else { this.FlowRepository = engine.ResolveFlowRepository(processContext); } #region init states var states = new JObject(); var metas = (node as Node).Metas; if (metas != null) { foreach (var pair in metas) { states.Add(pair.Key, pair.Value.DeepClone()); } } if (parent != null && node.Imports != null) { var pStates = parent.States as JObject; foreach (var pair in node.Imports) { var value = JSON.GetPathValue(pStates, pair.Value); JSON.SetPathValue(states, pair.Key, value); } } this.entity.States = states.ToString(); this.states = states; #endregion }
private void StartChildActivity(Context context) { string[] starts = this.Graph.Starts; if (starts == null || starts.Length == 0) { if (this.Graph.Start != null) { starts = new string[] { this.Graph.Start } } ; } if (starts == null || starts.Length == 0) { throw new InvalidGraphException("活动{0}配置了nodes,却没有配置start/starts", this.ToString()); } var nextActivities = new List <Activity>(); var nextEntities = new List <ActivityEntity>(); foreach (var startName in starts) { var startNode = this.Graph.Nodes.FirstOrDefault(p => p.Name == startName); if (startNode == null) { throw new InvalidGraphException("活动{0}无法找到起始节点{1}", this.ToString(), startName); } var startActivity = CreateActivityInstance(startNode, this.Dealer, this); this.children.Add(startActivity); nextEntities.Add(startActivity.Entity); nextActivities.Add(startActivity); } this.Engine.FlowRepository.Inserts(nextEntities, context.Transaction); this.DelayExecute((context) => { foreach (var nextActivity in nextActivities) { nextActivity.Process(context); } }); } #endregion void Done(object executeResults, ITransaction trans, Context context) { //没有返回任何结果 ,不做进一步尝试 if (executeResults == null) { return; } var changedStates = JObject.FromObject(executeResults); foreach (var pair in changedStates) { if (this.states == null) { if (!string.IsNullOrWhiteSpace(this.Entity.States)) { this.states = JObject.Parse(this.Entity.States); } } if (this.states == null) { this.states = new JObject(); } this.states[pair.Key] = pair.Value; this.statesChanged = true; } // 状态转换后,找到下一步的连线 var navs = this.ResolveNexts(context); if (navs == null) { // 图中就没有下一步 this.DoneTime = DateTime.Now; this.ExportStates(trans); // 指示后面执行 return(new List <NextInfo>()); } else if (navs.Count == 0) { // 当前状态不足以找到nexts, // 节点处于中间状态 // 返回null,指示deal函数,不做StepToNexts操作 return(null); } else { this.DoneTime = DateTime.Now; this.ExportStates(trans); return(navs); } } /// <summary> /// /// </summary> /// <param name="context"></param> /// <returns>null 表示图中没有下一步</returns> IList <NextInfo> ResolveNexts(Context context) { // 该Activity是一个顶层的Flow,没有下一步 if (this.Parent == null) { return(null); } var pNode = this.Flow.Graph; if (pNode.Associations == null || pNode.Associations.Count == 0) { return(null); } var assocsFromMe = pNode.Associations.Where(p => p.From == this.Name); // 没有找到下一步,不执行stepToNexts if (assocsFromMe.Count() == 0) { return(null); } var nexts = new List <NextInfo>(); foreach (var assoc in assocsFromMe) { var nav = CreateNavigationInstance(assoc.InstanceType); var navResult = nav.Navigate(this.states, context); if (navResult != null) { var toNode = pNode.Nodes.FirstOrDefault(p => p.Name == assoc.To); if (toNode == null) { throw new InvalidGraphException("节点{0}寻找{1}关联的To节点{2}失败,未找到该节点", this.NodePath, nav.Association.Name, nav.Association.To); } nexts.Add(new NextInfo(nav, toNode, navResult)); } } return(nexts); } void ExportStates(ITransaction trans) { var p = this.Flow; if (p == null || this.Graph.Exports == null) { return; } foreach (var pair in this.Graph.Exports) { string value = this[pair.Value]; p[pair.Key] = value; } p.SaveChanges(trans); } void StepToNexts(IList <NextInfo> nextInfos, Context context) { if (nextInfos.Count > 0) { List <ActivityEntity> nextEntities = new List <ActivityEntity>(); foreach (var nextInfo in nextInfos) { var nextActivity = CreateActivityInstance(nextInfo); nextInfo.NextActivity = nextActivity; nextEntities.Add(nextActivity.Entity); } this.Engine.FlowRepository.Inserts(nextEntities, context.Transaction); this.DelayExecute((context) => { foreach (var nextInfo in nextInfos) { nextInfo.NextActivity.Process(context); } }); this.Status = ActivityStates.Completed; } else { // 没有下一步了 if (this.Flow != null) { this.DelayExecute((context) => { this.Flow.Process(context); }); } } } void SaveChanges(ITransaction trans) { if (this.statesChanged) { this.Entity.States = JSON.Stringify(this.States); if (this.statusChanged) { if (this.Results != null) { this.Entity.Results = JSON.Stringify(this.Results); this.Engine.FlowRepository.SaveResults(this.Entity, trans); } else { this.Engine.FlowRepository.SaveStatusAndStates(this.Entity, trans); } } else { this.Engine.FlowRepository.SaveStates(this.Entity, trans); } } else { if (this.statusChanged) { if (this.results != null) { this.Entity.Results = JSON.Stringify(this.results); this.Engine.FlowRepository.SaveStatusAndResults(this.Entity, trans); } else { this.Engine.FlowRepository.SaveStatus(this.Entity, trans); } } } } Queue <Action <Context> > nextTicks; void DelayExecute(Action <Context> handler) { if (this.nextTicks == null) { this.nextTicks = new Queue <Action <Context> >(); } this.nextTicks.Enqueue(handler); } void DelayExecute(Context context) { if (this.nextTicks == null) { return; } Action <Context> handler = this.nextTicks.Dequeue(); while (this.nextTicks.Count > 0) { handler(context); handler = this.nextTicks.Dequeue(); } }
public Action(Engine engine, Action parent, Node node, string version, object inputs, IUser creator, IUser dealer = null) { this.Engine = engine; this.graph = node; this.parent = parent; #region init entity var entity = new ActivityEntity() { Id = Guid.NewGuid(), NodeName = node.Name, NodePath = parent == null?node.Name:parent.NodePath + "/" + node.Name, Status = ActivityStates.Created, Version = version ?? parent?.Version, Domain = engine.Name, ActivityType = node.InstanceType ?? engine.DefaultActivityInstanceType, Graph = JSON.Stringify(node), HasChildren = node.Nodes != null && node.Nodes.Count > 0, Inputs = JSON.Stringify(inputs), CreateTime = DateTime.Now, CreatorId = creator.Id, CreatorName = creator.Name }; this.entity = entity; if (dealer != null) { this.dealer = dealer; entity.DealerId = dealer.Id; entity.DealerName = dealer.Name; } #endregion #region init states var states = new JObject(); if (node.Meta != null) { foreach (var pair in node.Meta) { states.Add(pair.Key, pair.Value.DeepClone()); } } if (parent != null && node.Imports != null) { var pStates = parent.States as JObject; foreach (var pair in node.Imports) { var value = JSON.GetPathValue(pStates, pair.Value); JSON.SetPathValue(states, pair.Key, value); } } if (inputs != null) { var inputObj = JObject.FromObject(inputs); foreach (var pair in inputObj) { states[pair.Key] = pair.Value; } } this.entity.States = states.ToString(); this.states = states; #endregion }