Snapshot Dependency

Types of dependencies

Snapshots control versioning in TACTIC. When processing a checkin, TACTIC creates a snapshot that contains an XML description of what was checked in. Snapshots can also be dependent on any number of other snapshots (through a "ref" tag). Taking advantage of this dependency relationship, you can create complex dependency trees for complex scenes, with the option of undoing them if required.

There are two types of dependencies:

  • hierarchical: The given snapshot contains the referenced snapshot

  • input: The given snapshot used or was created from a referenced snapshot (but does not contain the contents of that snapshot)

Connecting snapshots

Dependencies are connected using the add_dependency_by_code() method, which takes an existing snapshot and adds the appropriate reference tag to it.

The following example shows how to connect two snapshots:

search_type = "prod/asset"
code = "chr001"
search_key = server.build_search_key(search_type, code)

# checkin a model
model_snapshot = server.simple_checkin(search_key, model_path, context="model")
model_snapshot_code = model_snapshot.get('code')

# checkin a rig
rig_snapshot = server.simple_checkin(search_key, rig_path, context="rig")
rig_snapshot_code = rig_snapshot.get('code')

# add the model dependency to the rig
snapshot = server.add_dependency_by_code(rig_snapshot_code, model_snapshot_code)
print snapshot.get('snapshot')

Executing the above example would output:

  <file name="" file_code="123BAR" type='main'/>
  <ref context='model' version='3' search_type='prod/asset?project=sample3d' search_id='4'/>

The ref tag is the reference to another checkin. In this case, the reference can be interpreted as being contained in the snapshot (that is, this is a hierarchical dependency).

Sometimes, it is not possible to store or retrieve version information for an SObject within a session if a particular application provides only the filename. It is generally assumed that a filename is unique for each search_type in each project (this is not strictly enforced, but should be as best practice), so it is possible to reverse-map a filename to a snapshot. In this case, you can try to add a dependency using the add_dependency() method:

file_path = extract_dependent_path()
snapshot = server.add_dependency(snapshot_code, file_path)

This method will attempt to link the filename with the appropriate snapshot.

Input references

As opposed to the previous example of hierarchical references, there is a second type of dependency called an input reference. Input references are dependencies where a particular snapshot was used to produce another snapshot, but the resulting snapshot does not contain the contents of the originating snapshot. As an example, a Photoshop file may be used to generate a texture map, but the texture map does not need to contain the Photoshop file.

Adding an input reference is simply a matter of setting the "type" argument to "input_ref":

source_path = "./test/texture.psd"
image_path = "./test/texture.tif"

# check in the photoshop file
source_snapshot = server.simple_checkin( search_key, context="source", file_path=source_path )
source_snapshot_code = source_snapshot.get('code')
source_repo_path = server.get_path_from_snapshot( source_snapshot_code )

# checkin the image
image_snapshot = server.simple_checkin( search_key, context="image", file_path=image_path )

# add an input dependency
image_snapshot_code = image_snapshot.get('code')
image_snapshot = server.add_dependency( image_snapshot_code, source_repo_path, type="input_ref")
print snapshot.get('snapshot')

The above code would produce output like the following:

  <file name="texture_image_v001.tif" file_code="123BAR" type='main'/>
  <ref context='source' version='3' search_type='prod/asset?project=sample3d' search_id='4' type="input_ref"/>

By managing dependencies at the time of each checkin, it is possible to build up a dependency tree. Thus each version of every checkin has its own independent dependency tree.