export class ChunkComponent {
public container: Pixi.Container;
staleProps!: Props;
state!: State;
public children: KeyedHashMap<PointNodeRef, PointNodeComponent>;
public _children: {childClass :any, instance: any, propsFactory: Function}[] = []
public forceUpdates: {childClass :any, instance: any, propsFactory: Function}[] = []
constructor(props: Props) {
this.staleProps = props;
this.state = {};
this.container = new Pixi.Container();
this.children = new KeyedHashMap();
this.upsertChildren(props);
this.renderSelf(props);
}
renderSelf(props: Props) {
this.container.position = PixiPointFrom(props.position);
}
public willUnmount() { }
/** callback passed to child - since child is not a pure component, it needs to inform us of updates if otherwise we wouldnt update */
markForceUpdate = (childInstance: any) => {
this.staleProps.args.markForceUpdate(this); // mark us for update in OUR parent
for (let childInfo of this._children) {
if (childInfo.instance === childInstance) { // we found the instance in our _children array, now ensure it is in force updates array then return
if (this.forceUpdates.indexOf(childInfo) === -1) {
this.forceUpdates.push(childInfo);
}
return;
}
}
throw new Error(`Error, child ${childInstance} not found in ${this}`);
}
updateSelf(props: Props) { }
shouldUpdate(prevProps: Props, props: Props): boolean {
// return true;
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(`chunk shouldUpdate differed in ${key}, returning true`);
return true;
} else {
continue;
}
}
if (key === 'selectedPointNode') {
if (prevProps[key]?.hash() !== props[key]?.hash()) {
console.log(`chunk shouldUpdate differed in ${key}, returning true`);
return true;
} else {
continue;
}
}
if (key === 'selfChunkRef') {
if (prevProps[key]?.hash() !== props[key]?.hash()) {
console.log(`chunk shouldUpdate differed in ${key}, returning true`);
return true;
} else {
continue;
}
}
if (key === 'allocatedPointNodeSubset') {
// subsets could be different objects but have the same contents
if (!prevProps[key].equals(props[key])) {
// console.log(`prevProps: ${JSON.stringify(prevProps[key])}`);
// console.log(`props: ${JSON.stringify(props[key])}`);
console.log(`chunk shouldUpdate differed in ${key}, returning true`);
return true;
} else {
continue;
}
}
if (prevProps[key] !== props[key]) {
console.log(`chunk shouldUpdate differed in ${key}, returning true`);
return true;
}
}
return false;
}
upsertChildren(props: Props) {
let childrenToDelete = this.children.clone(); // track which children need to be destroyed according to new props
console.log(`chunk component upsert children got here`);
// console.log(`chunk component upsert children has ${this.children.size()} children`);
for (let [pointNodeCoord, pointNodeGen] of props.chunkGen.pointNodes.entries()) {
const pointNodeRef = new PointNodeRef({
z: props.selfChunkRef.z,
chunkCoord: props.selfChunkRef.chunkCoord,
pointNodeCoord: pointNodeCoord,
pointNodeId: pointNodeGen.id
})
let childPropsFactory = (props: Props, state: State) => {
return {
delta: props.delta,
args: {
pointNodeTexture: props.args.pointNodeTexture,
markForceUpdate: this.markForceUpdate,
},
selfPointNodeRef: pointNodeRef,
updaters: props.updaters,
position: pointNodeRef.pointNodeCoord.multiply(RenderedChunkConstants.SPACING_PX),
pointNodeGen,
isSelected: props.selectedPointNode?.pointNodeId === pointNodeRef.pointNodeId,
isAllocated: props.allocatedPointNodeSubset.contains(pointNodeRef),
};
}
const childKey = pointNodeRef;