/// <summary> /// Execute next action in the ActionsToDo list. /// TODO: Can execute more actions at once asynchronously, method waits until some action is done. /// </summary> /// <param name="callerEnumerator">List enumerator that requested this method call.</param> /// <returns>False if there are no actions, and no action can be executed. /// True if an action finished since last DoNextAction call (and some new data might be here).</returns> protected virtual bool DoNextAction <S>(ExtractionListEnumerator <S> callerEnumerator) { Debug.Assert(ActionsToDo != null, "Object using DoNextAction() must initialize its ActionsToDo list."); // TODO: lock DoNextAction, CallAction on separated thread, wait for some thread to finish // another thread can try to process the same action in the same time ActionItem action = ActionsToDo.GetNextAction(); if (action != null) { action.CallAction(callerEnumerator); return(true); } else { if (Parent != null) // maybe parent object's action can initiate this object's properties { return(Parent.DoNextAction(callerEnumerator)); } else { return(false); } } }
/// <summary> /// Execute the action. /// Call the method on the specified data context with specified parameters. /// </summary> /// <param name="parametersTransform">List of transformations that will be performed onto the parameters list.</param> internal void CallAction <T>(ExtractionListEnumerator <T> callerEnumerator) { // parameters that will be passed to the extraction method. LocalVariables transformedParameters = new LocalVariables(); // transform the parameters to use with the extraction method foreach (var pair in parameters) { ExtractionObjectBase eObj; if ((eObj = pair.Value as ExtractionObjectBase) != null) { // transform the parameter by transformation method bool containsAction = (eObj.ActionsToDo != null && eObj.ActionsToDo.ContainsAction(this)); ExtractionObjectBase newValue = eObj.TransformArgument(containsAction, callerEnumerator); newValue.RemoveActionToDo(this); transformedParameters[pair.Key] = newValue; if (!containsAction)// add variable that cannot add an ActionItem within the following method call { transformedParameters.SetCannotAddActionForVariable(pair.Key); } } else { // parameter is a value, do not transform transformedParameters[pair.Key] = pair.Value; } } // call the method synchronously method(datacontext, transformedParameters); }
/// <summary> /// This list is not passed to extraction methods. The collection is filled only when the collection is enumerated using GetEnumerator() method. /// Therefore this list container is ignored in extraction methods and it does not invoke other extraction methods (has empty ActionsToDo all the time). /// </summary> /// <returns>If hasAction is false or caller is not enumerator of this, it returns Static EmptyList, without action list, without elements - unable to add elements into this.</returns> internal override ExtractionObjectBase TransformArgument <S>(bool hasAction, ExtractionListEnumerator <S> callerEnumerator) { if (hasAction && callerEnumerator != null && this.Equals(callerEnumerator.listContainer)) { return(callerEnumerator); } else { return(ExtractionListEmpty <T> .EmptyList); } }
/// <summary> /// Do next action to do, if there are no more actions to do, check the listContainer for some new action. /// </summary> /// <typeparam name="S"></typeparam> /// <param name="callerEnumerator">Always this.</param> /// <returns>True if there was processed some action.</returns> protected override bool DoNextAction <S>(ExtractionListEnumerator <S> callerEnumerator) { if (ActionsToDo.Count == 0 && ProcessedActions.Count < listContainer.ActionsToDo.Count) { // no more actions to do, and listCOntainer contains some new actions foreach (var x in listContainer.ActionsToDo) { if (!ProcessedActions.Contains(x)) { ProcessedActions.Add(x); ActionsToDo.AddAction(x); } } } // process the actions to do (mine or parent's) return(base.DoNextAction <S>(callerEnumerator)); }
/// <summary> /// This method returns an object that will be passed to the extraction method. /// Used for lists; list is passed to extraction method only if the list is just enumerated. /// </summary> /// <param name="hasAction">True if this object contains the called action. Otherwise the argument can be transformed to a ghost which will be lost, because this object already processed the action.</param> /// <param name="callerEnumerator">ListEnumerator that invoked this action call. If this is its listContainer, it should be transformed to the callerEnumerator object.</param> /// <returns>An object that has to be passed to extraction method. Typically it returns this.</returns> internal virtual ExtractionObjectBase TransformArgument <S>(bool hasAction, ExtractionListEnumerator <S> callerEnumerator) { return(this); }
protected override bool DoNextAction <S>(ExtractionListEnumerator <S> callerEnumerator) { // do nothing, should not be called! throw new InvalidOperationException("Should not be called. DoNextAction() method should be called on the ExtractionListEnumerator<T> object instance only!"); }
/// <summary> /// do no action. /// </summary> /// <param name="parametersTransform">ignored</param> /// <returns>Always false.</returns> protected override bool DoNextAction <S>(ExtractionListEnumerator <S> callerEnumerator) { return(false); }