From b1ec23e3579b1528e6e7eb12f5c9f89793b5390e Mon Sep 17 00:00:00 2001 From: alyx Date: Tue, 31 May 2022 15:15:17 +0000 Subject: moved some stuff around, updated circuitsv2.json, linked the grapher from the searcher --- lib/chipBehavior.js | 82 ++++++++++++++++++++ lib/chips.css | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/chips.js | 95 +++++++++++++++++++++++ lib/util.js | 5 ++ 4 files changed, 400 insertions(+) create mode 100644 lib/chipBehavior.js create mode 100644 lib/chips.css create mode 100644 lib/chips.js create mode 100644 lib/util.js (limited to 'lib') diff --git a/lib/chipBehavior.js b/lib/chipBehavior.js new file mode 100644 index 0000000..04c500b --- /dev/null +++ b/lib/chipBehavior.js @@ -0,0 +1,82 @@ +/* + Big object of code for each stateless chip. Each takes in (array<{type: String, value:any}>, {String:String}) + ^Ports^ ^typeoverrides^ + and returns an array or false. + int: bigint + float: number + bool: boolean + string: string + vector3: {x:number,y:number,z:number} + Player: Object ----------| These two have no meaning right now. null and undefined are invalid, everything else is valid. + Rec Room Object: Object -| +*/ +function dtr (n) {return n / 360 * Math.PI * 2} +function rtd (n) {return n / (Math.PI * 2) * 360} +const SchipBehaviors = { + //basic maths + "98b99011-9be8-43b3-89cc-1e9d55bd8b51": ([{value}], {T}) => { //abs + switch (T) { + case 'float': + return [Math.abs(value)] + break; + case 'int': + return [value < 0 ? value * -1n : value] + break; + default: + return false; + break; + } + }, + "0ccb153c-dd08-4f22-80fd-9d8c5940928c": (values, {T}) => { //add + switch(T) { + case 'int': + case 'float': + return [values.reduce((a,b) => a+b, 0)]; + break; + case 'Vector3': + return [values.reduce((a,b) => ({x:a.x+b.x,y:a.y+b.y,y:a.z+b.z}), {x:0,y:0,z:0})] + break; + default: + return false; + break; + } + }, + + //logic + "3fb9fd93-8d45-4395-b9a3-63a99a14442b": (values) => [values.reduce((a,{value:b}) => a && b, true)], //and + "b5dcded0-eb2b-468d-a4b9-ffb1054f6214": (values) => [values.reduce((a,{value:b}) => a || b, false)], //or + "ff551243-beb4-470e-ab48-9d616818d5e4": ([{value}]) => [!value], //not + "3663225d-e18d-40e6-a234-ef10378528be": ([{value:a},{value:b}]) => [a==b], //equals + "110c29b1-ac90-4a71-b3c0-53372aa134bc": ([{value:a},{value:b}]) => [a>b], //greater + "a10e7788-f016-4390-a68e-87d93b47edb1": ([{value:a},{value:b}]) => [a>=b], //greater equal + "7e58b3f4-2694-4ced-b3a8-0fe23f48f60f": ([{value:a},{value:b}]) => [a [a<=b], //less equal + + //trig + "46ce50b8-0a20-43d2-9646-484ce2a6752c": ([{value}]) => [rtd(Math.acos(dtr(value)))], + "aaa4e58f-16df-426a-b7a7-a654eab97037": ([{value}]) => [rtd(Math.asin(dtr(value)))], + "02d62908-550d-4f8b-8bc7-0960fb1b547f": ([{value:a},{value:b}]) => [rtd(Math.atan2(dtr(a),dtr(b)))], + "84646ed2-015e-4a8b-9d37-5115cb9ebadc": ([{value}]) => [rtd(Math.atan(dtr(value)))], + + //string + "77afc9dd-baa9-4312-b8b8-7ef479c840e6": ([{value:fmt}, ...props]) => + [props.reduce((p, {value:c}, i) => + p.replaceAll(`{${i}}`, c), + fmt)], + "aa24edab-c707-4cff-8c73-07e479b4cd07": ([{value:str}, {value:seq}]) => [Boolean(str.search(seq) != -1)], + "dcde9345-00f2-41fb-9a2d-5a938f39bfb5": ([{value:str}]) => [str.length], + "ad169649-1050-48c5-a540-f03a2059bcdb": ([{value:str}, {value:del}]) => [str.split(del)], + "6b92c345-e6bc-40d9-aae9-4754e634777c": ([{value:str}, {value:idx}]) => [[str.slice(0, idx), str.slice(idx)]], + "1af21999-38f8-4231-9de9-26b43f47fe0d": ([{value:str}, {value:seq}]) => [str.search(seq)], + "678f6d33-1e94-4be6-b959-0212c1a2207f": ([{value:str}]) => [str.toLowerCase()], + "8f5995c7-5af0-4064-9cb7-2b80d75d157f": ([{value:str}]) => [str.toUpperCase()], +} + +/* + Big object of code for each stateful(exec-having) chip. + "ReadonlyName": "String +*/ +const EchipBehaviors = { + +} +module.exports = SchipBehaviors; \ No newline at end of file diff --git a/lib/chips.css b/lib/chips.css new file mode 100644 index 0000000..12a3704 --- /dev/null +++ b/lib/chips.css @@ -0,0 +1,218 @@ +/* +Hello! This is a big fat CSS file for rendering CV2 chips, maintained +by Aleteoryx. If you need help, ask around for me in the #circuits-v2 +discord channel, or just ping me if you want. (Not too much!) + +To render a chip, create a .chip
. Inside it, put +.chipheader, .input, and .output divs. In the header, simply put +your chip's name. Then, in the input and output divs, add divs +with your chip's ports and types. +.bool, .int, .float, .string, .exec, and .special are all supported. + +A finished chip should look something like this: + +
+
If
+
+
+
Condition
+
+
+
Then
+
Else
+
+
+ +Currently, only regular chips are supported, though this will change +soon! +*/ +@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap'); + +@media (orientation: portrait) { + body { + --chip-scale: 6vw; + } +} +@media (orientation: landscape) { + body { + --chip-scale: 2rem; + } +} + +body { + /*chip bit colors*/ + --color-top: hsl(300,1%,32%); + --color-bottom: hsl(300,0%,50%); + + /*port colors*/ + --color-float: hsl(215, 80%, 48%); + --color-int: hsl(133,73%,23%); + --color-exec: hsl(18,92%,53%); + --color-string: hsl(290,33%,39%); + --color-bool: hsl(349,82%,55%); + --color-any: hsl(26,44%,94%); + --color-special: hsl(47,91%,54%); + + + --chipOffsetX: 0; + --chipOffsetY: 0; +} + +/*apply colors to classes*/ +.input > .float::before, .output > .float::after { + background-color: var(--color-float); +} +.input > .int::before, .output > .int::after { + background-color: var(--color-int); +} +.input > .exec::before, .output > .exec::after { + background-color: var(--color-exec); +} +.input > .string::before, .output > .string::after { + background-color: var(--color-string); +} +.input > .bool::before, .output > .bool::after { + background-color: var(--color-bool); +} +.input > .any::before, .output > .any::after { + background-color: var(--color-any); +} +.input > .special::before, .output > .special::after { + background-color: var(--color-special); +} + +.chip { + font-size: calc(var(--chip-scale) * .5); + font-family: 'Roboto', sans-serif; + color: white; + background-color: var(--color-bottom); + + position: relative; + display: inline-grid; + overflow: visible; + + grid-template-areas: "header header" "input output"; + + grid-gap: calc(var(--chip-scale) * .5); + margin: calc(var(--chip-scale) * 0.8); + padding: calc(var(--chip-scale) / 3); + border-radius: calc(var(--chip-scale) / 4); + min-width: 0; +} + +.input, .output { + display: inline-block; + margin-right: calc(var(--chip-scale) / 3); + margin-top: calc(var(--chip-scale) / -2); + margin-bottom: calc(var(--chip-scale) / -5); +} + +.chipheader { + margin: calc(var(--chip-scale) / -3); + margin-bottom: 0; + + padding: calc(var(--chip-scale) / 2); + text-align: center; + background-color: var(--color-top); + + border-top-left-radius: calc(var(--chip-scale) / 4); + border-top-right-radius: calc(var(--chip-scale) / 4); + + grid-area: header; + + font-size: calc(var(--chip-scale) * 0.75); + + -ms-high-contrast: white-on-black; +} + +.input { + grid-area: input; +} + +.output { + grid-area: output; + text-align: right; +} + +.type { + color: #fff0; + background-color: #0000; + position: fixed; + padding: calc(var(--chip-scale) * 0.1); + border: 0 solid #aaa0; + top: 0; + left: 0; + white-space: nowrap; +} + +:is(.exec, .float, .int, .bool, .string, .special, .any):hover + .type { + color: #fff; + background-color: #000; + border: calc(var(--chip-scale) * 0.1) solid #aaa; + z-index: 99; + top: calc(var(--mouse-y) + 10px - (var(--chipOffsetY) * 1px)); + left: calc(var(--mouse-x) + 10px - (var(--chipOffsetX) * 1px)); +} + +.input > .exec::before, +.output > .exec::after { + height: calc(.75 * var(--chip-scale)); + width: calc(1 * var(--chip-scale)); + background-color: var(--color-exec); + + clip-path: polygon(0 0, 62.5% 0, 100% 50%, 62.5% 100%, 0 100%); + top: calc(var(--chip-scale) * -0.075); +} + +:is(.exec, .float, .int, .bool, .string, .special, .any) { + margin-top: calc(var(--chip-scale) * 0.3); + margin-bottom: calc(var(--chip-scale) * 0.3); + position: relative; + clip-path: none; + overflow: visible; +} + +.input > :is(.exec, .float, .int, .bool, .string, .special, .any) { + margin-left: calc(var(--chip-scale) * 0.5); +} +.output > :is(.exec, .float, .int, .bool, .string, .special, .any) { + margin-right: calc(var(--chip-scale) * -0.05); +} + +.input > :is(.exec, .float, .int, .bool, .string, .special, .any)::before, +.output > :is(.exec, .float, .int, .bool, .string, .special, .any)::after { + position: absolute; + content: ""; + overflow: visible; +} + +.input > :is(.float, .int, .bool, .string, .special, .any)::before { + left: calc(var(--chip-scale) * -1.1); +} +.output > :is(.float, .int, .bool, .string, .special, .any)::after { + right: calc(var(--chip-scale) * -0.9); +} + +.input > .exec::before { + left: calc(var(--chip-scale) * -1.2); +} +.output > .exec::after { + right: calc(var(--chip-scale) * -1.2); +} + +.input > .list::before, +.output > .list::after { + color: black; + content: "[ ]"; + font-size: calc(var(--chip-scale) * 0.3); + display: flex; + align-content: center; + justify-content: center; +} + +.input > :is(.float, .int, .bool, .string, .special, .any)::before, +.output > :is(.float, .int, .bool, .string, .special, .any)::after { + height: calc(.5 * var(--chip-scale)); + width: calc(0.625 * var(--chip-scale)); + top: 1px; +} \ No newline at end of file diff --git a/lib/chips.js b/lib/chips.js new file mode 100644 index 0000000..0ba542e --- /dev/null +++ b/lib/chips.js @@ -0,0 +1,95 @@ +let root = document.documentElement; + +if (window.location.pathname != '/grapher/') + root.addEventListener("mousemove", e => { + root.style.setProperty('--mouse-x', e.clientX + "px"); + root.style.setProperty('--mouse-y', e.clientY + "px"); + }); + + +const portColors = { + float: '#186adc', + int: '#0f6522', + exec: '#f55b18', + string: '#794284', + bool: '#ea2e50', + any: '#f6eee8', + special: '#f4c61e' +} +const typeRegex = /(?:^|(?<=<))(?:int|float|bool|string|exec)(?:$|(?=>))/; +const unionRegex = /^T\d*$|(?<=List<)T\d*(?=>)/; + +function computeType(Type, TypeParams, to) { + let t = Type; + if (to) for (const o of Object.keys(to)) t = t.replace(o, to[o]); + let tc = "special" + if (typeRegex.test(t)) { + tc = t; + } else if (unionRegex.test(t)) { + let tn = t.match(unionRegex)[0]; + let ut = TypeParams[tn]; + t = t.replace(unionRegex, `${tn}: ${ut}`) + + tc = "any"; + } + return {typeclass: tc, type: t}; +} + +function generateChipHTML(NodeDescs, typeoverride = undefined) { + for (let cur of NodeDescs) { + let ins = cur.Inputs; + let outs = cur.Outputs; + + const root = newEl('div', 'chip'); + const header = newEl('div', 'chipheader'); + header.innerText = cur.Name; + const input = newEl('div', 'input'); + const output = newEl('div', 'output'); + root.append(header, input, output); + + for (const inp of ins) { + //work out the type + let {typeclass, type} = computeType(inp.ReadonlyType, cur.ReadonlyTypeParams, typeoverride); + + const port = newEl('div', typeclass); + port.innerHTML = inp.Name + " "; + if (type.includes("List")) port.classList.add("list"); + + const tooltip = newEl('div', 'type'); + tooltip.innerText = type; + + input.append(port, tooltip); + } + + for (const out of outs) { + //work out the type + let {typeclass, type} = computeType(out.ReadonlyType, cur.ReadonlyTypeParams, typeoverride); + + const port = newEl('div', typeclass); + port.innerHTML = out.Name + " "; + if (type.includes("List")) port.classList.add("list"); + + const tooltip = newEl('div', 'type'); + tooltip.innerText = type; + + output.append(port, tooltip); + } + + return root; + } + +} + +function ListAllTypes(Nodes) { + let m = new Set(); + for (const n of Object.values(Nodes)) { + for (const desc of n.NodeDescs) { + for (const td of Object.values(desc.ReadonlyTypeParams)) + if (/^[A-Za-z0-9 ]+$/.test(td)) m.add(td); + for (const port of [...desc.Inputs, ...desc.Outputs]) + if (/^[A-Za-z0-9 ]+$/.test(port.ReadonlyType) && !/^[A-Za-z]\d*$/.test(port.ReadonlyType)) m.add(port.ReadonlyType); + } + } + m.delete('any'); + return Array.from(m); +} \ No newline at end of file diff --git a/lib/util.js b/lib/util.js new file mode 100644 index 0000000..fe9e5b7 --- /dev/null +++ b/lib/util.js @@ -0,0 +1,5 @@ +function newEl(name, Class) { + ret = document.createElement(name); + if (Class) ret.classList.add(Class); + return ret; +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf