code: def track_change(self, tile, property_name, value, formatter=None):
          
  
          if not self.tracking:
              return
  
          if len(self._whitelist) > 0 and (tile, property_name) not in self._whitelist:
              return
  
          if formatter is None:
              formatter = str
  
          change = StateChange(monotonic(), tile, property_name, value, formatter(value))
  
          with self._lock:
              self.changes.append(change)
docs: Record that a change happened on a given tile's property.
  
          This will as a StateChange object to our list of changes if we
          are recording changes, otherwise, it will drop the change.
  
          Args:
              tile (int): The address of the tile that the change happened on.
              property_name (str): The name of the property that changed.
              value (object): The new value assigned to the property.
              formatter (callable): Optional function to convert value to a
                  string.  This function will only be called if track_changes()
                  is enabled and `name` is on the whitelist for properties that
                  should be tracked.  If `formatter` is not passed or is None,
                  it will default to `str`.