Esempio n. 1
0
        public unsafe void PoolCapacity(ParticlePool.ListPolicy policy)
        {
            const int maxParticles = 10;
            var pool = new ParticlePool(0, maxParticles, policy);

            const bool forceCreation = true;
            pool.FieldExists(ParticleFields.Position,       forceCreation);
            pool.FieldExists(ParticleFields.RemainingLife,  forceCreation);
            pool.FieldExists(ParticleFields.Velocity,       forceCreation);
            pool.FieldExists(ParticleFields.Size,           forceCreation);

            var testPos = new Vector3(1, 2, 3);
            var testVel = new Vector3(5, 6, 7);
            var testLife = 5f;
            var testSize = 4f;

            // Spawn all particles
            for (int i = 0; i < maxParticles; i++)
            {
                pool.AddParticle();
            }


            {
                // Field accessors break every time there is a change in the pool, so we need to exract them every time
                // We can extract them before the tight loop on all living particles
                var positionField   = pool.GetField(ParticleFields.Position);
                var lifetimeField   = pool.GetField(ParticleFields.RemainingLife);
                var velocityField   = pool.GetField(ParticleFields.Velocity);
                var sizeField       = pool.GetField(ParticleFields.Size);

                foreach (var particle in pool)
                {
                    *((Vector3*)particle[positionField]) = testPos;

                    *((float*)particle[lifetimeField]) = testLife;

                    *((Vector3*)particle[velocityField]) = testVel;

                    *((float*)particle[sizeField]) = testSize;
                }
            }

            // Double the pool capacity and assert that the first half of particles still have the same fields
            pool.SetCapacity(2 * maxParticles);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                var sorter = new ParticleSorterLiving(pool);
                sorter.Sort();

                var i = 0;
                foreach (var particle in sorter)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    Assert.That(*((Vector3*)particle[velocityField]), Is.EqualTo(testVel));

                    Assert.That(*((float*)particle[sizeField]), Is.EqualTo(testSize));

                    i++;
                }

                // Assert that the number of living particles is still maxParticles, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles));
            }

            // Halve the pool capacity from its original size. Now all the particles should still have the same fields
            pool.SetCapacity(maxParticles / 2);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                var sorter = new ParticleSorterLiving(pool);
                sorter.Sort();

                var i = 0;
                foreach (var particle in sorter)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    Assert.That(*((Vector3*)particle[velocityField]), Is.EqualTo(testVel));

                    Assert.That(*((float*)particle[sizeField]), Is.EqualTo(testSize));

                    i++;
                }

                // Assert that the number of living particles is still maxParticles /2, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles / 2));
            }

        }
        public unsafe void PoolFields(ParticlePool.ListPolicy policy)
        {
            const int maxParticles = 10;
            var pool = new ParticlePool(0, maxParticles, policy);

            // Spawn all particles
            for (int i = 0; i < maxParticles; i++)
            {
                pool.AddParticle();
            }

            const bool forceCreation = true;

            // Position
            pool.FieldExists(ParticleFields.Position, forceCreation);
            var testPos = new Vector3(1, 2, 3);
            {
                // Field accessors break every time there is a change in the pool, so we need to exract them every time
                // We can extract them before the tight loop on all living particles
                var positionField = pool.GetField(ParticleFields.Position);

                foreach (var particle in pool)
                {
                    *((Vector3*)particle[positionField]) = testPos;
                }
            }

            // Life
            pool.FieldExists(ParticleFields.RemainingLife, forceCreation);
            var testLife = 5f;
            {
                // Field accessors break every time there is a change in the pool, so we need to exract them every time
                // We can extract them before the tight loop on all living particles
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                foreach (var particle in pool)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    *((float*)particle[lifetimeField]) = testLife;
                }
            }


            // Velocity
            pool.FieldExists(ParticleFields.Velocity, forceCreation);
            var testVel = new Vector3(5, 6, 7);
            {
                // Field accessors break every time there is a change in the pool, so we need to exract them every time
                // We can extract them before the tight loop on all living particles
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);

                foreach (var particle in pool)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    *((Vector3*)particle[velocityField]) = testVel;
                }
            }

            // Size
            pool.FieldExists(ParticleFields.Size, forceCreation);
            var testSize = 4f;
            {
                // Field accessors break every time there is a change in the pool, so we need to exract them every time
                // We can extract them before the tight loop on all living particles
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                foreach (var particle in pool)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    Assert.That(*((Vector3*)particle[velocityField]), Is.EqualTo(testVel));

                    *((float*)particle[sizeField]) = testSize;
                }
            }

            // II. Change the capacity and assert that fields are still accessible
            pool.SetCapacity(2 * maxParticles);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                var sorter = new ParticleSorterLiving(pool);
                var sortedList = sorter.GetSortedList(new Vector3(0, 0, -1));

                var i = 0;
                foreach (var particle in sortedList)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    Assert.That(*((Vector3*)particle[velocityField]), Is.EqualTo(testVel));

                    Assert.That(*((float*)particle[sizeField]), Is.EqualTo(testSize));

                    i++;
                }

                sorter.FreeSortedList(ref sortedList);

                // Assert that the number of living particles is still maxParticles, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles));
            }

            // Halve the pool capacity from its original size. Now all the particles should still have the same fields
            pool.SetCapacity(maxParticles / 2);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                var sorter = new ParticleSorterLiving(pool);
                var sortedList = sorter.GetSortedList(new Vector3(0, 0, -1));

                var i = 0;
                foreach (var particle in sortedList)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    Assert.That(*((Vector3*)particle[velocityField]), Is.EqualTo(testVel));

                    Assert.That(*((float*)particle[sizeField]), Is.EqualTo(testSize));

                    i++;
                }

                sorter.FreeSortedList(ref sortedList);

                // Assert that the number of living particles is still maxParticles /2, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles / 2));
            }

            // III. Remove fields and assert the remaining fields are unchanged

            // Remove velocity
            pool.RemoveField(ParticleFields.Velocity);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                Assert.That(velocityField.IsValid(), Is.EqualTo(false));

                var sorter = new ParticleSorterLiving(pool);
                var sortedList = sorter.GetSortedList(new Vector3(0, 0, -1));

                var i = 0;
                foreach (var particle in sortedList)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    Assert.That(*((float*)particle[sizeField]), Is.EqualTo(testSize));

                    i++;
                }

                sorter.FreeSortedList(ref sortedList);

                // Assert that the number of living particles is still maxParticles /2, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles / 2));
            }

            // Remove size
            pool.RemoveField(ParticleFields.Size);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                Assert.That(velocityField.IsValid(), Is.EqualTo(false));
                Assert.That(sizeField.IsValid(), Is.EqualTo(false));

                var sorter = new ParticleSorterLiving(pool);
                var sortedList = sorter.GetSortedList(new Vector3(0, 0, -1));

                var i = 0;
                foreach (var particle in sortedList)
                {
                    Assert.That(*((Vector3*)particle[positionField]), Is.EqualTo(testPos));

                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    i++;
                }

                sorter.FreeSortedList(ref sortedList);

                // Assert that the number of living particles is still maxParticles /2, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles / 2));
            }

            // Remove position
            pool.RemoveField(ParticleFields.Position);
            {
                // Field accessors break every time there is a change in the pool
                var positionField = pool.GetField(ParticleFields.Position);
                var lifetimeField = pool.GetField(ParticleFields.RemainingLife);
                var velocityField = pool.GetField(ParticleFields.Velocity);
                var sizeField = pool.GetField(ParticleFields.Size);

                Assert.That(velocityField.IsValid(), Is.EqualTo(false));
                Assert.That(sizeField.IsValid(), Is.EqualTo(false));
                Assert.That(positionField.IsValid(), Is.EqualTo(false));

                var sorter = new ParticleSorterLiving(pool);
                var sortedList = sorter.GetSortedList(new Vector3(0, 0, -1));

                var i = 0;
                foreach (var particle in sortedList)
                {
                    Assert.That(*((float*)particle[lifetimeField]), Is.EqualTo(testLife));

                    i++;
                }

                sorter.FreeSortedList(ref sortedList);

                // Assert that the number of living particles is still maxParticles /2, not maxParticles x2
                Assert.That(i, Is.EqualTo(maxParticles / 2));
            }
        }