• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-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 * ObservedPropertyObject
18 *
19 * all definitions in this file are framework internal
20 *
21 * class that holds an actual property value of type T
22 * uses its base class to manage subscribers to this
23 * property.
24*/
25class ObservedPropertyObject<T extends Object> extends ObservedPropertyObjectAbstract<T>
26  implements ISinglePropertyChangeSubscriber<T> {
27
28  private wrappedValue_: T;
29
30  constructor(value: T, owningView: IPropertySubscriber, propertyName: PropertyInfo) {
31    super(owningView, propertyName);
32    this.setValueInternal(value);
33  }
34
35  aboutToBeDeleted(unsubscribeMe?: IPropertySubscriber) {
36    this.unsubscribeFromOwningProperty();
37    if (unsubscribeMe) {
38      this.unlinkSuscriber(unsubscribeMe.id__());
39    }
40    super.aboutToBeDeleted();
41  }
42
43  // notification from ObservedObject value one of its
44  // props has chnaged. Implies the ObservedProperty has changed
45  // Note: this function gets called when in this case:
46  //       thisProp.aObsObj.aProp = 47  a object prop gets changed
47  // It is NOT called when
48  //    thisProp.aObsObj = new ClassA
49  hasChanged(newValue: T): void {
50    stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}']: hasChanged`);
51    this.notifyHasChanged(this.wrappedValue_);
52  }
53
54  private unsubscribeFromOwningProperty() {
55    if (this.wrappedValue_) {
56      if (this.wrappedValue_ instanceof SubscribaleAbstract) {
57        (this.wrappedValue_ as SubscribaleAbstract).removeOwningProperty(this);
58      } else {
59        ObservedObject.removeOwningProperty(this.wrappedValue_, this);
60      }
61    }
62  }
63  /*
64    actually update this.wrappedValue_
65    called needs to do value change check
66    and also notify with this.aboutToChange();
67  */
68  private setValueInternal(newValue: T): boolean {
69    if (typeof newValue !== 'object') {
70      stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}'] new value is NOT an object. Application error. Ignoring set.`);
71      return false;
72    }
73
74    this.unsubscribeFromOwningProperty();
75
76    if (ObservedObject.IsObservedObject(newValue)) {
77      stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}'] new value is an ObservedObject already`);
78      ObservedObject.addOwningProperty(newValue, this);
79      this.wrappedValue_ = newValue;
80    } else if (newValue instanceof SubscribaleAbstract) {
81      stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}'] new value is an SubscribaleAbstract, subscribiung to it.`);
82      this.wrappedValue_ = newValue;
83      (this.wrappedValue_ as unknown as SubscribaleAbstract).addOwningProperty(this);
84    } else {
85      stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}'] new value is an Object, needs to be wrapped in an ObservedObject.`);
86      this.wrappedValue_ = ObservedObject.createNew(newValue, this);
87    }
88    return true;
89  }
90
91  public get(): T {
92    stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}']: get`);
93    this.notifyPropertyRead();
94    return this.wrappedValue_;
95  }
96
97  public set(newValue: T): void {
98    if (this.wrappedValue_ == newValue) {
99      stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}']: set with unchanged value - ignoring.`);
100      return;
101    }
102    stateMgmtConsole.debug(`ObservedPropertyObject[${this.id__()}, '${this.info() || 'unknown'}']: set, changed`);
103    this.setValueInternal(newValue);
104    this.notifyHasChanged(newValue);
105  }
106
107/**
108 * These functions are used
109 *   LocalStorage.link  (also in partial update config)
110 *   (FU)View.initializeConsumeinitializeConsume
111 */
112  public createLink(subscribeOwner?: IPropertySubscriber,
113    linkPropName?: PropertyInfo): ObservedPropertyAbstract<T> {
114    return new SynchedPropertyObjectTwoWay(this, subscribeOwner, linkPropName);
115  }
116
117  public createProp(subscribeOwner?: IPropertySubscriber,
118    linkPropName?: PropertyInfo): ObservedPropertyAbstract<T> {
119    throw new Error("Creating a 'Prop' property is unsupported for Object type property value.");
120  }
121}
122