At the last meeting, the IsAvailable property was to a method that takes "whoIsAsking" as an argument.
I (Stef) was one of the promotors of this extention, but having excersised with it I have learned that it confuses things.

The idea was that a consumer asks if data is available the way it wants it. So in the picture below, both input item B and C can check whether their data is available or not.

This will in general be done by code that looks like this:

	while ( ! inputItemB.Provider.IsAvailable(inputItemB) )
	{
		inputItemB.Provider.Component.Update();
	}
	valuesForInputItemB = inputItem.Provider.Values;

In the case pictured above it is implicitly clear that the values taken from the timeDecorator (==inputItemB.Provider) will contain the Values that the consumer wants, because the Values are taken out directly after the IsAvailable() call.

However, in the case of a spatial decorator that is reused by two input items of the same component (see picture below), the situation is less clear.

The component might first check if everything is available, and then start to do its work:

	while ( ! ( spatialDecorator.IsAvailable(inputItemB) && spatialDecorator.IsAvailable(inputItemC) ) )
	{
		timeDecorator.Component.Update();
	}
	valuesForInputItemB = spatialDecorator.Values;
	valuesForInputItemC = spatialDecorator.Values;

In this case, the inputItemB may end up with the values meant for C.

So my suggestion is to go back to the previous version, an IsAvailable property without arguments. However, with a different meaning then in the previous version. To my opinion, the meaning was that the output item would check wether the data is available according to the consumer (that is why the question arose: "for which consumer", and that is why the "whoIsAsking" argument was introduced in the first place). And think that the meaning of the IsAvailable should be the indication that the data indeed has been produced. Therefore it might be better to call it "IsUpdated". The check wether or the available data fits the required data can be handled outside the exchange items, prefably by offering one or more utilities that can perform the required checks.
For example:

	if ( inputItemB.Provider.IsUpdated &&
				ExchangeItemUtils.OutputFitsRequiredInput(inputItemB.Provider, inputItemB ) {
	{
		valuesForInputItemB = inputItem.Provider.Values;
	}

The above example is typical for the "loop approach".
For e.g. a visualization tool that presents the actual content of an output item or decorator (e.g. a time buffer), the code would look like:

	if ( outputItem.IsUpdated ) {
	{
		timesInBuffer = outputItem.TimeSet.Times;
		valuesInBuffer = outputItem.Values;
		show(timesInBuffer, valuesInBuffer);
	}

As discussed at the last meeting, the pull approach will use the GetValues(forMe) function. In a TimeProgressing component, that we will provide in the SDK, this typically looks like:

	foreach (IInputItem inputItem in InputItems)
	{
		if (inputItem.Provider != null)
		{
			IList providedValues = inputItem.Provider.GetValues(inputItem);
		}
	}

In this way, there is a clear difference between "getting the values as required", and "using the values as they are after the last update", e.g. for presentation:

  • No labels