aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chipBehavior.js82
-rw-r--r--lib/chips.css218
-rw-r--r--lib/chips.js95
-rw-r--r--lib/util.js5
4 files changed, 400 insertions, 0 deletions
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<any> 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<b], //less
+ "a027073f-9189-457f-a53d-8562e8829daf": ([{value:a},{value:b}]) => [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 <div>. 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:
+
+<div class="chip">
+ <div class="chipheader">If</div>
+ <div class="input">
+ <div class="exec"></div>
+ <div class="bool">Condition</div>
+ </div>
+ <div class="output">
+ <div class="exec">Then</div>
+ <div class="Exec">Else</div>
+ </div>
+</div>
+
+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 + "&nbsp;";
+ 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 + "&nbsp;";
+ 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