Attributes (OpScript)

Attribute Base Class

class Attribute

The abstract base class of all attributes.

getType() → int

Returns a number representing the type of the attribute. This is useful for checking whether two attributes are of the same type.

getHash() → string

Returns a string representation of the hash of the attribute.

getHash64() → int

Returns a number representation of the hash of the attribute. Note that the value is a 64-bit hash value truncated to a 53-bit integer, which is guaranteed to be representable as a Lua number.

getXML() → string

Returns a string containing a serialized XML representation of the attribute.

getSize() → int

Returns the total memory in bytes that was allocated when the attribute was created.

Null Attributes

class NullAttribute

A class representing a null value.

Data Attributes

class DataAttribute(number|string|table|sequence data[, number tupleSize=1])

The abstract base class of attributes containing data, possibly at multiple samples in time. DataAttribute implements common, data-agnostic functionality, such as querying the number and orientation of values and time samples. This class cannot be instantiated directly. Instead, use one of:

data should be one of:

  • A single value, e.g. 1

  • A sequence of values, represented by one of:

    • a Lua table, e.g. {1, 2, 3}
    • an OpScript Array, e.g. Array('int', {1, 2, 3})
    • an OpScript ArrayView
  • An associative table that maps each time sample to a sequence of values, e.g. {[0.25] = {1, 2, 3}, [0.75] = {4, 5, 6}}

When time samples are not explicitly given, the attribute is created with a single sample at t=0.0.

getNearestSample(float time) → table<value>

Returns the unmodified values of the sample nearest to a given time as value list.

Note

getNearestSample() returns a Lua table. Lua tables cannot contain more than 2^27 (134 million) values. Use getSamples() to inspect and manipulate large attributes.

getSamples() → SampleAccessor

Returns a read-only view into the samples of the attribute.

getNumberOfTimeSamples() → int

Returns the number of time samples at which data is recorded in this attribute.

getNumberOfTuples() → int

Returns the number of tuples in this attribute.

getNumberOfValues() → int

Returns the total number of data values for this attribute. This will be equal to getNumberOfTuples() * getTupleSize().

getSampleTime(int sampleIndex) → float

Returns a float value containing the time at a particular index for this attribute. If the index is not valid, 0.0 is returned.

getTupleSize() → int

Return the number of data values per tuple for this attribute.

getValue([value defaultValue, boolean throwOnError]) → value

Returns the first value from the time sample nearest 0.0. This is a convenience for the extremely common case of an attribute that stores a single sample of a single value at time 0.0.

By default, throws exception if there are no time samples or no values available. However, if defaultValue is provided and throwOnError is false, defaultValue will be returned.

class IntAttribute(number|table data[, number tupleSize=1])

A class representing a data attribute containing integers.

class FloatAttribute(number|table data[, number tupleSize=1])

A class representing a data attribute containing single-precision floats.

class DoubleAttribute(number|table data[, number tupleSize=1])

A class representing a data attribute containing double-precision floats.

class StringAttribute(string|table data[, number tupleSize=1])

A class representing a data attribute containing strings.

class SampleAccessor

SampleAccessor provides access to the sample buffers contained in a DataAttribute. Create one by calling the DataAttribute:getSamples() method of any DataAttribute.

Sample accessor objects support iterating over all time samples using the ipairs() function. For example:

for i, sample in ipairs(myAttr:getSamples()) do
  ProcessSample(sample)
end
size() → int

Alias of getNumberOfTimeSamples(). Note that you can also use the # operator.

Returns:number of samples in the attribute
empty() → boolean

Tests whether if the attribute has no time samples.

Returns:true if the attribute has no time samples, false otherwise.
front() → Sample

Returns the first sample. Raises an error if there are no time samples.

Returns:the first sample
back() → Sample

Returns the last sample. Raises an error if there are no time samples.

Returns:the last sample
getNumberOfTimeSamples() → int

Returns the number of samples in the attribute.

Returns:the number of samples in the attribute
getNumberOfValues() → int

Returns the number of values per sample.

Returns:the number of values in each time sample.
get(int sampleIndex) → Sample

Returns the sample at index sampleIndex.

Parameters:sampleIndex – the sample index to query
Returns:the sample at index sampleIndex
getNearestSample(float time) → Sample

Returns the sample closest to time. Returns an empty Sample object if the accessor contains no time samples.

Parameters:time – the time to query
Returns:the sample closest to time
getNearestSampleIndex(float time) → int

Returns the index of the sample closest to time. Returns 0 if the accessor contains no time samples.

Parameters:time – the time to query
Returns:the index of the sample closest to time
getSampleTimes() → ArrayView<float>

Returns a sequence of sample times.

Returns:A read-only view into the sequence of sample times in the attribute.
class Sample

Sample objects represent a lightweight, read-only view into a particlar time sample of a DataAttribute.

Like Lua tables, sample objects support iteration using the ipairs() function, as well as taking the size with the # operator. Unlike Lua tables, sample objects are indexed from 0, not 1. For example:

for i, sample in ipairs(myAttr:getSamples()) do
  for j, elem in ipairs(sample) do
    print(i, j, elem)
  end
end

This is equivalent to the following numeric for loop:

local samples = myAttr:getSamples()
for i = 0, #samples - 1 do
  local sample = samples:get(i)
  for j = 0, #sample - 1 do
    print(i, j, sample:get(j))
  end
end
size() → int

Returns the number of elements in this sample. (Note that you can also use the # operator.)

empty() → boolean

Checks whether the sample is empty.

front() → value

Returns the first element. Raises an error if there are no values.

back() → value

Returns the last element. Raises an error if there are no values.

data() → cdata<pointer>

Returns a LuaJIT cdata pointer to the underlying data. This is an advanced feature – be careful!

get(int pos) → value

Accesses the element at the specified index. Raises an error if pos is not a valid index.

Parameters:pos – position of the element to return
Returns:the element at the requested index
getSampleTime() → float

Returns the sample’s time.

Returns:the time of the sample
getSampleIndex() → int

Returns the index of the sample.

Returns:the index of this sample in the underlying attribute
getNumberOfValues() → int

Returns the number of values in the sample.

Returns:the number of values in this sample
toArray() → Array

Returns a mutable copy of this sample buffer.

Returns:a mutable copy of this sample’s data

Group Attributes

class GroupAttribute([table children={}, boolean groupInherit=true])

A class representing a group attribute, used for hierarchically encapsulating other attributes.

children, if given, should be a table of key-value pairs. Each pair should be a 2-element table, where the key is a string giving the attribute name, and the value is an attribute.

local myGroup = GroupAttribute({{"a", IntAttribute(1)},
                                {"b", IntAttribute(2)}}, true)

groupInherit, if given, specifies whether this attribute should be inherited by descendant scene graph locations.

GroupBuilder can be used to incrementally build a group attribute.

getChildByIndex(int index) → Attribute

Returns a child attribute at given index. If index is out of range, nil is returned.

getChildByName(string name) → Attribute

Looks up a child attribute by name and returns it. Returns nil if named child does not exist.

getChildName(int index) → string

Returns the name of the child attribute at given index.

getGroupInherit() → boolean

Returns group inherit flag.

getNumberOfChildren() → int

Returns the number of child attributes.

GroupBuilder

A factory class for constructing GroupAttribute objects.

Typical usage involves creating a GroupBuilder, adding attributes to it with the GroupBuilder:set() method, and, when finished, retrieving a newly constructed GroupAttribute using the GroupBuilder’s GroupBuilder:build() method.

Warning

There is currently no way to inspect the contents of the builder, other than by calling GroupBuilder:build() and inspecting the generated GroupAttribute. Note that by default GroupBuilder:build() clears the contents of the builder; to override this behaviour pass GroupBuilder.BuilderBuildMode.BuildAndRetain to GroupBuilder:build().

As a convenience, GroupBuilder has support for creating arbitrarily nested GroupAttribute structures by passing a dot-delimited string to GroupBuilder:set(), which is referred to as a “path”. Note that this implies that the . character is not a valid attribute name!

local gb = GroupBuilder()
gb:set("my.nested.attribute", IntAttribute(2))
gb:set("myTopLevelAttribute", StringAttribute("taco"))
gb:set("myOtherTopLevelAttribute", FloatAttribute(4.0))

local groupAttribute = gb:build()

-- Following the call to build(), gb is empty and groupAttribute has
-- the following structure:
--
-- {
--   "my": {
--     "nested": {
--       "attribute": IntAttribute(2)
--      }
--   },
--   "myTopLevelAttribute": StringAttribute("taco"),
--   "myOtherTopLevelAttribute": FloatAttribute(4.0f)
-- }
GroupBuilder([GroupBuilder.BuilderMode mode= GroupBuilder.BuilderMode.Normal])

Creates a new, empty GroupBuilder object.

Possible values for mode:

GroupBuilder.BuilderMode.Normal
The “normal” build mode, which allows the full suite of GroupBuilder functionality. This is the default.
GroupBuilder.BuilderMode.Strict

An advanced option that enables a more restrictive but higher performance mode of operation.

When working in this mode:

  • Callers must not pass dot-delimited paths to the GroupBuilder:set() method.
  • Callers must not make multiple calls to GroupBuilder:set() using the same path
  • Deletions are disallowed: the GroupBuilder:del() method becomes a no-op.
class GroupBuilder

All methods except for GroupBuilder:build() return a reference to self for method chaining.

set(string path, Attribute attr[, boolean groupInherit=true])

Sets the value for the attribute identified by the given path.

If path refers to an existing attribute in the builder and the builder was created with GroupBuilder.BuilderMode.Normal, the attribute is replaced. attr must be an Attribute object. If path is a dot-delimited path, groupInherit specifies the groupInherit flag for any new groups added by this call.

setWithUniqueName(string path, Attribute attr[, boolean groupInherit=true])

Sets the value for an attribute identified using a unique name derived from the given path.

If no attribute exists for the given path, this is equivalent to calling set(). Otherwise, setWithUniqueName() chooses a new path by suffixing the given path with an integer. For example, calling setWithUniqueName("foo", ...) multiple times will produce paths foo, foo1, foo2, and so on.

update(GroupAttribute group)

Updates the contents of the GroupBuilder with the attributes from the given GroupAttribute.

Any new attributes with the same names as existing attributes replace the old ones. Existing attributes not matching new attributes are left intact. (This is analogous to the Python dictionary’s update() method.)

If GroupBuilder:setGroupInherit() has not been previously called, the GroupBuilder will also adopt on the incoming GroupAttribute’s groupInherit.

deepUpdate(GroupAttribute group)

Recursively updates the contents of the builder with attributes from the given GroupAttribute.

Groups are traversed until set operations can be applied at the leaves which are not GroupAttributes themselves.

If GroupBuilder:setGroupInherit() has not been previously called, the GroupBuilder will also adopt on the incoming GroupAttribute’s groupInherit.

del(string path)

Deletes the attribute of the builder specified with the given path.

reserve(int size)

Reserves space for size attributes.

This is an optimisation only. Calling reserve() before adding attributes will avoid having to reallocate internal data structures.

sort()

Sorts the top-level attributes by name.

Note

sort() uses bytewise lexicographic ordering

setGroupInherit(boolean groupInherit)

Sets a special attribute on the builder that determines the value returned by GroupAttribute:getGroupInherit() for the top-level GroupAttribute returned by GroupBuilder:build().

This groupInherit flag is sticky, so once it’s been set – either through an explicit call to GroupBuilder:setGroupInherit(), or indirectly via a call to GroupBuilder:update()/GroupBuilder:deepUpdate() – further calls to setGroupInherit() will have no effect.

build([BuilderBuildMode mode= GroupBuilder.BuilderBuildMode.BuildAndFlush]) → GroupAttribute

Returns a newly created group attribute with the contents of the builder.

Possible values for mode:

GroupBuilder.BuilderBuildMode.BuildAndFlush
Specifies that the builder’s contents are cleared following a call to build(). This is the default.
GroupBuilder.BuilderBuildMode.BuildAndRetain
Specifies that the builder’s contents are retained following a call to build().

Utility Classes

class Array

An OpScript array stores an ordered list of values of the same type. Elements are stored in a contiguous block of memory, which is expanded and contracted as needed. OpScript arrays are an advanced feature, and facilitate creating or manipulating large attributes.

This interface is modelled on C++’s std::vector class, and differs from Lua’s built-in table data structure in a number of ways:

  • OpScript arrays can only store values of the same type.
  • OpScript arrays are indexed from 0, not 1.
  • Attempting to access an invalid index raises a Lua error instead of returning nil.
  • OpScript arrays have a theoretical maximum size of well above 2^32 elements; Lua tables can address only 2^27 elements. (Note that at this time DataAttribute objects are themselves limited to 2^32 elements.)
  • OpScript arrays cannot be indexed with the square bracket notation as tables can. Use myArray:get(myIndex), myArray:set(myIndex, myNewValue), not myTable[myIndex] and myTable[myIndex] = myNewValue.
-- Creates an integer array of three elements
local myIntArray = Array('int', {1, 2, 3})

-- Creates a float array of three elements
local myFloatArray = Array('float', {1, 2, 3})

-- Creates a double array of three elements
local myDoubleArray = Array('double', {1, 2, 3})

-- Creates a string array of two elements
local myStringArray = Array('string', {'hello', 'pony'})

Like Lua tables, OpScript arrays support iteration using the ipairs() function, as well as taking the size with the # operator. For example:

for i, elem in ipairs(myArray) do
  print(i, elem)
end

This is equivalent to the following numeric for loop:

for i = 0, #myArray - 1 do
  print(i, myArray:get(i))
end
Array(ctype valueType)

Creates an empty array.

Parameters:valueType – ctype (or ctype string) describing the element type
Array(ctype valueType, sequence elems)

Creates an array with a copy of elems.

Parameters:
  • valueType – ctype (or ctype string) describing the element type
  • elems – sequence of elements to initialize the array with
Array(ctype valueType, number count[, value value])

Creates an array with count copies of value.

Parameters:
  • valueType – ctype (or ctype string) describing the element type
  • count – size of the array
  • value – value to initialize the array with
size() → int

Returns the number of elements. (Note that you can also use the # operator.)

capacity() → int

Returns the number of elements that can be held in currently allocated storage.

empty() → boolean

Checks whether the container is empty.

front() → value

Returns the first element. Raises an error if the container is empty.

back() → value

Returns the last element. Raises an error if the container is empty.

data() → cdata<pointer>

Returns a LuaJIT cdata pointer to the underlying data. This is an advanced feature – be careful!

get(int pos) → value

Accesses the element at the index pos. Raise an error if pos is not a valid index.

Parameters:pos – position of the element to return
Returns:the element at the requested index
set(int pos, value value)

Assigns a value to an index pos. Raises an error if pos is not a valid index.

Parameters:
  • pos – position of the element to assign
  • value – the element to assign
clear()

Clears the contents.

shrinkToFit()

Reduces memory usage by freeing unused memory.

reserve(int newCapacity)

Reserves storage. If newCapacity is greater than the current capacity, new storage is allocated, otherwise the method does nothing.

Parameters:newCapacity – amount of storage to reserve
resize(int count[, value value])

Changes the number of elements stored. If count is greater than the current size, additional elements are initialized with copies of value.

Parameters:
  • count – count the new size of the container
  • value – the value to initialize new elements with
assign(sequence elems)

Assigns a sequence of elements – for example, a Lua table or another array – to the array.

Parameters:elems – a sequence of elements to assign to the container
assign(int count, value value)

Assigns count copies of value to the array.

Parameters:
  • count – the new size of the container
  • value – the value to initialize elements of the container with
pushBack(value value)

Appends value to the end of the array.

Parameters:value – the value of the element to append
popBack() → value

Removes the last element. Raises an error if the container is empty.

Returns:the removed element
insert(int pos, value value)

Inserts an element at index pos. Raises an error if pos is less than zero or greater than the number of elements in the container.

Parameters:
  • pos – position before which the content will be inserted
  • value – element value to insert
insert(int pos, sequence elems)

Inserts elements from sequence at index pos. Raises an error if pos is less than zero or greater than the number of elements in the container.

Parameters:
  • pos – position before which the content will be inserted
  • elems – the elements to insert
insert(int pos, int count, value value)

Inserts count copies of value at index pos. Raises an error if pos is less than zero or greater than the number of elements in the container.

Parameters:
  • pos – position before which the content will be inserted
  • count – the number of values to insert
  • value – element value to insert
erase(int pos)

Erases the element at index pos. Raise an error if pos is not a valid index.

Parameters:pos – position of the element to erase
erase(int first, int last)

Erases elements in the half-open range [first last). Raises an error this does not denote a valid half-open range.

Parameters:
  • first – position of the first element to erase
  • last – position of the first element greater than or equal to first that should be preserved
class ArrayView

A class representing a lightweight, read-only view into a typed data buffer.

ArrayView’s interface differs from Lua’s built-in table data structure in a number of ways:

  • Array view objects are indexed from 0, not 1.
  • Attempting to access an invalid index raises a Lua error instead of returning nil.
  • Array view objects cannot be indexed with the square bracket notation as tables can. Use myView:get(myIndex), not myTable[myIndex].

Like Lua tables, array view objects support iteration using the ipairs() function, as well as taking the size with the # operator. For example:

for i, elem in ipairs(myView) do
  print(i, elem)
end

This is equivalent to the following numeric for loop:

for i = 0, #myView - 1 do
  print(i, myView:get(i))
end
ArrayView(ctype valueType, cdata<pointer> data, int count[, object owner])

Creates an ArrayView. Instantiating an ArrayView directly is an advanced feature not required in typical OpScript usage.

Parameters:
  • valueType – ctype (or ctype string) describing the element type
  • data – LuaJIT cdata pointer to a data buffer
  • count – number of values in the buffer
  • owner – object who owns the data being pointed at. ArrayView will ensure this object is not garbage collected until the view object is itself garbage collected.
size() → int

Returns the number of elements. (Note that you can also use the # operator.)

empty() → boolean

Checks whether the container is empty.

front() → value

Returns the first element. Raises an error if the container is empty.

back() → value

Returns the last element. Raises an error if the container is empty.

data() → cdata<pointer>

Returns a LuaJIT cdata pointer to the underlying data. This is an advanced feature – be careful!

get(int pos) → value

Accesses the element at the specified index. Raise an error if pos is not a valid index.

Parameters:pos – position of the element to return
Returns:the element at the requested index

Utility Functions

Attribute.DelimiterEncode(string token) → string

Utility function that encodes (escapes) period (.) and slash (/) characters in token and returns the result. This is useful when adding GroupAttribute children with periods and slashes in their names. On retrieval these names can be decoded with DelimiterDecode().

Performs the following substitutions:

  • FULL STOP (0x2E) -> DEGREE SIGN (0xB0)
  • SLASH (0x2F) -> PLUS-MINUS SIGN (0xB1)
Attribute.DelimiterDecode(string token) → string

Utility function that decodes escaped period (.) and slash (/) characters in token and returns the result. This is useful when retrieving GroupAttribute children whose names were previously encoded via DelimiterEncode().

Performs the following substitutions:

  • DEGREE SIGN (0xB0) -> FULL STOP (0x2E)
  • PLUS-MINUS SIGN (0xB1) -> SLASH (0x2F)
Attribute.GetTotalSize() → int

Returns the total memory currently allocated by the FnAttribute library.

Attribute.GetIntValue(object obj, number defaultValue) → int

If obj is an IntAttribute, this function returns its first value. Otherwise it returns defaultValue.

Attribute.GetFloatValue(object obj, float defaultValue) → float

If obj is a FloatAttribute, this function returns its first value. Otherwise it returns defaultValue.

Attribute.GetDoubleValue(object obj, float defaultValue) → float

If obj is a DoubleAttribute, this function returns its first value. Otherwise it returns defaultValue.

Attribute.GetStringValue(object obj, string defaultValue) → string

If obj is a StringAttribute, this function returns its first value. Otherwise it returns defaultValue.

Attribute.IsAttribute(object obj) → boolean

Returns true if obj is an Attribute, false otherwise.

Attribute.IsNull(object obj) → boolean

Returns true if obj is an NullAttribute, false otherwise.

Attribute.IsInt(object obj) → boolean

Returns true if obj is an IntAttribute, false otherwise.

Attribute.IsFloat(object obj) → boolean

Returns true if obj is an FloatAttribute, false otherwise.

Attribute.IsDouble(object obj) → boolean

Returns true if obj is an DoubleAttribute, false otherwise.

Attribute.IsString(object obj) → boolean

Returns true if obj is an StringAttribute, false otherwise.

Attribute.IsGroup(object obj) → boolean

Returns true if obj is an GroupAttribute, false otherwise.