1/* 2 * Copyright (c) 2021-2024 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 16class EventHub { 17 constructor() { 18 this.eventMap = {}; 19 this.nativeEventHubRef = null; 20 this.contextIndex = -1; 21 this.emitMultiThreadingEnabled = false; 22 this.emitter = undefined; 23 } 24 25 setNativeEventHubRef(ref) { 26 this.nativeEventHubRef = ref; 27 } 28 29 onEmitterFunction(eventData = {'data':{}}) { 30 let eventName = eventData.data[`arg${0}`]; 31 let arrays = Object.keys(eventData.data); 32 let result = {}; 33 for (let index = 1; index < arrays.length; index++) { 34 result[`arg${index - 1}`] = eventData.data[`arg${index}`]; 35 } 36 let args = this.dataToArgs(result); 37 this.emitInner(eventName, ...args); 38 } 39 40 getEmitterEventName(event) { 41 return 'ohos.event.' + this.contextIndex + '.' + event; 42 } 43 44 argsToData(args = []) { 45 let eventData = {}; 46 let data = args.reduce((acc, value, index)=>{ 47 acc[`arg${index}`] = value; 48 return acc; 49 }, {}); 50 eventData.data = data; 51 return eventData; 52 } 53 54 dataToArgs(data = {}) { 55 if (!data) { 56 return []; 57 } 58 let args = []; 59 let oLen = Object.keys(data).length; 60 for (let index = 0; index < oLen; index++) { 61 args[index] = data[`arg${index}`]; 62 } 63 return args; 64 } 65 66 setEventHubEmitMultiThreadingEnabled(enable) { 67 if (this.emitMultiThreadingEnabled === enable) { 68 return; 69 } 70 this.emitter = requireNapi('events.emitter'); 71 this.emitMultiThreadingEnabled = enable; 72 let keys = Object.keys(this.eventMap); 73 for (let i = 0; i < keys.length; i++) { 74 if (this.emitMultiThreadingEnabled === true) { 75 this.emitter.on(this.getEmitterEventName(keys[i]), (eventData) => this.onEmitterFunction(eventData)); 76 } else { 77 this.emitter.off(this.getEmitterEventName(keys[i])); 78 } 79 } 80 } 81 82 on(event, callback) { 83 if ((typeof (event) !== 'string') || (typeof (callback) !== 'function')) { 84 return; 85 } 86 if (!this.eventMap[event]) { 87 this.eventMap[event] = []; 88 } 89 if (this.eventMap[event].indexOf(callback) === -1) { 90 this.eventMap[event].push(callback); 91 } 92 if (this.emitMultiThreadingEnabled === true && this.emitter !== undefined) { 93 if (this.emitter.getListenerCount(this.getEmitterEventName(event)) === 0) { 94 this.emitter.on(this.getEmitterEventName(event), (eventData) => this.onEmitterFunction(eventData)); 95 } 96 } 97 } 98 99 offByNativeContext(event, callback) { 100 if (typeof (event) !== 'string') { 101 return; 102 } 103 if (this.eventMap[event]) { 104 if (callback) { 105 let cbArray = this.eventMap[event]; 106 let index = cbArray.indexOf(callback); 107 if (index > -1) { 108 for (; index + 1 < cbArray.length; index++) { 109 cbArray[index] = cbArray[index + 1]; 110 } 111 cbArray.pop(); 112 } 113 } else { 114 delete this.eventMap[event]; 115 } 116 } 117 } 118 119 off(event, callback) { 120 if (typeof (event) !== 'string') { 121 return; 122 } 123 if (this.eventMap[event]) { 124 if (callback) { 125 let cbArray = this.eventMap[event]; 126 let index = cbArray.indexOf(callback); 127 if (index > -1) { 128 for (; index + 1 < cbArray.length; index++) { 129 cbArray[index] = cbArray[index + 1]; 130 } 131 cbArray.pop(); 132 } 133 } else { 134 delete this.eventMap[event]; 135 } 136 } 137 if (this.nativeEventHubRef != null) { 138 // call native eventHub off 139 if (callback) { 140 this.nativeEventHubRef.offByDynamicContext(event, callback); 141 } else { 142 this.nativeEventHubRef.offByDynamicContext(event); 143 } 144 } 145 if (this.emitMultiThreadingEnabled === true && this.emitter !== undefined) { 146 let array = this.eventMap[event]; 147 if (array === null || array === undefined) { 148 this.emitter.off(this.getEmitterEventName(event)); 149 } 150 } 151 } 152 153 emit(event, ...args) { 154 if (this.emitMultiThreadingEnabled === true && this.emitter !== undefined) { 155 let eventNameArrays = [event]; 156 let newArgsArrays = eventNameArrays.concat(args); 157 let eventData = this.argsToData(newArgsArrays); 158 this.emitter.emit(this.getEmitterEventName(event), eventData); 159 } else { 160 this.emitInner(event, ...args); 161 } 162 } 163 164 emitInner(event, ...args) { 165 if (typeof (event) !== 'string') { 166 return; 167 } 168 if (this.eventMap[event]) { 169 const cloneArray = [...this.eventMap[event]]; 170 const len = cloneArray.length; 171 for (let i = 0; i < len; ++i) { 172 cloneArray[i].apply(this, args); 173 } 174 } 175 if (this.nativeEventHubRef != null) { 176 this.nativeEventHubRef.emitByDynamicContext(event, ...args); 177 } 178 } 179 180 emitByNativeContext(event, ...args) { 181 if (typeof (event) !== 'string') { 182 return; 183 } 184 if (this.eventMap[event]) { 185 const cloneArray = [...this.eventMap[event]]; 186 const len = cloneArray.length; 187 for (let i = 0; i < len; ++i) { 188 cloneArray[i].apply(this, args); 189 } 190 } 191 } 192} 193 194class Context { 195 constructor(obj) { 196 this.__context_impl__ = obj; 197 let eventHub = new EventHub(); 198 eventHub.contextIndex = obj.index; 199 this.__context_impl__.eventHub = eventHub; 200 } 201 202 createBundleContext(bundleName) { 203 return this.__context_impl__.createBundleContext(bundleName); 204 } 205 206 createModuleContext(moduleName) { 207 return this.__context_impl__.createModuleContext(moduleName); 208 } 209 210 createModuleContext(bundleName, moduleName) { 211 return this.__context_impl__.createModuleContext(bundleName, moduleName); 212 } 213 214 createSystemHspModuleResourceManager(bundleName, moduleName) { 215 return this.__context_impl__.createSystemHspModuleResourceManager(bundleName, moduleName); 216 } 217 218 createModuleResourceManager(bundleName, moduleName) { 219 return this.__context_impl__.createModuleResourceManager(bundleName, moduleName); 220 } 221 222 getApplicationContext() { 223 return this.__context_impl__.getApplicationContext(); 224 } 225 226 getGroupDir(groupId, callback) { 227 return this.__context_impl__.getGroupDir(groupId, callback); 228 } 229 230 createAreaModeContext(areaMode) { 231 return this.__context_impl__.createAreaModeContext(areaMode); 232 } 233 234 createDisplayContext(displayId) { 235 return this.__context_impl__.createDisplayContext(displayId); 236 } 237 238 set area(mode) { 239 return this.__context_impl__.switchArea(mode); 240 } 241 242 get area() { 243 return this.__context_impl__.getArea(); 244 } 245 246 get resourceManager() { 247 return this.__context_impl__.resourceManager; 248 } 249 250 get applicationInfo() { 251 return this.__context_impl__.applicationInfo; 252 } 253 254 get cacheDir() { 255 return this.__context_impl__.cacheDir; 256 } 257 258 get tempDir() { 259 return this.__context_impl__.tempDir; 260 } 261 262 get resourceDir() { 263 return this.__context_impl__.resourceDir; 264 } 265 266 get filesDir() { 267 return this.__context_impl__.filesDir; 268 } 269 270 get distributedFilesDir() { 271 return this.__context_impl__.distributedFilesDir; 272 } 273 274 get databaseDir() { 275 return this.__context_impl__.databaseDir; 276 } 277 278 get preferencesDir() { 279 return this.__context_impl__.preferencesDir; 280 } 281 282 get bundleCodeDir() { 283 return this.__context_impl__.bundleCodeDir; 284 } 285 286 get cloudFileDir() { 287 return this.__context_impl__.cloudFileDir; 288 } 289 290 get eventHub() { 291 return this.__context_impl__.eventHub; 292 } 293 294 get processName() { 295 return this.__context_impl__.processName; 296 } 297 298 get stageMode() { 299 return true; 300 } 301} 302 303export default Context; 304