class ZLevelComponent2 extends LifecycleHandlerBase<Props, State> {
public container: Pixi.Container;
protected state: State;
public children: KeyedHashMap<ChunkRef, ChunkComponent> = new KeyedHashMap();
constructor(props: Props) {
super(props);
this.state = {};
this.container = new Pixi.Container();
this.upsertChildren(props);
}
protected renderSelf(props: Props) {
this.container.position = PixiPointFrom(props.position);
}
protected didMount() {
const { updaters } = this._staleProps;
// if we mounted but our data is not generated, please generate ourselves
updaters.worldGen.zLevels.enqueueUpdate((prev, prevGameState) => {
if (!prev[this._staleProps.z]) {
return { [this._staleProps.z]: new ZLevelGenFactory({}).create({ seed: prevGameState.worldGen.seed, z: this._staleProps.z }) };
}
return prev;
})
}
protected didForceUpdateChild(instance: LifecycleHandlerBase<any, any>) {
// IMPORTANT! this is intended to raise the child that asked for a force update to the top so it isn't covered
// by other sibling pixi containers. however this code doesnt work well during the update call, for some reason (not sure why)
this.container.removeChild(instance.container);
this.container.addChild(instance.container);
}
protected shouldUpdate(prevProps: Props, prevState: State, props: Props, state: State): boolean {
for (let key of (Object.keys(prevProps) as (keyof Props)[])) {
if (key === 'delta' || key === 'args' || key === 'updaters') { continue; }
if (key === 'position') {
if (!prevProps[key].equals(props[key])) {
console.log(`zlevel shouldUpdate differed in ${key}, returning true`);
return true;
} else {
continue;
}
}
if (key === 'selectedPointNode') {
if (prevProps[key]?.hash() !== props[key]?.hash()) {
console.log(`zlevel shouldUpdate differed in ${key}, returning true`);
return true;
} else {
continue;
}
}
if (prevProps[key] !== props[key]) {
console.log(`zlevel shouldUpdate differed in ${key}, returning true`);
return true;
}
}
return false;
}
private upsertChildren(props: Props) {
let childrenToDelete = this.children.clone(); // track which children need to be destroyed according to new props
console.log(`zlevel component have ${this.children.size()} children`)
for (let [chunkCoord, chunkGen] of props.zLevelGen?.chunks?.entries() || []) {
const { childKey, childPropsFactory } = this.doChild(props, chunkCoord, chunkGen);
let childComponent = this.children.get(childKey);
if (childComponent) {
// childComponent.update(childPropsFactory(props, this.state));
childrenToDelete.remove(childKey);
} else {
childComponent = new ChunkComponent(childPropsFactory(props, this.state));
this.children.put(childKey, childComponent);
// this.container.addChild(childComponent.container);
this.addChild({
childClass: ChunkComponent,
instance: childComponent,
propsFactory: childPropsFactory
});
}
}
console.log(`zlevel component have ${childrenToDelete.size()} children to delete`)
for (let [childKey, childComponent] of childrenToDelete.entries()) {
// childComponent.willUnmount();
this.children.remove(childKey);
// this.container.removeChild(childComponent.container);
// this._children.splice(this._children.findIndex(it => it.instance === childComponent), 1);
this.removeChild(childComponent);
}
}
private doChild(props: Props, chunkCoord: Vector2, chunkGen: ChunkGen): { childKey: ChunkRef, childPropsFactory: (p: Props, s: State) => ChunkComponentProps } {
const chunkRef = new ChunkRef({
z: props.z,
chunkCoord,
chunkId: chunkGen.id,
});