aboutsummaryrefslogtreecommitdiff
path: root/src/RaytraceDispatcher.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/RaytraceDispatcher.ts')
-rw-r--r--src/RaytraceDispatcher.ts70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/RaytraceDispatcher.ts b/src/RaytraceDispatcher.ts
new file mode 100644
index 0000000..866d2d1
--- /dev/null
+++ b/src/RaytraceDispatcher.ts
@@ -0,0 +1,70 @@
+import {Colour} from './Colour';
+import {Framebuffer} from './Framebuffer';
+import {RaytraceContext} from './RaytraceContext';
+import {instanceToPlain} from 'class-transformer';
+import 'reflect-metadata';
+
+export class RaytraceDispatcher {
+ private renderStartMs: number;
+ private responsesReceived = 0;
+ constructor(
+ readonly framebuffer: Framebuffer,
+ readonly context: RaytraceContext
+ ) {
+ this.renderStartMs = new Date().getTime();
+ }
+
+ requestRender() {
+ // Assumes height and threads are always even
+ const rowBatchSize = this.context.height / this.context.options.numThreads;
+
+ for (let y = 0; y < this.context.height; y += rowBatchSize) {
+ const rowStartIndex = y;
+ const rowEndIndex = y + rowBatchSize - 1;
+ this.dispatchRaytraceWorker(rowStartIndex, rowEndIndex, this.context);
+ }
+ }
+
+ private dispatchRaytraceWorker(
+ rowStartIndex: number,
+ rowEndIndex: number,
+ context: RaytraceContext
+ ) {
+ console.log(
+ `Dispatching worker for lines ${rowStartIndex} to ${rowEndIndex}`
+ );
+
+ const raytracer = new Worker(new URL('./Raytracer.ts', import.meta.url));
+
+ raytracer.postMessage({
+ type: 'raytraceStart',
+ rowStartIndex: rowStartIndex,
+ rowEndIndex: rowEndIndex,
+ context: JSON.stringify(instanceToPlain(context)),
+ });
+
+ raytracer.onmessage = ({data}) => {
+ if (data.type === 'raytraceResultRow') {
+ this.processResponse(data.rowIndex, data.resultBuffer);
+ }
+ if (data.type === 'raytraceComplete') {
+ this.handleWorkerComplete();
+ }
+ };
+ }
+
+ private handleWorkerComplete() {
+ if (++this.responsesReceived === this.context.options.numThreads) {
+ console.log(
+ `Render completed in ${new Date().getTime() - this.renderStartMs}ms`
+ );
+ }
+ }
+
+ private processResponse(rowIndex: number, rowData: Colour[]) {
+ for (let x = 0; x < this.framebuffer.width; x++) {
+ this.framebuffer.writePixelAt(x, rowIndex, rowData[x]);
+ }
+ this.framebuffer.flush();
+ }
+}