Chunkifying Details
When a Bundle is 'Chunkified' by the Layout/Chunking system the Bundle creates a cache of data in each TileBundle for rapid loading or re-loading of tiles using the TileChangeData
and Tilemap.SetTiles(TileChangeData[] tileChangeDataArray, bool ignoreLockFlags)
.
When the layout system wants to fetch a chunk of tiles to load in this fashion it uses the Bundle's `GetCachedTcd(RectInt locator, out TileChangeData[]? tcd)' method.
For Unity tiles the cached data are directly copied into the output array. The array itself is an instance field of the Bundle.
For TPT tiles, these are new, fresh, clones of the archived, Locked, TPT tile assets which are sub-objects of the Bundle asset.
What this means is that every time that the chunk of tile data are retrieved in this fashion new, fresh TPT tile instances are created. Immediately after SetTiles
is used the instance array is cleared.
Why do this??
Since each TPT tile is an independent instance, once it's loaded to a Tilemap its internal state may change during the time it's actually in the Tilemap; i.e., until it's unloaded. Hence, we really don't want to re-used these modified tiles once they're unloaded.
If these were unloaded and re-loaded later then the modified fields will still be modified, which can cause all sort of bizarre errors that would be hard to troubleshoot. Obviously you'd like an unmodified clone of the corresponding locked tile in the Bundle asset.
The end result here is that the TPT instance which gets loaded to the Tilemap has no references anywhere else. That way, when the tile is eventually unloaded it becomes garbage collected properly rather than be a potential memory leak.
You Need to be Vigilant!
This can be affected by your own code. If you cache a TPT tile reference, it won't be garbage collected and it may not even be actually placed on a Tilemap anywhere when you try to access its fields and properties, some of which may be unexpectedly null.
One approach to follow is to use Unity's pools to re-use Lists of TilePlusBase when you need to provide a list to one of the TpLib query methods. When creating such a 'ListPool' you should ensure that the Release callback clears the list. Get used to the idea of wrapping these methods with using
statements to ensure that the lists are returned to the pool.
This type of code block is peppered throughout TilePlus and TilePlusPainter. Examples of pools can be found in the TpLib source.