В последнее время я много играл с XNA, а также много читал о сборке мусора в играх. Я думаю, что проделал разумную работу по сокращению количества мусора, используя пул и избегая зависимости от foreach.
В настоящий момент мои базовые игровые сущности хранятся в KeyedCollection, что позволяет мне перебирать все сущности (например, список) и ссылаться на сущность по ключу (например, словарь).
Я хотел бы иметь возможность запрашивать мою коллекцию и возвращать другую коллекцию, не создавая мусора каждый запрос. Я включил образец концепции ниже, потому что я думаю, что я лучше их кодирую, я объясняю ...
/// <summary>
/// Defines a sample entity.
/// </summary>
public class SampleEntity
{
public uint Id;
public Vector2 Position;
}
/// <summary>
/// Defines a collection of sample entities.
/// </summary>
public class EntityCollection : KeyedCollection<uint, SampleEntity>
{
/// <summary>
/// Return the key for the supplied item.
/// </summary>
protected override uint GetKeyForItem(SampleEntity item)
{
return item.Id;
}
}
/// <summary>
/// Defines the sample game class.
/// </summary>
public class GameSample
{
/// <summary>
/// Create a new instance of the GameSample class.
/// </summary>
public GameSample()
{
Entities = new EntityCollection();
}
/// <summary>
/// Get the collection of game entities.
/// </summary>
public EntityCollection Entities { get; private set; }
/// <summary>
/// Return the collection of entities within a radius of the supplied point.
/// </summary>
public List<SampleEntity> Query(Vector2 center, float radius)
{
List<SampleEntity> results = new List<SampleEntity>() // BAD, BAD, BAD!!!!!
//
// add the entities to the results collection
//
return results;
}
}
В этом (чрезмерно упрощенном) примере будет много мусора, потому что он создает новый объект List при каждом вызове. Я также играл с созданием глобального списка результатов и очисткой каждого звонка, но это кажется уродливым.
/// <summary>
/// Return the collection of entities within a radius of the specified point.
/// </summary>
public List<SampleEntity> Query(Vector2 center, float radius)
{
_globalResults.Clear();
//
// add the entities to the global results collection
//
return _globalResults;
}
Я просто что-то упустил? Есть ли более элегантное решение, о котором я просто не знаю?