public override void GenerateLandscape(Chunk chunk, BlockOffset blockOffset)
        {
            Vector3 coord = chunk.GetAbsPosition(blockOffset);

            float height = _landScapeHeight - _noiseLandscape.GetSimplexFractal(coord.X, coord.Z) * (_heightGain.GetSimplexFractal(coord.X, coord.Z) * 50);

            IBlock block = new BlockAir();

            if (coord.Y <= height)
            {
                block = new BlockGrass();
            }

            if ((coord.Y <= height - 1) && (coord.Y > height - 5))
            {
                block = new BlockDirt();
            }

            if (coord.Y <= height - 5)
            {
                block = new BlockStone();
            }

            chunk.SetBlock(blockOffset, block);
        }
Beispiel #2
0
        public BlockOffset[] Remove(int count)
        {
            var offsets = this.ToArray();
            if (offsets.Length < count)
            {
                throw new ArgumentOutOfRangeException("count",count,"Not enough offsets in the block to satisfy the remove request.");
            }

            // Move offsets to result, setting them to 0 in the offset-array
            var result = new BlockOffset[count];
            for (var i = 0; i < result.Length; i++)
            {
                var revIdx = offsets.Length - 1 - i;
                result[i] = offsets[revIdx];
                offsets[revIdx] = (BlockOffset) 0;
            }

            // Write back the modified offsets
            ReplaceOffsets(offsets);

            // Also update the free block count
            TotalFreeBlockCount -= count;

            return result;
        }
Beispiel #3
0
        public unsafe void ReplaceOffsets(BlockOffset[] offsets)
        {
            if (offsets == null)
                throw new ArgumentNullException("offsets");

            if (offsets.Length > ListCapacity)
            {
                throw new ArgumentOutOfRangeException("offsets",offsets.Length,"Not all block offsets fit into this block.");
            }

            // Replace all offsets in the block with the supplied offsets,
            // padding with 0 if the array is too short.
            //

            var ptr = ((uint*) ThisPointer)+MetaDataPrefixUInt32Count;

            for (var i = 0; i < ListCapacity; i++)
            {
                if (i < offsets.Length)
                {
                    ptr[i] = offsets[i].Offset;
                }
                else
                {
                    ptr[i] = 0u;
                }
            }

            OnBlockChanged();
        }
Beispiel #4
0
        public RowBlockBuilder <TPointer> SetField(int index, IBlockBuilder block)
        {
            BlockOffset field = Table.Layout.GetField(index);

            using (MemoryStream stream = new MemoryStream(_data, (int)field.Start, (int)field.Length, true, false))
                block.WriteTo(stream);

            return(this);
        }
Beispiel #5
0
 public void SetBlock(BlockOffset blockOffset, IBlock block)
 {
     if (blockOffset.X >= 0 && blockOffset.X < SizeX &&
         blockOffset.Y >= 0 && blockOffset.Y < SizeY &&
         blockOffset.Z >= 0 && blockOffset.Z < SizeZ)
     {
         _blocks[blockOffset.X, blockOffset.Y, blockOffset.Z] = block;
         _needRebuild = true;
     }
 }
        public override void GenerateWater(Chunk chunk, BlockOffset blockOffset)
        {
            Vector3 coord = chunk.GetAbsPosition(blockOffset);

            IBlock block = chunk.GetBlock(blockOffset);

            if (block is BlockAir && coord.Y == 79995)
            {
                chunk.SetBlock(blockOffset, new BlockWater());
            }
        }
        public override void GenerateCave(Chunk chunk, BlockOffset blockOffset)
        {
            Vector3 coord = chunk.GetAbsPosition(blockOffset);

            float n = _noiseCave.GetPerlin(coord.X, coord.Y, coord.Z);

            if (n < _shearCaveMax && n > _shearCaveMin)
            {
                chunk.SetBlock(blockOffset, new BlockAir());
            }
        }
Beispiel #8
0
        public IBlock GetBlock(BlockOffset blockOffset)
        {
            if (blockOffset.X >= 0 && blockOffset.X < SizeX &&
                blockOffset.Y >= 0 && blockOffset.Y < SizeY &&
                blockOffset.Z >= 0 && blockOffset.Z < SizeZ)
            {
                return(_blocks[blockOffset.X, blockOffset.Y, blockOffset.Z]);
            }

            return(new BlockAir());
        }
Beispiel #9
0
        public void Append(BlockOffset[] freeBlockOffsets)
        {
            if (freeBlockOffsets == null)
                throw new ArgumentNullException("freeBlockOffsets");

            ThrowIfDeallocated();
            if (_offsets.Count + freeBlockOffsets.Length > ListCapacity)
            {
                throw new ArgumentOutOfRangeException("freeBlockOffsets", "Not enough free space in offset list.");
            }
            _offsets.AddRange(freeBlockOffsets);
        }
        public override void GenerateDiamond(Chunk chunk, BlockOffset blockOffset)
        {
            Vector3 coord = chunk.GetAbsPosition(blockOffset);

            float height = _landScapeHeight - _noiseLandscape.GetSimplexFractal(coord.X, coord.Z) * (_heightGain.GetSimplexFractal(coord.X, coord.Z) * 50);
            float n      = _noiseDiamond.GetPerlin(coord.X, coord.Y, coord.Z);

            if (coord.Y <= height - _minHeightDiamond - 5 && coord.Y > height - _maxHeightDiamond &&
                n < _shearDiamondMax && n > _shearDiamondMin)
            {
                chunk.SetBlock(blockOffset, new BlockDiamond());
            }
        }
Beispiel #11
0
    BlockOffset[] UpdateBlockData(Vector3 cubeSize)
    {
        var blockOffsets = new BlockOffset[this.blockDatas.Length];

        for (var i = 0; i < this.blockDatas.Length; ++i)
        {
            var blockData   = this.blockDatas[i];
            var blockOffset = new BlockOffset
            {
                name        = blockData.GetType().Name,
                cellOffsets = this.GetCubeOffsets(blockData)
            };
            blockOffsets[i] = blockOffset;
        }

        return(blockOffsets);
    }
Beispiel #12
0
        public void Append(BlockOffset[] freeBlockOffsets)
        {
            if (freeBlockOffsets == null)
                throw new ArgumentNullException("freeBlockOffsets");

            // This is a very simplistic implementation of append:
            //  reading the entire blocklist, appending the new offsets in memory and
            //  then writing the entire list back.

            // A more sophisticated implementation would just write the modified entries.
            var offsets = this.ToList();
            offsets.AddRange(freeBlockOffsets);
            if(offsets.Count > ListCapacity)
                throw new ArgumentOutOfRangeException("freeBlockOffsets",freeBlockOffsets.Length,"Not all offsets fit into this block.");

            ReplaceOffsets(offsets.ToArray());
            TotalFreeBlockCount += freeBlockOffsets.Length;
        }
        public override void Generate(Chunk chunk)
        {
            for (int x = 0; x < Chunk.SizeX; x++)
            {
                for (int y = 0; y < Chunk.SizeY; y++)
                {
                    for (int z = 0; z < Chunk.SizeZ; z++)
                    {
                        BlockOffset blockOffset = new BlockOffset(x, y, z);

                        GenerateLandscape(chunk, blockOffset);

                        GenerateCoal(chunk, blockOffset);
                        GenerateIron(chunk, blockOffset);
                        GenerateGold(chunk, blockOffset);
                        GenerateDiamond(chunk, blockOffset);

                        GenerateCave(chunk, blockOffset);

                        GenerateWater(chunk, blockOffset);
                    }
                }
            }
        }
Beispiel #14
0
 public virtual IDirectoryBlock GetDirectoryBlock(BlockOffset blockOffset)
 {
     return new RawDirectoryBlock(this,blockOffset,(uint)BlockSize);
 }
Beispiel #15
0
        public virtual void FreeBlock(BlockOffset blockOffset)
        {
            if (blockOffset.Offset + 1 == Break.Offset)
            {
                // The block to be free lies next to break,
                // reduce break instead
                Break = (BlockOffset) (Break.Offset - 1u);
                if(Space.CanShrink)
                    Space.Resize(Break.Offset*BlockSize);

                // We treat a freed block as a changed block since that
                // allows us to retrieve the original version in case of
                // a rollback
                OnBlockChanged(blockOffset);
            }
            else
            {
                // The block lies within our allocated space
                // We need to track it in our empty space list.
                var head = GetEmptyListBlock(EmptyListOffset);

                // If we don't have enough space to add a new offset
                // then prepend a new empty list block.
                if (head.Count >= head.ListCapacity)
                {
                    var newHead = AllocateEmptyListBlock();
                    newHead.ContinuationBlockOffset = head.Offset;
                    EmptyListOffset = newHead.Offset;
                    head = newHead;
                }

                head.Append(new[] { blockOffset });

                // Here we don't need to record the block as changed since
                // it is being left as it is by free block
                // Should it be repurposed, that operation will generate
                // a journal entry.
                // This enables a relatively cheap restoration of deleted
                // files if their blocks have not been reused yet.
            }
        }
Beispiel #16
0
 public MemDirectoryBlock(BlockOffset offset, int capacity)
     : base(offset,capacity)
 {
 }
Beispiel #17
0
        public virtual void DirectRead(BlockOffset blockOffset, byte[] destination, int index)
        {
            var raw = BlockManager as RawBlockManager;
            if (raw == null)
                throw new NotSupportedException(
                    "The block manager underlying this virtual disk does not support synchronization.");

            raw.ReadDataBlock(blockOffset, destination, index,0,null);
        }
Beispiel #18
0
        internal static unsafe void Initialize(
            [NotNull]
            IRawPersistenceSpace space,
            uint blockCount,
            uint blockSize = VirtualFileSystem.DefaultBlockSize,
            BlockOffset? rootDirectoryOffset = null,
            BlockOffset? emptyListOffset = null)
        {
            if (blockSize < MinimumBlockSize)
                throw new ArgumentOutOfRangeException("blockSize", blockSize,
                                                      "Block size must be at least " + MinimumBlockSize + ".");
            if (space == null)
                throw new ArgumentNullException("space");

            var actualRootDirectoryOffset = rootDirectoryOffset ?? (BlockOffset)1;
            var actualEmptyListOffset = emptyListOffset ?? (BlockOffset)2;

            if (actualRootDirectoryOffset.Offset >= blockCount)
                throw new ArgumentOutOfRangeException("rootDirectoryOffset", rootDirectoryOffset, "Root directory offset is beyond the end of the disk.");

            if (actualEmptyListOffset.Offset >= blockCount)
                throw new ArgumentOutOfRangeException("emptyListOffset", emptyListOffset, "Empty list offset is beyond the end of the disk.");

            var uintPtr = (uint*)space.Pointer;

            uintPtr[BlockCountFieldOffset] = blockCount;
            uintPtr[BlockSizeFieldOffset] = blockSize;
            uintPtr[RootDirectoryFieldOffset] = actualRootDirectoryOffset.Offset;
            uintPtr[EmptyListFieldOffset] = actualEmptyListOffset.Offset;
            uintPtr[BreakFieldOffset] = Math.Max(actualRootDirectoryOffset.Offset, actualEmptyListOffset.Offset) + 1;
            uintPtr[JournalFieldOffset] = 0;

            var end = ((byte*)space.Pointer) + blockSize;
            for (var bytePtr = (byte*)&uintPtr[BreakFieldOffset + 1]; bytePtr < end; bytePtr++)
                *bytePtr = 0;

            _initZero(space, blockSize, actualRootDirectoryOffset);
            _initZero(space, blockSize, actualEmptyListOffset);
        }
Beispiel #19
0
        public unsafe virtual void WriteBlockDirect(BlockOffset blockOffset, byte[] data)
        {
            if (data == null)
                throw new ArgumentNullException("data");

            var dataBlockSize = BlockSize;

            if (data.Length > dataBlockSize)
                throw new ArgumentException(
                    string.Format("Data array is longer than block size. (block size = {0}, data length = {1})",
                        dataBlockSize, data.Length), "data");

            // Copy the provided data
            var blockAddress = _blockAt(blockOffset);
            Marshal.Copy(data, 0, (IntPtr)blockAddress, data.Length);

            // Padd rest with 0
            // (this is not really necessary, but it will help us debug)
            var start = (byte*)blockAddress;
            var end = start + dataBlockSize;
            for (var ptr = start + data.Length; ptr < end; ptr++)
                *ptr = 0;
        }
Beispiel #20
0
 public virtual IFileContinuationBlock GetFileContinuationBlock(BlockOffset blockOffset)
 {
     return new RawOffsetListBlock(this,blockOffset,(uint) BlockSize);
 }
Beispiel #21
0
        public void SetBlock(ChunkOffset chunkOffset, BlockOffset blockOffset, IBlock block)
        {
            Chunk chunk = FindChunk(chunkOffset);

            chunk?.SetBlock(blockOffset, block);
        }
Beispiel #22
0
 private unsafe void* _blockAt(BlockOffset offset)
 {
     var bytePtr = (byte*)_space.Pointer;
     return bytePtr + BlockSize * offset.Offset;
 }
Beispiel #23
0
        protected IJournalBlock GetJournalBlock(BlockOffset blockOffset)
        {
            if (blockOffset.Offset >= Break.Offset)
                throw new ArgumentOutOfRangeException("blockOffset", blockOffset,
                    "Block offset points to location beyond allocation allocated space.");

            return new RawJournalBlock(this,blockOffset, (uint) BlockSize);
        }
Beispiel #24
0
        public IBlock GetBlock(ChunkOffset chunkOffset, BlockOffset blockOffset)
        {
            Chunk chunk = FindChunk(chunkOffset);

            return(chunk?.GetBlock(blockOffset));
        }
Beispiel #25
0
 public Vector3 GetAbsPosition(BlockOffset blockOffset) => CoordinateConverter.ToAbsPosition(Offset, blockOffset);
Beispiel #26
0
        public virtual void ReceiveChanges(BlockOffset blockOffset, byte[] data)
        {
            var raw = BlockManager as RawBlockManager;
            if (raw == null)
                throw new NotSupportedException(
                    "The block manager underlying this virtual disk does not support synchronization.");

            raw.WriteBlockDirect(blockOffset, data);
        }
Beispiel #27
0
 public virtual IDirectoryContinuationBlock GetDirectoryContinuationBlock(BlockOffset blockOffset)
 {
     return new RawDirectoryEntryListBlock(this,blockOffset,(uint) BlockSize);
 }
Beispiel #28
0
 public virtual IFileBlock GetFileBlock(BlockOffset blockOffset)
 {
     return new RawFileBlock(this, blockOffset, (uint)BlockSize);
 }
Beispiel #29
0
 private async Task _mergeRemoteBlockAsync(DiskViewModel diskModel, BlockOffset blockOffset, byte[] buffer)
 {
     using (var blockResp = await _serviceClient.GetAsync(new GetBlock()
         {
             DiskName = diskModel.Name,
             BlockOffset = blockOffset.Offset
         }))
     {
         // incorporate into the local disk
         blockResp.Read(buffer, 0, buffer.Length);
         diskModel.SynchronizingDisk.ReceiveChanges(blockOffset, buffer);
     }
 }
Beispiel #30
0
        public unsafe virtual void ReadDataBlock(BlockOffset blockOffset, byte[] destination, int destinationIndex,
                                  int blockIndex,
                                  int? count)
        {
            if (destination == null)
                throw new ArgumentNullException("destination");
            if (destinationIndex < 0)
                throw new ArgumentOutOfRangeException("destinationIndex", destinationIndex, "Destination index cannot be negative.");
            if (blockIndex < 0)
                throw new ArgumentOutOfRangeException("blockIndex", blockIndex, "Block index cannot be negative.");

            // Check block index
            var blockRemainingLength = BlockSize - blockIndex;
            if (blockRemainingLength < 0)
                throw new ArgumentOutOfRangeException("blockIndex", blockIndex,
                    string.Format(
                        "Index into data block is beyond block boundary. (block size = {0})", BlockSize));

            // Check destination index
            var destinationRemainingLength = destination.Length - destinationIndex;
            if (destinationRemainingLength < 0)
                throw new ArgumentOutOfRangeException("destinationIndex", destinationIndex,
                    string.Format(
                        "Index into destination is beyond block boundary. (destination length = {0})",
                        destination.Length));

            // Check count
            var actualCount = count ?? Math.Min(destinationRemainingLength, blockRemainingLength);
            if (actualCount > destinationRemainingLength || actualCount > blockRemainingLength)
                throw new ArgumentOutOfRangeException("count", count,
                    "Read count is larger than either the remaining block or the remaining destination array.");
            if (actualCount < 0)
                throw new ArgumentOutOfRangeException("count", count, "Count cannot be negative.");

            // Perform copy
            var ptr = (IntPtr)_blockAt(blockOffset);
            Marshal.Copy(IntPtr.Add(ptr, blockIndex), destination, destinationIndex, actualCount);
        }
Beispiel #31
0
 public MemOffsetList(BlockOffset offset, int listCapacity)
     : base(offset)
 {
     _listCapacity = listCapacity;
 }
Beispiel #32
0
 public unsafe virtual void WriteDataBlock(BlockOffset blockOffset, byte[] data)
 {
     WriteBlockDirect(blockOffset, data);
     OnBlockChanged(blockOffset);
 }
Beispiel #33
0
 public RawJournalBlock([NotNull] RawBlockManager manager, BlockOffset offset, uint blockSize)
     : base(manager, offset, blockSize)
 {
 }
Beispiel #34
0
        /// <summary>
        /// Called whenever a block has been changed. Used to write the journal.
        /// </summary>
        /// <param name="blockOffset">Offset of the block that has changed.</param>
        protected internal void OnBlockChanged(BlockOffset blockOffset)
        {
            Contract.Ensures(!IsJournaling || _journalJobQueue.Count == 0);

            // Check if journaling is even enabled
            if(!IsJournaling)
                return;

            // Between two synchronization operations don't add the same block
            // more than once.
            // This "optimization" is crucial as the journal pages
            // are being changed constantly and we only want them to appear once
            // in the journal itself.
            if(_modifiedBlocks.Contains(blockOffset))
                return;

            var alreadyRunning = _journalJobQueue.Count > 0;
            _journalJobQueue.Enqueue(blockOffset);
            _modifiedBlocks.Add(blockOffset);

            // If OnBlockChanges is already running and this is a recursive/nested call, putting
            // the block offset in the queue was enough. The activation higher up in the call stack
            // will make sure it is stored.
            if(alreadyRunning)
                return;

            // Get the latest journal block (or allocate a new journal if this
            // disk hasn't kept a journal before)
            var nextJournalOffset = JournalOffset;
            IJournalBlock journalBlock;
            if (nextJournalOffset == null)
            {
                journalBlock = AllocateJournalBlock();
                JournalOffset = journalBlock.Offset;
            }
            else
            {
                journalBlock = GetJournalBlock(nextJournalOffset.Value);
            }

            while (_journalJobQueue.Count > 0)
            {
                var jobOffset = _journalJobQueue.Dequeue();
                var success = journalBlock.TryAppendEntry(new JournalEntry(DateTime.Now, jobOffset));
                if (!success)
                {
                    // there was not enough room for the entry in the current journal block
                    // save the entry for later and allocate more space
                    _journalJobQueue.Enqueue(jobOffset);
                    var nextBlock = AllocateJournalBlock();
                    // link new block to old list and move the journal head pointer to the new block
                    nextBlock.ContinuationBlockOffset = journalBlock.Offset;
                    JournalOffset = nextBlock.Offset;

                    // start inserting into the new journal block
                    journalBlock = nextBlock;
                }
            }
        }
Beispiel #35
0
 public MemDirectoryBase(BlockOffset offset, int capacity)
     : base(offset)
 {
     _capacity = capacity;
 }
Beispiel #36
0
        private static unsafe void _initZero([NotNull] IRawPersistenceSpace space, uint blockSize, BlockOffset blockOffset)
        {
            var ptr = (byte*)space.Pointer;
            ptr = ptr + blockSize * blockOffset.Offset;
            var end = ptr + blockSize;

            // Use platform-specific pointer size when possible
            if (_isAligned(ptr) && blockSize % sizeof(void*) == 0)
            {
                var ptrEnd = (void*)end;
                for (var ptrAligned = (void**)ptr; ptrAligned < ptrEnd; ptrAligned++)
                {
                    *ptrAligned = null;
                }
            }
            else
            {
                // Fall back to byte-by-byte, slower but works regardless of alignment and processor word size
                for (; ptr < end; ptr++)
                {
                    *ptr = 0;
                }
            }
        }
Beispiel #37
0
 public MemFileBlock(BlockOffset offset, int listCapacity)
     : base(offset, listCapacity)
 {
 }
Beispiel #38
0
 public abstract void GenerateLandscape(Chunk chunk, BlockOffset blockOffset);
Beispiel #39
0
 public abstract void GenerateGold(Chunk chunk, BlockOffset blockOffset);
 public MemDirectoryContinuationBlock(BlockOffset offset, int capacity)
     : base(offset, capacity)
 {
 }
Beispiel #41
0
 public abstract void GenerateDiamond(Chunk chunk, BlockOffset blockOffset);
Beispiel #42
0
 public RawFileBlock([NotNull] RawBlockManager manager, BlockOffset offset, uint size)
     : base(manager, offset, size)
 {
 }
Beispiel #43
0
 public RawBlock([NotNull] RawBlockManager manager, BlockOffset offset, uint blockSize)
 {
     _manager = manager;
     _offset = offset;
     _blockSize = blockSize;
 }
Beispiel #44
0
 public RawContinuedBlock(RawBlockManager manager, BlockOffset offset, uint blockSize)
     : base(manager, offset, blockSize)
 {
 }
Beispiel #45
0
 public void ReplaceOffsets(BlockOffset[] offsets)
 {
     ThrowIfDeallocated();
     _offsets.Clear();
     Append(offsets);
 }