public void Execute()
        {
            Block block = (Block)BlockPointer.Target;

            // unsettle chunks
            for (int i = 0; i < ChunksToUnsettle.Length; i++)
            {
                block.Chunks[ChunksToUnsettle[i]].Unsettle();
            }

            ChunksToUnsettle.Clear();

            // add just settled voxels to components
            FluidComponentManager componentManager = (FluidComponentManager)ComponentManagerPointer.Target;

            lock (componentManager.hashSetLock)
            {
                for (int i = 0; i < VoxelsToProcess.Length; i++)
                {
                    componentManager.VoxelsToProcess.Add(VoxelsToProcess[i]);
                }
            }

            VoxelsToProcess.Clear();

            // prepare for the next iteration
            FluidBlockSimData simData = block.SimData;

            simData.SwapArrays();
        }
        /// <summary>
        /// Initialize array of voxels and chunks.
        /// </summary>
        public void Initialize(int id, Transform parent, WorldApi worldApi, VectorI3 coords)
        {
            Id = id;
            transform.parent = parent;
            Coords           = coords;

            worldApi.GetBlockWorldPos(id, out Vector3 worldPos);
            WorldPos = worldPos;

            Chunks  = new Chunk[WorldGridInfo.kTotalChunksInBlock];
            _voxels = new NativeArray <Voxel>(WorldGridInfo.kTotalVoxelsInBlock, Unity.Collections.Allocator.Persistent);

            SimData            = new FluidBlockSimData(this);
            SimData.ReadVoxels = _voxels;

            for (int chunkX = 0; chunkX < WorldGridInfo.kChunksPerBlock; chunkX++)
            {
                for (int chunkY = 0; chunkY < WorldGridInfo.kChunksPerBlock; chunkY++)
                {
                    for (int chunkZ = 0; chunkZ < WorldGridInfo.kChunksPerBlock; chunkZ++)
                    {
                        int chunkId = chunkX * WorldGridInfo.kChunksPerBlock * WorldGridInfo.kChunksPerBlock + chunkY * WorldGridInfo.kChunksPerBlock + chunkZ;

                        Chunk chunk = new GameObject($"Chunk ({chunkX}, {chunkY}, {chunkZ})").AddComponent <Chunk>();
                        Chunks[chunkId] = chunk;

                        chunk.Initialize(chunkId, transform, worldApi, this);

                        for (int voxelX = 0; voxelX < WorldGridInfo.kVoxelsPerChunk; voxelX++)
                        {
                            for (int voxelY = 0; voxelY < WorldGridInfo.kVoxelsPerChunk; voxelY++)
                            {
                                for (int voxelZ = 0; voxelZ < WorldGridInfo.kVoxelsPerChunk; voxelZ++)
                                {
                                    int voxelId = voxelX * WorldGridInfo.kVoxelsPerChunk * WorldGridInfo.kVoxelsPerChunk + voxelY * WorldGridInfo.kVoxelsPerChunk + voxelZ;

                                    _voxels.GetWritable(chunkId, voxelId).Valid = true;
                                }
                            }
                        }
                    }
                }
            }
        }