protected virtual void UpdateLoopVersion(ICollection <EngineOutputItem> requiredOutputItems) { Status = LinkableComponentStatus.Updating; foreach (ITimeSpaceInput inputItem in Inputs) { if (inputItem.Provider != null) { if (!ExchangeItemHelper.OutputAndInputFit((ITimeSpaceOutput)inputItem.Provider, inputItem)) { Status = LinkableComponentStatus.WaitingForData; return; } } } // All data available, get all values // TODO JGr: Check if we can reuse the ProcessActiveInputItems(); foreach (ITimeSpaceInput inputItem in Inputs) { if (inputItem.Provider != null) { // get and store input ITimeSpaceValueSet incomingValues = (ITimeSpaceValueSet)inputItem.Provider.Values; inputItem.Values = incomingValues; } } // compute and produce output PerformTimestep(requiredOutputItems); ProcessActiveOutputItems(); // Assuming the time step was successfull, then we can update the time horizon // start time of all input items, to indicate that we are never going to ask // data before this time. Done here in order to support redoing of time steps // to the horizon start time should only be updated on a successfull performTimestep foreach (EngineInputItem inputItem in ActiveInputItems) { // Assuming this input item is never (ever again) going to ask // for data before the current inputTime inputItem.TimeSet.SetTimeHorizonStart(inputItem.TimeSet.Times[0]); } // indicate that Update is done Status = CurrentTime.StampAsModifiedJulianDay >= EndTime.StampAsModifiedJulianDay ? LinkableComponentStatus.Done : LinkableComponentStatus.Updated; }
/// <summary> /// Checks the <paramref name="querySpecifier"/> if it matches the current values. If not, /// try and update the component and the item. /// /// If failing, this will throw an exception /// </summary> protected void CheckSpecificationAndTryUpdateIfRequired(ITimeSpaceExchangeItem querySpecifier) { if (!ExchangeItemHelper.OutputAndInputElementSetsFit(this, querySpecifier)) { throw new Exception("ElementSet of output item \"" + Id + "\" does not fit the ElementSet of requesting item \"" + querySpecifier.Id); } if (!ExchangeItemHelper.OutputAndInputTimeSetsFit(this, querySpecifier)) { TimeComponentUpdater.Update(this, querySpecifier); // TODO JGR: Remove commented code when tested properly //if (querySpecifier.TimeSet == null || // querySpecifier.TimeSet.Times == null || // querySpecifier.TimeSet.Times.Count != 1) //{ // // Time independent target item, but for some reason this output item's time set does // // not fit (most probably because is has either 0 or more then 1 timesteps). // throw new Exception("Given the TimeSet of output item \"" + Id + // "\", it can not produce one set of values for \"" + querySpecifier.Id + "\""); //} //// Compute until the value are available indeed //// Check the max #of steps, to avoid an eternal loop //double targetTimeAsMJD = querySpecifier.TimeSet.Times[0].End().StampAsModifiedJulianDay; //while ((_linkableEngine.Status == LinkableComponentStatus.Valid || // _linkableEngine.Status == LinkableComponentStatus.Updated) && // _linkableEngine.CurrentTime.StampAsModifiedJulianDay + Time.EpsilonForTimeCompare < targetTimeAsMJD) //{ // _linkableEngine.Update(); //} } if (!ExchangeItemHelper.OutputAndInputTimeSetsFit(this, querySpecifier)) { throw new Exception("Could not update engine \"" + _linkableEngine.Id + "\" to required time for output item \"" + Id + "\" (requiring input item \"" + querySpecifier.Id + "\"). Use a Time Extrapolator."); } }
public override ITimeSpaceValueSet GetValues(IBaseExchangeItem basequerySpecifier) { ITimeSpaceExchangeItem querySpecifier = basequerySpecifier as ITimeSpaceExchangeItem; if (querySpecifier == null) { throw new ArgumentException("querySpecifier must be an ITimeSpaceExchangeItem - add an adaptor"); } //------------------------------------------------------ // Check if we need to update the output component // Time set of query must be defined and have at least 1 time if (querySpecifier.TimeSet == null || querySpecifier.TimeSet.Times == null || querySpecifier.TimeSet.Times.Count == 0) { throw new Exception("Invalid query specifier \"" + querySpecifier.Id + "\" for in GetValues() call to time decorater " + Id); } // Determine query time double queryTimeMjd = querySpecifier.TimeSet.Times[querySpecifier.TimeSet.Times.Count - 1].End().StampAsModifiedJulianDay; // Determine the times available in the buffer double availableTimeMjd = Double.NegativeInfinity; IList <ITime> currentTimes = TimeSet.Times; if (currentTimes.Count > 0) { availableTimeMjd = currentTimes[currentTimes.Count - 1].End().StampAsModifiedJulianDay; } // Check if we need to update // In case the output component is "busy", this may not actually update values // up to queryTimeMjd, in which case the _buffer.GetValues below will extrapolate. if (availableTimeMjd < queryTimeMjd) { if (ComponentUpdater == null) { throw new Exception("Failed when trying to update time buffer (no updater is specified)"); } ComponentUpdater.Update(querySpecifier); } //------------------------------------------------------ // Retrieve values from the buffer // Return the values for the required time(s) IList <IList <double> > resultValues = new List <IList <double> >(); if (querySpecifier.TimeSet != null && querySpecifier.TimeSet.Times != null) { for (int t = 0; t < querySpecifier.TimeSet.Times.Count; t++) { ITime queryTime = querySpecifier.TimeSet.Times[t]; double[] valuesForTimeStep = _buffer.GetValues(queryTime); resultValues.Add(valuesForTimeStep); } } ITime earliestConsumerTime = ExchangeItemHelper.GetEarliestConsumerTime(this); if (earliestConsumerTime != null) { _buffer.ClearBefore(earliestConsumerTime); } return(new TimeSpaceValueSet <double>(resultValues)); }