private ParallelWorkflowModel BuildParallelModels(List<StandardFlowModel> model) { ParallelWorkflowModel currParallelModel = new ParallelWorkflowModel(null, null); ParallelWorkflowModel head = currParallelModel; ParallelWorkflowModel nextParallelModel, prevParallelModel; int iterator = 0, totalModels = model.Count; do { StandardFlowModel childModel = model[iterator++]; nextParallelModel = new ParallelWorkflowModel(null, null); currParallelModel.ActivityModel1 = childModel; currParallelModel.ActivityModel2 = nextParallelModel; totalModels--; //model.Remove(childModel); //Prepare for next iteration prevParallelModel = currParallelModel; currParallelModel = nextParallelModel; } while (totalModels > 1); //} while (model.Count > 1); StandardFlowModel sequentialChild = model[0]; // The last element //SequentialWorkflowModel sequential = new SequentialWorkflowModel(sequentialChild); //nextParallelModel.ActivityModel2 = sequentialChild; prevParallelModel.ActivityModel2 = sequentialChild; currParallelModel = null; return head; }
private void QueueActivitiesIntoOrder() { #region Select the Start Model StandardFlowModel StartModel = null; StandardFlowModel EndModel = null; try { StartModel = (from keyvalue in activityDict where (keyvalue.Value.Activity.IsStartFlow == true) select keyvalue.Value).Single(); EndModel = (from keyvalue in activityDict where (keyvalue.Value.Activity.IsEndFlow == true) select keyvalue.Value).Single(); if (StartModel == null) throw new ArgumentException ("Please make sure you have a Start Model that are linked up in the workflow."); else if (EndModel == null) throw new ArgumentException ("Could not locate End Model in the workflow make sure there is one before proceeding."); } catch (Exception e) { throw new Exception(e.Message); } #endregion #region Sort all activities into their respective Level Dictionary<int, List<StandardFlowModel>> groups = new Dictionary<int, List<StandardFlowModel>>(); GroupItemByLevel(0, StartModel, groups); //Transverse to the deepest node and group them #endregion #region Iterate through each level of collections and build their flow (sequential/parallel) int currLevel = 0; for (int i = 0; i < groups.Keys.Count; i++) { groups .Where(lv => lv.Key == currLevel) .Select(lv => lv.Value) .ToList() .ForEach(delegate(List<StandardFlowModel> model) { #region For each level, build the models into flow of sequential / parallel trays System.Diagnostics.Debug.WriteLine("Curr Level > " + model[0].Activity.ActivityClass); if (model.Count == 1) { //Simplest scenario of all, only an activity exist so a sequential tray is only needed StandardFlowModel activity = model[0]; SequentialWorkflowModel sequential = new SequentialWorkflowModel(activity); workflow.Root.Insert(currLevel, sequential); } else if (model.Count == 2) { //2 activities for this step thus a Parallel is sufficient StandardFlowModel activity1 = model[0]; StandardFlowModel activity2 = model[1]; ParallelWorkflowModel parallel = new ParallelWorkflowModel(activity1, activity2); workflow.Root.Insert(currLevel, parallel); } else if (model.Count > 2) { //Complex scenario where there are more than 2 activities //Here we need several parallel models and a sequential model ParallelWorkflowModel complexType = BuildParallelModels(model); workflow.Root.Insert(currLevel, complexType); } else throw new ArgumentOutOfRangeException ("Unexpected error ocurred while parsing the workflow model."); #endregion }); currLevel++; } #endregion }