wip
This commit is contained in:
parent
b9f76b85c0
commit
e40feeffdd
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { colorizeEmoji } from '@/scripts/emojilist.js';
|
import { colorizeEmoji } from '@/to-be-shared/emojilist.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
emoji: string;
|
emoji: string;
|
||||||
|
|
|
@ -13,8 +13,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import DrawBlurhash from '@/workers/draw-blurhash?worker';
|
import DrawBlurhash from '@/workers/draw-blurhash?worker';
|
||||||
import TestWebGL2 from '@/workers/test-webgl2?worker';
|
import TestWebGL2 from '@/workers/test-webgl2?worker';
|
||||||
import { WorkerMultiDispatch } from '@/scripts/worker-multi-dispatch.js';
|
import { WorkerMultiDispatch } from '@/to-be-shared/worker-multi-dispatch.js';
|
||||||
import { extractAvgColorFromBlurhash } from '@/scripts/extract-avg-color-from-blurhash.js';
|
import { extractAvgColorFromBlurhash } from '@/to-be-shared/extract-avg-color-from-blurhash.js';
|
||||||
|
|
||||||
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
||||||
// テスト環境で Web Worker インスタンスは作成できない
|
// テスト環境で Web Worker インスタンスは作成できない
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function extractAvgColorFromBlurhash(hash: string) {
|
||||||
|
return typeof hash === 'string'
|
||||||
|
? '#' + [...hash.slice(2, 6)]
|
||||||
|
.map(x => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~'.indexOf(x))
|
||||||
|
.reduce((a, c) => a * 83 + c, 0)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(6, '0')
|
||||||
|
: undefined;
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
function defaultUseWorkerNumber(prev: number, totalWorkers: number) {
|
||||||
|
return prev + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WorkerMultiDispatch<POST = any, RETURN = any> {
|
||||||
|
private symbol = Symbol('WorkerMultiDispatch');
|
||||||
|
private workers: Worker[] = [];
|
||||||
|
private terminated = false;
|
||||||
|
private prevWorkerNumber = 0;
|
||||||
|
private getUseWorkerNumber = defaultUseWorkerNumber;
|
||||||
|
private finalizationRegistry: FinalizationRegistry<symbol>;
|
||||||
|
|
||||||
|
constructor(workerConstructor: () => Worker, concurrency: number, getUseWorkerNumber = defaultUseWorkerNumber) {
|
||||||
|
this.getUseWorkerNumber = getUseWorkerNumber;
|
||||||
|
for (let i = 0; i < concurrency; i++) {
|
||||||
|
this.workers.push(workerConstructor());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalizationRegistry = new FinalizationRegistry(() => {
|
||||||
|
this.terminate();
|
||||||
|
});
|
||||||
|
this.finalizationRegistry.register(this, this.symbol);
|
||||||
|
|
||||||
|
if (_DEV_) console.log('WorkerMultiDispatch: Created', this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public postMessage(message: POST, options?: Transferable[] | StructuredSerializeOptions, useWorkerNumber: typeof defaultUseWorkerNumber = this.getUseWorkerNumber) {
|
||||||
|
let workerNumber = useWorkerNumber(this.prevWorkerNumber, this.workers.length);
|
||||||
|
workerNumber = Math.abs(Math.round(workerNumber)) % this.workers.length;
|
||||||
|
if (_DEV_) console.log('WorkerMultiDispatch: Posting message to worker', workerNumber, useWorkerNumber);
|
||||||
|
this.prevWorkerNumber = workerNumber;
|
||||||
|
|
||||||
|
// 不毛だがunionをoverloadに突っ込めない
|
||||||
|
// https://stackoverflow.com/questions/66507585/overload-signatures-union-types-and-no-overload-matches-this-call-error
|
||||||
|
// https://github.com/microsoft/TypeScript/issues/14107
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
this.workers[workerNumber].postMessage(message, options);
|
||||||
|
} else {
|
||||||
|
this.workers[workerNumber].postMessage(message, options);
|
||||||
|
}
|
||||||
|
return workerNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
||||||
|
this.workers.forEach(worker => {
|
||||||
|
worker.addEventListener('message', callback, options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
||||||
|
this.workers.forEach(worker => {
|
||||||
|
worker.removeEventListener('message', callback, options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public terminate() {
|
||||||
|
this.terminated = true;
|
||||||
|
if (_DEV_) console.log('WorkerMultiDispatch: Terminating', this);
|
||||||
|
this.workers.forEach(worker => {
|
||||||
|
worker.terminate();
|
||||||
|
});
|
||||||
|
this.workers = [];
|
||||||
|
this.finalizationRegistry.unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public isTerminated() {
|
||||||
|
return this.terminated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getWorkers() {
|
||||||
|
return this.workers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSymbol() {
|
||||||
|
return this.symbol;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue