-
Notifications
You must be signed in to change notification settings - Fork 0
/
DemoCopy.ulam
182 lines (149 loc) · 4.37 KB
/
DemoCopy.ulam
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
local typedef BondStatus BS;
/**
Copy non-executable package (looped) sequence, hardcoded for testing
\symbol DC
\color #caf7b7
*/
element DemoCopy : QStateT(3) + QBondableT(2) + QDiffusableT(100) + QMortal + Fail {
constant QBond.Index cORIG = 0;
constant QBond.Index cCOPY = 1;
constant State cSTATE_ATTACH = 0;
constant State cSTATE_COPY = 1;
constant State cSTATE_ADVANCE_COPY = 2;
constant State cSTATE_ADVANCE = 3;
constant State cSTATE_COMPLETE = 4;
constant State cSTATE_DETACH = 5;
@Override Void behave() {
if (isState(cSTATE_ATTACH)) {
attach();
} else if (isState(cSTATE_COPY)) {
copy();
} else if (isState(cSTATE_ADVANCE_COPY)) {
advanceCopy();
} else if (isState(cSTATE_ADVANCE)) {
advance();
} else if (isState(cSTATE_COMPLETE)) {
complete();
} else if (isState(cSTATE_DETACH)) {
detach();
}
if (isState(cSTATE_DONE)) {
die();
} else {
diffuse();
}
}
Void attach() {
AtomUtils au;
BondStatus bs;
BondUtils bu;
// Find non-exec package to attach to
Package pkg;
WindowServices ws;
ws.reset(1, bu.maxDist(pkg, self));
if (!ws.scan(au.getType(pkg)))
return;
SiteNum site = ws.getPick();
if (bs.isOk(bu.attach(0, cORIG, site, Package.cCOMMON)))
setState(cSTATE_COPY);
}
Void copy() {
BondStatus bs;
BondUtils bu;
EventWindow ew;
EventWindowMisc ewm;
PackageData pd;
QBond& origBond = getBond(cORIG);
QBond& copyBond = getBond(cCOPY);
// Get current package
SiteNum origSite = origBond.getSiteNumber();
Package& orig = (Package&) ew[origSite];
if (orig.getBond(Package.cOTHER).isAttached()) {
// First item
setState(cSTATE_COMPLETE);
return;
}
// Make copy
Package pkg;
pkg.setData(orig.getData());
pkg.setAux(pd.resetIsActive(orig.getAux()));
// Place around self
SiteNum site = ewm.findEmptySite(1, bu.maxDist(self, pkg));
if (site == SiteNum.maxof)
return;
ew[site] = pkg;
if (!copyBond.isAttached()) {
/// First item
BS.Status status = BS.cOK;
// Attach to self
status = bu.attach(0, cCOPY, site, Package.cCOMMON);
// Attach to original (marking beginning of copy)
if (bs.isOk(status)) {
status = bu.attach(origSite, Package.cOTHER, site, Package.cOTHER);
if (!bs.isOk(status)) {
// Try to detach and start over
if (!bs.isOk(bu.detach(0, cCOPY)))
fail("Demo_Copy.copy: failed to detach first item copy");
}
}
// Cleanup on error
if (!bs.isOk(status)) {
Empty empty;
ew[site] = empty;
return;
}
setState(cSTATE_ADVANCE);
} else {
/// Attaching to previous item
// Get current copy
SiteNum copySite = copyBond.getSiteNumber();
Package& copy = (Package&) ew[copySite];
// Attach new copy package to current copy as next
if (!bs.isOk(bu.attach(copySite, Package.cNEXT, site, Package.cPREV))) {
Empty empty;
ew[site] = empty;
return;
}
setState(cSTATE_ADVANCE_COPY);
}
}
Void advanceCopy() {
BondStatus bs;
BondUtils bu;
BS.Status status = bu.traverse(0, cCOPY, Package.cNEXT);
if (bs.isOk(status))
setState(cSTATE_ADVANCE);
}
Void advance() {
BondStatus bs;
BondUtils bu;
BS.Status status = bu.traverse(0, cORIG, Package.cNEXT);
if (bs.isOk(status))
setState(cSTATE_COPY);
}
Void complete() {
BondStatus bs;
BondUtils bu;
EventWindow ew;
QBond& origBond = getBond(cORIG);
QBond& copyBond = getBond(cCOPY);
SiteNum origSite = origBond.getSiteNumber();
SiteNum copySite = copyBond.getSiteNumber();
Package& orig = (Package&) ew[origSite];
QBond& firstBond = orig.getBond(Package.cOTHER);
SiteNum firstSite = firstBond.getSiteNumber(origSite);
// Attach first to last, completing copy loop
BS.Status status = bu.attach(copySite, Package.cNEXT, firstSite, Package.cPREV);
if (bs.isOk(status))
setState(cSTATE_DETACH);
}
Void detach() {
BondStatus bs;
BondUtils bu;
QBond& origBond = getBond(cORIG);
SiteNum origSite = origBond.getSiteNumber();
BS.Status status = bu.detach(origSite, Package.cOTHER);
if (bs.isOk(status))
setState(cSTATE_DONE);
}
}