@playcanvas/react
Version:
A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.
85 lines • 2.99 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useEffect, useState } from 'react';
const PhysicsContext = createContext({
isPhysicsEnabled: false,
isPhysicsLoaded: false,
physicsError: null,
});
// Track how many Application instances are using physics
let physicsInstanceCount = 0;
/**
* Hook to access physics context information.
*
* @returns Physics context containing physics state information
*
* @example
* ```tsx
* import { usePhysics } from '@playcanvas/react/hooks';
*
* const MyComponent = () => {
* const { isPhysicsEnabled, isPhysicsLoaded, physicsError } = usePhysics();
*
* if (physicsError) {
* return <div>Physics error: {physicsError.message}</div>;
* }
*
* if (!isPhysicsLoaded) {
* return <div>Loading physics...</div>;
* }
*
* return <div>Physics is ready!</div>;
* };
* ```
*/
export const usePhysics = () => useContext(PhysicsContext);
export const PhysicsProvider = ({ children, enabled, app }) => {
const [isPhysicsLoaded, setIsPhysicsLoaded] = useState(false);
const [physicsError, setPhysicsError] = useState(null);
useEffect(() => {
if (!enabled) {
setIsPhysicsLoaded(false);
setPhysicsError(null);
return;
}
const loadPhysics = async () => {
try {
// @ts-expect-error The PC Physics system expects a global Ammo instance
if (!globalThis.Ammo) {
const Ammo = await import('sync-ammo');
// @ts-expect-error The PC Physics system expects a global Ammo instance
globalThis.Ammo = Ammo.default;
}
// Only initialize the library if not already done so
if (!app.systems.rigidbody?.dispatcher) {
app.systems.rigidbody?.onLibraryLoaded();
}
setIsPhysicsLoaded(true);
setPhysicsError(null);
physicsInstanceCount++;
}
catch (error) {
const err = error instanceof Error ? error : new Error('Failed to load physics library');
setPhysicsError(err);
setIsPhysicsLoaded(false);
}
};
loadPhysics();
return () => {
// Only clean up Ammo if this is the last instance using physics
if (enabled) {
physicsInstanceCount--;
if (physicsInstanceCount === 0) {
// @ts-expect-error Clean up the global Ammo instance
if (globalThis.Ammo)
delete globalThis.Ammo;
}
}
};
}, [enabled, app]);
return (_jsx(PhysicsContext.Provider, { value: {
isPhysicsEnabled: enabled,
isPhysicsLoaded,
physicsError,
}, children: children }));
};
//# sourceMappingURL=physics-context.js.map