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 * SynchedPropertySimpleOneWayPU 17 * implementation of @Prop decorated variable of types boolean | number | string | enum 18 * 19 * all definitions in this file are framework internal 20 */ 21 22class SynchedPropertySimpleOneWayPU<T> extends ObservedPropertySimpleAbstractPU<T> 23 implements PeerChangeEventReceiverPU<T> { 24 25 private wrappedValue_: T; 26 private source_: ObservedPropertyAbstract<T>; 27 28 // true for @Prop code path, 29 // false for @(Local)StorageProp 30 private sourceIsOwnObject: boolean; 31 32 constructor(source: ObservedPropertyAbstract<T> | T, subscribeMe?: IPropertySubscriber, thisPropertyName?: PropertyInfo) { 33 super(subscribeMe, thisPropertyName) 34 35 if (source && (typeof (source) === "object") && ("notifyHasChanged" in source) && ("subscribeMe" in source)) { 36 // code path for @(Local)StorageProp 37 this.source_ = source as ObservedPropertyAbstract<T>; 38 this.sourceIsOwnObject = false; 39 // subscribe to receive value chnage updates from LocalStorge source property 40 this.source_.subscribeMe(this); 41 } else { 42 // code path for @Prop 43 this.source_ = new ObservedPropertySimplePU<T>(source as T, this, thisPropertyName); 44 this.sourceIsOwnObject = true; 45 } 46 47 // use own backing store for value to avoid 48 // value changes to be propagated back to source 49 this.wrappedValue_ = this.source_.getUnmonitored(); 50 } 51 52 /* 53 like a destructor, need to call this before deleting 54 the property. 55 */ 56 aboutToBeDeleted() { 57 if (this.source_) { 58 this.source_.unlinkSuscriber(this.id__()); 59 if (this.sourceIsOwnObject == true && this.source_.numberOfSubscrbers()==0){ 60 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: aboutToBeDeleted. owning source_ ObservedPropertySimplePU, calling its aboutToBeDeleted`); 61 this.source_.aboutToBeDeleted(); 62 } 63 this.source_ = undefined; 64 this.sourceIsOwnObject == false; 65 } 66 super.aboutToBeDeleted(); 67 } 68 69 public syncPeerHasChanged(eventSource: ObservedPropertyAbstractPU<T>) { 70 if (eventSource && (eventSource == this.source_)) { 71 // defensive, should always be the case 72 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: \ 73 syncPeerHasChanged peer '${eventSource.info()}'.`); 74 this.sourceHasChanged(eventSource); 75 } 76 } 77 78 protected sourceHasChanged(eventSource: ObservedPropertyAbstractPU<T>): void { 79 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: sourceHasChanged: source '${eventSource.info()}' has changed value to ${eventSource.getUnmonitored()}.`) 80 this.wrappedValue_ = eventSource.getUnmonitored(); 81 this.notifyPropertyHasChangedPU(); 82} 83 84 public getUnmonitored(): T { 85 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: getUnmonitored returns '${JSON.stringify(this.wrappedValue_)}' .`); 86 // unmonitored get access , no call to otifyPropertyRead ! 87 return this.wrappedValue_; 88 } 89 90 // get 'read through` from the ObservedProperty 91 public get(): T { 92 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: get returns '${this.wrappedValue_}'`); 93 this.notifyPropertyHasBeenReadPU() 94 return this.wrappedValue_; 95 } 96 97 public set(newValue: T): void { 98 if (this.wrappedValue_ == newValue) { 99 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: set with unchanged value '${this.wrappedValue_}'- ignoring.`); 100 return; 101 } 102 103 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: set from '${this.wrappedValue_} to '${newValue}'.`); 104 this.wrappedValue_ = newValue; 105 this.notifyPropertyHasChangedPU(); 106 } 107 108 public reset(sourceChangedValue: T): void { 109 stateMgmtConsole.debug(`SynchedPropertySimpleOneWayPU[${this.id__()}, '${this.info() || "unknown"}']: reset from '${this.wrappedValue_} to '${sourceChangedValue}'.`); 110 // if set causes an actual change, then, ObservedPropertySimple source_ will call hasChanged 111 this.source_.set(sourceChangedValue); 112 } 113} 114 115