public async Task ChunklerClient_CanHandle_SubscribeUpdates() { var taskCompletionSource = new TaskCompletionSource <object>(); ChunkUpdate update = null; await ChunklerClient.SubscribeOnChunkUpdateAsync(ActiveBattleChunkKey, chunkUpdate => { update = chunkUpdate; taskCompletionSource.SetResult(new object()); return(Task.CompletedTask); }); var action = new ChunkAction() { Color = 0, XIndex = 0, YIndex = 0 }; var changeIndex = await ChunklerClient.ProcessChunkActionAsync(ActiveBattleChunkKey, action); await Task.WhenAny(taskCompletionSource.Task, Task.Delay(10000)); Assert.NotNull(update); Assert.Equal(changeIndex, update.ChangeIndex); Assert.Equal(action.XIndex, update.XIndex); Assert.Equal(action.YIndex, update.YIndex); Assert.Equal(action.Color, update.Color); }
public ChunkRequest(RequestType chunkRequestType, ChunkUpdate chunkUpdate) { this.chunkRequestType = chunkRequestType; this.ChunkX = 0; this.ChunkZ = 0; this.update = chunkUpdate; }
/// <summary> /// Called, when a chunk was completed. /// </summary> protected virtual void OnChunkUpdate(long streamPosition, long streamLength, int chunkSize, TimeSpan totalTime, TimeSpan chunkTime, ChunkEventArgs.ProcessType type) { var args = new ChunkEventArgs(); args.ChunkSize = chunkSize; args.CompletedChunks = (int)(Math.Ceiling(streamPosition / (float)_chunkSize)); args.TotalChunks = (int)(Math.Ceiling(streamLength / (float)_chunkSize)); args.TotalTime = totalTime; args.ChunkTime = chunkTime; args.Type = type; ChunkUpdate?.Invoke(this, args); }
public void UpdateData(ChunkUpdate update) { for (int i = 0; i < update.positions.Count; i++) { long[] pos = update.positions[i]; int index = -1; try { index = (int)(pos[1] * (Constants.ChunkWidth + 1) * (Constants.ChunkHeight + 1) + pos[3] * (Constants.ChunkHeight + 1) + pos[2]); data.values[index] = update.values[i]; } catch (Exception e) { Debug.Log(e.Message + "\n" + e.StackTrace + "\n" + index + ":" + pos[0] + ":" + pos[1] + ":" + pos[2] + ":" + pos[3] + ":" + update.positions.Count + ":" + update.values.Count); } } }
private async Task OnChunkUpdateAsync(ChunkKey key, ChunkUpdate update, Channel <ChunkStreamMessage> channel) { await OutgoingChannel.Writer.WriteAsync(new ChunkStreamMessage(key, update)); }
public ChunkStreamMessage(ChunkKey key, ChunkUpdate update) { Key = key; Update = update; }
//Repeating Thread Method. private void GenerateChunk() { while (true) { if (KillThread) { return; } try { ChunkRequest request = generationRequests.Pop(); if (request == null) { return; } switch (request.chunkRequestType) { #region Generation case ChunkRequest.RequestType.Generation: { long hash = Hash(request.chunk); request.chunk.Generate(); if (!lockMap.ContainsKey(hash)) { lockMap.Add(hash, new object()); } lock (lockMap[hash]) { if (updateGenerationMap.ContainsKey(hash)) { ChunkUpdate update = updateGenerationMap[hash]; updateGenerationMap.Remove(hash); request.chunk.UpdateData(update); } } request.chunk.Mesh(); finishedGeneration.Push(request.chunk); break; } #endregion #region Update case ChunkRequest.RequestType.Update: { ChunkUpdate update = request.update; long hash = update.positions[0][0]; if (!lockMap.ContainsKey(hash)) { lockMap.Add(hash, new object()); } lock (lockMap[hash]) { if (chunkMap.ContainsKey(hash)) { chunkMap[hash].UpdateData(update); chunkMap[hash].Mesh(); finishedUpdate.Push(chunkMap[hash]); } else if (generatedChunk.ContainsKey(hash)) { Debug.Log("Could not find Hashed chunk at: " + hash + " but it has been generated!"); if (updateMap.ContainsKey(hash)) { updateMap[hash].positions.AddRange(update.positions); updateMap[hash].values.AddRange(update.values); } updateMap.Add(hash, update); } else { Debug.Log("Chunk at: " + (hash % int.MaxValue) + "," + (hash >> 31) + " doesn't exist!"); if (updateGenerationMap.ContainsKey(hash)) { updateGenerationMap[hash].positions.AddRange(update.positions); updateGenerationMap[hash].values.AddRange(update.values); } else { updateGenerationMap.Add(hash, update); } } } break; } #endregion #region Load case ChunkRequest.RequestType.Load: { break; } #endregion #region Save case ChunkRequest.RequestType.Save: { break; } #endregion #region Delete case ChunkRequest.RequestType.Deletion: { break; } #endregion } } catch (Exception e) { Debug.Log(e.Message + " :: " + e.StackTrace + "::" + e.Data); } } }
public void SetBlock(long x, int y, long z, uint value) { long hash = HashBlock(x, z); int xVal = (int)(x % Constants.ChunkWidth); int zVal = (int)(z % Constants.ChunkWidth); #region Specified Block if (!lockMap.ContainsKey(hash)) { lockMap.Add(hash, new object()); } lock (lockMap[hash]) { if (xVal < 0) { xVal = Constants.ChunkWidth + xVal; } if (zVal < 0) { zVal = Constants.ChunkWidth + zVal; } if (updateMap.ContainsKey(hash)) { updateMap[hash].positions.Add(new long[] { hash, xVal, y, zVal }); updateMap[hash].values.Add(value); } else { ChunkUpdate update = new ChunkUpdate(); update.positions.Add(new long[] { hash, xVal, y, zVal }); update.values.Add(value); updateMap[hash] = update; } } #endregion #region x=0 if (xVal == 0) { hash = HashBlock(x - 1, z); if (!lockMap.ContainsKey(hash)) { lockMap.Add(hash, new object()); } lock (lockMap[hash]) { xVal = Constants.ChunkWidth; zVal = (int)(z % Constants.ChunkWidth); if (zVal < 0) { zVal = Constants.ChunkWidth + zVal; } if (updateMap.ContainsKey(hash)) { updateMap[hash].positions.Add(new long[] { hash, xVal, y, zVal }); updateMap[hash].values.Add(value); } else { ChunkUpdate update = new ChunkUpdate(); update.positions.Add(new long[] { hash, xVal, y, zVal }); update.values.Add(value); updateMap.Add(hash, update); } } } xVal = (int)(x % Constants.ChunkWidth); #endregion #region z=0 if (zVal == 0) { hash = HashBlock(x, z - 1); if (!lockMap.ContainsKey(hash)) { lockMap.Add(hash, new object()); } lock (lockMap[hash]) { xVal = (int)(x % Constants.ChunkWidth); zVal = Constants.ChunkWidth; if (xVal < 0) { xVal = Constants.ChunkWidth + xVal; } if (updateMap.ContainsKey(hash)) { updateMap[hash].positions.Add(new long[] { hash, xVal, y, zVal }); updateMap[hash].values.Add(value); } else { ChunkUpdate update = new ChunkUpdate(); update.positions.Add(new long[] { hash, xVal, y, zVal }); update.values.Add(value); updateMap.Add(hash, update); } } } #endregion zVal = (int)(z % Constants.ChunkWidth); #region x&z=0 if (xVal == 0 && zVal == 0) { hash = HashBlock(x - 1, z - 1); if (!lockMap.ContainsKey(hash)) { lockMap.Add(hash, new object()); } lock (lockMap[hash]) { xVal = Constants.ChunkWidth; zVal = Constants.ChunkWidth; if (updateMap.ContainsKey(hash)) { updateMap[hash].positions.Add(new long[] { hash, xVal, y, zVal }); updateMap[hash].values.Add(value); } else { ChunkUpdate update = new ChunkUpdate(); update.positions.Add(new long[] { hash, xVal, y, zVal }); update.values.Add(value); updateMap.Add(hash, update); } } } #endregion }