Skip to content

Template Set Format

A code template set is a folder holding a manifest.yaml file and the template files it lists. The format is the same in the machine catalog and in a driver’s CodeTemplateSet folder.

The quickest way to start a set is the Create New button on the Code Templates page, which writes a working starter set into the driver. Its templates are the defaults, and their bodies report that the member is not implemented, like Nimbus’s own stubs, so they change nothing until they are edited.

In the machine catalog, a set is a folder named for the set, with a part for each driver type it supports:

<ProgramData>\Pacific MindWorks\Nimbus\<version>\CodeTemplates\
Acme\ a template set named "Acme"
IviC\ its IVI-C part
manifest.yaml
trace-scope.cpp a function template
simulated-default-get.cpp ┐ an attribute template
simulated-default-set.cpp ┘
IviNet\ its IVI.NET part
manifest.yaml
trace-scope.cs

A set needs a part only for the driver types it is used with. In a driver, the CodeTemplateSet folder holds a copy of one part, the one for the driver’s type:

AcmeDmm\
AcmeDmmDriver\ the driver project
CodeTemplateSet\ the driver's template set
manifest.yaml
trace-scope.cpp
simulated-default-get.cpp
simulated-default-set.cpp

The driver’s set has no name of its own. The files in it are part of the driver project so that they can be edited in Visual Studio and are kept under source control, but they are never compiled.

An IVI.NET driver with a linked IVI-C driver has a CodeTemplateSet folder in each driver project, holding the set’s IVI.NET part and its IVI-C part. See Linked IVI-C drivers.

AcmeDmm\
AcmeDmmDriver\ the IVI.NET driver project
CodeTemplateSet\ the set's IVI.NET part
AcmeDmmIviCDriver\ the linked IVI-C driver project
CodeTemplateSet\ the set's IVI-C part

The manifest.yaml file lists the set’s templates:

templates:
- name: Trace scope
description: Wraps the implementation in a trace scope.
applies-to: function
file: trace-scope.cpp
use-standard-preamble: false
default: true
- name: Simulated default
description: Returns the attribute's default value when simulating.
applies-to: attribute
get: simulated-default-get.cpp
set: simulated-default-set.cpp

Each template has these fields:

FieldRequiredMeaning
nameYesThe name shown on the Code Templates page and in the Apply Code Template dialog. Names must be unique among the templates with the same applies-to, ignoring case.
descriptionNoA description shown with the template on the Code Templates page and in the Apply Code Template dialog.
applies-toYesThe kind of member the template is for: method or property in an IVI.NET or IVI-COM set, and function or attribute in an IVI-C set.
fileFor methods and functionsThe template file.
get, setFor properties and attributes, at least oneThe getter and setter files. In an IVI-COM set, set is the file for the property’s put accessor.
use-standard-preambleNotrue (the default) or false. See The preamble setting.
defaultNotrue makes the template the default for its applies-to, so new members of that kind get its body. The default is false, and at most one template of each kind can be true.

File names are relative to the manifest, and a template file may be in a subfolder of the set. A file outside the set’s folder is not allowed.

The defaults are part of the manifest so that a set carries its own: choosing a set, in the new driver wizard or on the Code Templates page, makes new members follow its conventions at once. The defaults can be changed on the Code Templates page, which rewrites the default values in the manifest, or by editing the manifest by hand.

The manifest supports only the part of YAML shown above: a templates key holding a list of templates, each a set of key: value lines. Comments start with #, and a value may be enclosed in single or double quotes. Indentation must use spaces, not tabs.

Anything else is an error rather than being ignored, because a mistake would silently change the code of every member the set produces. This includes an unknown key, a missing required field, an applies-to value that is not valid for the driver type, a true or false value that is neither, two templates of one kind with the same name, and two defaults for one kind. A set whose manifest has an error cannot be used: the Code Templates page shows the error, with its line number and a link to the manifest, and Nimbus refuses to add a member that would use the set until the error is fixed. A default template whose file is missing is refused the same way.

A template file holds the code of one body, written starting in the first column. When Nimbus writes the template into a body, it indents each line to fit the body, removes trailing spaces and any blank lines at the start and end, and otherwise uses the text exactly as it is.

Template files keep their language’s extension, .cs for IVI.NET and .cpp for IVI-C and IVI-COM, so that Visual Studio colors them when they are edited.

A default template’s text goes into every new member of its kind, whatever its signature. A template that does not refer to parameter names or types compiles in any member of its kind.

Every Manual member comes in one of two forms, chosen by its Use standard preamble setting in the Driver Designer. A template’s use-standard-preamble field decides which form a member takes, both when the member is created from a default template and when the template is applied to it:

  • true: Nimbus writes the standard preamble and keeps it up to date as the member’s settings change, and the template supplies the code that follows it.
  • false: the template supplies the whole body. The member’s Use standard preamble setting is turned off, and Nimbus never changes the body again.

What the preamble is depends on the driver type:

Driver typeWith true, Nimbus writesThe template supplies
IVI.NETThe using var preamble = …; statement, and in a property accessor, the if (preamble.SkipBody) … statement that follows itEverything after them, including any simulation code in a method
IVI-CEverything down to and including the auto status = VI_SUCCESS; line, including the simulation codeEverything after that line, ending with the return
IVI-COMThe preamble in the member’s forwarding shim, in ForwardingShims.nimbus.cppThe whole body, whatever the setting

A template cannot put code of its own ahead of a preamble that Nimbus maintains, since Nimbus finds the preamble by its position at the top of the body. A template that needs code there sets use-standard-preamble: false and supplies the whole body.

For example, with this getter file and use-standard-preamble: true:

// TODO: Implement.
throw new NotImplementedException();

a new double property’s getter is:

get
{
using var preamble = GetterPreamble()
.CheckSimulation(defaultValue: 0);
if (preamble.SkipBody)
return (double)preamble.Value;
// TODO: Implement.
throw new NotImplementedException();
}

The IVI-C preamble ends with auto status = VI_SUCCESS;, which declares the status variable a template’s code can use. For example, with this getter file and use-standard-preamble: true:

// TODO: Implement.
status = IVIC_ERROR_ATTRIBUTE_NOT_SUPPORTED;
return status;

a new attribute’s getter is:

ViStatus _VI_FUNC Acme_get_FUNCTION(ViSession Vi, ViConstString RepCapIdentifier, ViInt32* AttributeValue)
{
ValidateSession(Vi);
ObtainLock(Vi);
CheckForNull(Vi, AttributeValue);
GetterCacheManager<ViInt32> cacheManager(Vi, ACME_ATTR_FUNCTION, *AttributeValue);
if (SimulationEnabled(Vi))
{
if (!cacheManager.GetCachedValue(AttributeValue))
{
*AttributeValue = ACME_VAL_DC_VOLTS;
}
return VI_SUCCESS;
}
auto status = VI_SUCCESS;
// TODO: Implement.
status = IVIC_ERROR_ATTRIBUTE_NOT_SUPPORTED;
return status;
}

With use-standard-preamble: false, the template’s text is the whole body, so it must declare anything it uses.

An IVI-COM member’s body never contains a preamble. Nimbus generates the preamble into the member’s forwarding shim in ForwardingShims.nimbus.cpp, which then calls the body, so a template is always the whole body. The use-standard-preamble field decides whether the forwarding shim runs the preamble. For example:

HRESULT hr = S_OK;
// TODO: Implement.
hr = E_NOTIMPL;
return hr;

The preamble setting belongs to the property or attribute, not to one accessor, so one use-standard-preamble value covers both the getter and the setter.

A property or attribute template may have a getter file, a setter file, or both. An accessor the template has no file for gets Nimbus’s usual code: with use-standard-preamble: true, Nimbus’s normal accessor, preamble included, and with false, Nimbus’s stub without the preamble. This lets a template with only a getter file be the default, even though the Driver Designer creates every property and attribute read/write.

When a property or attribute gains an accessor, for example when a read-only property is made read/write, the new accessor gets the default template’s file for it, if the template’s preamble setting matches the member’s. If it does not, a warning says so and the accessor gets Nimbus’s stub.