DynamoDS/Dynamo — pull request #1575 by Benglin (2014-04-29 08:21:38+00:00)
Title: Optimized the way NodeModel handles its MirrorData

Hi Luke/Ian, this one is for you guys. See if there's a need for ```NodeModel.CachedValue``` for your scenarios to avoid retrieving ```MirrorData``` for too many times. Something that can be used in your ```VisualizationManager``` enhancement?

Thanks,
Ben.

#### Current Issue
This pull request makes ```NodeModel.OldValue``` property obsolete, replacing it with ```NodeModel.CachedValue``` property instead. The way ```OldValue``` works was that it retrieves the ```MirrorData``` from ```LiveRunner``` API each time its getter is invoked.

This is less than optimal if we have cases such as this:

```cs
if (node.OldValue != null) // MirrorData retrieved once
result = node.OldValue; // MirrorData retrieved twice
```

#### Improvements
Instead of retrieving ```MirrorData``` each time ```OldValue``` property is read, the new ```CachedValue``` keeps the reference to ```MirrorData``` that it previously retrieved as a data member ```NodeModel.cachedMirrorData```. This way a subsequent calls to read ```CachedValue``` property will simply return the previously cached data.

But when does it refresh its internal copy of ```NodeModel.cachedMirrorData```, should a node be updated again? The cached data is invalidated (i.e. set to ```null```) when ```EngineController``` sets ```NodeModel.IsUpdated``` property to ```true``` as part of its evaluation process. This causes ```CachedValue``` to be refreshed the next time its value is queried.

#### Additional Changes
Note how the following will invoke the property getter of ```OldValue``` twice for each visible node, causing twice as many calls to retrieve ```MirrorData``` if it were to use ```OldValue``` way of retrieving the data:

```cs
private void visualizationManager_VisualizationUpdateComplete(object sender, EventArgs e)
{
IEnumerable values = dynSettings.Controller.DynamoModel.Nodes
.Where(x => x.IsVisible).Where(x => x.OldValue != null) // Get data once
.Select(x => x.OldValue.Data as FScheme.Value); // Get data once more
}
```

#### Unit Tests
All affected unit test cases are updated to use ```CachedValue```, I have observed the test cases continue to work the same way they did before the change.