Skip to content

Commit

Permalink
chore(core): strict null checks (#2024)
Browse files Browse the repository at this point in the history
  • Loading branch information
ibgreen committed Mar 13, 2024
1 parent e7c1c57 commit 33de6f1
Show file tree
Hide file tree
Showing 25 changed files with 80 additions and 69 deletions.
18 changes: 11 additions & 7 deletions modules/core/src/adapter-utils/get-attribute-from-layouts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@ export function getAttributeInfosFromLayouts(
): Record<string, AttributeInfo> {
const attributeInfos: Record<string, AttributeInfo> = {};
for (const attribute of shaderLayout.attributes) {
attributeInfos[attribute.name] = getAttributeInfoFromLayouts(
shaderLayout,
bufferLayout,
attribute.name
);
const attributeInfo = getAttributeInfoFromLayouts(shaderLayout, bufferLayout, attribute.name);
if (attributeInfo) {
attributeInfos[attribute.name] = attributeInfo;
}
}
return attributeInfos;
}
Expand Down Expand Up @@ -98,7 +97,10 @@ function getAttributeInfoFromLayouts(
name: string
): AttributeInfo | null {
const shaderDeclaration = getAttributeFromShaderLayout(shaderLayout, name);
const bufferMapping: BufferAttributeInfo = getAttributeFromBufferLayout(bufferLayout, name);
const bufferMapping: BufferAttributeInfo | null = getAttributeFromBufferLayout(
bufferLayout,
name
);

// TODO should no longer happen
if (!shaderDeclaration) {
Expand All @@ -124,7 +126,7 @@ function getAttributeInfoFromLayouts(
normalized: vertexFormatInfo.normalized,
// integer is a property of the shader declaration
integer: attributeTypeInfo.integer,
stepMode: bufferMapping?.stepMode || shaderDeclaration.stepMode,
stepMode: bufferMapping?.stepMode || shaderDeclaration.stepMode || 'vertex',
byteOffset: bufferMapping?.byteOffset || 0,
byteStride: bufferMapping?.byteStride || 0
};
Expand Down Expand Up @@ -211,6 +213,7 @@ function getAttributeFromAttributesList(
if (typeof bufferLayout.byteStride !== 'number') {
for (const attributeMapping of bufferLayout.attributes || []) {
const info = decodeVertexFormat(attributeMapping.format);
// @ts-ignore
byteStride += info.byteLength;
}
}
Expand All @@ -223,6 +226,7 @@ function getAttributeFromAttributesList(
stepMode: bufferLayout.stepMode,
vertexFormat: attributeMapping.format,
byteOffset: attributeMapping.byteOffset,
// @ts-ignore
byteStride
};
}
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/adapter/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class DeviceFeatures {
}

has(feature: DeviceFeature): boolean {
return !this.disabledFeatures[feature] && this.features.has(feature);
return !this.disabledFeatures?.[feature] && this.features.has(feature);
}
}

Expand Down
10 changes: 5 additions & 5 deletions modules/core/src/adapter/resources/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,17 @@ export abstract class Buffer extends Resource<BufferProps> {
byteOffset: number,
byteLength: number
): void {
const buffer: ArrayBuffer | null = ArrayBuffer.isView(data) ? data.buffer : data;
const arrayBuffer: ArrayBuffer | null = ArrayBuffer.isView(data) ? data.buffer : data;
const debugDataLength = Math.min(
data ? data.byteLength : byteLength,
Buffer.DEBUG_DATA_MAX_LENGTH
);
if (data === null) {
if (arrayBuffer === null) {
this.debugData = new ArrayBuffer(debugDataLength);
} else if (byteOffset === 0 && byteLength === data.byteLength) {
this.debugData = buffer.slice(0, debugDataLength);
} else if (byteOffset === 0 && byteLength === arrayBuffer.byteLength) {
this.debugData = arrayBuffer.slice(0, debugDataLength);
} else {
this.debugData = buffer.slice(byteOffset, byteOffset + debugDataLength);
this.debugData = arrayBuffer.slice(byteOffset, byteOffset + debugDataLength);
}
}
}
2 changes: 1 addition & 1 deletion modules/core/src/adapter/resources/command-encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export type CommandEncoderProps = ResourceProps & {
export abstract class CommandEncoder extends Resource<CommandEncoderProps> {
static override defaultProps: Required<CommandEncoderProps> = {
...Resource.defaultProps,
measureExecutionTime: undefined
measureExecutionTime: undefined!
};

override get [Symbol.toStringTag](): string {
Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/adapter/resources/compute-pass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ export type ComputePassProps = ResourceProps & {
export abstract class ComputePass extends Resource<ComputePassProps> {
static override defaultProps: Required<ComputePassProps> = {
...Resource.defaultProps,
timestampQuerySet: undefined,
beginTimestampIndex: undefined,
endTimestampIndex: undefined
timestampQuerySet: undefined!,
beginTimestampIndex: undefined!,
endTimestampIndex: undefined!
};

override get [Symbol.toStringTag](): string {
Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/adapter/resources/compute-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export type ComputePipelineProps = ResourceProps & {
export abstract class ComputePipeline extends Resource<ComputePipelineProps> {
static override defaultProps: Required<ComputePipelineProps> = {
...Resource.defaultProps,
shader: undefined,
entryPoint: undefined,
shader: undefined!,
entryPoint: undefined!,
constants: {},
shaderLayout: undefined
shaderLayout: undefined!
};

override get [Symbol.toStringTag](): string {
Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/adapter/resources/query-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export type QuerySetProps = ResourceProps & {
export abstract class QuerySet extends Resource<QuerySetProps> {
static override defaultProps: Required<QuerySetProps> = {
...Resource.defaultProps,
type: undefined,
count: undefined
type: undefined!,
count: undefined!
};

get [Symbol.toStringTag](): string {
Expand Down
10 changes: 5 additions & 5 deletions modules/core/src/adapter/resources/render-pass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,18 @@ export abstract class RenderPass extends Resource<RenderPassProps> {
static override defaultProps: Required<RenderPassProps> = {
...Resource.defaultProps,
framebuffer: null,
parameters: undefined,
parameters: undefined!,
clearColor: [0, 0, 0, 0],
clearDepth: 1,
clearStencil: 0,
depthReadOnly: false,
stencilReadOnly: false,
discard: false,

occlusionQuerySet: undefined,
timestampQuerySet: undefined,
beginTimestampIndex: undefined,
endTimestampIndex: undefined
occlusionQuerySet: undefined!,
timestampQuerySet: undefined!,
beginTimestampIndex: undefined!,
endTimestampIndex: undefined!
};

override get [Symbol.toStringTag](): string {
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/adapter/resources/render-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export abstract class RenderPipeline extends Resource<RenderPipelineProps> {

constructor(device: Device, props: RenderPipelineProps) {
super(device, props, RenderPipeline.defaultProps);
this.shaderLayout = this.props.shaderLayout;
this.shaderLayout = this.props.shaderLayout!;
this.bufferLayout = this.props.bufferLayout || [];
}

Expand Down
12 changes: 6 additions & 6 deletions modules/core/src/adapter/resources/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export abstract class Resource<Props extends ResourceProps> {
static defaultProps: Required<ResourceProps> = {
id: 'undefined',
handle: undefined,
userData: undefined
userData: undefined!
};

abstract get [Symbol.toStringTag](): string;
Expand All @@ -39,7 +39,7 @@ export abstract class Resource<Props extends ResourceProps> {
/** For resources that allocate GPU memory */
private allocatedBytes: number = 0;
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
private _attachedResources = new Set<Resource<unknown>>();
private _attachedResources = new Set<Resource<ResourceProps>>();

/**
* Create a new Resource. Called from Subclass
Expand Down Expand Up @@ -91,21 +91,21 @@ export abstract class Resource<Props extends ResourceProps> {
* Attaches a resource. Attached resources are auto destroyed when this resource is destroyed
* Called automatically when sub resources are auto created but can be called by application
*/
attachResource(resource: Resource<unknown>): void {
attachResource(resource: Resource<ResourceProps>): void {
this._attachedResources.add(resource);
}

/**
* Detach an attached resource. The resource will no longer be auto-destroyed when this resource is destroyed.
*/
detachResource(resource: Resource<unknown>): void {
detachResource(resource: Resource<ResourceProps>): void {
this._attachedResources.delete(resource);
}

/**
* Destroys a resource (only if owned), and removes from the owned (auto-destroy) list for this resource.
*/
destroyAttachedResource(resource: Resource<unknown>): void {
destroyAttachedResource(resource: Resource<ResourceProps>): void {
if (this._attachedResources.delete(resource)) {
resource.destroy();
}
Expand All @@ -117,7 +117,7 @@ export abstract class Resource<Props extends ResourceProps> {
resource.destroy();
}
// don't remove while we are iterating
this._attachedResources = new Set<Resource<unknown>>();
this._attachedResources = new Set<Resource<ResourceProps>>();
}

// PROTECTED METHODS
Expand Down
6 changes: 2 additions & 4 deletions modules/core/src/adapter/resources/shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export abstract class Shader extends Resource<ShaderProps> {
static override defaultProps: Required<ShaderProps> = {
...Resource.defaultProps,
language: 'auto',
stage: undefined,
stage: undefined!,
source: '',
sourceMap: null,
entryPoint: 'main',
Expand Down Expand Up @@ -134,9 +134,7 @@ ${htmlLog}
document.body.appendChild(button);

const errors = document.getElementsByClassName('luma-compiler-log-error');
if (errors[0]?.scrollIntoView) {
errors[0].scrollIntoView();
}
errors[0]?.scrollIntoView();

// TODO - add a small embedded copy button (instead of main button)
button.onclick = () => {
Expand Down
8 changes: 4 additions & 4 deletions modules/core/src/adapter/resources/texture-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export type TextureViewProps = ResourceProps & {
export abstract class TextureView extends Resource<TextureViewProps> {
static override defaultProps: Required<TextureViewProps> = {
...Resource.defaultProps,
format: undefined,
dimension: undefined,
format: undefined!,
dimension: undefined!,
aspect: 'all',
baseMipLevel: 0,
mipLevelCount: undefined,
mipLevelCount: undefined!,
baseArrayLayer: 0,
arrayLayerCount: undefined
arrayLayerCount: undefined!
};

abstract texture: Texture;
Expand Down
1 change: 1 addition & 0 deletions modules/core/src/adapter/resources/texture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ export abstract class Texture extends Resource<TextureProps> {

// Calculate size, if not provided
if (this.props.width === undefined || this.props.height === undefined) {
// @ts-ignore
const size = this.getTextureDataSize(this.props.data);
this.width = size?.width || 1;
this.height = size?.height || 1;
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/adapter/resources/transform-feedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export abstract class TransformFeedback extends Resource<TransformFeedbackProps>
return 'TransformFeedback';
}

constructor(device: Device, props?: TransformFeedbackProps) {
constructor(device: Device, props: TransformFeedbackProps) {
super(device, props, TransformFeedback.defaultProps);
}

Expand Down
8 changes: 6 additions & 2 deletions modules/core/src/adapter/resources/vertex-array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ export abstract class VertexArray extends Resource<VertexArrayProps> {
super(device, props, VertexArray.defaultProps);
this.maxVertexAttributes = device.limits.maxVertexAttributes;
this.attributes = new Array(this.maxVertexAttributes).fill(null);
const {shaderLayout, bufferLayout} = props.renderPipeline || {};
if (!shaderLayout || !bufferLayout) {
throw new Error('VertexArray');
}
this.attributeInfos = getAttributeInfosByLocation(
props.renderPipeline.shaderLayout,
props.renderPipeline.bufferLayout,
shaderLayout,
bufferLayout,
this.maxVertexAttributes
);
}
Expand Down
16 changes: 8 additions & 8 deletions modules/core/src/adapter/types/parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,12 @@ export const DEFAULT_PARAMETERS: Required<Parameters> = {
polygonMode: 'fill',
polygonOffsetLine: false,

clipDistance0: undefined,
clipDistance1: undefined,
clipDistance2: undefined,
clipDistance3: undefined,
clipDistance4: undefined,
clipDistance5: undefined,
clipDistance6: undefined,
clipDistance7: undefined
clipDistance0: undefined!,
clipDistance1: undefined!,
clipDistance2: undefined!,
clipDistance3: undefined!,
clipDistance4: undefined!,
clipDistance5: undefined!,
clipDistance6: undefined!,
clipDistance7: undefined!
};
2 changes: 1 addition & 1 deletion modules/core/src/gpu-type-utils/decode-attribute-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type ShaderAttributeTypeInfo = {
/** Whether this data type is signed */
signed: boolean;
/** The simplest vertex format that matches the shader attribute's data type */
defaultVertexFormat?: VertexFormat;
defaultVertexFormat: VertexFormat;
};

/** Decodes a vertex type, returning byte length and flags (integer, signed, normalized) */
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/portable/uniform-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class UniformBlock<
shaderLayout?: ShaderLayout;
uniformTypes?: Record<keyof TUniforms, Record<string, ShaderUniformType>>;
}) {
this.name = props?.name;
this.name = props?.name || 'unnamed';

// TODO - Extract uniform layout from the shaderLayout object
if (props?.name && props?.shaderLayout) {
Expand Down
16 changes: 9 additions & 7 deletions modules/core/src/portable/uniform-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class UniformStore<
uniforms: Partial<{[group in keyof TPropGroups]: Partial<TPropGroups[group]>}>
): void {
for (const [blockName, uniformValues] of Object.entries(uniforms)) {
this.uniformBlocks.get(blockName).setUniforms(uniformValues);
this.uniformBlocks.get(blockName)?.setUniforms(uniformValues);
// We leverage logging in updateUniformBuffers(), even though slightly less efficient
// this.updateUniformBuffer(blockName);
}
Expand All @@ -89,13 +89,14 @@ export class UniformStore<

/** Get the required minimum length of the uniform buffer */
getUniformBufferByteLength(uniformBufferName: keyof TPropGroups): number {
return this.uniformBufferLayouts.get(uniformBufferName).byteLength;
return this.uniformBufferLayouts.get(uniformBufferName)?.byteLength || 0;
}

/** Get formatted binary memory that can be uploaded to a buffer */
getUniformBufferData(uniformBufferName: keyof TPropGroups): Uint8Array {
const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms();
return this.uniformBufferLayouts.get(uniformBufferName).getData(uniformValues);
const uniformValues = this.uniformBlocks.get(uniformBufferName)?.getAllUniforms() || {};
// @ts-ignore
return this.uniformBufferLayouts.get(uniformBufferName)?.getData(uniformValues);
}

/**
Expand Down Expand Up @@ -132,6 +133,7 @@ export class UniformStore<
this.uniformBuffers.set(uniformBufferName, uniformBuffer);
}
// this.updateUniformBuffers();
// @ts-ignore
return this.uniformBuffers.get(uniformBufferName);
}

Expand All @@ -154,16 +156,16 @@ export class UniformStore<
const uniformBuffer = this.uniformBuffers.get(uniformBufferName);

let reason: false | string = false;
if (uniformBuffer && uniformBlock.needsRedraw) {
if (uniformBuffer && uniformBlock?.needsRedraw) {
reason ||= uniformBlock.needsRedraw;
// This clears the needs redraw flag
const uniformBufferData = this.getUniformBufferData(uniformBufferName);

const uniformBuffer = this.uniformBuffers.get(uniformBufferName);
uniformBuffer.write(uniformBufferData);
uniformBuffer?.write(uniformBufferData);

// logging - TODO - don't query the values unnecessarily
const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms();
const uniformValues = this.uniformBlocks.get(uniformBufferName)?.getAllUniforms();
log.log(
4,
`Writing to uniform buffer ${String(uniformBufferName)}`,
Expand Down
1 change: 1 addition & 0 deletions modules/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"exclude": ["node_modules"],
"compilerOptions": {
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true,
"composite": true,
"rootDir": "src",
Expand Down
2 changes: 1 addition & 1 deletion modules/engine/src/animation-loop/animation-loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ export class AnimationLoop {
// end callback

// Submit commands (necessary on WebGPU)
this.device.submit();
this.device?.submit();
}

_clearNeedsRedraw(): void {
Expand Down
Loading

0 comments on commit 33de6f1

Please sign in to comment.