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;
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 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);
         }
     }
 }
Beispiel #5
0
 private async Task OnChunkUpdateAsync(ChunkKey key, ChunkUpdate update, Channel <ChunkStreamMessage> channel)
 {
     await OutgoingChannel.Writer.WriteAsync(new ChunkStreamMessage(key, update));
 }
Beispiel #6
0
 public ChunkStreamMessage(ChunkKey key, ChunkUpdate update)
 {
     Key    = key;
     Update = update;
 }
Beispiel #7
0
    //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);
            }
        }
    }
Beispiel #8
0
    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
    }