<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def track_change(self, tile, property_name, value, formatter=None):
 """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`. """


        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)