2012-02-01 2 views
1

XNA 용 작은 게임 엔진을 작성 중입니다. 현재 엔티티 관리자는 업데이트하고 렌더링 할 수있는 모든 엔티티의 목록을 가지고 있습니다. 그러나이 목록을 '하위 목록'으로 나누고 싶습니다. 일부 엔티티는 렌더링이 필요하지 않을 수 있으므로 렌더링 엔티티를 비 렌더링 엔티티에서 분리하고 모든 엔티티가 업데이트되도록 표시하는 또 다른 목록을 유지하려고합니다. 그래서 thats 3 목록.C# 목록 간의 일관성

목록간에 일관성을 유지하는 방법이 있습니까? 정확히 같은 개체가 두 목록에서 참조되고 있는지 확인하려면? (객체의 사본이 아님). C++에서 우리는 렌더링하는 엔티티에 대한 포인터 배열을 가지고 있고, 그렇지 않은 엔티티에 대한 포인터를 가지고 있습니다.

이 문제는 엔티티를 실제로이 목록에 넣는 것이 아닙니다. 엔티티를 파괴하기 위해서, 나는 그 엔티티에서 단순히 '처분'bool을 true로 설정합니다. 엔티티 관리자는 모든 엔티티를 반복 할 때 'dispose'가 true로 설정된 경우 해당 엔티티에 대한 참조를 제거하고 더 이상 참조가 남아 있지 않으므로 가비지 클리너가 엔티티를 삭제합니다. 수동으로 일일이 Entities와 관련이있는 모든 목록을 살펴보고 일관성을 유지하기 위해 해당 목록에서 엔티티를 제거해야합니까?

'문제'의 또 다른 예는 쿼드 트리입니다. 나는 2 차원 게임을 가지고 있고 모든 엔티티에 대해 쿼드 트리를 생성합니다. 2 개의 그리드 위치 사이에있는 엔티티는 트리의 2 가지 분기에 있습니다. 내가 나무에서 어떻게 제거 할까? 해당 엔티티에 대한 참조를 전체 트리에서 검색 하시겠습니까? 그게 사실이라면 쿼드 트리를 가지고 조금 무의미한 것 같습니다 ..!

답변

3

3 개의 목록 대신 1 개의 목록과 2 개의 해당 목록에 대한 쿼리를 고려하십시오. 여기

var list = GetYourMainList(); 
var renderableEntities = list.Where(item => item.IsRenderable); 
var nonrenderableEntities = list.Where(item => !item.IsRenderable); 

// work with the queries 
foreach (var item in renderableEntities) 
{ 
    // do whatever 
} 

, 당신은 결과가 주요 목록에서 스트리밍됩니다, 각 쿼리를 반복 할 수 있으며, 그들이 반복 될 때 그 목록에 대한 업데이트는 쿼리 결과에 반영됩니다. 주의 사항은 쿼리가 반복되는 동안 목록을 수정하거나 삭제할 수 없다는 것입니다.

+0

이 방법을 자주 호출해야하는 경우 느려질 수 있습니다. –

+1

@Chris, 3 개의 목록을 동시에 유지하면서 동기화, 크기 조정 등을 유지 하시겠습니까? 이는 성능이 고려 사항이 아니라는 의미는 아니지만 여러 목록 접근 방식이 실제로 더 빠르다는 증거 일뿐만 아니라 Linq 쿼리를 가리키는 성능 저하를 볼 수 있습니다. –

0

처분 문제에 대해서는 IDisposable을 구현할 수 있습니다. 목록의 경우 두 목록이 포함 된 클래스를 만들 수 있으며 전체 목록이 필요한 경우 두 목록을 열거하는 열거자를 구현할 수 있습니다.

0

목록을 알고있는 엔티티 주변에 래퍼를 넣을 수 있습니다. 래퍼를 제거하려고 할 때 비교적 쉽게 모든 곳에서 제거 할 수 있습니다.

0

여러 목록에 항목이있는 경우 해당 항목을 제거하려면 해당 항목이있는 모든 목록에서 항목을 제거해야합니다. 이 작업을 수행하는 간단한 방법은 항목 자체에 항목을 제거하는 책임을 할당하는 것입니다. 예를 들어 렌더링 항목은 RemoveFromLists()를 호출 할 때 렌더링 항목 목록에서 자신을 제거합니다.

Anthony Pegram의 설명에 따라 쿼리를 사용하면이 복잡성이 제거되지만 증분 업데이트 할 수 없으므로 목록이 클 경우 비효율적입니다.

쿼트 트리의 경우 직선적 인 일은 각 항목에 발생하는 쿼드 트리 노드 목록을 유지하는 것입니다 (항목을 필드에 추가하지 않으려는 경우 사전 사용). 그런 다음 일정 시간 내에 발생하는 모든 노드에서 노드를 제거하는 것이 간단합니다.

0

귀하의 사업체가 처분되기 전에 해고 된 "처분"이벤트를 노출하게 할 수 있습니다. 그런 다음 목록의 Add 메서드에 이벤트 처리기를 등록하고 추가 할 엔터티를 추가하면 제거 된 엔터티가 목록에서 제거됩니다.