首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >独立线程中的JBullet NullPointer on step模拟

独立线程中的JBullet NullPointer on step模拟
EN

Stack Overflow用户
提问于 2014-05-06 04:24:58
回答 1查看 159关注 0票数 1

我在我的游戏中有一个设置,物理在一个单独的线程中更新,实现如下

物理处理器(物理线程)

代码语言:javascript
复制
public class PhysicsProcessor extends Runnable {
    private DynamicsWorld world;

    public PhysicsProcessor() {
        /* basic dynamics world setup with dvbt broadphase :P */
    }

    public synchronized getDynamicsWorld() { return world; }

    @Override
    public void run() {
        /* update time */

        //update phyics
        getDynamicsWorld().stepSimulation(/* delta time */);
    }
}

在主线程中创建对象示例

代码语言:javascript
复制
myPhysicsProcessor.getDynamicsWorld.addRigidBody(/* some rigid body created here */);

问题是,当游戏运行时,我偶尔会在"stepSimulation“上的单独线程中得到一个空指针异常,这是由我的dbvt宽阶段中的setAabb引起的。

有没有人有什么建议,我可以做些什么来防止这种异常,或者如何解决它?

EN

回答 1

Stack Overflow用户

发布于 2014-05-07 06:06:18

从外观上看,你可以让这个世界变得final。然后这将向您展示同步访问的无用之处:

代码语言:javascript
复制
public class PhysicsProcessor extends Runnable {
    private final DynamicsWorld world;

    public synchronized DynamicsWorld getDynamicsWorld() { return world; } //why sync? it can't change
}

您可以看到,当您执行以下操作时:myPhysicsProcessor.getDynamicsWorld().addRigidBody(...)getDynamicsWorld()返回后同步停止。因此,在安全同步上下文之外调用addRigidBody(...)

不,您要做的是确保在a sync块中始终使用它:

代码语言:javascript
复制
@Override
public void run() {
    //update physics
    synchronized(this) {
      world.stepSimulation(/* delta time */);
    }
}

public void addBody(/*args here*/) {
    synchronized(this) {
      world.addRigidBody(/*args here*/);
    }
}

现在这对于一种方法来说是可以的,但是如果你发现自己想要用这种方式在runner之外做很多DynamicsWorld方法,或者只是想要另一种选择,那么这个方法不需要同步:

代码语言:javascript
复制
public interface IWorldRunable {    
  void run(DynamicsWorld world);    
}    

public class PhysicsProcessor extends Runnable {
    private final DynamicsWorld world;
    private final ConcurrentLinkedQueue<IWorldRunable> worldRunables = ConcurrentLinkedQueue<IWorldRunable>();

    public PhysicsProcessor() {
        /* basic dynamics world setup with dvbt broadphase :P */
    }

    @Override
    public void run() {
        /* update time */

        //run runables on world
        for(IWorldRunable runable : worldRunables)
          runable.run(world);

        //clear runables
        worldRunables.clear();

        //update phyics
        world.stepSimulation(/* delta time */);
    }

    public void do(IWorldRunable runnable) {
        worldRunables.add(runnable);
    }
}

然后,您将执行以下操作,以添加body:

代码语言:javascript
复制
myPhysicsProcessor.do(new IWorldRunable(){      
  @Override
  public void run(DynamicsWorld world){
     world.addRigidBody(...);
  }
});

它将在同一线程上的下一个stepSimulation之前执行,所以不用担心线程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23481191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档