Class DynamicVirtualValue

(Abstract) A container a base value and many VirtualValues which are "stacked" together.

A DynamicVirtualValue (or DVV for short) is a VirtualValue which can also have child VirtualValues added to it. Like a plain VirtualValue, a DVV still contains a value, which is called the base value (retrieved using getBase), in addition to its children.

When you get the value of a DVV, you get the stacked value instead of the base value. This is calculated from the base value and values of the children using the stack method. The calculation is as follows:

 stacked_value = base_value + value1 + value2 + ... + valueN

Where valueN indicates the value gotten from each child, and + represents the operation defined by the stack method. The operations are completed left-to-right. This is an O(n) calculation.

Children and Nesting

  • Any VirtualValue can be added as a child, including other DVVs. During a stacked value calculation a DVV calls get on its children. For child DVVs, this returns their stacked value (not their base value).
  • A VirtualValue can also be added as a child to multiple DVVs. In other words, a VirtaulValue may have any number of parents.
  • Beware of disasterous non-halting infinite loops when two DVVs are decendants of each other.

Caching and "Dirtiness"

When the stacked value is calculated, it is cached so that future calls skip recalculation (providing a runtime of O(1)). However, if the DVV's base value changes or if a child is added/removed/changed, then the DVV is considered dirty. The next time the value is gotten, it will be recalculated. Furthermore, a DVV is also dirtied whenever a child DVV is dirtied.

Runtime Bewares

Understanding when the DVV is dirtied is important, as this can affect runtime. To avoid excessive recalculations, you should adjust a DVV's base value and children before you get, listen or bind, as these methods recalculate the stacked value; in the case of listen and bind, these recalculate also when DVV is dirtied). If you're making a lot of modifications to the base value or child values, disconnect the connections these functions return temporarily. When you are done making changes, re-listen or re-bind.

local dvnv = DynamicVirtualNumberValue.new("Add", 0)
local conn = dvnv:listen(myFunction)
-- At this point, when any dirty-ing change is made,
-- the value is recalculated (an O(n) operation)
-- To stop this, disconnect and forget about the old connection:
conn:disconnect()
conn = nil
-- Now, we can make changes without causing recalculations:
dvnv:set(8)
dvnv:addChild(VirtualNumberValue.new(5))
dvnv:removeChild(someOtherChild)
-- Re-listen once finished; this recalculates then calls myFunction:
conn = dvnv:listen(myFunction) --> calls myFunction(13)

Implementations:

See also:

Events

DynamicVirtualValue.onChildAdded Fires when a VirtualValue is added as a child
DynamicVirtualValue.onChildRemoved Fires when a child is removed
DynamicVirtualValue.onDirtied Fires when the base value is changed or any child is changed/dirtied, indicating the value must be recaluclated the next time it is gotten.

Functions

DynamicVirtualValue.new(expectedType) Constructs a new DynamicVirtualValue which contains a certain expectedType

Metamethods

DynamicVirtualValue:__tostring() Returns the current value passed to tostring, followed by a comma-separated list of the child values passed to tostring.

Methods

DynamicVirtualValue:stack(_lhs, _rhs) (Abstract) Defines how two values are "stacked" together, usually through some operation.
DynamicVirtualValue:isDirty() Returns whether this value is dirty and will be recalculated the next time it is gotten
DynamicVirtualValue:getChildren() Returns an array (numerically-indexed table) of the children.
DynamicVirtualValue:children() Returns an iterator function which returns each index-child pair
DynamicVirtualValue:isChild(child) Returns whether the given object is a child
DynamicVirtualValue:addChild(child) Adds the given VirtualValue as a child.
DynamicVirtualValue:newChild(...) Constructs a new child with the given parameters using the implementation's associated VirtualValue implementation, then adds it.
DynamicVirtualValue:newChildren(values) Constructs multiple new children with the table of single parameters.
DynamicVirtualValue:addChildren(children) Adds a table of children
DynamicVirtualValue:getChildIndex(child) Returns the index of the given child
DynamicVirtualValue:removeChildAtIndex(idx) Removes the child at the given index.
DynamicVirtualValue:removeChild(child) Removes the child similar to how removeChildAtIndex does
DynamicVirtualValue:removeAllChildren() Removes all children
DynamicVirtualValue:getBase() Returns the base value, which is the raw value stored by this DynamicVirtualValue.
DynamicVirtualValue:set(newValue) Sets the new base value
DynamicVirtualValue:get() Gets the stacked value, recalculating it if dirty
DynamicVirtualValue:listen(func) Calls func immediately with the stacked value, then again every time this value is dirtied.
DynamicVirtualValue:bind(object, property) Sets object[property] to the stacked value, then again every time this value is dirtied.


Events

DynamicVirtualValue.onChildAdded
Fires when a VirtualValue is added as a child
DynamicVirtualValue.onChildRemoved
Fires when a child is removed
DynamicVirtualValue.onDirtied
Fires when the base value is changed or any child is changed/dirtied, indicating the value must be recaluclated the next time it is gotten.

Functions

Methods
DynamicVirtualValue.new(expectedType)
Constructs a new DynamicVirtualValue which contains a certain expectedType

Parameters:

  • expectedType string expected type (or table of expected types) to be contained

Metamethods

DynamicVirtualValue:__tostring()
Returns the current value passed to tostring, followed by a comma-separated list of the child values passed to tostring.

Returns:

    string

Methods

DynamicVirtualValue:stack(_lhs, _rhs)
(Abstract) Defines how two values are "stacked" together, usually through some operation.

Parameters:

  • _lhs The left-hand side of the operation
  • _rhs The right-hand side of the operation
DynamicVirtualValue:isDirty()
Returns whether this value is dirty and will be recalculated the next time it is gotten

Returns:

    boolean Whether this value is dirty
DynamicVirtualValue:getChildren()
Returns an array (numerically-indexed table) of the children.
DynamicVirtualValue:children()
Returns an iterator function which returns each index-child pair

Usage:

    for i, child in dvv:children() do ... end
DynamicVirtualValue:isChild(child)
Returns whether the given object is a child

Parameters:

  • child The object to query

Returns:

    boolean
DynamicVirtualValue:addChild(child)
Adds the given VirtualValue as a child. Dirties the DVV and fires onChildAdded. When this child is changed or dirtied (for child DVVs), this DVV is dirtied.

Parameters:

Returns:

    number The child's index
DynamicVirtualValue:newChild(...)
Constructs a new child with the given parameters using the implementation's associated VirtualValue implementation, then adds it. For example, DynamicVirtualNumberValue:newChild constructs a VirtualNumberValue). The child will be cleaned up when this value is cleaned up.

Parameters:

  • ... The arguments to pass to the VirtualValue constructor

Returns:

    The newly-constructed child

Usage:

    local dvnv = DynamicVirtualNumberValue.new("Add", 3)
    dvnv:newChild(5)
DynamicVirtualValue:newChildren(values)
Constructs multiple new children with the table of single parameters.

Parameters:

  • values

Returns:

    A table of all the newly-constructed children
DynamicVirtualValue:addChildren(children)
Adds a table of children

Parameters:

  • children table The children to add
DynamicVirtualValue:getChildIndex(child)
Returns the index of the given child

Parameters:

  • child

Returns:

    number The index of the child
DynamicVirtualValue:removeChildAtIndex(idx)
Removes the child at the given index. Dirties the DVV and fires onChildRemoved

Parameters:

  • idx number The index of the child to remove
DynamicVirtualValue:removeChild(child)
Removes the child similar to how removeChildAtIndex does

Parameters:

  • child
DynamicVirtualValue:removeAllChildren()
Removes all children
DynamicVirtualValue:getBase()
Returns the base value, which is the raw value stored by this DynamicVirtualValue.

See also:

DynamicVirtualValue:set(newValue)
Sets the new base value

Parameters:

  • newValue The new base value
DynamicVirtualValue:get()
Gets the stacked value, recalculating it if dirty

Returns:

    The calculated stack value
DynamicVirtualValue:listen(func)
Calls func immediately with the stacked value, then again every time this value is dirtied. As this function must get the current value each time it is dirtied, it will cause continual recalculations. This can negatively affect runtimes if you are making lots of changes while the connection is active. Therefore, it's recommended you disconnect if you're excessively dirtying the value so you don't cause needless recalculations.

Parameters:

  • func function The listener function

Returns:

    Connection When disconnected, stops func from being called when the value changes

See also:

DynamicVirtualValue:bind(object, property)
Sets object[property] to the stacked value, then again every time this value is dirtied. As this function must get the current value each time it is dirtied, it will cause continual recalculations. This can negatively affect runtimes if you are making lots of changes while the connection is active. Therefore, it's recommended you disconnect if you're excessively dirtying the value so you don't cause needless recalculations.

Parameters:

  • object A table, userdata, etc which can accept [property] = ...
  • property string The index on object to set

Returns:

    Connection When disconnected, stops func from being called when the DVV is dirtied

See also:

generated by LDoc 1.4.6 Last updated 2021-01-21 07:22:00