Socket values, enumerations, validators#

The values of the input sockets are always stored as strings. They are only converted to real types at runtime, by the ng::Parser<T> of the data bank (see The runtime).

Attributes of a socket#

Attribute

Sockets

Role

name

both

Displayed name.

id

both

Local ID in the node (see Identifiers).

type

both

Bit mask of the accepted types. Links require intersecting masks.

active

both

Stored and serialized, but not used by any logic yet.

callbacks on link added / broken

both

Qualifiers of callbacks (see Registries and self-registration).

value

input

Current value, used at runtime when the socket isn’t linked.

allowed_values

input

If not empty, the socket is an enumeration.

linkable

input

If false, the socket only accepts a constant value: add_link returns NotLinkable.

callbacks on value changed

input

Qualifiers of callbacks.

Checks done by Graph::set_socket_value#

  1. Allowed values (InputSocket::is_allowed_value): if the socket has a non-empty list of allowed values, the value must be one of them (case-sensitive). Otherwise NotAllowedValue. A socket without allowed values accepts anything.

  2. Validators (InputSocket::check_validity): for each bit set in the socket’s type, the validator registered for that bit in ng::ValidatorsRegistry is looked up.

    • If no validator is registered for any of the socket’s types, the value is valid.

    • Otherwise, the value is valid if at least one of the registered validators accepts it. A socket Number | Text accepts “3” and “abc”.

    • A type without validator doesn’t make the value valid on its own: for Number | Unchecked, “abc” is refused because the Number validator refuses it.

    Otherwise InvalidValue.

  3. The value is set and the “value changed” callbacks are triggered with the old value.

Note

InputSocket::set_value alone only checks the allowed values, not the validators. Always go through Graph::set_socket_value to change the value of a socket in a graph.

The default values given in a NodeDefinition are not checked: they should be valid for the socket’s validators, or the operator will fail to read them at runtime.

Registering a validator#

constexpr ng::socket_t TYPE_NUMBER = ng::socket_t{1} << 0;

namespace {
    bool is_number(const std::string& value) { return ng::parse_from_string<double>(value).has_value(); }

    bool registered = ng::ValidatorsRegistry::instance().register_entry(TYPE_NUMBER, is_number);
}

Using the data bank’s parser as validator (like tests/elements/validators.cc) guarantees that every accepted value can be converted at runtime.