示例#1
0
        private void Schedule(ChunkCoordinates coords, WorkItemPriority priority)
        {
            CancellationTokenSource taskCancelationToken =
                CancellationTokenSource.CreateLinkedTokenSource(CancelationToken.Token);

            Interlocked.Increment(ref _threadsRunning);

            //_tasksQueue.
            if (_workItems.TryAdd(coords, taskCancelationToken))
            {
                Enqueued.Remove(coords);
            }

            var task = Task.Factory.StartNew(() =>
            {
                if (Chunks.TryGetValue(coords, out var val))
                {
                    UpdateChunk(coords, val);
                }

                Interlocked.Decrement(ref _threadsRunning);
                _workItems.TryRemove(coords, out _);
            }, taskCancelationToken.Token, TaskCreationOptions.None, _priorityTaskScheduler);

            if (priority == WorkItemPriority.Highest)
            {
                _priorityTaskScheduler.Prioritize(task);
            }
        }
示例#2
0
        public void ScheduleChunkUpdate(ChunkCoordinates position, ScheduleType type, bool prioritize = false)
        {
            if (Chunks.TryGetValue(position, out IChunkColumn chunk))
            {
                var currentSchedule = chunk.Scheduled;
                if (prioritize)
                {
                    chunk.Scheduled = type;

                    if (!Enqueued.Contains(position) && Enqueued.TryAdd(position))
                    {
                        HighestPriority.Enqueue(position);
                    }

                    return;
                }


                if (currentSchedule != ScheduleType.Unscheduled)
                {
                    return;
                }

                if (!_workItems.ContainsKey(position) &&
                    !Enqueued.Contains(position) && Enqueued.TryAdd(position))
                {
                    chunk.Scheduled = type;

                    Interlocked.Increment(ref _chunkUpdates);
                }
            }
        }
示例#3
0
        public override void Dispose()
        {
            if (_isDisposed)
            {
                _logger.LogTrace("Queue {Name} ({Id})  dispose was already called.", _options.Name, QueueId);
                return;
            }

            _isDisposed = true;
            _logger.LogTrace("Queue {Name} ({Id}) dispose", _options.Name, QueueId);
            _queueDisposedCancellationTokenSource?.Cancel();
            _queueDisposedCancellationTokenSource?.Dispose();
            base.Dispose();

            Abandoned?.Dispose();
            Completed?.Dispose();
            Dequeued?.Dispose();
            Enqueued?.Dispose();
            Enqueuing?.Dispose();
            LockRenewed?.Dispose();

            foreach (var behavior in _behaviors.OfType <IDisposable>())
            {
                behavior.Dispose();
            }

            _behaviors.Clear();
        }
示例#4
0
        public void RemoveChunk(ChunkCoordinates position, bool dispose = true)
        {
            if (_workItems.TryGetValue(position, out var r))
            {
                if (!r.IsCancellationRequested)
                {
                    r.Cancel();
                }
            }

            IChunkColumn chunk;

            if (Chunks.TryRemove(position, out chunk))
            {
                if (dispose)
                {
                    chunk?.Dispose();
                }
            }

            if (_chunkData.TryRemove(position, out var data))
            {
                data?.Dispose();
            }

            if (Enqueued.Remove(position))
            {
                Interlocked.Decrement(ref _chunkUpdates);
            }

            //SkylightCalculator.Remove(position);
            r?.Dispose();
        }
示例#5
0
        public T Enqueue <T>(T command) where T : CommandBase
        {
            _commands.Enqueue(command);

            Enqueued?.Invoke(this, new CommandRunnerEvent(command));

            DispatchNext();

            return(command);
        }
示例#6
0
        public bool TryEnqueue(TValue element)
        {
            lock (_sync)
            {
                if (_order.ContainsKey(element))
                {
                    return(false);
                }

                _order.Add(element, _counter++);
                _values.Add(element);
            }

            Enqueued?.Invoke(this, element);
            return(true);
        }
示例#7
0
 public bool TryEnqueue(T item, int timeout = System.Threading.Timeout.Infinite)
 {
     if (Monitor.TryEnter(q, timeout))
     {
         try
         {
             q.Enqueue(item);
             Enqueued?.Invoke(this, EventArgs.Empty);
         }
         finally { Monitor.Exit(q); }
         return(true);
     }
     else
     {
         return(false);
     }
 }
示例#8
0
文件: QueueBase.cs 项目: nj/Foundatio
        public override void Dispose()
        {
            _logger.Trace("Queue {0} dispose", _queueName);
            base.Dispose();

            Abandoned?.Dispose();
            Completed?.Dispose();
            Dequeued?.Dispose();
            Enqueued?.Dispose();
            Enqueuing?.Dispose();
            LockRenewed?.Dispose();

            foreach (var behavior in _behaviors.OfType <IDisposable>())
            {
                behavior.Dispose();
            }

            _behaviors.Clear();
        }
示例#9
0
        public void Dispose()
        {
            CancelationToken.Cancel();

            foreach (var chunk in Chunks.ToArray())
            {
                Chunks.TryRemove(chunk.Key, out IChunkColumn _);
                Enqueued.Remove(chunk.Key);
                chunk.Value.Dispose();
            }

            foreach (var data in _chunkData.ToArray())
            {
                _chunkData.TryRemove(data.Key, out _);
                data.Value?.Dispose();
            }

            _chunkData = null;
        }
示例#10
0
        public override void Dispose()
        {
            _logger.LogTrace("Queue {0} dispose", _options.Name);
            _queueDisposedCancellationTokenSource?.Cancel();
            base.Dispose();

            Abandoned?.Dispose();
            Completed?.Dispose();
            Dequeued?.Dispose();
            Enqueued?.Dispose();
            Enqueuing?.Dispose();
            LockRenewed?.Dispose();

            foreach (var behavior in _behaviors.OfType <IDisposable>())
            {
                behavior.Dispose();
            }

            _behaviors.Clear();
        }
示例#11
0
        public void ClearChunks()
        {
            var chunks = Chunks.ToArray();

            Chunks.Clear();

            foreach (var chunk in chunks)
            {
                chunk.Value.Dispose();
            }

            var data = _chunkData.ToArray();

            _chunkData.Clear();
            foreach (var entry in data)
            {
                entry.Value?.Dispose();
            }

            Enqueued.Clear();
        }
示例#12
0
 public void Enqueue(T item)
 {
     queue.Enqueue(item);
     Enqueued?.Invoke(null, item);
 }
示例#13
0
 public void OnEnqueued(object sender, PersonModel person, RoomModel room)
 {
     Enqueued?.Invoke(sender, new EnqueingEventArgs(person, room));
 }
示例#14
0
 public override void OnEnqueue(MachineId machineId, string eventName)
 {
     base.OnEnqueue(machineId, eventName);
     Enqueued?.Invoke(machineId, eventName);
 }
示例#15
0
 public virtual void Enqueue(T item)
 {
     queue.Enqueue(item);
     Enqueued?.Invoke(this, new ItemEventArgs <T>(item));
     dequeueEvent.Set();
 }
示例#16
0
        private void ChunkUpdateThread()
        {
            //Environment.ProcessorCount / 2;
            Stopwatch sw = new Stopwatch();

            while (!CancelationToken.IsCancellationRequested)
            {
                int maxThreads = Options.VideoOptions.ChunkThreads;

                var cameraChunkPos = new ChunkCoordinates(new PlayerLocation(_cameraPosition.X, _cameraPosition.Y,
                                                                             _cameraPosition.Z));
                //SpinWait.SpinUntil(() => Interlocked.Read(ref _threadsRunning) < maxThreads);

                foreach (var data in _chunkData.ToArray().Where(x =>
                                                                QuickMath.Abs(cameraChunkPos.DistanceTo(x.Key)) > Options.VideoOptions.RenderDistance))
                {
                    data.Value?.Dispose();
                    _chunkData.TryRemove(data.Key, out _);
                }

                //var cameraChunkPos = new ChunkCoordinates(new PlayerLocation(camera.Position.X, camera.Position.Y,
                //     camera.Position.Z));

                var renderedChunks = Chunks.ToArray().Where(x =>
                {
                    if (Math.Abs(x.Key.DistanceTo(cameraChunkPos)) > Options.VideoOptions.RenderDistance)
                    {
                        return(false);
                    }

                    var chunkPos = new Vector3(x.Key.X * ChunkColumn.ChunkWidth, 0, x.Key.Z * ChunkColumn.ChunkDepth);
                    return(_cameraBoundingFrustum.Intersects(new Microsoft.Xna.Framework.BoundingBox(chunkPos,
                                                                                                     chunkPos + new Vector3(ChunkColumn.ChunkWidth, 256 /*16 * ((x.Value.GetHeighest() >> 4) + 1)*/,
                                                                                                                            ChunkColumn.ChunkDepth))));
                }).ToArray();

                foreach (var c in renderedChunks)
                {
                    if (_chunkData.TryGetValue(c.Key, out var data))
                    {
                        if (_renderedChunks.TryAdd(data))
                        {
                        }
                    }
                }

                foreach (var c in _renderedChunks.ToArray())
                {
                    if (c == null || c.Coordinates == default || !renderedChunks.Any(x => x.Key.Equals(c.Coordinates)))
                    {
                        _renderedChunks.Remove(c);
                    }
                }

                if (Interlocked.Read(ref _threadsRunning) >= maxThreads)
                {
                    continue;
                }


                bool nonInView = false;
                try
                {
                    if (HighestPriority.TryDequeue(out var coords))
                    {
                        if (Math.Abs(cameraChunkPos.DistanceTo(coords)) > Options.VideoOptions.RenderDistance)
                        {
                            if (!Enqueued.Contains(coords))
                            {
                                Enqueued.Add(coords);
                            }
                        }
                        else
                        {
                            Enqueued.Remove(coords);
                            Schedule(coords, WorkItemPriority.Highest);
                        }

                        //Enqueued.Remove(coords);
                    }
                    else if (Enqueued.Count > 0)
                    {
                        //var cc = new ChunkCoordinates(CameraPosition);

                        var where = Enqueued.Where(x => IsWithinView(x, _cameraBoundingFrustum)).ToArray();
                        if (where.Length > 0)
                        {
                            coords = where.MinBy(x => Math.Abs(x.DistanceTo(new ChunkCoordinates(_cameraPosition))));
                        }
                        else
                        {
                            coords = Enqueued.MinBy(x => Math.Abs(x.DistanceTo(new ChunkCoordinates(_cameraPosition))));
                        }

                        if (Math.Abs(cameraChunkPos.DistanceTo(coords)) <= Options.VideoOptions.RenderDistance)
                        {
                            if (!_workItems.ContainsKey(coords))
                            {
                                Schedule(coords, WorkItemPriority.AboveNormal);
                            }
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    break;
                }
            }

            if (!CancelationToken.IsCancellationRequested)
            {
                Log.Warn($"Chunk update loop has unexpectedly ended!");
            }

            //TaskScheduler.Dispose();
        }
示例#17
0
 public void Enqueue(T directory)
 {
     Queue.Enqueue(directory);
     Enqueued?.Invoke();
 }
示例#18
0
 private void WakeProcessor() => Enqueued?.Invoke(this, EventArgs.Empty);