blob: bf84870fa9e9ec8f72144e788b0516b476580e56 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
pragma Strict
import QtQml
BaseConstraint {
id: self
property Variable myInput
property Variable myOutput
property Variable scale
property Variable offset
function addToGraph() {
let ihn = myInput;
if (ihn)
ihn.addConstraint(self);
let out = myOutput;
if (out)
out.addConstraint(self);
let s = scale;
if (s)
s.addConstraint(self);
let o = offset;
if (o)
o.addConstraint(self);
satisfaction = Satisfaction.NONE;
}
function removeFromGraph() {
if (myInput)
myInput.removeConstraint(self);
if (myOutput)
myOutput.removeConstraint(self);
if (scale)
scale.removeConstraint(self);
if (offset)
offset.removeConstraint(self);
satisfaction = Satisfaction.NONE;
}
property Variable input: (satisfaction === Satisfaction.BACKWARD)
? myOutput
: myInput
property Variable output: (satisfaction === Satisfaction.BACKWARD)
? myInput
: myOutput
function recalculate() {
let ihn = input;
let out = output;
if (!ihn) {
out.walkStrength = strength;
out.stay = !isInput;
return;
}
out.walkStrength = Strength.weakestOf(strength, ihn.walkStrength);
let stay = ihn.stay;
// Optimize for number of lookups. We lookup scale and offset only once and we keep
// stay in a local as long as we can.
let s = scale
if (s)
stay = stay && s.stay;
let o = offset
if (o)
stay = stay && o.stay;
out.stay = stay;
if (stay)
out.value = evaluate();
}
function chooseMethod(mark: int) {
let ihn = myInput;
let out = myOutput;
let outStrength = out.walkStrength;
if (!ihn) {
satisfaction = (out.mark !== mark && Strength.stronger(strength, outStrength))
? Satisfaction.FORWARD
: Satisfaction.NONE;
return;
}
let ihnStrength = ihn.walkStrength;
if (Strength.weaker(ihnStrength, outStrength)) {
satisfaction = Strength.stronger(strength, ihnStrength)
? Satisfaction.BACKWARD
: Satisfaction.NONE;
return;
}
satisfaction = Strength.stronger(strength, outStrength)
? Satisfaction.FORWARD
: Satisfaction.BACKWARD
}
function markInputs(mark: int) {
let i = input;
if (i)
i.mark = mark;
let s = scale;
if (s)
s.mark = mark;
let o = offset;
if (o)
o.mark = mark;
}
function inputsKnown(mark: int) : bool {
let ihn = input;
return !ihn || ihn.mark === mark || ihn.stay || ihn.determinedBy === null;
}
function evaluate() : int {
let result = input.value;
// This is a rather hot code path. It pays off to do the lookups for offset and scale
// only once
let o = offset;
let s = scale;
if (satisfaction === Satisfaction.BACKWARD) {
if (o)
result = result - o.value;
if (s)
result = result / s.value;
} else {
if (s)
result = result * s.value;
if (o)
result = result + o.value; // TODO: += and -= miscompile!
}
return result;
}
}
|