public SetTextCommand( BlockKey blockKey, string text) : base(blockKey) { Text = text; }
public ChangeBlockTypeCommand( BlockKey blockKey, BlockType blockType) : base(blockKey) { BlockType = blockType; }
public InsertAfterBlockCommand( BlockKey blockKey, int count) : base(blockKey) { // Make sure we have a sane state. if (count <= 0) { throw new ArgumentOutOfRangeException( "count", "Cannot insert or zero or less blocks."); } // Keep track of the counts. Count = count; // We have to keep track of the blocks we added. addedBlocks = new List<Block>(); }
public void UpdateBlockLight (int lx, int ly, int lz) { BlockKey primary = new BlockKey(lx, ly, lz); _update.Enqueue(primary); //BlockInfo info = _blockset.GetInfo(lx, ly, lz); //if (info.Luminance > BlockInfo.MIN_LUMINANCE || info.TransmitsLight) { if (ly > 0) { QueueRelight(new BlockKey(lx, ly - 1, lz)); } if (ly < _ydim - 1) { QueueRelight(new BlockKey(lx, ly + 1, lz)); } QueueRelight(new BlockKey(lx - 1, ly, lz)); QueueRelight(new BlockKey(lx + 1, ly, lz)); QueueRelight(new BlockKey(lx, ly, lz - 1)); QueueRelight(new BlockKey(lx, ly, lz + 1)); //} UpdateBlockLight(); }
public BlockSet GetBlock(int x, int y, int z) { BlockKey key = GetAt(x, y, z); return(new BlockSet(GameData.JavaEdition.GetBlock(key.BlockName), key.Metadata)); }
public TagCompound BuildTag() { List <PaletteObj> palette = new List <PaletteObj>(); TagList blocks = new TagList("blocks", TagType.Compound); for (int x = 0; x < _width; x++) { for (int y = 0; y < _height; y++) { for (int z = 0; z < _length; z++) { BlockKey set = GetAt(x, y, z); PaletteObj plt = new PaletteObj() { Name = set.BlockName, Metadata = set.Metadata }; if (!palette.Contains(plt)) { palette.Add(plt); } int state = palette.IndexOf(plt); TagCompound blk = new TagCompound("") { new TagInt("state", state), new TagList("pos") { new TagInt(set.X), new TagInt(set.Y), new TagInt(set.Z) } }; if (set.NBT != null) { blk.Add("nbt", set.NBT); } blocks.Add(blk); } } } TagList paletteTag = new TagList("palette", TagType.Compound); for (int i = 0; i < palette.Count; i++) { paletteTag.Add(palette[i].BuildTag()); } TagList entities = new TagList("entities", TagType.Compound); foreach (TagCompound e in _entityList) { entities.Add(e); } TagList size = new TagList("size") { new TagInt(_width), new TagInt(_height), new TagInt(_length) }; TagCompound root = new TagCompound() { new TagInt("DataVersion", _dataVersion), new TagString("author", _author), paletteTag, blocks, entities, size }; return(root); }
private void BuildTileEntityCache() { _tileEntityTable = new Dictionary<BlockKey, TagNodeCompound>(); foreach (TagNodeCompound te in _tileEntities) { int tex = te["x"].ToTagInt(); int tey = te["y"].ToTagInt(); int tez = te["z"].ToTagInt(); BlockKey key = new BlockKey(tex, tey, tez); _tileEntityTable[key] = te; } }
private int TileInflow(BlockKey key) { // Check if water is falling on us if (key.y < _ydim - 1) { BlockCoord up = TranslateCoord(key.x, key.y + 1, key.z); BlockInfo upInfo = up.chunk.GetInfo(up.lx, up.ly, up.lz); if (upInfo.State == BlockState.FLUID) { return up.chunk.GetData(up.lx, up.ly, up.lz) | (int)LiquidState.FALLING; } } // Otherwise return the min inflow of our neighbors + step BlockKey[] keys = { new BlockKey(key.x - 1, key.y, key.z), new BlockKey(key.x + 1, key.y, key.z), new BlockKey(key.x, key.y, key.z - 1), new BlockKey(key.x, key.y, key.z + 1), }; int minFlow = 16; // XXX: Might have different neighboring fluids for (int i = 0; i < 4; i++) { BlockCoord neighbor = TranslateCoord(keys[i].x, keys[i].y, keys[i].z); if (neighbor.chunk == null) { continue; } BlockInfo neighborInfo = neighbor.chunk.GetInfo(neighbor.lx, neighbor.ly, neighbor.lz); if (neighborInfo.State == BlockState.FLUID) { int flow = neighbor.chunk.GetData(neighbor.lx, neighbor.ly, neighbor.lz); bool flowFall = (flow & (int)LiquidState.FALLING) != 0; if (flowFall) { if (keys[i].y == 0) { continue; } BlockCoord low = TranslateCoord(keys[i].x, keys[i].y - 1, keys[i].z); BlockInfo lowinfo = low.chunk.GetInfo(low.lx, low.ly, low.lz); if (lowinfo.BlocksFluid) { return 0; } continue; } if (flow < minFlow) { minFlow = flow; } } } return minFlow; }
private void QueueRelight(BlockKey key) { if (key.x < -15 || key.x >= 31 || key.z < -15 || key.z >= 31) { return; } int index = LightBitmapIndex(key); if (!_lightbit[index]) { _lightbit[index] = true; _update.Enqueue(key); } }
public void UpdateBlockSkyLight(int lx, int ly, int lz) { BlockKey primary = new BlockKey(lx, ly, lz); _update.Enqueue(primary); UpdateBlockSkyLight(); }
protected MultipleBlockKeyCommand(BlockKey blockKey) : base(blockKey) { }
public void Dispose(bool disposing) { if (!_isSharedMemory) { DoDispose(); } else { lock (this) { DoDispose(); } } void DoDispose() { if (!disposing) { // Cache has a weak reference, so finalizer could start running while a handle is still in the cache // As if _rc was 1 and we called DecrementIfOne - if successful, no resurrect is possible // because Retain uses IncrementIfRetained. var current = Volatile.Read(ref _rc); var existing = Interlocked.CompareExchange(ref _rc, 0, current); if (existing != current) { // Resurrected while we tried to set rc to zero. // What if rc was wrong and not 1? At some point all new users will // dispose the proxy and it will be in the cache with // positive rc but without GC root, then it will be // collected and finalized and will return to this // place where we will try to set rc to 0 again. // TODO trace this condition, it indicates dropped proxies // From user code it could be possible only when manually using cursors // and forgetting to dispose them, so all blame is on users, but we should not fail. ThrowHelper.AssertFailFast(existing > 1, "existing > 1 when resurrected"); return; } } else { var remaining = AtomicCounter.Decrement(ref _rc); if (remaining > 1) { return; } if (AtomicCounter.DecrementIfOne(ref _rc) != 0) { return; } } ThrowHelper.AssertFailFast(_rc == 0, "_rc must be 0 to proceed with proxy disposal"); try { // remove self from cache _cache._blocks.TryRemove(_key, out var handle); if (handle.IsAllocated) { handle.Free(); } } finally { // If we are shutting down, e.g. unhandled exception in other threads // increase the chances we do release shared memory ref. #pragma warning disable 618 // ReSharper disable once InconsistentlySynchronizedField Block.DisposeFree(); #pragma warning restore 618 } // Do not pool finalized objects. // TODO (review) proxy does not have ref type fields, // probably could add to pool without thinking about GC/finalization order. // However, this case should be very rare (e.g. unhandled exception) // and we care about releasing RC of shared memory above all. if (disposing) { GC.SuppressFinalize(this); // ReSharper disable once InconsistentlySynchronizedField Block = default; _key = default; AtomicCounter.Dispose(ref _rc); _isSharedMemory = default; } } }
public IDisposable AcquireBlockLock( RequestLock requestedCollectionLock, RequestLock requestedBlockLock, BlockKey blockKey, out Block block) { // Start by getting a read lock on the collection itself. IDisposable collectionLock = AcquireLock(requestedCollectionLock); // Grab the block via the index. block = this[blockKey]; // Get a read lock on the block and then return it. IDisposable blockLock = block.AcquireLock(collectionLock, requestedBlockLock); return blockLock; }
public IDisposable AcquireBlockLock( RequestLock requestedBlockLock, BlockKey blockKey, out Block block) { return AcquireBlockLock( RequestLock.Read, requestedBlockLock, blockKey, out block); }
private void ComputeBlockKeys(ScopeBlock rootScope) { var blocks = rootScope.GetBasicBlocks().OfType <ILBlock>().ToList(); uint id = 1; this.Keys = blocks.ToDictionary( block => block, block => new BlockKey { Entry = id++, Exit = id++ }); EHMap ehMap = this.MapEHs(rootScope); bool updated; do { updated = false; BlockKey key; key = this.Keys[blocks[0]]; key.Entry = 0xfffffffe; this.Keys[blocks[0]] = key; key = this.Keys[blocks[blocks.Count - 1]]; key.Exit = 0xfffffffd; this.Keys[blocks[blocks.Count - 1]] = key; // Update the state ids with the maximum id foreach (ILBlock block in blocks) { key = this.Keys[block]; if (block.Sources.Count > 0) { uint newEntry = block.Sources.Select(b => this.Keys[(ILBlock)b].Exit).Max(); if (key.Entry != newEntry) { key.Entry = newEntry; updated = true; } } if (block.Targets.Count > 0) { uint newExit = block.Targets.Select(b => this.Keys[(ILBlock)b].Entry).Max(); if (key.Exit != newExit) { key.Exit = newExit; updated = true; } } this.Keys[block] = key; } // Match finally enter = finally exit = try end exit // Match filter start = 0xffffffff this.MatchHandlers(ehMap, ref updated); } while(updated); // Replace id with actual values var idMap = new Dictionary <uint, uint>(); idMap[0xffffffff] = 0; idMap[0xfffffffe] = this.methodInfo.EntryKey; idMap[0xfffffffd] = this.methodInfo.ExitKey; foreach (ILBlock block in blocks) { BlockKey key = this.Keys[block]; uint entryId = key.Entry; if (!idMap.TryGetValue(entryId, out key.Entry)) { key.Entry = idMap[entryId] = (byte)this.runtime.Descriptor.Random.Next(); } uint exitId = key.Exit; if (!idMap.TryGetValue(exitId, out key.Exit)) { key.Exit = idMap[exitId] = (byte)this.runtime.Descriptor.Random.Next(); } this.Keys[block] = key; } }
protected BlockKeyCommand(BlockKey blockKey) { BlockKey = blockKey; UseBlockKey = true; UpdateTextPosition = DoTypes.All; }
public static Structure FromNBT(TagCompound root) { if (!((root.ContainsKey("version", TagType.Int) || root.ContainsKey("DataVersion", TagType.Int)) && root.ContainsKey("blocks", TagType.List) && root.ContainsKey("palette", TagType.List) && root.ContainsKey("entities", TagType.List) && root.ContainsKey("size", TagType.List))) { throw new ArgumentException("Unknown format"); } TagList size = root["size"] as TagList; if (size == null) { throw new ArgumentException("Unknown format"); } int version = root.ContainsKey("version") ? root.GetInt("version") : root.GetInt("DataVersion"); Structure template = new Structure(((TagInt)size[0]).Value, ((TagInt)size[1]).Value, ((TagInt)size[2]).Value, version); TagList palette = root["palette"] as TagList; TagList blocks = root["blocks"] as TagList; for (int i = 0; i < blocks.Count; i++) { TagCompound btag = blocks[i] as TagCompound; if (btag == null) { continue; } int statue = btag.GetInt("state"); if (statue >= palette.Count) { continue; } TagCompound cmd = palette[statue] as TagCompound; BlockKey block = GetFromCompound(cmd); TagList pos = btag["pos"] as TagList; if (pos != null && pos.Count == 3) { block.X = ((TagInt)pos[0]).Value; block.Y = ((TagInt)pos[1]).Value; block.Z = ((TagInt)pos[2]).Value; } if (btag.ContainsKey("nbt", TagType.Compound)) { block.NBT = btag["nbt"] as TagCompound; } template._blockList[block.X, block.Y, block.Z] = block; } TagList entities = root["entities"] as TagList; foreach (TagCompound en in entities) { TagList _pos = en["pos"] as TagList; TagList bpos = en["blockPos"] as TagList; if (en.ContainsKey("nbt", TagType.Compound)) { template._entityList.Add(en); } } return(template); }
private void DoLava(int x, int y, int z) { Queue<BlockKey> flowQueue = new Queue<BlockKey>(); BlockKey prikey = new BlockKey(x, y, z); flowQueue.Enqueue(prikey); List<BlockKey> outflow = TileOutflow(prikey); foreach (BlockKey outkey in outflow) { flowQueue.Enqueue(outkey); } while (flowQueue.Count > 0) { BlockKey key = flowQueue.Dequeue(); int curflow = 16; int inflow = TileInflow(key); BlockCoord tile = TranslateCoord(key.x, key.y, key.z); BlockInfo tileInfo = tile.chunk.GetInfo(tile.lx, tile.ly, tile.lz); if (tileInfo.ID == BlockInfo.StationaryLava.ID || tileInfo.ID == BlockInfo.Lava.ID) { curflow = tile.chunk.GetData(tile.lx, tile.ly, tile.lz); } else if (tileInfo.BlocksFluid) { continue; } bool curFall = (curflow & (int)LiquidState.FALLING) != 0; bool inFall = (inflow & (int)LiquidState.FALLING) != 0; // We won't update from the following states if (curflow == 0 || curflow == inflow || curFall) { continue; } int newflow = curflow; // Update from inflow if necessary if (inFall) { newflow = inflow; } else if (inflow >= 6) { newflow = 16; } else { newflow = inflow + 2; } // If we haven't changed the flow, don't propagate if (newflow == curflow) { continue; } // Update flow, add or remove lava tile as necessary if (newflow < 16 && curflow == 16) { // If we're overwriting water, replace with appropriate stone type and abort propagation if (tileInfo.ID == BlockInfo.StationaryWater.ID || tileInfo.ID == BlockInfo.Water.ID) { if ((newflow & (int)LiquidState.FALLING) == 0) { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Cobblestone.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); continue; } } tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.StationaryLava.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } else if (newflow == 16) { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Air.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); } else { tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } // Process outflows outflow = TileOutflow(key); foreach (BlockKey nkey in outflow) { flowQueue.Enqueue(nkey); } } }
private int LightBitmapIndex(BlockKey key) { int x = key.x + _xdim; int y = key.y; int z = key.z + _zdim; int zstride = _ydim; int xstride = _zdim * 3 * zstride; return (x * xstride) + (z * zstride) + y; }
public DeleteBlockCommand(BlockKey blockKey) { this.blockKey = blockKey; UpdateTextPosition = DoTypes.All; }
private void DoWater(int x, int y, int z) { Queue<BlockKey> flowQueue = new Queue<BlockKey>(); BlockKey prikey = new BlockKey(x, y, z); flowQueue.Enqueue(prikey); List<BlockKey> outflow = TileOutflow(prikey); foreach (BlockKey outkey in outflow) { flowQueue.Enqueue(outkey); } while (flowQueue.Count > 0) { BlockKey key = flowQueue.Dequeue(); int curflow = 16; int inflow = TileInflow(key); BlockCoord tile = TranslateCoord(key.x, key.y, key.z); BlockInfo tileInfo = tile.chunk.GetInfo(tile.lx, tile.ly, tile.lz); if (tileInfo.ID == BlockType.STATIONARY_WATER || tileInfo.ID == BlockType.WATER) { curflow = tile.chunk.GetData(tile.lx, tile.ly, tile.lz); } else if (tileInfo.BlocksFluid) { continue; } bool curFall = (curflow & (int)LiquidState.FALLING) != 0; bool inFall = (inflow & (int)LiquidState.FALLING) != 0; // We won't update from the following states if (curflow == 0 || curflow == inflow || curFall) { continue; } int newflow = curflow; // Update from inflow if necessary if (inFall) { newflow = inflow; } else if (inflow >= 7) { newflow = 16; } else { newflow = inflow + 1; } // If we haven't changed the flow, don't propagate if (newflow == curflow) { continue; } // Update flow, add or remove water tile as necessary if (newflow < 16 && curflow == 16) { // If we're overwriting lava, replace with appropriate stone type and abort propagation if (tileInfo.ID == BlockType.STATIONARY_LAVA || tileInfo.ID == BlockType.LAVA) { if ((newflow & (int)LiquidState.FALLING) != 0) { int odata = tile.chunk.GetData(tile.lx, tile.ly, tile.lz); if (odata == 0) { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockType.OBSIDIAN); } else { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockType.COBBLESTONE); } tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); continue; } } // Otherwise replace the tile with our water flow tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockType.STATIONARY_WATER); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } else if (newflow == 16) { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockType.AIR); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); } else { tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } // Process outflows outflow = TileOutflow(key); foreach (BlockKey nkey in outflow) { flowQueue.Enqueue(nkey); } } }
protected SingleBlockKeyCommand(BlockKey blockKey) : base(blockKey) { }
// ----- private List<BlockKey> TileOutflow(BlockKey key, int reach = 5) { Queue<BlockKey> searchQueue = new Queue<BlockKey>(); Queue<KeyValuePair<BlockKey, int>> traceQueue = new Queue<KeyValuePair<BlockKey, int>>(); Dictionary<BlockKey, int> markTable = new Dictionary<BlockKey,int>(); searchQueue.Enqueue(key); markTable.Add(key, 0); // Identify sinks while (searchQueue.Count > 0) { BlockKey branch = searchQueue.Dequeue(); int distance = markTable[branch]; // Ignore blocks out of range if (distance > reach) { continue; } // Ignore invalid blocks BlockCoord branchHigh = TranslateCoord(branch.x, branch.y, branch.z); if (branchHigh.chunk == null || branch.y == 0) { markTable.Remove(branch); continue; } // If we're not the magical source block... if (distance > 0) { // Ignore blocks that block fluid (and thus could not become a fluid) BlockInfo branchHighInfo = branchHigh.chunk.GetInfo(branchHigh.lx, branchHigh.ly, branchHigh.lz); if (branchHighInfo.BlocksFluid) { markTable.Remove(branch); continue; } } // If we found a hole, add as a sink, mark the sink distance. BlockCoord branchLow = TranslateCoord(branch.x, branch.y - 1, branch.z); BlockInfo branchLowInfo = branchLow.chunk.GetInfo(branchLow.lx, branchLow.ly, branchLow.lz); if (!branchLowInfo.BlocksFluid) { // If we are our own sink, return the only legal outflow if (key == branch) { List<BlockKey> ret = new List<BlockKey>(); ret.Add(new BlockKey(branch.x, branch.y - 1, branch.z)); return ret; } reach = distance; traceQueue.Enqueue(new KeyValuePair<BlockKey, int>(branch, distance)); continue; } // Expand to neighbors if (distance < reach) { BlockKey[] keys = { new BlockKey(branch.x - 1, branch.y, branch.z), new BlockKey(branch.x + 1, branch.y, branch.z), new BlockKey(branch.x, branch.y, branch.z - 1), new BlockKey(branch.x, branch.y, branch.z + 1), }; for (int i = 0; i < 4; i++) { if (!markTable.ContainsKey(keys[i])) { searchQueue.Enqueue(keys[i]); markTable.Add(keys[i], distance + 1); } } } } // Candidate outflows are marked BlockKey[] neighbors = { new BlockKey(key.x - 1, key.y, key.z), new BlockKey(key.x + 1, key.y, key.z), new BlockKey(key.x, key.y, key.z - 1), new BlockKey(key.x, key.y, key.z + 1), }; List<BlockKey> outflow = new List<BlockKey>(); foreach (BlockKey n in neighbors) { if (markTable.ContainsKey(n)) { outflow.Add(n); } } // If there's no sinks, all neighbors are valid outflows if (traceQueue.Count == 0) { return outflow; } // Trace back from each sink eliminating shortest path marks while (traceQueue.Count > 0) { KeyValuePair<BlockKey, int> tilekv = traceQueue.Dequeue(); BlockKey tile = tilekv.Key; int distance = tilekv.Value; markTable.Remove(tile); BlockKey[] keys = { new BlockKey(tile.x - 1, tile.y, tile.z), new BlockKey(tile.x + 1, tile.y, tile.z), new BlockKey(tile.x, tile.y, tile.z - 1), new BlockKey(tile.x, tile.y, tile.z + 1), }; for (int i = 0; i < 4; i++) { int nval; if (!markTable.TryGetValue(keys[i], out nval)) { continue; } if (nval < distance) { markTable.Remove(keys[i]); traceQueue.Enqueue(new KeyValuePair<BlockKey, int>(keys[i], nval)); } } } // Remove any candidates that are still marked foreach (BlockKey n in neighbors) { if (markTable.ContainsKey(n)) { outflow.Remove(n); } } return outflow; }
internal MergeComplement(BPlusTree <BlockKey <C>, BlockValue> di4_2R, BlockKey <C> left, BlockKey <C> right, SortedDictionary <BlockKey <C>, int> blocks, object lockOnMe) { _di4_2R = di4_2R; _left = left; _right = right; _lockOnMe = lockOnMe; _blocks = blocks; }