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 * SynchedPropertySimpleTwoWayPU 18 * implementation of @Link and @Consume decorated variables of types boolean | number | string | enum 19 * 20 * all definitions in this file are framework internal 21 */ 22 23class SynchedPropertySimpleTwoWayPU<T> extends ObservedPropertySimpleAbstractPU<T> 24 implements PeerChangeEventReceiverPU<T> { 25 26 private source_: ObservedPropertyAbstract<T>; 27 private changeNotificationIsOngoing_: boolean = false; 28 29 constructor(source: ObservedPropertyAbstract<T>, owningView: IPropertySubscriber, owningViewPropNme: PropertyInfo) { 30 super(owningView, owningViewPropNme); 31 this.source_ = source; 32 this.source_.subscribeMe(this); 33 } 34 35 /* 36 like a destructor, need to call this before deleting 37 the property. 38*/ 39 aboutToBeDeleted() { 40 if (this.source_) { 41 this.source_.unlinkSuscriber(this.id__()); 42 this.source_ = undefined; 43 } 44 super.aboutToBeDeleted(); 45 } 46 47 /** 48 * Called when sync peer ObservedPropertySimple or SynchedPropertySimpletTwoWay has chnaged value 49 * that peer can be in either parent or child component if 'this' is used for a @Link 50 * that peer can be in either acestor or descendant component if 'this' is used for a @Consume 51 * @param eventSource 52 */ 53 syncPeerHasChanged(eventSource : ObservedPropertyAbstractPU<T>) { 54 if (!this.changeNotificationIsOngoing_) { 55 stateMgmtConsole.debug(`SynchedPropertySimpleTwoWayPU[${this.id__()}, '${this.info() || "unknown"}']: propertyHasChangedPU, property ${eventSource.info()}`); 56 this.notifyPropertyHasChangedPU(); 57 } 58 } 59 60 public getUnmonitored(): T { 61 stateMgmtConsole.debug(`SynchedPropertySimpleTwoWayPU[${this.id__()}, '${this.info() || "unknown"}']: getUnmonitored`); 62 return (this.source_ ? this.source_.getUnmonitored() : undefined); 63 } 64 65 // get 'read through` from the ObservedProperty 66 public get(): T { 67 stateMgmtConsole.debug(`SynchedPropertySimpleTwoWayPU[${this.id__()}, '${this.info() || "unknown"}']: get`); 68 this.notifyPropertyHasBeenReadPU() 69 return this.getUnmonitored(); 70 } 71 72 // set 'writes through` to the ObservedProperty 73 public set(newValue: T): void { 74 if (!this.source_) { 75 stateMgmtConsole.debug(`SynchedPropertySimpleTwoWayPU[${this.id__()}IP, '${this.info() || "unknown"}']: set, no source, returning.`); 76 return; 77 } 78 79 if (this.source_.get() == newValue) { 80 stateMgmtConsole.debug(`SynchedPropertySimpleTwoWayPU[${this.id__()}IP, '${this.info() || "unknown"}']: set with unchanged value '${newValue}'- ignoring.`); 81 return; 82 } 83 84 stateMgmtConsole.debug(`SynchedPropertySimpleTwoWayPU[${this.id__()}IP, '${this.info() || "unknown"}']: set to newValue: '${newValue}'.`); 85 86 // avoid circular notifications @Link -> source @State -> other but also to same @Link 87 this.changeNotificationIsOngoing_ = true; 88 89 // the source_ ObservedProeprty will call: this.hasChanged(newValue); 90 this.source_.set(newValue); 91 this.notifyPropertyHasChangedPU(); 92 93 this.changeNotificationIsOngoing_ = false; 94 } 95} 96