가능한 해결책:
응용 프로그램에서 요소가 사용자 데이터 값이고 인덱스가 PlayRho 에서 본문을 생성하여 반환 된 기본 값과 일치하는 배열을 사용할 수 있습니다 .
예를 들어 void*
호환 가능한 사용자 데이터에 대한 간단하고 순진한 구현 은 다음과 같을 수 있습니다.
int main() {
struct MyEntity {
int totalHealth;
int currentHealth;
int strength;
int intellect;
};
std::vector<void*> myUserData;
auto world = World{};
// If you want to pre-allocate 100 spaces...
myUserData.resize(100);
const auto body = world.CreateBody();
// If your # bodies is unlimited or you don't want to preallocate space...
if (body.get() >= myUserData.size()) myUserData.resize(body.get());
// Set your user data...
myUserData[body.get()] = new MyEntity();
// Gets your user data...
const auto myEntity = static_cast<MyEntity*>(myUserData[body.get()]);
// Frees your dynamically allocated MyEntity instances.
// Even with Box2D `userData` you may want to free these.
for (const auto& element: myUserDAta) {
delete element;
}
return 0;
}
그러나 메모리 누수와 같은 골칫거리를 다루지 않으려면 myUserData
대신 std::vector<MyEntity> myUserData;
, new MyEntity()
및 delete element;
호출을 피할 수 있습니다.
이것에 대한 몇 가지 장점 :
userData
필드 의 모든 사용이 동일한 유형을 갖습니다.단점 :
배경 / 설명 :
PlayRho 물리 엔진이 Box2D 물리 엔진의 포크로 시작되었지만 PlayRho는 참조 의미론 (포인터)에서 값 의미론으로 이동했습니다.(값). 따라서 포인터가 교체되었고 "사용자 데이터"는이 가능한 솔루션과 같은 대안을 위해 완전히 제거되었습니다. 또한 값 의미론으로의 전환으로 인해 본문을 만드는 개념은 세계에서 새 본문에 대한 포인터를 가져 오는 것에서 기본적으로 대신 세계에서 새 본문에 대한 정수 인덱스를 가져 오는 것으로 변경되었습니다. 이 인덱스는 세계 내의 새 본문에 대한 식별자 역할을하며 기본적으로 0부터 시작하여 새 본문을 만들 때마다 증가하는 세계에서 증가하는 카운터입니다. 즉, 기본 본문 ID 값을 사용자 데이터를 저장하는 요소에 대한 인덱스로 사용하여 배열에서 O (1) 조회를 수행 할 수 있습니다. 사용std::unordered_map<b2Body*, b2BodyUserData>
또한 O (1) 조회를 제공하지만 해시 된 맵은 배열보다 최신 하드웨어에서 캐시 친화적이지 않은 경향이 있으므로 PlayRho에서보다 바디 당 사용자 데이터 값에 대한 스토리지를 따로 설정하여 Box2D에서 이러한 오버 헤드를 피하는 것이 더 합리적입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다