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> { 23 24 private dependentElementIds_: Set<number> = new Set<number>(); 25 26 constructor(subscribingView: IPropertySubscriber, viewName: PropertyInfo) { 27 super(subscribingView, viewName); 28 } 29 30 protected notifyHasChanged(newValue: T) { 31 stateMgmtConsole.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged, notifying.`); 32 this.subscribers_.forEach((subscribedId) => { 33 var subscriber: IPropertySubscriber = SubscriberManager.Find(subscribedId) 34 if (subscriber) { 35 if ('hasChanged' in subscriber) { 36 (subscriber as ISinglePropertyChangeSubscriber<T>).hasChanged(newValue); 37 } 38 if ('viewPropertyHasChanged' in subscriber) { 39 (subscriber as ViewPU).viewPropertyHasChanged(this.info_, this.dependentElementIds_); 40 } else if ('propertyHasChanged' in subscriber) { 41 (subscriber as IMultiPropertiesChangeSubscriber).propertyHasChanged(this.info_); 42 } 43 } else { 44 stateMgmtConsole.warn(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged: unknown subscriber ID '${subscribedId}' error!`); 45 } 46 }); 47 } 48 49 protected notifyPropertyRead() { 50 super.notifyPropertyRead(); 51 this.recordDependentUpdate(); 52 } 53 54 public markDependentElementsDirty(view: ViewPU) { 55 // TODO ace-ets2bundle, framework, compilated apps need to update together 56 // this function will be removed after a short transiition periode 57 stateMgmtConsole.warn(`markDependentElementsDirty no longer supported. App will work ok, but 58 please update your ace-ets2bundle and recompile your application!`); 59 } 60 61 /** 62 * factory function for concrete 'object' or 'simple' ObservedProperty object 63 * depending if value is Class object 64 * or simple type (boolean | number | string) 65 * @param value 66 * @param owningView 67 * @param thisPropertyName 68 * @returns either 69 */ 70 static CreateObservedObject<C>(value: C, owningView: IPropertySubscriber, thisPropertyName: PropertyInfo) 71 : ObservedPropertyAbstract<C> { 72 return (typeof value === "object") ? 73 new ObservedPropertyObject(value, owningView, thisPropertyName) 74 : new ObservedPropertySimple(value, owningView, thisPropertyName); 75 } 76 77 78 /** 79 * during 'get' access recording take note of the created component and its elmtId 80 * and add this component to the list of components who are dependent on this property 81 */ 82 protected recordDependentUpdate() { 83 const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); 84 if (elmtId < 0) { 85 // not access recording 86 return; 87 } 88 stateMgmtConsole.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: recordDependentUpdate on elmtId ${elmtId}.`) 89 this.dependentElementIds_.add(elmtId); 90 } 91 92 93 public purgeDependencyOnElmtId(rmElmtId: number): void { 94 stateMgmtConsole.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']:purgeDependencyOnElmtId ${rmElmtId}`); 95 this.dependentElementIds_.delete(rmElmtId); 96 } 97 98 public SetPropertyUnchanged(): void { 99 // function to be removed 100 // keep it here until transpiler is updated. 101 } 102 103 // FIXME check, is this used from AppStorage. 104 // unified Appstorage, what classes to use, and the API 105 public createLink(subscribeOwner?: IPropertySubscriber, 106 linkPropName?: PropertyInfo): ObservedPropertyAbstractPU<T> { 107 throw new Error("Can not create a AppStorage 'Link' from a @State property. "); 108 } 109 110 public createProp(subscribeOwner?: IPropertySubscriber, 111 linkPropName?: PropertyInfo): ObservedPropertyAbstractPU<T> { 112 throw new Error("Can not create a AppStorage 'Prop' from a @State property. "); 113 } 114}