public void AddItems () {
            var l = new UnorderedList<int>();

            l.Add(0);
            l.Add(2);
            l.Add(3);
            l.Add(5);

            Assert.AreEqual(
                new int[] { 0, 2, 3, 5 },
                l.ToArray()
            );                
        }
Exemple #2
0
        private HardwareBufferEntry PrepareToFillBuffer(
            HardwareBufferEntry currentBufferEntry,
            int vertexOffset, int indexOffset,
            int additionalVertexCount, int additionalIndexCount,
            bool forceExclusiveBuffer
            )
        {
            var allocateNew = (currentBufferEntry == null) ||
                              forceExclusiveBuffer ||
                              CannotFitInBuffer(currentBufferEntry, additionalVertexCount, additionalIndexCount);

            if (allocateNew)
            {
                var newBuffer = AllocateSuitablySizedHardwareBuffer(additionalVertexCount, additionalIndexCount, forceExclusiveBuffer);
                HardwareBufferEntry entry;

                if (!_ReusableHardwareBufferEntries.TryPopFront(out entry))
                {
                    // FIXME: This frequently happens and it seems like the reason is that switching buffer generators to thread local
                    //  means that parallel prepare ends up creating dozens of generators that all fail to pool enough instances
                    // Console.WriteLine("New entry");
                    entry = new HardwareBufferEntry();
                }
                else
                {
                    // Console.WriteLine("Reused entry");
                }

                entry.Initialize(
                    newBuffer, vertexOffset, indexOffset, additionalVertexCount, additionalIndexCount
                    );
                entry.AddedToList = true;
                _UsedHardwareBufferEntries.Add(entry);

                _FillingHardwareBufferEntry = entry;

                return(entry);
            }
            else
            {
                if (!currentBufferEntry.AddedToList)
                {
                    currentBufferEntry.AddedToList = true;
                    _UsedHardwareBufferEntries.Add(currentBufferEntry);
                }
                currentBufferEntry.SourceVertexCount += additionalVertexCount;
                currentBufferEntry.SourceIndexCount  += additionalIndexCount;

                return(currentBufferEntry);
            }
        }
            public void ReplicateFrom(Table source)
            {
                var sourceArray = source.ValuesById;
                var sourceCount = sourceArray.Count;
                var i           = ValuesById.Count;

                while (i < sourceCount)
                {
                    var item = sourceArray.DangerousGetItem(i);
                    ValuesById.Add(item);
                    IdsByValue[item] = i;
                    i++;
                }
            }
Exemple #4
0
        public void MutableEnumeratorRemoveCurrentAndGetNext()
        {
            var l = new UnorderedList<int>();
            l.Add(1);
            l.Add(2);

            int item;
            using (var e = l.GetEnumerator())
            while (e.GetNext(out item))
                e.RemoveCurrent();

            Assert.AreEqual(
                new int[] { },
                l.ToArray()
            );
        }
Exemple #5
0
        /// <summary>
        /// Internal method to add an entity to the entity manager and register it with all
        /// associated systems. This executes the add immediately.
        /// </summary>
        /// <param name="toAdd">The entity to add.</param>
        private void InternalAddEntity(RuntimeEntity toAdd)
        {
            toAdd.GameEngine = this;

            // notify listeners that we both added and created the entity
            Log <GameEngine> .Info("Submitting internal EntityAddedEvent for " + toAdd);

            EventNotifier.Submit(EntityAddedEvent.Create(toAdd));
            EventNotifier.Submit(ShowEntityEvent.Create(toAdd));

            // add it to the entity index
            _entityIndex.AddEntity(toAdd);

            // register listeners
            toAdd.ModificationNotifier.Listener    += OnEntityModified;
            toAdd.DataStateChangeNotifier.Listener += OnEntityDataStateChanged;

            // notify ourselves of data state changes so that it the entity is pushed to systems
            toAdd.DataStateChangeNotifier.Notify();

            // ensure it contains metadata for our keys
            toAdd.Metadata.UnorderedListMetadata[_entityUnorderedListMetadataKey] = new UnorderedListMetadata();

            // add it our list of entities
            _entities.Add(toAdd, GetEntitiesListFromMetadata(toAdd));
        }
Exemple #6
0
        protected void MakeDrawArguments(
            PrimitiveType primitiveType,
            ref Internal.VertexBuffer <GeometryVertex> vb, ref Internal.IndexBuffer ib,
            ref int vertexOffset, ref int indexOffset, out int primCount,
            int vertexCount, int indexCount
            )
        {
            if ((vertexCount == 0) || (indexCount == 0))
            {
                primCount = 0;
                return;
            }

            primCount = primitiveType.ComputePrimitiveCount(indexCount);

            _DrawArguments.Add(new DrawArguments {
                PrimitiveType  = primitiveType,
                VertexOffset   = vertexOffset,
                VertexCount    = vertexCount,
                IndexOffset    = indexOffset,
                IndexCount     = indexCount,
                PrimitiveCount = primCount
            });

            vertexOffset += vertexCount;
            indexOffset  += indexCount;
        }
Exemple #7
0
        private HardwareBufferEntry PrepareToFillBuffer(
            HardwareBufferEntry currentBufferEntry,
            int vertexOffset, int indexOffset,
            int additionalVertexCount, int additionalIndexCount,
            bool forceExclusiveBuffer
            )
        {
            var allocateNew = (currentBufferEntry == null) ||
                              forceExclusiveBuffer ||
                              CannotFitInBuffer(currentBufferEntry, additionalVertexCount, additionalIndexCount);

            if (allocateNew)
            {
                var newBuffer = AllocateSuitablySizedHardwareBuffer(additionalVertexCount, additionalIndexCount);
                var entry     = new HardwareBufferEntry(newBuffer, vertexOffset, indexOffset, additionalVertexCount, additionalIndexCount);

                _UsedHardwareBuffers.Add(entry);
                _FillingHardwareBufferEntry = entry;

                return(entry);
            }
            else
            {
                currentBufferEntry.SourceVertexCount += additionalVertexCount;
                currentBufferEntry.SourceIndexCount  += additionalIndexCount;

                return(currentBufferEntry);
            }
        }
Exemple #8
0
        private T[] EnsureBufferCapacity <T> (
            ref T[] array, ref int usedElementCount,
            int elementsToAdd, out int oldElementCount
            )
        {
            oldElementCount = usedElementCount;
            int newElementCount = (usedElementCount += elementsToAdd);

            var oldArray     = array;
            var oldArraySize = array.Length;

            if (oldArraySize >= newElementCount)
            {
                return(array);
            }

            var newSize  = PickNewArraySize(oldArraySize, newElementCount);
            var newArray = new T[newSize];

            _PendingCopies.Add(new PendingCopy {
                Source           = oldArray,
                SourceIndex      = 0,
                Destination      = newArray,
                DestinationIndex = 0,
                Count            = oldElementCount
            });

            return(array = newArray);
        }
Exemple #9
0
        protected void BuildMaterialCache()
        {
            lock (Lock) {
                MaterialCacheScratchSet.Clear();

                foreach (var field in AllMaterialFields)
                {
                    var material = field();
                    if (material != null)
                    {
                        MaterialCacheScratchSet.Add(material);
                    }
                }

                foreach (var coll in AllMaterialCollections)
                {
                    coll()?.AddToSet(MaterialCacheScratchSet);
                }

                foreach (var m in ExtraMaterials)
                {
                    MaterialCacheScratchSet.Add(m);
                }

                MaterialCache.Clear();
                foreach (var m in MaterialCacheScratchSet)
                {
                    MaterialCache.Add(m);
                }
            }
        }
        public void Clear () {
            var l = new UnorderedList<int>(new int[] { 1, 2 });

            l.Clear();
            Assert.AreEqual(
                new int[0],
                l.ToArray()
            );

            l.Add(1);
            l.Add(2);
            Assert.AreEqual(
                new int[] { 1, 2 },
                l.ToArray()
            );
        }
Exemple #11
0
        public void Release(ref UnorderedList <T> _list)
        {
            var list = _list;

            _list = null;

            if (list == null)
            {
                return;
            }

            if (list.Capacity > MaxItemCapacity)
            {
                lock (_LargePool) {
                    if (_LargePool.Count >= LargePoolCapacity)
                    {
                        return;
                    }

                    _LargePool.Add(list);
                }

                return;
            }

            lock (_Pool) {
                if (_Pool.Count >= PoolCapacity)
                {
                    return;
                }

                _Pool.Add(list);
            }
        }
Exemple #12
0
        protected override void Initialize()
        {
            base.Initialize();

            var rng = new Random();

            float now = (float)Time.Seconds;

            for (int i = 0; i < NumberOfOrbs; i++)
            {
                Orbs.Add(new Orb(rng, now - (float)rng.NextDouble()));
            }

            RNGSeed = rng.Next();

            RNGs.Add(rng);
        }
            public void Write(Vector2 a, Vector2 b)
            {
                if (CropBounds.HasValue && Geometry.DoesLineIntersectRectangle(a, b, CropBounds.Value))
                {
                    return;
                }

                Lines.Add(new DeltaLine(a, b));
            }
        private void RunPendingDraws()
        {
            lock (PendingDrawQueue)
                if (PendingDrawQueue.Count == 0)
                {
                    return;
                }

            int        i  = 0;
            BatchGroup bg = null;

            while (true)
            {
                PendingDraw pd;
                lock (PendingDrawQueue) {
                    if (PendingDrawQueue.Count == 0)
                    {
                        return;
                    }
                    pd = PendingDrawQueue.DangerousGetItem(0);
                    PendingDrawQueue.DangerousRemoveAt(0);
                }

                ExceptionDispatchInfo excInfo = null;
                try {
                    if (!AutoRenderTarget.IsRenderTargetValid(pd.RenderTarget))
                    {
                        throw new Exception("Render target for pending draw was disposed between queue and prepare");
                    }

                    if (!DoSynchronousDrawToRenderTarget(pd.RenderTarget, pd.Materials, pd.Handler, pd.UserData, ref pd.ViewTransform, "Pending Draw"))
                    {
                        throw new Exception("Unknown failure performing pending draw");
                    }
                } catch (Exception exc) {
                    excInfo = ExceptionDispatchInfo.Capture(exc);
                }
                // throw new Exception("Unexpected error performing pending draw");

                if (pd.OnComplete != null)
                {
                    lock (CompletedPendingDrawQueue)
                        CompletedPendingDrawQueue.Add(new CompletedPendingDraw {
                            UserData     = pd.UserData,
                            Exception    = excInfo,
                            OnComplete   = pd.OnComplete,
                            RenderTarget = pd.RenderTarget
                        });
                }
                else if (excInfo != null)
                {
                }
                else
                {
                }
            }
        }
Exemple #15
0
        public virtual void Release(T obj)
        {
            lock (_Pool) {
                if (_Pool.Count > PoolCapacity)
                {
                    return;
                }

                _Pool.Add(obj);
            }
        }
Exemple #16
0
        private void OnClearListDrained(int listsCleared, bool moreRemain)
        {
            var cl = ClearedLists.Value;

            if (cl == null) // FIXME: This shouldn't be possible
            {
                return;
            }

            bool isSmallLocked = false, isLargeLocked = false;

            try {
                foreach (var item in cl)
                {
                    var isLarge = (item.Capacity > SmallPoolMaxItemSize);
                    if (isLarge)
                    {
                        if (!isLargeLocked)
                        {
                            isLargeLocked = true;
                            Monitor.Enter(_LargePool);
                        }
                        if (_LargePool.Count >= LargePoolCapacity)
                        {
                            continue;
                        }
                        _LargePool.Add(item);
                    }
                    else
                    {
                        if (!isSmallLocked)
                        {
                            isSmallLocked = true;
                            Monitor.Enter(_Pool);
                        }
                        if (_Pool.Count >= SmallPoolCapacity)
                        {
                            continue;
                        }
                        _Pool.Add(item);
                    }
                }
            } finally {
                if (isSmallLocked)
                {
                    Monitor.Exit(_Pool);
                }
                if (isLargeLocked)
                {
                    Monitor.Exit(_LargePool);
                }
                cl.Clear();
            }
        }
Exemple #17
0
        public void Release(ref UnorderedList <T> _list)
        {
            var list = _list;

            _list = null;

            if (list == null)
            {
                return;
            }

            if (list.Capacity > SmallPoolMaxItemSize)
            {
                if (list.Capacity < LargePoolMaxItemSize)
                {
                    lock (_LargePool) {
                        if (_LargePool.Count >= LargePoolCapacity)
                        {
                            return;
                        }
                    }

                    list.Clear();

                    lock (_LargePool) {
                        if (_LargePool.Count >= LargePoolCapacity)
                        {
                            return;
                        }

                        _LargePool.Add(list);
                    }
                }

                return;
            }

            lock (_Pool) {
                if (_Pool.Count >= SmallPoolCapacity)
                {
                    return;
                }
            }

            list.Clear();

            lock (_Pool) {
                if (_Pool.Count >= SmallPoolCapacity)
                {
                    return;
                }
                _Pool.Add(list);
            }
        }
Exemple #18
0
        void IBufferGenerator.Reset()
        {
            lock (_StateLock) {
                _FillingHardwareBufferEntry = null;
                _FlushedToBuffers           = 0;
                _VertexCount = _IndexCount = 0;

                // Any buffers that remain unused (either from being too small, or being unnecessary now)
                //  should be disposed.
                THardwareBuffer hb;
                using (var e = _UnusedHardwareBuffers.GetEnumerator())
                    while (e.GetNext(out hb))
                    {
                        hb.Age += 1;

                        bool shouldKill = (hb.Age >= MaxBufferAge) ||
                                          ((_UnusedHardwareBuffers.Count > MaxUnusedBuffers) && (hb.Age > 1));

                        if (shouldKill)
                        {
                            e.RemoveCurrent();
                            hb.Invalidate();

                            DisposeResource(hb);
                        }
                    }

                // Return any buffers that were used this frame to the unused state.
                foreach (var _hb in _UsedHardwareBuffers)
                {
                    // HACK
                    var hwb = _hb.Buffer;
                    hwb.Invalidate();

                    _UnusedHardwareBuffers.Add(hwb);
                }

                _UsedHardwareBuffers.Clear();

                foreach (var swb in _SoftwareBuffers)
                {
                    swb.Uninitialize();
                    _SoftwareBufferPool.Release(swb);
                }

                _SoftwareBuffers.Clear();

                /*
                 * Array.Clear(_VertexArray, 0, _VertexArray.Length);
                 * Array.Clear(_IndexArray, 0, _IndexArray.Length);
                 */
            }
        }
Exemple #19
0
            public void UpdateItems()
            {
                var items = (from kvp in ListsByPriority orderby kvp.Key descending select kvp.Value);

                Items.Clear();
                foreach (var l in items)
                {
                    var buf = new IWorkQueue[l.Count];
                    l.CopyTo(buf, 0, l.Count);
                    Items.Add(buf);
                }
            }
Exemple #20
0
        private void CreateList(int?capacity = null)
        {
            if (!capacity.HasValue)
            {
                capacity = ListCapacity;
            }

            _HasList = true;
            if (ListPool != null)
            {
                Items = ListPool.Allocate(capacity);
            }
            else if (capacity.HasValue)
            {
                Items = new UnorderedList <T>(capacity.Value);
            }
            else
            {
                Items = new UnorderedList <T>();
            }

            if (_Count > 0)
            {
                Items.Add(ref Item1);
            }
            if (_Count > 1)
            {
                Items.Add(ref Item2);
            }
            if (_Count > 2)
            {
                Items.Add(ref Item3);
            }
            if (_Count > 3)
            {
                Items.Add(ref Item4);
            }
            Item1  = Item2 = Item3 = Item4 = default(T);
            _Count = 0;
        }
        protected void UpdateSector(ParticleCollection sector)
        {
            if (sector.Count == 0)
            {
                return;
            }

            _SectorsFromLastUpdate.Add(sector);

            UpdateArgs.SetSector(sector);
            Updater(UpdateArgs);
            UpdateArgs.Enumerator.Dispose();
        }
Exemple #22
0
        private void AddChild(CancellationScope child)
        {
            if (this == Null)
            {
                return;
            }

            if (Children == null)
            {
                Children = new UnorderedList <CancellationScope>();
            }

            Children.Add(child);
        }
Exemple #23
0
        /// <summary>
        /// You can use this to request a work queue for a given type of work item, then queue
        ///  multiple items cheaply. If you queue items directly, it's your responsibility to call
        ///  ThreadGroup.NotifyQueuesChanged to ensure that a sufficient number of threads are ready
        ///  to perform work.
        /// </summary>
        /// <param name="forMainThread">Pass true if you wish to queue a work item to run on the main thread. Will be set automatically for main-thread-only work items.</param>
        public WorkQueue <T> GetQueueForType <T> (bool forMainThread = false)
            where T : IWorkItem
        {
            var           type = typeof(T);
            bool          resultIsNew;
            IWorkQueue    existing;
            WorkQueue <T> result;

            var queues           = Queues;
            var isMainThreadOnly = typeof(IMainThreadWorkItem).IsAssignableFrom(type) || forMainThread;

            // If the job must be run on the main thread, add to the main thread queue
            // Note that you must manually pump this queue yourself.
            if (isMainThreadOnly)
            {
                queues = MainThreadQueues;
            }

            lock (queues) {
                if (!queues.TryGetValue(type, out existing))
                {
                    result = CreateQueueForType <T>(isMainThreadOnly);
                    queues.Add(type, result);
                    resultIsNew = true;
                }
                else
                {
                    result      = (WorkQueue <T>)existing;
                    resultIsNew = false;
                }
            }

            if (isMainThreadOnly && resultIsNew)
            {
                lock (MainThreadQueueList)
                    MainThreadQueueList.Add(result);
            }

            if (resultIsNew)
            {
                NewQueueCreated();
                NotifyQueuesChanged();
            }

            return(result);
        }
Exemple #24
0
        public void Write(Vector2 a, Vector2 b)
        {
            if (CropBounds.HasValue)
            {
                // constructor doesn't get inlined here :(
                Bounds lineBounds;
                lineBounds.TopLeft.X     = Math.Min(a.X, b.X);
                lineBounds.TopLeft.Y     = Math.Min(a.Y, b.Y);
                lineBounds.BottomRight.X = Math.Max(a.X, b.X);
                lineBounds.BottomRight.Y = Math.Max(a.Y, b.Y);

                if (!CropBounds.Value.Intersects(lineBounds))
                {
                    return;
                }
            }

            Lines.Add(new Line(a, b));
        }
Exemple #25
0
        public void Add(Batch batch)
        {
            if (State != State_Initialized)
            {
                throw new InvalidOperationException();
            }

            lock (Batches) {
#if DEBUG && PARANOID
                if (Batches.Contains(batch))
                {
                    throw new InvalidOperationException("Batch already added to this frame");
                }
#endif

                Batches.Add(batch);
                batch.Container = this;
            }
        }
Exemple #26
0
        public void Reset(int frameIndex)
        {
            lock (_StateLock) {
                _FillingHardwareBufferEntry = null;
                _FlushedToBuffers           = 0;
                _VertexCount = _IndexCount = 0;

                lock (_StaticStateLock)
                    StaticReset(frameIndex, RenderManager);

                // Return any buffers that were used this frame to the unused state.
                foreach (var _hb in _UsedHardwareBuffers)
                {
                    // HACK
                    var hwb = _hb.Buffer;
                    hwb.Invalidate(frameIndex);

                    lock (_StaticStateLock)
                        _UnusedHardwareBuffers.Add(hwb);
                }

                _UsedHardwareBuffers.Clear();

                _BufferCache.Clear();

                foreach (var swb in _SoftwareBuffers)
                {
                    swb.Uninitialize();
                    _SoftwareBufferPool.Release(swb);
                }

                _SoftwareBuffers.Clear();

                _LastFrameReset = frameIndex;

                /*
                 * Array.Clear(_VertexArray, 0, _VertexArray.Length);
                 * Array.Clear(_IndexArray, 0, _IndexArray.Length);
                 */
            }
        }
Exemple #27
0
        private void SpawnThread(bool force)
        {
            // Just in case thread state gets out of sync...
            if ((Threads.Count >= MaximumThreadCount) && !force)
            {
                return;
            }

            Interlocked.Exchange(ref LastTimeThreadWasIdle, TimeProvider.Ticks);
            var thread = new GroupThread(this);

            Threads.Add(thread);

            Thread.MemoryBarrier();

            HasNoThreads       = false;
            CanMakeNewThreads  = Threads.Count < MaximumThreadCount;
            CurrentThreadCount = Threads.Count;

            Thread.MemoryBarrier();
        }
Exemple #28
0
        private void ClearAndReturn(UnorderedList <T> list, UnorderedList <UnorderedList <T> > pool, int limit, WorkQueueNotifyMode notifyMode = WorkQueueNotifyMode.Stochastically)
        {
            if (
                !FastClearEnabled &&
                (list.Count > DeferredClearSizeThreshold) &&
                (_ClearQueue != null)
                )
            {
                _ClearQueue.Enqueue(new ListClearWorkItem {
                    List = list,
                }, notifyChanged: notifyMode);
                return;
            }

            // HACK: Acquiring the lock here would be technically correct but
            //  unnecessarily slow, since we're just trying to avoid doing a clear
            //  in cases where the list will be GCd anyway
            if (pool.Count >= limit)
            {
                return;
            }

            if (FastClearEnabled)
            {
                list.UnsafeFastClear();
            }
            else
            {
                list.Clear();
            }

            lock (pool) {
                if (pool.Count >= limit)
                {
                    return;
                }

                pool.Add(list);
            }
        }
        /// <summary>
        /// Queues a draw operation to the specified render target.
        /// The draw operation will occur at the start of the next frame before the frame itself has been rendered.
        /// </summary>
        /// <param name="onComplete">A Future instance that will have userData stored into it when rendering is complete.</param>
        public bool QueueDrawToRenderTarget(
            RenderTarget2D renderTarget, DefaultMaterialSet materials,
            PendingDrawHandler handler, object userData = null, IFuture onComplete = null,
            ViewTransform?viewTransform = null
            )
        {
            if (!ValidateDrawToRenderTarget(renderTarget, materials))
            {
                return(false);
            }

            lock (PendingDrawQueue)
                PendingDrawQueue.Add(new PendingDraw {
                    RenderTarget  = renderTarget,
                    Handler       = handler,
                    Materials     = materials,
                    UserData      = userData,
                    OnComplete    = onComplete,
                    ViewTransform = viewTransform
                });
            return(true);
        }
Exemple #30
0
            /// <summary>
            /// Updates the status of the entity inside of the cache; ie, if the entity is now
            /// passing the filter but was not before, then it will be added to the cache.
            /// </summary>
            /// <returns>The change in cache status for the entity</returns>
            public CacheChangeResult UpdateCache(RuntimeEntity entity)
            {
                UnorderedListMetadata metadata = GetMetadata(entity);

                bool passed   = _filter.Check(entity);
                bool contains = CachedEntities.Contains(entity, metadata);

                // The entity is not in the cache it now passes the filter, so add it to the cache
                if (contains == false && passed)
                {
                    CachedEntities.Add(entity, metadata);
                    return(CacheChangeResult.Added);
                }

                // The entity is in the cache but it no longer passes the filter, so remove it
                if (contains && passed == false)
                {
                    CachedEntities.Remove(entity, metadata);
                    return(CacheChangeResult.Removed);
                }

                // no change to the cache
                return(CacheChangeResult.NoChange);
            }
Exemple #31
0
        /// <summary>
        /// Allocates a software vertex/index buffer pair that you can write vertices and indices into.
        /// Once this generator is flushed, it will have an associated hardware buffer containing your vertex/index data.
        /// </summary>
        /// <param name="vertexCount">The number of vertices.</param>
        /// <param name="indexCount">The number of indices.</param>
        /// <param name="forceExclusiveBuffer">Forces a unique hardware vertex/index buffer pair to be created for this allocation. This allows you to ignore the hardware vertex/index offsets.</param>
        /// <returns>A software buffer.</returns>
        public SoftwareBuffer Allocate(int vertexCount, int indexCount, bool forceExclusiveBuffer = false)
        {
            var requestedVertexCount = vertexCount;
            var requestedIndexCount  = indexCount;

            if (vertexCount > MaxVerticesPerHardwareBuffer)
            {
                throw new ArgumentOutOfRangeException("vertexCount", vertexCount, "Maximum vertex count on this platform is " + MaxVerticesPerHardwareBuffer);
            }

            lock (_StateLock) {
                if (_FlushedToBuffers != 0)
                {
                    throw new InvalidOperationException("Already flushed");
                }

                // When we resize our internal array, we have to queue up copies from the old small array to the new large array.
                // This is because while Allocate is thread-safe, consumers are allowed to write to their allocations without synchronization,
                //  so we can't be sure that the old array has been filled yet.
                // Flush() is responsible for doing all these copies to ensure that all vertex data eventually makes it into the large array
                //  from which actual hardware buffer initialization occurs.

                SoftwareBuffer swb;

                int oldVertexCount, oldIndexCount;
                var didArraysChange = EnsureBufferCapacity(
                    ref _VertexArray, ref _VertexCount, vertexCount, out oldVertexCount
                    );
                if (EnsureBufferCapacity(
                        ref _IndexArray, ref _IndexCount, indexCount, out oldIndexCount
                        ))
                {
                    didArraysChange = true;
                }

                if (didArraysChange)
                {
                    foreach (var _swb in _SoftwareBuffers)
                    {
                        _swb.ArraysChanged(_VertexArray, _IndexArray);
                    }
                }

                HardwareBufferEntry hardwareBufferEntry;

                hardwareBufferEntry = _FillingHardwareBufferEntry;

                hardwareBufferEntry = PrepareToFillBuffer(
                    hardwareBufferEntry,
                    oldVertexCount, oldIndexCount,
                    vertexCount, indexCount,
                    forceExclusiveBuffer
                    );

                int oldHwbVerticesUsed, oldHwbIndicesUsed;
                oldHwbVerticesUsed = hardwareBufferEntry.VerticesUsed;
                oldHwbIndicesUsed  = hardwareBufferEntry.IndicesUsed;

                hardwareBufferEntry.VerticesUsed += vertexCount;
                hardwareBufferEntry.IndicesUsed  += indexCount;

                hardwareBufferEntry.SoftwareBufferCount += 1;

                swb = _SoftwareBufferPool.Allocate();
                if (swb.IsInitialized)
                {
                    throw new ThreadStateException();
                }
                swb.Initialize(
                    new ArraySegment <TVertex>(_VertexArray, hardwareBufferEntry.VertexOffset + oldHwbVerticesUsed, requestedVertexCount),
                    new ArraySegment <TIndex>(_IndexArray, hardwareBufferEntry.IndexOffset + oldHwbIndicesUsed, requestedIndexCount),
                    hardwareBufferEntry.Buffer,
                    oldHwbVerticesUsed,
                    oldHwbIndicesUsed
                    );

                _SoftwareBuffers.Add(swb);

                return(swb);
            }
        }
Exemple #32
0
        public void Reset(int frameIndex)
        {
            var id = RenderManager.DeviceManager.DeviceId;

            lock (_StateLock) {
                _FillingHardwareBufferEntry = null;
                _FlushedToBuffers           = 0;
                _VertexCount = _IndexCount = 0;

                lock (_StaticStateLock)
                    StaticReset(frameIndex, RenderManager);

                foreach (var _hb in _PreviouslyUsedHardwareBufferEntries)
                {
                    _ReusableHardwareBufferEntries.Add(_hb);
                }
                _PreviouslyUsedHardwareBufferEntries.Clear();

                // Return any buffers that were used this frame to the unused state.
                foreach (var _hb in _UsedHardwareBufferEntries)
                {
                    _hb.AddedToList = false;
                    _PreviouslyUsedHardwareBufferEntries.Add(_hb);

                    // HACK
                    var hwb = _hb.Buffer;
                    if (hwb.DeviceId < id)
                    {
                        continue;
                    }
                    hwb.Invalidate(frameIndex);

                    lock (_StaticStateLock) {
                        if (hwb.IsLarge)
                        {
                            _LargeUnusedBufferCount++;
                        }
                        else
                        {
                            _SmallUnusedBufferCount++;
                        }
                        _UnusedHardwareBuffers.Add(hwb);
                    }
                }

                _UsedHardwareBufferEntries.Clear();

                foreach (var kvp in _BufferCache)
                {
                    var swb = kvp.Value;
                    if (!swb.IsInitialized)
                    {
                        continue;
                    }

                    // Console.WriteLine($"Uninit corner buffer {swb}");
                    swb.Uninitialize();
                    _SoftwareBufferPool.Release(swb);
                }
                _BufferCache.Clear();

                foreach (var swb in _SoftwareBuffers)
                {
                    if (!swb.IsInitialized)
                    {
                        continue;
                    }

                    swb.Uninitialize();
                    _SoftwareBufferPool.Release(swb);
                }

                _SoftwareBuffers.Clear();

                _LastFrameReset = frameIndex;

                /*
                 * Array.Clear(_VertexArray, 0, _VertexArray.Length);
                 * Array.Clear(_IndexArray, 0, _IndexArray.Length);
                 */
            }
        }
Exemple #33
0
        /// <param name="onException">To avoid generating garbage use a static method or a cached delegate</param>
        public void Execute()
        {
            defaultTimer.UpdateCurrentTime();

            timesUpdated++;
            for (int i = 0; i < recurrentCallbacks.Length; i++)
            {
                var queue = recurrentCallbacks[i];

                // Execute Delayed Deletes
                var delayedQueue = delayedRemoves[i];
                if (delayedQueue.Count > 0)
                {
                    lock (delayedQueue) {
                        while (delayedQueue.Count > 0)
                        {
                            var reference = delayedQueue.ExtractLast();
                            for (int j = 0; j < queue.Count; j++)
                            {
                                if (queue.elements[j].id == reference.id)
                                {
                                    queue.RemoveAt(j);
                                    break;
                                }
                            }
                        }
                    }
                }

                for (int j = 0; j < queue.Count; j++)
                {
                    try {
                        queue.elements[j].action();
                    }
                    catch (Exception e) {
                        Console.WriteLine(e);
                        if (null != onException)
                        {
                            onException.Invoke(e);
                        }
                    }
                }
            }


            for (int i = 0; i < actionsStillWaiting.Count;)
            {
                if (actionsStillWaiting[i].ItsTime())
                {
                    try {
                        actionsStillWaiting[i].action.Invoke();
                    }
                    catch (Exception e) {
                        Console.WriteLine(e);
                        if (null != onException)
                        {
                            onException.Invoke(e);
                        }
                    }
                    finally {
                        actionsStillWaiting.RemoveAt(i);
                    }
                }
                else
                {
                    i++;
                }
            }

            TimedAction timedAction;

            while (queuedUpdateCallbacks.Dequeue(out timedAction))
            {
                if (timedAction.ItsTime())
                {
                    try {
                        timedAction.action();
                    }
                    catch (Exception e) {
                        Console.WriteLine(e);
                        if (null != onException)
                        {
                            onException.Invoke(e);
                        }
                    }
                }
                else
                {
                    actionsStillWaiting.Add(timedAction);
                }
            }
        }