Skip to content

Commit fe8d4f6

Browse files
authored
[Optimization] Refactor block connection checks to O(1) (sugarlabs#5270)
Optimizes the _testConnectionType method in js/blocks.js by replacing a linear series of string comparisons with a constant-time Set lookup. This reduces complexity and improves maintainability.
1 parent c4b5948 commit fe8d4f6

File tree

1 file changed

+76
-160
lines changed

1 file changed

+76
-160
lines changed

js/blocks.js

Lines changed: 76 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,77 @@ const VIDEOVALUE = "##__VIDEO__##";
6969
const NOTEBLOCKS = ["newnote", "osctime"];
7070
const PITCHBLOCKS = ["pitch", "steppitch", "hertz", "pitchnumber", "nthmodalpitch", "playdrum"];
7171

72+
const ALLOWED_CONNECTIONS = new Set([
73+
"vspaceout:vspacein",
74+
"vspacein:vspaceout",
75+
"in:out",
76+
"out:in",
77+
"in:vspaceout",
78+
"vspaceout:in",
79+
"out:vspacein",
80+
"vspacein:out",
81+
"numberin:numberout",
82+
"numberin:anyout",
83+
"numberout:numberin",
84+
"anyout:numberin",
85+
"textin:textout",
86+
"textin:anyout",
87+
"textout:textin",
88+
"anyout:textin",
89+
"booleanout:booleanin",
90+
"booleanin:booleanout",
91+
"mediain:mediaout",
92+
"mediaout:mediain",
93+
"mediain:textout",
94+
"textout:mediain",
95+
"filein:fileout",
96+
"fileout:filein",
97+
"casein:caseout",
98+
"caseout:casein",
99+
"vspaceout:casein",
100+
"casein:vspaceout",
101+
"vspacein:caseout",
102+
"caseout:vspacein",
103+
"solfegein:anyout",
104+
"solfegein:solfegeout",
105+
"solfegein:textout",
106+
"solfegein:noteout",
107+
"solfegein:scaledegreeout",
108+
"solfegein:numberout",
109+
"anyout:solfegein",
110+
"solfegeout:solfegein",
111+
"textout:solfegein",
112+
"noteout:solfegein",
113+
"scaledegreeout:solfegein",
114+
"numberout:solfegein",
115+
"notein:solfegeout",
116+
"notein:scaledegreeout",
117+
"notein:textout",
118+
"notein:noteout",
119+
"solfegeout:notein",
120+
"scaledegreeout:notein",
121+
"textout:notein",
122+
"noteout:notein",
123+
"pitchout:anyin",
124+
"gridout:anyin",
125+
"anyin:textout",
126+
"anyin:mediaout",
127+
"anyin:numberout",
128+
"anyin:anyout",
129+
"anyin:fileout",
130+
"anyin:solfegeout",
131+
"anyin:scaledegreeout",
132+
"anyin:noteout",
133+
"textout:anyin",
134+
"mediaout:anyin",
135+
"numberout:anyin",
136+
"anyout:anyin",
137+
"fileout:anyin",
138+
"solfegeout:anyin",
139+
"scaledegreeout:anyin",
140+
"noteout:anyin"
141+
]);
142+
72143
/**
73144
* Blocks holds the list of blocks and most of the block-associated
74145
* methods, since most block manipulations are inter-block.
@@ -1432,9 +1503,8 @@ class Blocks {
14321503
this.blockList[silenceBlockobj.connections[0]].connections[c] ===
14331504
silenceBlock
14341505
) {
1435-
this.blockList[silenceBlockobj.connections[0]].connections[
1436-
c
1437-
] = this.blockList.indexOf(thisBlockobj);
1506+
this.blockList[silenceBlockobj.connections[0]].connections[c] =
1507+
this.blockList.indexOf(thisBlockobj);
14381508
break;
14391509
}
14401510
}
@@ -1865,9 +1935,8 @@ class Blocks {
18651935
i > ci + 1;
18661936
i--
18671937
) {
1868-
this.blockList[newBlock].connections[i] = this.blockList[
1869-
newBlock
1870-
].connections[i - 1];
1938+
this.blockList[newBlock].connections[i] =
1939+
this.blockList[newBlock].connections[i - 1];
18711940
}
18721941
}
18731942
/** The new block is added below the current connection... */
@@ -2184,160 +2253,7 @@ class Blocks {
21842253
*/
21852254
this._testConnectionType = (type1, type2) => {
21862255
/** Can these two blocks dock? */
2187-
if (type1 === "vspaceout" && type2 === "vspacein") {
2188-
return true;
2189-
}
2190-
if (type1 === "vspacein" && type2 === "vspaceout") {
2191-
return true;
2192-
}
2193-
2194-
if (type1 === "in" && type2 === "out") {
2195-
return true;
2196-
}
2197-
if (type1 === "out" && type2 === "in") {
2198-
return true;
2199-
}
2200-
if (type1 === "in" && type2 === "vspaceout") {
2201-
return true;
2202-
}
2203-
if (type1 === "vspaceout" && type2 === "in") {
2204-
return true;
2205-
}
2206-
if (type1 === "out" && type2 === "vspacein") {
2207-
return true;
2208-
}
2209-
if (type1 === "vspacein" && type2 === "out") {
2210-
return true;
2211-
}
2212-
if (type1 === "numberin" && ["numberout", "anyout"].includes(type2)) {
2213-
return true;
2214-
}
2215-
if (["numberout", "anyout"].includes(type1) && type2 === "numberin") {
2216-
return true;
2217-
}
2218-
if (type1 === "textin" && ["textout", "anyout"].includes(type2)) {
2219-
return true;
2220-
}
2221-
if (["textout", "anyout"].includes(type1) && type2 === "textin") {
2222-
return true;
2223-
}
2224-
if (type1 === "booleanout" && type2 === "booleanin") {
2225-
return true;
2226-
}
2227-
if (type1 === "booleanin" && type2 === "booleanout") {
2228-
return true;
2229-
}
2230-
if (type1 === "mediain" && type2 === "mediaout") {
2231-
return true;
2232-
}
2233-
if (type1 === "mediaout" && type2 === "mediain") {
2234-
return true;
2235-
}
2236-
if (type1 === "mediain" && type2 === "textout") {
2237-
return true;
2238-
}
2239-
if (type2 === "mediain" && type1 === "textout") {
2240-
return true;
2241-
}
2242-
if (type1 === "filein" && type2 === "fileout") {
2243-
return true;
2244-
}
2245-
if (type1 === "fileout" && type2 === "filein") {
2246-
return true;
2247-
}
2248-
if (type1 === "casein" && type2 === "caseout") {
2249-
return true;
2250-
}
2251-
if (type1 === "caseout" && type2 === "casein") {
2252-
return true;
2253-
}
2254-
if (type1 === "vspaceout" && type2 === "casein") {
2255-
return true;
2256-
}
2257-
if (type1 === "casein" && type2 === "vspaceout") {
2258-
return true;
2259-
}
2260-
if (type1 === "vspacein" && type2 === "caseout") {
2261-
return true;
2262-
}
2263-
if (type1 === "caseout" && type2 === "vspacein") {
2264-
return true;
2265-
}
2266-
if (
2267-
type1 === "solfegein" &&
2268-
[
2269-
"anyout",
2270-
"solfegeout",
2271-
"textout",
2272-
"noteout",
2273-
"scaledegreeout",
2274-
"numberout"
2275-
].includes(type2)
2276-
) {
2277-
return true;
2278-
}
2279-
if (
2280-
type2 === "solfegein" &&
2281-
[
2282-
"anyout",
2283-
"solfegeout",
2284-
"textout",
2285-
"noteout",
2286-
"scaledegreeout",
2287-
"numberout"
2288-
].includes(type1)
2289-
) {
2290-
return true;
2291-
}
2292-
if (
2293-
type1 === "notein" &&
2294-
["solfegeout", "scaledegreeout", "textout", "noteout"].includes(type2)
2295-
) {
2296-
return true;
2297-
}
2298-
if (type1 === "pitchout" && type2 === "anyin") {
2299-
return true;
2300-
}
2301-
if (type1 === "gridout" && type2 === "anyin") {
2302-
return true;
2303-
}
2304-
if (
2305-
type2 === "notein" &&
2306-
["solfegeout", "scaledegreeout", "textout", "noteout"].includes(type1)
2307-
) {
2308-
return true;
2309-
}
2310-
if (
2311-
type1 === "anyin" &&
2312-
[
2313-
"textout",
2314-
"mediaout",
2315-
"numberout",
2316-
"anyout",
2317-
"fileout",
2318-
"solfegeout",
2319-
"scaledegreeout",
2320-
"noteout"
2321-
].includes(type2)
2322-
) {
2323-
return true;
2324-
}
2325-
if (
2326-
type2 === "anyin" &&
2327-
[
2328-
"textout",
2329-
"mediaout",
2330-
"numberout",
2331-
"anyout",
2332-
"fileout",
2333-
"solfegeout",
2334-
"scaledegreeout",
2335-
"noteout"
2336-
].includes(type1)
2337-
) {
2338-
return true;
2339-
}
2340-
return false;
2256+
return ALLOWED_CONNECTIONS.has(type1 + ":" + type2);
23412257
};
23422258

23432259
/**

0 commit comments

Comments
 (0)