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.
Folder layout
Section titled “Folder layout”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.csA 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.cppThe 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 partThe manifest
Section titled “The manifest”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.cppEach template has these fields:
| Field | Required | Meaning |
|---|---|---|
name | Yes | The 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. |
description | No | A description shown with the template on the Code Templates page and in the Apply Code Template dialog. |
applies-to | Yes | The 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. |
file | For methods and functions | The template file. |
get, set | For properties and attributes, at least one | The getter and setter files. In an IVI-COM set, set is the file for the property’s put accessor. |
use-standard-preamble | No | true (the default) or false. See The preamble setting. |
default | No | true 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.
What the manifest may contain
Section titled “What the manifest may contain”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.
Template files
Section titled “Template files”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.
The preamble setting
Section titled “The preamble setting”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 type | With true, Nimbus writes | The template supplies |
|---|---|---|
| IVI.NET | The using var preamble = …; statement, and in a property accessor, the if (preamble.SkipBody) … statement that follows it | Everything after them, including any simulation code in a method |
| IVI-C | Everything down to and including the auto status = VI_SUCCESS; line, including the simulation code | Everything after that line, ending with the return |
| IVI-COM | The preamble in the member’s forwarding shim, in ForwardingShims.nimbus.cpp | The 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.
IVI.NET
Section titled “IVI.NET”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.
IVI-COM
Section titled “IVI-COM”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;Properties and attributes
Section titled “Properties and attributes”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.