|
| 1 | +# Guidelines |
| 2 | + |
| 3 | +This document covers general best-practices when authoring Traits and/or |
| 4 | +Specifications for inclusion in the library. |
| 5 | + |
| 6 | +## Traits |
| 7 | + |
| 8 | +Traits define unique qualities or characteristics of an Entity or |
| 9 | +Relationship. |
| 10 | + |
| 11 | +- Traits must be atomic. No single trait should ever change the |
| 12 | + meaning of another trait _or its properties_. This ensures that future |
| 13 | + traits not known at the time code is written can't change the meaning |
| 14 | + of previously defined values. |
| 15 | + |
| 16 | +- Traits should contain the minimum number of properties required to |
| 17 | + define a particular characteristic. They must document in their |
| 18 | + description if properties are optional. Non-optional properties are |
| 19 | + required to be populated by a host during publishing, and during |
| 20 | + resolve by a supporting manager. |
| 21 | + |
| 22 | +- In order to facilitate identification, traits must define a single |
| 23 | + characteristic. Consider splitting 'optional' properties into a |
| 24 | + separate trait. For example the bounding box of a 3D object would be |
| 25 | + best expressed through the `BoundingBox` trait, rather than an |
| 26 | + optional `boundingBox` property of the `Spatial` trait. |
| 27 | + |
| 28 | +- Traits should _not_ use properties to differentiate between different |
| 29 | + exhibited characteristics. Individual traits should be created for |
| 30 | + each one. Properties are then used to describe specific details of |
| 31 | + that quality. For example, instead of an `Animated` trait with a |
| 32 | + boolean `isAnimated` property, we have `Static` and `FrameRanged` |
| 33 | + traits. This ensures the _set of trait ids_ is sufficient to identify |
| 34 | + the qualities of an entity, and that the properties of these traits |
| 35 | + are then appropriate to each. Illustrated by the `startFrame` and |
| 36 | + `endFrame` of the `FrameRanged` trait - a future `TimeRanged` trait |
| 37 | + would naturally require different parameterisation. |
| 38 | + |
| 39 | +- Effort should me made to ensure a minimal overlap between trait names. |
| 40 | + The namespace and package name can be leveraged in order to reduce |
| 41 | + ambiguity if necessary, avoiding the need to be truly unique within |
| 42 | + the ecosystem in all cases. |
| 43 | + |
| 44 | +- Trait property names should describe the nature of the value as |
| 45 | + precisely as possible. They shouldn't require the user to consult the |
| 46 | + documentation. For example: |
| 47 | + - Good: `framesPerSecond`, `metersPerLinearUnit` |
| 48 | + - Bad: `frameRate`, `units` |
| 49 | + |
| 50 | +- "Family" traits can be defined where applicable to allow high-level |
| 51 | + partitioning of entity space. For example the `Image` and `Spatial` |
| 52 | + traits exist solely to allow users to broadly filter 2D and 3D |
| 53 | + entities without needing multiple top-level trait sets. Care should be |
| 54 | + taken when defining properties for these traits, to ensure they are |
| 55 | + genuinely applicable to all entities with the quality in question. Eg. |
| 56 | + `Spatial` does not include a bounding box as there are many unbounded |
| 57 | + or zero-volume concepts in the 3D world, this should be expressed |
| 58 | + through a peer trait in the `threeDimensional` namespace that can be |
| 59 | + composed as needed. |
| 60 | + |
| 61 | +- The absence of a trait _does not_ imply its inverse, and so companion |
| 62 | + traits may be needed to define antonyms or other mutually exclusive |
| 63 | + qualities |
| 64 | + |
| 65 | +## Specifications |
| 66 | + |
| 67 | +Specifications define well-known collections of traits that map to |
| 68 | +first-class concepts within our workflows. They are used to create a |
| 69 | +common definition of the nature of entities ("assets") and relationships |
| 70 | +between them. The collection of traits is known formally within the |
| 71 | +OpenAssetIO ecosystem as a "trait set". |
| 72 | + |
| 73 | +- Specifications must contain the minimum number of traits required to |
| 74 | + define a particular concrete workflow entity. Trait sets are |
| 75 | + [additive](https://openassetio.github.io/OpenAssetIO/entities_traits_and_specifications.html#Specifications), |
| 76 | + and so each trait stipulates that the entity _must_ possess that |
| 77 | + quality, _in addition to_ the qualities of all the other traits in the |
| 78 | + set. There is no way to define a specification that states "one trait |
| 79 | + or the other". |
| 80 | + |
| 81 | +- Effort should me made to ensure a minimal overlap between |
| 82 | + specification names. The namespace and package name can be leveraged |
| 83 | + in order to reduce ambiguity if necessary, avoiding the need to be |
| 84 | + truly unique within the ecosystem in all cases. |
| 85 | + |
| 86 | +- Specifications that define a relationship should append `Relationship` |
| 87 | + to their names to help with cognition. |
| 88 | + |
| 89 | +- "Family" specifications can be defined to allow high-level |
| 90 | + partitioning of entity space. For example the `Image` and `Spatial` |
| 91 | + specifications exist solely to allow users to broadly filter 2D and 3D |
| 92 | + entities without needing multiple top-level specifications. Care should be |
| 93 | + taken to ensure that their trait sets are not overly constrained to |
| 94 | + preclude future evolution. These specifications do not include the |
| 95 | + `LocatableContent` trait to ensure we can support inline Image or |
| 96 | + Spatial data (eg. a procedural checkerboard pattern), even though at |
| 97 | + the time of going to press, known workflows only used independent |
| 98 | + resource data. |
| 99 | + |
| 100 | +- Specifications should form well-known base trait sets. They do not |
| 101 | + necessarily need to be exhaustively defined for all specialisations. |
| 102 | + Taking images as an example, we define bases for core variations of |
| 103 | + how they are encoded in our problem space (`PlanarBitmapImage`, |
| 104 | + `DeepBitmapImage`, etc). We do not define an exhaustive set of |
| 105 | + additional specifications for the matrix of images that are some |
| 106 | + combination of `Static`, `FrameRanged`, `OCIOColorManaged`. Users are |
| 107 | + encouraged to compose or resolve other meaningful traits with the |
| 108 | + well-known specifications as appropriate. Formally defining these |
| 109 | + "well-known combinations" in a non-limiting way is something to be |
| 110 | + investigated. |
| 111 | + |
| 112 | +- All specifications must contain a single trait from the `usage` |
| 113 | + namespace to define their meaning when encountered at runtime. |
| 114 | + |
| 115 | +- Care should be taken when composing traits to ensure |
| 116 | + that there is a specific trait present that defines each required |
| 117 | + quality, rather than relying on the omission of a contrary quality. |
| 118 | + The absence of a trait within a specification's trait set only means the |
| 119 | + set does not specify whether it exhibits that quality or not. This |
| 120 | + allows trait sets to be used as filter predicates: |
| 121 | + - `{ Entity, Image }`: All images (static, animated or any other). |
| 122 | + - `{ Entity, Image, Static }`: Only static images without animation. |
| 123 | + - `{ Entity, Image, FrameRanged }`: Only animated images that cover a |
| 124 | + discrete series of frames. |
| 125 | + |
| 126 | +- Hosts and managers are encouraged to _extend_ well-known |
| 127 | + specifications with their own proprietary traits to sufficiently to |
| 128 | + differentiate from other entities. A common pattern for |
| 129 | + application-specific "documents" is to define a trait named after the |
| 130 | + application (eg.`Blender`) and compose this with existing Media |
| 131 | + Creation `Workfile` specification. This facilitates more generic |
| 132 | + handling via the well-known trait set, but achieve suitable filtering |
| 133 | + if needed when only the app-specific variant is required. |
| 134 | + |
| 135 | +- **Hosts and managers are _strongly discouraged_ from only using |
| 136 | + proprietary traits in their specifications as it defeats |
| 137 | + interoperability.** Using custom traits require explicit support in |
| 138 | + every host _and_ manager, which limits compatibility between systems. |
0 commit comments