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 16/** 17 * ObservedPropertyAbstractPU aka ObservedPropertyAbstract for partial update 18 * 19 * all definitions in this file are framework internal 20 */ 21 22abstract class ObservedPropertyAbstractPU<T> extends ObservedPropertyAbstract<T> 23implements ISinglePropertyChangeSubscriber<T>, IMultiPropertiesChangeSubscriber, IMultiPropertiesReadSubscriber 24// these interfaces implementations are all empty functioms, overwrite FU base class implementations. 25{ 26 private dependentElementIds_: Set<number> = new Set<number>(); 27 28 constructor(subscribingView: IPropertySubscriber, viewName: PropertyInfo) { 29 super(subscribingView, viewName); 30 } 31 32 protected notifyPropertyRead() { 33 stateMgmtConsole.error(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: \ 34 notifyPropertyRead, DO NOT USE with PU. Use notifyPropertyHasBeenReadPU`); 35 } 36 37 protected notifyPropertyHasBeenReadPU() { 38 stateMgmtConsole.debug(`ObservedPropertyAbstractPU[${this.id__()}, '${this.info() || "unknown"}']: notifyPropertyHasBeenReadPU.`) 39 this.subscribers_.forEach((subscribedId) => { 40 var subscriber: IPropertySubscriber = SubscriberManager.Find(subscribedId) 41 if (subscriber) { 42 if ('propertyHasBeenReadPU' in subscriber) { 43 (subscriber as unknown as PropertyReadEventListener<T>).propertyHasBeenReadPU(this); 44 } 45 } 46 }); 47 this.recordDependentUpdate(); 48 } 49 50 protected notifyPropertyHasChangedPU() { 51 stateMgmtConsole.debug(`ObservedPropertyAbstractPU[${this.id__()}, '${this.info() || "unknown"}']: notifyPropertyHasChangedPU.`) 52 this.subscribers_.forEach((subscribedId) => { 53 var subscriber: IPropertySubscriber = SubscriberManager.Find(subscribedId) 54 if (subscriber) { 55 if ('viewPropertyHasChanged' in subscriber) { 56 (subscriber as ViewPU).viewPropertyHasChanged(this.info_, this.dependentElementIds_); 57 } else if ('syncPeerHasChanged' in subscriber) { 58 (subscriber as unknown as PeerChangeEventReceiverPU<T>).syncPeerHasChanged(this); 59 } else { 60 stateMgmtConsole.warn(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyPropertryHasChangedPU: unknown subscriber ID '${subscribedId}' error!`); 61 } 62 } 63 }); 64 } 65 66 67 public markDependentElementsDirty(view: ViewPU) { 68 // TODO ace-ets2bundle, framework, compilated apps need to update together 69 // this function will be removed after a short transiition periode 70 stateMgmtConsole.warn(`markDependentElementsDirty no longer supported. App will work ok, but 71 please update your ace-ets2bundle and recompile your application!`); 72 } 73 74 /** 75 * factory function for concrete 'object' or 'simple' ObservedProperty object 76 * depending if value is Class object 77 * or simple type (boolean | number | string) 78 * @param value 79 * @param owningView 80 * @param thisPropertyName 81 * @returns either 82 */ 83 static CreateObservedObject<C>(value: C, owningView: IPropertySubscriber, thisPropertyName: PropertyInfo) 84 : ObservedPropertyAbstract<C> { 85 return (typeof value === "object") ? 86 new ObservedPropertyObject(value, owningView, thisPropertyName) 87 : new ObservedPropertySimple(value, owningView, thisPropertyName); 88 } 89 90 91 /** 92 * during 'get' access recording take note of the created component and its elmtId 93 * and add this component to the list of components who are dependent on this property 94 */ 95 protected recordDependentUpdate() { 96 const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); 97 if (elmtId < 0) { 98 // not access recording 99 return; 100 } 101 stateMgmtConsole.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: recordDependentUpdate on elmtId ${elmtId}.`) 102 this.dependentElementIds_.add(elmtId); 103 } 104 105 106 public purgeDependencyOnElmtId(rmElmtId: number): void { 107 stateMgmtConsole.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']:purgeDependencyOnElmtId ${rmElmtId}`); 108 this.dependentElementIds_.delete(rmElmtId); 109 } 110 111 public SetPropertyUnchanged(): void { 112 // function to be removed 113 // keep it here until transpiler is updated. 114 } 115 116 // FIXME check, is this used from AppStorage. 117 // unified Appstorage, what classes to use, and the API 118 public createLink(subscribeOwner?: IPropertySubscriber, 119 linkPropName?: PropertyInfo): ObservedPropertyAbstractPU<T> { 120 throw new Error("Can not create a AppStorage 'Link' from a @State property. "); 121 } 122 123 public createProp(subscribeOwner?: IPropertySubscriber, 124 linkPropName?: PropertyInfo): ObservedPropertyAbstractPU<T> { 125 throw new Error("Can not create a AppStorage 'Prop' from a @State property. "); 126 } 127 128 /* 129 Below empty functions required to keep as long as this class derives from FU version 130 ObservedPropertyAbstract. Need to overwrite these functions to do nothing for PU 131 */ 132 protected notifyHasChanged(_: T) { 133 stateMgmtConsole.error(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: \ 134 notifyHasChanged, DO NOT USE with PU. Use syncPeerHasChanged() or objectPropertyHasChangedPU()`); 135 } 136 137 hasChanged(_: T): void { 138 // unused for PU 139 // need to overwrite impl of base class with empty function. 140 } 141 142 propertyHasChanged(_?: PropertyInfo): void { 143 // unused for PU 144 // need to overwrite impl of base class with empty function. 145 } 146 147 propertyRead(_?: PropertyInfo): void { 148 // unused for PU 149 // need to overwrite impl of base class with empty function. 150 } 151}