Click or drag to resize

SetterCacheManager Class

As the name implies, the SetterCacheManager is used to manage cached values for attributes in IVI-C drivers. It is important to note that the Nimbus caching engine for IVI-C drivers is used for two purposes -- 1) to support the IVI-defined state caching features which drivers may optionally implement, and 2) to support simulation which all IVI drivers are required to implement. Because the same cache is used for both state caching and simulation, the SetterCacheManager appears in most attribute implementation code. Understanding the tasks it performs is useful in understanding the overall flow of Nimbus-generated attribute implementation code.

The SetterCacheManager simplifies simulation and state caching code by performing the following tasks:

  • Checks to see if either state caching or simulation is enabled and does nothing if neither are enabled.

  • Automatically retrieves the cache entry for the specified attribute. If the attribute is associated with a repeated capability, then the SetterCacheManager retrieves all cache entries for the physical names supplied in the attribute setter's RepCapIdentifier parameter.

  • Automatically updates the cached value and sets its cached state to valid upon function exit. This is done in the class destructor so that the cache will be properly updated when the function has multiple return locations.

  • Provides a NonCachedPhysicalNames function which allows implementation code to operate only upon those physical names for which a cache entry is not valid. This is important when determining which physical names should be operated upon in an attribute setter implementation.

Using the SetterCacheManager without Repeated Capabilities

The following code shows how the SetterCacheManager is declared in a an attribute setter implementation. In this example, the ACME4321_ATTR_BANDWIDTH attribute is not associated with a repeated capability.

C++
ViStatus _VI_FUNC acme4321_set_BANDWIDTH(ViSession Vi, ViConstString RepCapIdentifier, ViReal64 AttributeValue)
{
    // ...

    // At this point, when the cacheManager variable is declared, the SetterCacheManager checks to
    // see if either state caching or simulation are enabled.  If enabled, then the constructor
    // checks to see if the cache entry is valid and has the value passed in the AttributeValue
    // parameter.  
    // 
    SetterCacheManager<ViReal64> cacheManager(Vi, ACME4321_ATTR_BANDWIDTH, AttributeValue);

    if (SimulationEnabled(Vi))
    {
        // Since the cacheManager destructor updates the cache, the AttributeValue will be stored
        // in the cache for simulation purposes at this point as well.
        // 
        return VI_SUCCESS;
    }

    // ...

}   // Upon function exit, the final value of AttributeValue will be stored in the cache
Using the SetterCacheManager with Repeated Capabilities

The following code shows how the SetterCacheManager is declared in a an attribute setter implementation. In this example, the ACME4321_ATTR_FREQUENCY attribute is associated with a channel repeated capability. When a repeated capability is involved, multiple cache entries must be managed by the SetterCacheManager class.

C++
ViStatus _VI_FUNC acme4321_set_FREQUENCY(ViSession Vi, ViConstString RepCapIdentifier, ViReal64 AttributeValue)
{
    // ...

    auto status = VI_SUCCESS;

    PhysicalNameList<Channel> physicalNames;
    ReturnOnError(Channel::ExpandSelector(Vi, RepCapIdentifier, physicalNames));

    // At this point, when the cacheManager variable is declared, the SetterCacheManager checks to
    // see if either state caching or simulation are enabled.  If enabled, then the constructor
    // checks to see if the cache entry for each physical name is valid and it stores the invalid
    // ones internally so that the code later in the implementation can discriminate.
    // 
    SetterCacheManager<ViReal64, Channel> cacheManager(Vi, physicalNames, ACME4321_ATTR_FREQUENCY, AttributeValue);

    if (SimulationEnabled(Vi))
    {
        // Since the cacheManager destructor updates the cache, the AttributeValue will be stored
        // in the cache (for each physicalName) for simulation purposes at this point as well.
        // 
        return VI_SUCCESS;
    }

    // Send a command to the instrument for each physical name whose cached value is not valid
    // 
    for (const auto& physicalName : cacheManager.NonCachedPhysicalNames(Vi))
    {        
        status = viPrintf(GetVisaSession(), "SENS:FREQ%s %0.15g", physicalName.Name(), AttributeValue);
        ReturnOnError(status);
    }

    // ...

}   // Upon function exit, the final value of AttributeValue will be stored in the cache for all physical names supplied

Download a complete CHM version of this documentation here.