• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { WorkerType } from "../WorkFactory"
17import worker from '@ohos.worker';
18import HiLog from '../../utils/HiLog';
19import buffer from "@ohos.buffer"
20
21const TAG = "WorkerWrapper"
22
23export class WorkerMessage {
24    request: string;
25    callBackId: number;
26    type?: WorkerType;
27    param?: any;
28}
29
30/*
31 * WorkerWrapper
32 *
33 * Processes sending tasks to workers and receiving work processing results.
34 */
35export abstract class WorkerWrapper {
36    protected mWorker: worker.ThreadWorker = undefined;
37    private callBacks: Map<string, (result?: any) => void> = new Map();
38    private requestIndex: number = 0;
39
40    constructor() {
41        this.initWorker();
42    }
43
44    async initWorker() {
45        HiLog.i(TAG, `WorkerWrapper initWorker ${WorkerType[this.getWorkerType()]}`)
46        let initWorker = await new worker.ThreadWorker("entry/ets/workers/base/Worker.ts", {
47            name: WorkerType[this.getWorkerType()]
48        });
49        let that = this;
50        initWorker.onexit = function (message) {
51            HiLog.w(TAG, "onexit")
52            that.mWorker = undefined;
53        }
54        initWorker.onerror = function (e) {
55            HiLog.w(TAG, "onerror:" + JSON.stringify(e))
56        }
57        initWorker.onmessageerror = function (e) {
58            HiLog.w(TAG, "onmessageerror:" + JSON.stringify(e))
59        }
60        initWorker.onmessage = function (message) {
61            const buff = <ArrayBuffer> message.data;
62            const str = buffer.from(buff).toString();
63            let data = <WorkerMessage> JSON.parse(str)
64            HiLog.i(TAG, `onmessage ${data.request}`)
65            const key = that.getCallBackKey(data);
66            if (that.callBacks.has(key)) {
67                HiLog.i(TAG, `onmessage notify result.`)
68                const callback = that.callBacks.get(key);
69                if (callback) {
70                    callback(data.param);
71                }
72                that.callBacks.delete(key);
73            }
74        }
75        this.mWorker = initWorker;
76        HiLog.i(TAG, `WorkerWrapper initWorker end`)
77    }
78
79    public abstract getWorkerType(): WorkerType;
80
81    /**
82     * SendRequest to worker thread.
83     *
84     * @param {string} request the request worker to do
85     * @param {Object} requestData  request param Data
86     * @param {Object} callBack Call back from worker
87     */
88    public async sendRequest(request: string, requestData?: any, callBack?: (result?: any) => void) {
89        HiLog.i(TAG, "sendRequest in " + request)
90        if (this.mWorker) {
91            const message = {
92                request: request,
93                callBackId: this.requestIndex,
94                type: this.getWorkerType(),
95                param: requestData
96            }
97            if (callBack) {
98                this.callBacks.set(this.getCallBackKey(message), callBack);
99            }
100            this.mWorker?.postMessage(message);
101            HiLog.d(TAG, `${this.getWorkerType()} ${request} send succ!`);
102            this.requestIndex++;
103        } else {
104            HiLog.w(TAG, `${this.getWorkerType()} ${request} send fail, worker has been closed!`);
105        }
106    }
107
108    /**
109     * Close  close worker thread.
110     */
111    public close() {
112        HiLog.i(TAG, `${this.getWorkerType()} worker close!`);
113        this.mWorker.terminate();
114        this.mWorker = undefined;
115        this.callBacks.clear();
116    }
117
118    private getCallBackKey(message: WorkerMessage): string {
119        return message.request + message.callBackId;
120    }
121}
122
123export default WorkerWrapper;