libgdx/libgdx — pull request #544 by xoppa (2013-08-19 20:54:16+00:00)
Title: Bullet: various changes (breaks api)

The diff is probably huge, this commit shows the actual changes: https://github.com/xoppa/libgdx/commit/d492533c3ed9447560770a7482d32c2bfbae5df7

This is a fundamental change in the bullet wrapper and likely breaks existing code (updating probably isn't too hard). Although I've been testing this change for a couple of weeks now, it might still have some rough edges.

The main reason for this change is that with the new 3d api there was no good method for creating a (static) shape for a model. Because a model can contain multiple nodes (with a different or the same mesh part) and node transformations, it became virtually impossible to correctly maintain a shape for it.

Furthermore the wrapper was inconsistent at some points and made it hard to debug if e.g. an object was destroyed due to garbage collection.

So, I made the following changes:
- The swig wrapper now defines the fundamental structure in a javabody typemap (the javacode can be freely altered where needed), see common/gdxDefault.i.
- Every wrapper class now also implement the toString() method which returns the classname (and C pointer) for easy debugging.
- The delete() method is protected now, it is no longer possible to directly destroy the native object.
- Instead every bullet class extends the BulletBase class, which implements Disposable and managed the life cycle of each wrapper class.

The life cycle of each bullet wrapper class is defined with the methods:
- The (highest) constructor calls the protected construct() method
- The (highest) finalize method calls the protected destroy() method

Because the wrapper classes must be reusable (e.g. for pooling), they can be reused (after destroying) using the protected reset() method (which will destroy() and then construct() the class)

The dispose() method can be used to delete the underlying native object and perform any java cleanups (like removing references or disposing child objects). After which the wrapper is unusable and must be destroyed by either the garbage collector or the reset() method (in case of pooling).

If an object is destroyed (e.g. by GC or pooling) but not yet disposed, it will be disposed automatically. But because of this change, the bullet classes can now warn the user that this is probably going to cause problems. This can be enabled/disabled with an argument of the call to Bullet.init() and is enabled by default.

Every wrapper class now also supports ref counting using the obtain() and release() methods. Ref counting is disabled by default (so the behaviour is most like before) and can be enabled using an argument to the Bullet.init() method. Where possible, wrapper classes which references another wrapper class uses those methods (like btCompoundShape etc.). If enabled and the last release() method is called, the object will be automatically disposed (so an user doesn't have to maintain it own references to e.g. compound child shapes). Again, if logging is enabled, messages will be logged when e.g. a class is disposed that has still references on it.

Other changes:
- The wrapper now includes methods to create a (static compound) shape from a Model, where mesh shapes are reused and transformed if needed.
- The ContactListener classes are completely rewritten to a single listener class, using jni/reflection the wrapper now determines which and the most optimal methods to use.
- To further reduce the amount of jni calls I added onContactStarted and onContactEnded callbacks.
- To even further reduce the jni calls I added ContactCache which removes small hickups in contacts.
- Various other changes