简介
我已经为游戏引擎创建了一个民意调查数据结构,如下所述: -
http://experilous.com/1/blog/post/dense-dynamic-arrays-with-stable-handles-part-1
简而言之,结构存储值而不是指针。
这是草稿。
template<class T> class Handle{
int id;
}
template<class T> class PackArray{
std::vector <int>indirection ; //promote indirection here
std::vector <T>data;
//... some fields for pooling (for recycling instance of T)
Handle<T> create(){
data.push_back(T());
//.... update indirection ...
return Id( .... index , usually = indirection.size()-1 .... )
}
T* get(Handle<T> id){
return &data[indirection[id.id]];
//the return result is not stable, caller can't hold it very long
}
//... others function e.g. destroy(Id<T>) ...
}
问题
重构器采用这种新数据结构的大多数步骤都很简单,例如
Bullet* bullet= new Bullet(); //old version
Handle<Bullet> bullet= packBulletArray.create(); //new version
当问题指向某些接口时,问题就开始了。
例如,其中一个接口是物理引擎。
如果我想要引擎的碰撞回调,物理引擎喜欢Box2D和Bullet Physics要求我传递void *。
Bullet* bullet= .... ;
physicBody->setUserData(bullet); <-- It requires void*.
问题:如何将第二行更改为有效代码?
Handle<Bullet> bullet = .... ;
physicBody->setUserData( ???? );
警告:
(1)无法保证这个&#34; Handle&#34;的实例将来会存在。
physicBody->setUserData( &bullet ); //can't do this
//e.g. "Handle<Bullet> bullet" in the above code is a local variable, it will be deleted soon
(2)无法保证&#34; bullet&#34;的基础对象将来会存在于同一地址。
physicBody->setUserData( bullet->get() ); //can't do this
//because "std::vector<T> data" may reallocate in the future
答案可以假设:
(1)&#34; physicBody&#34;已被我封装。如果需要,它可以缓存通用指针,但不允许缓存Handle的值,因为它会产生严重的耦合。
(2)&#34; bullet&#34;有办法访问正确的&#34; physicBody&#34;通过它的封装器。 &#34; physicBody&#34;总是在&#34; bullet&#34;。
之前删除(3)&#34; Handle&#34;还缓存&#34; PackArray *&#34;,此缓存始终是正确的指针。
我想解决方案是关于unique-pointer / make_pointer的,但我没有足够的经验来使用它们来解决这个问题。
P.S。我关心表现 作为参考,这是一个已经解决的问题create dense dynamic array (array of value) as library的续集。