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