|
Rapier C — 3D / f64 0.36.0+c.0
|
| Value | Ownership rule |
|---|---|
| World pointer | Owns inserted bodies, colliders, joints, and soft bodies. Release with FreeWorld. |
| Entity handle | Small borrowed value carrying its world pointer, index, and generation. Never free it. |
| Description/configuration | Copyable POD; initialize with its constructor/default function. No destructor. |
| Input array view | Borrows elements through the consuming build/insert call. Copying the view does not copy data. |
| SharedShape pointer | Owned reference-counted geometry wrapper. Release each wrapper with FreeSharedShape. |
| Controller/event collector/snapshot/mesh | Owned pointer with a matching Free function. |
| Callback context or MJCF visual pointer | Borrowed; never free or retain beyond its documented lifetime. |
Constructors supply meaningful defaults; {0} is not a replacement for them. Insertion borrows descriptions, copies their data, and retains shared geometry. After insertion returns, input arrays and temporary shared-shape wrappers can be released. Setters on descriptions may retain borrowed views until insertion.
Removing an entity invalidates its handle. Generations detect stale entities only while the owning world is alive: no API can safely validate a freed world pointer. Destroying a world invalidates all its handles, including copies held elsewhere. Use the explicit INVALID_*_HANDLE constants instead of assuming zero is invalid. Opaque owned pointers must be released through their matching Rapier Free function, never C free. Free functions accept NULL unless stated otherwise.
Ordinary world reads may overlap. A mutation/step requires exclusive access; conflicting or reentrant access reports WORLD_BUSY rather than waiting. The caller must keep the world alive throughout every call and synchronize its destruction with all users. Controllers, collectors, and other independently owned objects require external synchronization when shared between threads.
Callbacks may run on physics worker threads in parallel builds. Keep callback code and user data alive until the operation returns. Use the callback's ReadContext with Read* accessors; ordinary world access may report WORLD_BUSY during stepping. Do not mutate the world from callbacks. Never unwind a C++ exception or longjmp through Rust frames. Copy callback data if it is needed after return.