From 7f6f5549fe6d1bd03772c13e96f9d92a26660929 Mon Sep 17 00:00:00 2001 From: alyx Date: Mon, 6 Jun 2022 18:16:16 +0000 Subject: goofy bits of gass and such, more typing --- grapher/script.js | 37 +++++++++++++++++---- images/grapher.png | Bin 0 -> 63804 bytes images/searcher.png | Bin 0 -> 17803 bytes index.html | 50 +++++++++++++++++++++++----- lib/chips.css | 2 +- lib/types.js | 90 +++++++++++++++++++++++++++++++++++++++++++++++--- pwathings/appver.json | 2 +- style.css | 63 +++++++++++++++++++++++++++++++++++ 8 files changed, 222 insertions(+), 22 deletions(-) create mode 100644 images/grapher.png create mode 100644 images/searcher.png diff --git a/grapher/script.js b/grapher/script.js index 4df4516..70be078 100644 --- a/grapher/script.js +++ b/grapher/script.js @@ -56,6 +56,7 @@ var mode; var targ; var start; var wirestate; +var maintouch; const lastmp = {x:0,y:0}; const graphPos = {x:0,y:0}; @@ -315,9 +316,7 @@ window.onload = async function() { } - graph.addEventListener('mousedown', function(e) { - if ((e.buttons & 1) && !locked) { - start = performance.now(); + function clickToWire(e) {start = performance.now(); targ = e.target; if (e.target.parentElement.matches('.input')) { if (!e.target.matches('.exec')) delConnections(e.target); @@ -349,11 +348,21 @@ window.onload = async function() { else if (e.target == graph) switchID(null, 'selected') clean = false + } + + graph.addEventListener('mousedown', function(e) { + if ((e.buttons & 1) && !locked) { + clickToWire(e); + } + }); + graph.addEventListener('touchstart', function(e) { + if (e.touches.length <= 1) { + maintouch = e.changedTouches[0]; + clickToWire(e); } }); - rootel.addEventListener("mouseup", e => { - if ((e.button == 0) && !locked) { + function unclickToWire(e) { let newCon; switch (mode) { case 'wire_i-o': @@ -371,13 +380,23 @@ window.onload = async function() { connections.push(newCon); break; case 'drag': - if ((performance.now() - start) < 150 && !targ.querySelector('.selUI').matches('#selected')) { + if ((performance.now() - start) < 300 && !targ.querySelector('.selUI').matches('#selected')) { switchID(targ.children[0], 'selected') } break; } mode = null; - clean = false + clean = false; + } + rootel.addEventListener("mouseup", e => { + if ((e.button == 0) && !locked) { + unclickToWire(e); + } + }); + graph.addEventListener('touchend', e => { + if (e.changedTouches[0] == maintouch) { + maintouch = null; + unclickToWire(e); } }); @@ -409,6 +428,10 @@ window.onload = async function() { if (mode) clean = false }); + rootel.addEventListener('touchdrag', e => { + lastmp.x = e.changedTouches[0].clientX; + lastmp.y = e.changedTouches[0].clientY; + }) root.addEventListener("mousemove", e => { diff --git a/images/grapher.png b/images/grapher.png new file mode 100644 index 0000000..83b9d1a Binary files /dev/null and b/images/grapher.png differ diff --git a/images/searcher.png b/images/searcher.png new file mode 100644 index 0000000..adee09b Binary files /dev/null and b/images/searcher.png differ diff --git a/index.html b/index.html index db3d610..5b0d7a3 100644 --- a/index.html +++ b/index.html @@ -26,12 +26,46 @@ Below you'll find a collection of tools for understanding and explaining R2C, as well as playing with it out-of-game. This site is in a perpetual state of work-in-progress, but there's a changelog below, too.

- +
+ +
+

Chip Searcher

+

+
+
+ +
+

Chip Grapher

+

+
+
+
+
+
+

June 6, 2022 - Just the same as you and me!

+
+
    +
  • Created a nicer display for the links, with neat frosted glass effeects.
  • +
+
+
+

June 3, 2022 - The Three Clicks Edition

+
+
    +
  • Continued work on type inference logic.
  • +
      +
    • There is now something that can parse in R2C types, + as well as plenty of methods for computing intersections between them.
    • +
    • As Always:
    • +
        +
      • You can view it at types.html, by opening the DevTools console.
      • +
      • The actual logic is contained in /lib/types.js.
      • +
      +
    +
  • The links at the bottom of the homepage now use funny icons for the ::marker bit!
  • +
+

June 2, 2022 - The Three Clicks Edition


@@ -61,9 +95,9 @@

Credits:

Though I've tried to keep as much of this codebase my own as possible, R2CUtils depends on the following projects:

-
    -
  • Open Iconic - Various Icons
  • -
  • fuse.js - Searching through the JSON
  • + \ No newline at end of file diff --git a/lib/chips.css b/lib/chips.css index 00d4d3b..7202438 100644 --- a/lib/chips.css +++ b/lib/chips.css @@ -19,7 +19,7 @@ A finished chip should look something like this:
    Then
    -
    Else
    +
    Else
    diff --git a/lib/types.js b/lib/types.js index 3e37424..0253780 100644 --- a/lib/types.js +++ b/lib/types.js @@ -4,6 +4,15 @@ function Type(TypeName,Params=[]) { this.typename = ""; this.mode = ""; + + if (TypeName instanceof Type) { + const t = TypeName.copy(); + for (const k in t) { + this[k] = t[k]; + } + return; + } + //Union/Tuple if (/^\(.+\)$/.test(TypeName)) { const types = []; @@ -39,7 +48,7 @@ function Type(TypeName,Params=[]) { workspace += c; } if (workspace) types.push(workspace); - this.template = types.map(t => t.trim()).map(t => ["any", ...Params].includes(t) ? t : new Type(t, Params)); + this.template = types.map(t => t.trim()).map(t => Params.includes(t) ? Type.any : new Type(t, Params)); } //Template @@ -70,13 +79,84 @@ function Type(TypeName,Params=[]) { workspace += c; } if (workspace) types.push(workspace); - this.template = types.map(t => t.trim()).map(t => ["any", ...Params].includes(t) ? t : new Type(t, Params)); + this.template = types.map(t => t.trim()).map(t => Params.includes(t) ? t : new Type(t, Params)); } //Standard Type else if (/^[^()|<>,]+$/.test(TypeName)) { this.typename = TypeName; - this.mode = "standard" + this.mode = (TypeName == 'any') ? "any" : "standard" + } +} + +Type.prototype.toString = function() { + switch (this.mode) { + case "tuple": + return `(${this.template.join(',')})`; + case "union": + return `(${this.template.join('|')})`; + case "templated": + return `${this.typename}<${this.template.join(',')}>`; + case "any": + case "standard": + return this.typename; + } +} + +Type.prototype._resolve = function(idx, val) { + if (val === undefined && this.template.length === 1) { + val = idx; + idx = 0; } + if (0 <= idx && this.template.length > idx) { + this.template = this.template?.map(t => (t === name) ? val.copy() : ((typeof t == 'string') ? t : t.resolve(name, val))) + } +} + +Type.prototype.resolve = function(idx, val) { + const t = this.copy(); + t._resolve(idx, val); + return t; +} + +Type.prototype.copy = function() { + const t = new Type(this.toString(), this.template?.filter(t => typeof t == 'string')); + return t; +} + +Type.prototype.intersect = function(ot, params=[]) { + if (!ot instanceof Type) ot = new Type(ot, params) + if (this.mode == 'any') return ot.copy(); + if (ot.mode == 'any') return this.copy(); + if (ot.mode != this.mode) return undefined; - this.params = Object.fromEntries(Params.map(p => [p, 'any'])); -} \ No newline at end of file + switch (ot.mode) { + case 'templated': + case 'union': + case 'tuple': + if (this.template.length != ot.template.length) return undefined; + case 'standard': + if (ot.typename == this.typename) + return this.copy(); + else return undefined; + + } +} + +Type.typeDef = (function(typename, name, params=[]) { + Object.defineProperty(this, typename, { + get: () => new Type(name, params) + }) +}).bind(Type) +Type.QuickTD = (function(name, params=[]) { + Object.defineProperty(this, (new Type(name, params)).typename, { + get: () => new Type(name, params) + }) +}).bind(Type) + +Type.QuickTD("any"); +Type.QuickTD("int"); +Type.QuickTD("float"); +Type.QuickTD("string"); +Type.QuickTD("bool"); +Type.QuickTD("Vector3"); +Type.QuickTD("List", ["T"]); \ No newline at end of file diff --git a/pwathings/appver.json b/pwathings/appver.json index 9449acd..da656d1 100644 --- a/pwathings/appver.json +++ b/pwathings/appver.json @@ -1,3 +1,3 @@ { - "ver": 5 + "ver": 8 } \ No newline at end of file diff --git a/style.css b/style.css index d8f884f..cf84ede 100644 --- a/style.css +++ b/style.css @@ -1,4 +1,5 @@ @import url('https://fonts.googleapis.com/css2?family=Raleway&display=swap'); +@import url('https://circuits.aleteoryx.me/oi.css'); html { --foreforeground: #3788ae; @@ -20,6 +21,7 @@ html { } body > * { width: max(60vw, 8cm); + --body-width: max(60vw, 8cm); } hr { @@ -139,4 +141,65 @@ section#changelog > article { 100% { box-shadow: 0mm 0mm 1cm white, 0mm 0mm 0mm white; } +} + +ul.links > li::marker { + font-family: "Icons"; + font-size: 2.5mm; + content: "\e064 "; +} + +#projects { + display: grid; + box-shadow: inset 0mm 0mm 5mm black; + padding: 1cm; + background: #020d12; + grid-gap: 1cm; + justify-content: center; +} + +#projects > a { + border: solid white 1mm; + padding: 0; + background-size: cover; + background-position: center center; + overflow: hidden; + box-shadow: inset 0 0 3mm black , 0 0 3mm black; + position: relative; + color: white; +} + +#projects > a * { + margin: 0mm; +} +#projects > a > div { + background-color: #0008; + backdrop-filter: blur(5px); + width: 100%; + margin: 0; + padding: 0.5cm; + position: absolute; + bottom: 0; +} + +@media (orientation:portrait) { + #projects { + grid-template-columns: 100%; + grid-auto-rows: var(--body-width); + } + #projects > a { + display: block; + min-height: var(--body-width); + } +} + +@media (orientation:landscape) { + #projects { + --widhei: calc(var(--body-width) / 2 - 2cm); + grid-template-columns: var(--widhei) var(--widhei); + } + #projects > a { + display: block; + height: calc(var(--widhei) - 2cm); + } } \ No newline at end of file -- cgit v1.2.3-54-g00ecf