Dependency Class

From Derivative
Jump to navigation Jump to search

A Dependency object is a value that automatically causes any expression referencing it to update when the dependency value has changed. These objects eliminate the need to manually force cook operators referencing values in Extensions or Storage for example. For information about dependencies in mutable objects (lists, dicts, sets), see Deeply Dependable Collections


Members[edit]

valvalue :

The value associated with this object. Referencing this value in an expression will cause the operator to become dependent on its value. Setting this value will cause those operators to be recooked as necessary.

peekValvalue (Read Only):

This returns the same value as .val but does not create a dependency on the value.

opslist (Read Only):

A list of operators currently dependent on the object.

listAttributeslist (Read Only):

A list of list attributes currently dependent on the object.

Methods[edit]

modified()None:

This call is needed when changing not the value itself, but a subcomponent. For example, if Dependency.val is a dictionary, setting any of the members will not notify the dependent operators. A call to modified is necessary.

Usage[edit]

Consider the following module, used as an extension in a component called comp1 for example

class MyClass:
	def __init__(self):
		self.Scale = 5

Any expressions that reference Scale will not update when Scale is manually changed. For example, if either of these expressions was in the value field of a Constant CHOP, it would not be updated if the Scale value was updated.

Example:

# using a non-promoted extension
op('comp1').ext.MyClass.Scale

# using a promoted extension
op('comp1').Scale

If you need your references to dynamically update, you can create a Dependency. Start by defining a tdu.Dependency as below:

class MyClass:
	def __init__(self):
		self.Scale = tdu.Dependency(5)

Now there is a cook dependency created between the Scale value, and the Operator referencing it. There are two ways to reference the value. The first is similar to how we were referencing the value previous:

# using a non-promoted extension
op('comp1').ext.MyClass.Scale

# using a promoted extension
op('comp1').Scale

and the other method is to explicitly call the Scale's val:

# use for non-promoted extension
op('comp1').ext.MyClass.Scale.val

# use for a promoted extension
op('comp1').Scale.val

Note the .val is often not required, as the Dependency object will cast itself to its underlying value in most cases.

To update this value, you must reference the member's val. A Dependency value is a type in and of itself and writing the expression below would actually overwrite the Dependency value with a regular interger and remove the cook dependency from the references:

# wrong way to update dependency of a promoted extension
op('comp1').Scale = 5

What you should do instead is assign the value to the val of the Dependency as below:

# correct way to update dependency of a promoted extension
op('comp1').Scale.val = 5

Using this method will update the value of Scale while keeping the Dependency intact.

Dictionaries, lists, sets, and other objects with changing contents are called "mutable" objects. If the contents of a mutable object changes, a dependency wrapping it does not automatically register as being modified! You must either use a deeply dependable collection or call the .modified() function manually as in the example below:

op('comp1').Scale.val = [1,2,3]
op('comp1').Scale.val[1] = 15 # changing the contents doesn't update dependency!
op('comp1').Scale.modified() # this call notifies TouchDesigner that the value has changed

TouchDesigner Build: