Esempio n. 1
0
        /// <summary>
        /// Adds a particle field to this pool with the specified description, or gets an existing one
        /// </summary>
        /// <param name="fieldDesc">Description of the field</param>
        /// <returns>The newly added or already existing field</returns>
        internal ParticleField AddField(ParticleFieldDescription fieldDesc)
        {
            // Fields with a stride of 0 are meaningless and cannot be added or removed
            if (fieldDesc.FieldSize == 0)
            {
                return(new ParticleField());
            }

            ParticleField existingField;

            if (fields.TryGetValue(fieldDesc, out existingField))
            {
                return(existingField);
            }


            var newParticleSize = ParticleSize + fieldDesc.FieldSize;

#if PARTICLES_SOA
            var newField = new ParticleField(fieldDesc.FieldSize, IntPtr.Zero);
#else
            var newField = new ParticleField()
            {
                Offset = ParticleSize, Size = fieldDesc.FieldSize
            };
#endif

            fieldDescriptions.Add(fieldDesc);
            fields.Add(fieldDesc, newField);

            ReallocatePool(newParticleSize, ParticleCapacity, ReallocateForFieldAdded);

            return(fields[fieldDesc]);
        }
Esempio n. 2
0
        /// <summary>
        /// Unsafe method for getting a <see cref="ParticleFieldAccessor"/>.
        /// If the field doesn't exist an invalid accessor is returned to the user.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fieldDesc"></param>
        /// <returns></returns>
        public ParticleFieldAccessor <T> GetField <T>(ParticleFieldDescription <T> fieldDesc) where T : struct
        {
            ParticleField field;

            return(fields.TryGetValue(fieldDesc, out field) ?
                   new ParticleFieldAccessor <T>(field) :
                   ParticleFieldAccessor <T> .Invalid());
        }
Esempio n. 3
0
        /// <summary>
        /// Gets the particle field with the specified description if the field exists in this pool
        /// </summary>
        /// <typeparam name="T">Type data for the field</typeparam>
        /// <param name="fieldDesc">Field's decription</param>
        /// <param name="accessor">Accessor for the field</param>
        /// <returns></returns>
        public bool TryGetField <T>(ParticleFieldDescription <T> fieldDesc, out ParticleFieldAccessor <T> accessor) where T : struct
        {
            ParticleField field;

            if (!fields.TryGetValue(fieldDesc, out field))
            {
                accessor = ParticleFieldAccessor <T> .Invalid();

                return(false);
            }

            accessor = new ParticleFieldAccessor <T>(field);
            return(true);
        }
Esempio n. 4
0
        /// <summary>
        /// Remove a particle field no longer required by a dependent module. It only gets removed from the pool if it reaches 0 reference counters.
        /// </summary>
        /// <param name="description"></param>
        internal void RemoveRequiredField(ParticleFieldDescription description)
        {
            int fieldReferences;

            if (requiredFields.TryGetValue(description, out fieldReferences))
            {
                requiredFields[description] = fieldReferences - 1;

                // If this was not the last field, other Updaters are still using it so don't remove it from the pool
                if (fieldReferences > 1)
                {
                    return;
                }

                pool.RemoveField(description);

                requiredFields.Remove(description);
            }

            // This line can be reached when a AddModule was unsuccessful and the required fields should be cleaned up
        }
Esempio n. 5
0
        /// <summary>
        /// Polls if a filed with this description exists in the pool and optionally forces creation of a new field
        /// </summary>
        /// <param name="fieldDesc">Description of the field</param>
        /// <param name="forceCreate">Force the creation of non-existing fields if <c>true</c></param>
        /// <returns></returns>
        public bool FieldExists(ParticleFieldDescription fieldDesc, bool forceCreate = false)
        {
            ParticleField field;

            if (fields.TryGetValue(fieldDesc, out field))
            {
                return(true);
            }

            if (!forceCreate)
            {
                return(false);
            }

            if (fields.Count >= DefaultMaxFielsPerPool)
            {
                return(false);
            }

            AddField(fieldDesc);
            return(true);
        }
Esempio n. 6
0
        /// <summary>
        /// Removes a particle field from this pool with the specified description, or gets an existing one
        /// </summary>
        /// <param name="fieldDesc">Description of the field</param>
        /// <returns><c>true</c> if the field was successfully removed, <c>false</c> otherwise</returns>
        public bool RemoveField(ParticleFieldDescription fieldDesc)
        {
            // Fields with a stride of 0 are meaningless and cannot be added or removed
            if (fieldDesc.FieldSize == 0)
            {
                return(false);
            }

            // Check if the field exists in this particle pool. If it doesn't, obviously it cannot be removed
            ParticleField existingField;

            if (!fields.TryGetValue(fieldDesc, out existingField))
            {
                return(false);
            }

            var newParticleSize = ParticleSize - fieldDesc.FieldSize;

            fieldDescriptions.Remove(fieldDesc);

#if PARTICLES_SOA
            fields[fieldDesc] = new ParticleField(0, IntPtr.Zero);
#else
            fields[fieldDesc] = new ParticleField()
            {
                Offset = 0, Size = 0
            };
#endif

            // The field is not removed yet. During relocation it will appear as having Size and Offset of 0, and should be ignored for the purpose of copying memory
            ReallocatePool(newParticleSize, ParticleCapacity, ReallocateForFieldRemoved);

            fields.Remove(fieldDesc);

            return(true);
        }
Esempio n. 7
0
        /// <summary>
        /// Add a particle field required by some dependent module. If the module already exists in the pool, only its reference counter is increased.
        /// </summary>
        /// <param name="description"></param>
        internal void AddRequiredField(ParticleFieldDescription description)
        {
            int fieldReferences;

            if (requiredFields.TryGetValue(description, out fieldReferences))
            {
                // Field already exists. Increase the reference counter by 1
                requiredFields[description] = fieldReferences + 1;
                return;
            }

            // Check if the pool doesn't already have too many fields
            if (requiredFields.Count >= ParticlePool.DefaultMaxFielsPerPool)
            {
                return;
            }

            if (!pool.FieldExists(description, forceCreate: true))
            {
                return;
            }

            requiredFields.Add(description, 1);
        }
        /// <summary>
        /// Remove a particle field no longer required by a dependent module. It only gets removed from the pool if it reaches 0 reference counters.
        /// </summary>
        /// <param name="description"></param>
        internal void RemoveRequiredField(ParticleFieldDescription description)
        {
            int fieldReferences;
            if (requiredFields.TryGetValue(description, out fieldReferences))
            {
                requiredFields[description] = fieldReferences - 1;

                // If this was not the last field, other Updaters are still using it so don't remove it from the pool
                if (fieldReferences > 1)
                    return;

                pool.RemoveField(description);

                requiredFields.Remove(description);
            }

            // This line can be reached when a AddModule was unsuccessful and the required fields should be cleaned up
        }
        /// <summary>
        /// Add a particle field required by some dependent module. If the module already exists in the pool, only its reference counter is increased.
        /// </summary>
        /// <param name="description"></param>
        internal void AddRequiredField(ParticleFieldDescription description)
        {
            int fieldReferences;
            if (requiredFields.TryGetValue(description, out fieldReferences))
            {
                // Field already exists. Increase the reference counter by 1
                requiredFields[description] = fieldReferences + 1;
                return;
            }

            // Check if the pool doesn't already have too many fields
            if (requiredFields.Count >= ParticlePool.DefaultMaxFielsPerPool)
                return;

            if (!pool.FieldExists(description, forceCreate: true))
                return;

            requiredFields.Add(description, 1);
        }
Esempio n. 10
0
 /// <summary>
 /// Returns a particle field accessor for the contained <see cref="ParticlePool"/>
 /// </summary>
 /// <typeparam name="T">Type data for the field</typeparam>
 /// <param name="fieldDesc">The field description</param>
 /// <returns></returns>
 public ParticleFieldAccessor <T> GetField <T>(ParticleFieldDescription <T> fieldDesc) where T : struct
 {
     return(particlePool.GetField <T>(fieldDesc));
 }