1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.constraintlayout.core.widgets.analyzer;
18 
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 public class DependencyNode implements Dependency {
23     public Dependency updateDelegate = null;
24     public boolean delegateToWidgetRun = false;
25     public boolean readyToSolve = false;
26 
27     enum Type {
28         UNKNOWN, HORIZONTAL_DIMENSION, VERTICAL_DIMENSION,
29         LEFT, RIGHT, TOP, BOTTOM, BASELINE
30     }
31 
32     WidgetRun mRun;
33     Type mType = Type.UNKNOWN;
34     int mMargin;
35     public int value;
36     int mMarginFactor = 1;
37     DimensionDependency mMarginDependency = null;
38     public boolean resolved = false;
39 
DependencyNode(WidgetRun run)40     public DependencyNode(WidgetRun run) {
41         this.mRun = run;
42     }
43 
44     List<Dependency> mDependencies = new ArrayList<>();
45     List<DependencyNode> mTargets = new ArrayList<>();
46 
47     @Override
toString()48     public String toString() {
49         return mRun.mWidget.getDebugName() + ":" + mType + "("
50                 + (resolved ? value : "unresolved") + ") <t="
51                 + mTargets.size() + ":d=" + mDependencies.size() + ">";
52     }
53 
54     // @TODO: add description
resolve(int value)55     public void resolve(int value) {
56         if (resolved) {
57             return;
58         }
59 
60         this.resolved = true;
61         this.value = value;
62         for (Dependency node : mDependencies) {
63             node.update(node);
64         }
65     }
66 
67     // @TODO: add description
68     @Override
update(Dependency node)69     public void update(Dependency node) {
70         for (DependencyNode target : mTargets) {
71             if (!target.resolved) {
72                 return;
73             }
74         }
75         readyToSolve = true;
76         if (updateDelegate != null) {
77             updateDelegate.update(this);
78         }
79         if (delegateToWidgetRun) {
80             mRun.update(this);
81             return;
82         }
83         DependencyNode target = null;
84         int numTargets = 0;
85         for (DependencyNode t : mTargets) {
86             if (t instanceof DimensionDependency) {
87                 continue;
88             }
89             target = t;
90             numTargets++;
91         }
92         if (target != null && numTargets == 1 && target.resolved) {
93             if (mMarginDependency != null) {
94                 if (mMarginDependency.resolved) {
95                     mMargin = mMarginFactor * mMarginDependency.value;
96                 } else {
97                     return;
98                 }
99             }
100             resolve(target.value + mMargin);
101         }
102         if (updateDelegate != null) {
103             updateDelegate.update(this);
104         }
105     }
106 
107     // @TODO: add description
addDependency(Dependency dependency)108     public void addDependency(Dependency dependency) {
109         mDependencies.add(dependency);
110         if (resolved) {
111             dependency.update(dependency);
112         }
113     }
114 
115     // @TODO: add description
name()116     public String name() {
117         String definition = mRun.mWidget.getDebugName();
118         if (mType == Type.LEFT
119                 || mType == Type.RIGHT) {
120             definition += "_HORIZONTAL";
121         } else {
122             definition += "_VERTICAL";
123         }
124         definition += ":" + mType.name();
125         return definition;
126     }
127 
128     // @TODO: add description
clear()129     public void clear() {
130         mTargets.clear();
131         mDependencies.clear();
132         resolved = false;
133         value = 0;
134         readyToSolve = false;
135         delegateToWidgetRun = false;
136     }
137 }
138