To minimize garbage collection in performance-sensitive applications, ECSY uses component pooling. When entity.addComponent(ComponentA) is called, the engine attempts to reuse an existing instance from a pool. When entity.removeComponent(ComponentA) is called, the instance is returned to the pool.
Customizing Pooling
Overriding Component Methods
You can manually implement constructor, copy, and reset to handle complex data structures or optimize performance. The reset method is critical as it is called frequently when components are returned to the pool; avoid memory allocation inside reset and reuse existing data structures where possible.
Disabling Pooling
If a component cannot be safely copied or reset, disable pooling by passing false as the second argument to world.registerComponent().
Custom ObjectPools
You can provide a custom ObjectPool instance to registerComponent to control how instances are acquired, released, or expanded.
import { Component, ObjectPool } from 'ecsy';
// 1. Overriding methods for custom logic/performance
class ColorArray extends Component {
constructor(props) {
super(false); // Disable schema-based defaults
this.value = [];
}
copy(src) {
this.value.length = src.value.length;
for (let i = 0; i < src.value.length; i++) {
const srcColor = src.value[i];
const destColor = this.value[i];
destColor.r = srcColor.r;
destColor.g = srcColor.g;
destColor.b = srcColor.b;
}
return this;
}
reset() {
this.value.forEach(color => {
color.r = 0;
color.g = 0;
color.b = 0;
});
}
}
// 2. Disabling pooling for specific components
world.registerComponent(AudioListener, false);
// 3. Using a custom ObjectPool with a specific initial size
world.registerComponent(MyComponent, new ObjectPool(MyComponent, 1000));