This utility library asset provides the programmer with the ability to detect changes in a set of variables by assigning them the DeltaAttribute.
This utility library asset provides the programmer with the ability to detect changes in a set of variables by assigning them the DeltaAttribute. Using the asset’s DeltaDetector class, the programmer can then initiate a check for, any changed values, with a single line of code. “Changed” means a different (not Equal) value or reference has been assigned to the variable, as compared to the internally/transparently cashed variable, that is stored in the attribute. The DeltaDetector also provides a single call method to “reset” all change detection, by setting all those cashed values, to current values. While the basic functionality is pretty simple, there are several configuration options for each attribute, which is where most of the complexity comes from. The most notable feature is the ability to specify a different class to be used for the copied data (obviously, certain cast/compare requirements apply). Also worth noting, is the ability to “drill down” a single level, and assign the attribute to a member of the member. An important option, is the ability to turn detection on or off, for any specific attribute, at runtime. If detection is off, comparisons will not be performed, allowing for faster processing.
The DeltaDetector class also has the ability to present (serialize) the attributes assigned to a class as two sets of strings: a full list of all attributes contained in the class, and a sub-set list of only the attributes that have change detection enabled. I have created a property drawer for the DeltaDetector class, that uses these two lists to provide the end-user with a generic looking MASK control. This allows the end-user to see/specify which DeltaAttributes should be enabled, in the editor.
Accessors (get/set) can provide a similar, but not identical, feature; by allowing you to easily set a “changed” flag whenever a value is set. However this ALWAYS sets the changed value, even if the new value assigned is the same. Certainly a check can be done, in the accessor, to compare the two values, but it is more efficient to do this only when needed, rather than every-time the variable is assigned a value. Ideally, the single comparison-on-need would only be performed if a new value has been assigned since the last check. Unfortunately, this ideal optimization is NOT built into the DeltaDetector. However, by manually enabling and disabling DeltaAttributes a programmer could implement this fairly easily with accessors.
The DeltaAttribute class, can be assigned to any member variable (or accessor) of your class. To make using the attributes easy, the DeltaDetector class is provided, which is added as a member of your class. The DeltaDetector member can generate an internal list of all the attributes in your class during initialization, and then, on command, check them all for changes. Together they allow automatic detection of changes to be specified for each member variable in your class, easily, and in one place. Internally, this is done by storing a copy of the member variable, in the DeltaAttribute itself. The DeltaDetector class, compares the member’s data against, or assign the member’s data to, the copy stored in the attribute. It does this for every member detected during initialization.
The DeltaDetector class also has the ability to present (serialize) the attributes assigned to a class as two sets of strings: a full list of all attributes contained in the class, and a sub-set list of only the attributes that have change detection enabled. I have created a property drawer for the DeltaDetector class, that serializes, and deserializes these two lists to provide the end-user with a generic looking MASK control.
Also included are three variants of an abstract class derived from the Monobehavior class. These classes demonstrate how to initialize, and use the DeltaDetector class to detect changes during a MonoBehavior’s Update() function. You can use this class as a template for coding your own classes, or simply inherit from it when you want to add change detection features to a MonoBehavior derived class.
Classes | |
class | DeltaAttribute |
This attribute may be applied to FIELDS and PROPERTIES only (Called "variables", for brevity, below.) At it's core, it does little more than store a copy of the attributed variable's value, for later comparison. It provides the programmer with the ability to check that comparison via hasChanged() The values is re-copied and stored by calling resetChangeValue Thats the important stuff, though there are a few more detailed options, like how to store classes that the programmer cannot simply make a copy of (StoreAsType), and a name for use in inspector GUIs. Details within. WARNING: the use of this attribute has the potential to significantly impact performance; use with caution. | |