• 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 * SynchedPropertyObjectTwoWay
18 *
19 * all definitions in this file are framework internal
20 */
21class SynchedPropertyObjectTwoWay<C extends Object>
22  extends ObservedPropertyObjectAbstract<C>
23  implements ISinglePropertyChangeSubscriber<C> {
24
25  private linkedParentProperty_: ObservedPropertyObjectAbstract<C>;
26  private changeNotificationIsOngoing_: boolean = false;
27
28  constructor(linkSource: ObservedPropertyObjectAbstract<C>,
29    owningChildView: IPropertySubscriber,
30    thisPropertyName: PropertyInfo) {
31    super(owningChildView, thisPropertyName);
32    this.linkedParentProperty_ = linkSource;
33    // register to the parent property
34    this.linkedParentProperty_.subscribeMe(this);
35
36    // register to the ObservedObject
37    ObservedObject.addOwningProperty(this.getObject(), this);
38  }
39
40  /*
41  like a destructor, need to call this before deleting
42  the property.
43  */
44  aboutToBeDeleted() {
45    if (this.linkedParentProperty_) {
46        // unregister from parent of this link
47        this.linkedParentProperty_.unlinkSuscriber(this.id__());
48
49        // unregister from the ObservedObject
50        ObservedObject.removeOwningProperty(this.getObject(), this);
51    }
52    super.aboutToBeDeleted();
53  }
54
55  private getObject(): C {
56    this.notifyPropertyRead();
57    return (this.linkedParentProperty_ ? this.linkedParentProperty_.get() : undefined);
58  }
59
60  private setObject(newValue: C): void {
61    if (this.linkedParentProperty_) {
62        this.linkedParentProperty_.set(newValue)
63    }
64  }
65
66  // this object is subscriber to ObservedObject
67  // will call this cb function when property has changed
68  hasChanged(newValue: C): void {
69    if (!this.changeNotificationIsOngoing_) {
70      stateMgmtConsole.debug(`SynchedPropertyObjectTwoWay[${this.id__()}, '${this.info() || "unknown"}']: contained ObservedObject hasChanged'.`)
71      this.notifyHasChanged(this.getObject());
72    }
73  }
74
75
76
77  // get 'read through` from the ObservedProperty
78  public get(): C {
79    stateMgmtConsole.debug(`SynchedPropertyObjectTwoWay[${this.id__()}, '${this.info() || "unknown"}']: get`)
80    return this.getObject();
81  }
82
83  // set 'writes through` to the ObservedProperty
84  public set(newValue: C): void {
85    if (this.getObject() == newValue) {
86      stateMgmtConsole.debug(`SynchedPropertyObjectTwoWay[${this.id__()}IP, '${this.info() || "unknown"}']: set with unchanged value '${newValue}'- ignoring.`);
87      return;
88    }
89
90    stateMgmtConsole.debug(`SynchedPropertyObjectTwoWay[${this.id__()}, '${this.info() || "unknown"}']: set to newValue: '${newValue}'.`);
91
92    ObservedObject.removeOwningProperty(this.getObject(), this);
93
94    // the purpose of the changeNotificationIsOngoing_ is to avoid
95    // circular notifications @Link -> source @State -> other but alos same @Link
96    this.changeNotificationIsOngoing_ = true;
97    this.setObject(newValue);
98    ObservedObject.addOwningProperty(this.getObject(), this);
99    this.notifyHasChanged(newValue);
100    this.changeNotificationIsOngoing_ = false;
101  }
102
103  /**
104 * These functions are meant for use in connection with the App Stoage and
105 * business logic implementation.
106 * the created Link and Prop will update when 'this' property value
107 * changes.
108 */
109  public createLink(subscribeOwner?: IPropertySubscriber,
110    linkPropName?: PropertyInfo): ObservedPropertyAbstract<C> {
111    return new SynchedPropertyObjectTwoWay(this, subscribeOwner, linkPropName);
112  }
113  public createProp(subscribeOwner?: IPropertySubscriber,
114    linkPropName?: PropertyInfo): ObservedPropertyAbstract<C> {
115    throw new Error("Creating a 'Prop' property is unsupported for Object type property value.");
116  }
117
118}
119