summaryrefslogtreecommitdiffstats
path: root/virtual-programs
diff options
context:
space:
mode:
authorOmar Rizwan <omar@omar.website>2023-06-15 06:32:25 +0000
committerOmar Rizwan <omar@omar.website>2023-06-15 06:32:25 +0000
commit6e8b6f4f52b503e8217aa10825bf901ddee25ab5 (patch)
tree598edd5b6a1c2a792de0a1495d323f91529a584d /virtual-programs
parentMerge branch 'main' into osnr/camera-pipeline (diff)
parentUse diffs to make peering more efficient. Narrow change detect (diff)
downloadfolk-6e8b6f4f52b503e8217aa10825bf901ddee25ab5.tar.gz
folk-6e8b6f4f52b503e8217aa10825bf901ddee25ab5.zip
Merge branch 'main' into osnr/camera-pipeline
Diffstat (limited to 'virtual-programs')
-rw-r--r--virtual-programs/archive/CPS-clock.folk12
-rw-r--r--virtual-programs/archive/hello-name.folk1
-rw-r--r--virtual-programs/archive/highlight.folk2
-rw-r--r--virtual-programs/archive/image.folk30
-rw-r--r--virtual-programs/archive/metrics.folk2
-rw-r--r--virtual-programs/archive/welcome.folk1
-rw-r--r--virtual-programs/camera-slice.folk11
-rw-r--r--virtual-programs/esc-restart.folk2
-rw-r--r--virtual-programs/intersect.folk2
-rw-r--r--virtual-programs/keyboard.folk1
-rw-r--r--virtual-programs/label.folk2
-rw-r--r--virtual-programs/music.folk1
-rw-r--r--virtual-programs/new-program-web-editor.folk348
-rw-r--r--virtual-programs/outline.folk2
-rw-r--r--virtual-programs/points-at.folk47
-rw-r--r--virtual-programs/print.folk2
-rw-r--r--virtual-programs/process.folk1
-rw-r--r--virtual-programs/regions.folk20
-rw-r--r--virtual-programs/rfid/rfid-fetcher.folk97
-rw-r--r--virtual-programs/rfid/rfid-radios.folk10
-rw-r--r--virtual-programs/shapes.folk2
-rw-r--r--virtual-programs/sounds.folk2
-rw-r--r--virtual-programs/tags-and-calibration.folk23
-rw-r--r--virtual-programs/unix-commands.folk2
-rw-r--r--virtual-programs/watchdog.folk2
-rw-r--r--virtual-programs/web-editor.folk200
26 files changed, 360 insertions, 465 deletions
diff --git a/virtual-programs/archive/CPS-clock.folk b/virtual-programs/archive/CPS-clock.folk
deleted file mode 100644
index e7886157..00000000
--- a/virtual-programs/archive/CPS-clock.folk
+++ /dev/null
@@ -1,12 +0,0 @@
-Wish $this is outlined blue
-Wish $this has filename "CPS-clock.folk"
-#Wish $this is labelled "CPS clock"
-
-## Hmmmmm, how to do this in Tcl? Use `tcl
-
-When $::nodename has step count /c/ {
-}
-
-
-# Wish $this is outlined red
-# Claim firstname is "something"
diff --git a/virtual-programs/archive/hello-name.folk b/virtual-programs/archive/hello-name.folk
index bef035e2..be31ba5c 100644
--- a/virtual-programs/archive/hello-name.folk
+++ b/virtual-programs/archive/hello-name.folk
@@ -1,4 +1,3 @@
-Wish $this has filename "hello-name.folk"
Wish $this is outlined blue
When someone claims /firstName/ is /text/ {
diff --git a/virtual-programs/archive/highlight.folk b/virtual-programs/archive/highlight.folk
index 79cdb4db..768e4bc9 100644
--- a/virtual-programs/archive/highlight.folk
+++ b/virtual-programs/archive/highlight.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "highlight.folk"
-
When /someone/ wishes /thing/ is highlighted /color/ & /thing/ has region /region/ {
# it's not really correct to just stick a side-effect in the
# When handler like this. but we did it in Realtalk, and it
diff --git a/virtual-programs/archive/image.folk b/virtual-programs/archive/image.folk
deleted file mode 100644
index b3364d14..00000000
--- a/virtual-programs/archive/image.folk
+++ /dev/null
@@ -1,30 +0,0 @@
-Wish $this has filename "image.folk"
-
-namespace eval ::image {
- proc width {im} { dict get $im width }
- proc height {im} { dict get $im height }
- proc subimage {im x y subwidth subheight} {
- dict with im {
- set x [expr {int($x)}]
- set y [expr {int($y)}]
- set subdata [expr {$data + ($y*$width + $x) * $components}]
- dict create \
- width $subwidth height $subheight \
- components $components \
- bytesPerRow $bytesPerRow \
- data [format 0x%x $subdata]
- }
- }
- namespace export *
- namespace ensemble create
-}
-
-When the camera frame is /f/ & $this has region /r/ {
- lassign [projectorToCamera [lindex $r 0 0]] x0 y0
- lassign [projectorToCamera [lindex $r 0 2]] x1 y1
- set thisimage [image subimage $f \
- [expr {min($x0,$x1)}] [expr {min($y0,$y1)}] \
- [expr {int(abs($x1-$x0))}] [expr {int(abs($y1-$y0))}]]
- Wish display runs [list Display::image {*}[lindex $r 0 0] $thisimage]
-}
-Wish $this is outlined red
diff --git a/virtual-programs/archive/metrics.folk b/virtual-programs/archive/metrics.folk
index a1f52c61..b4f76fa0 100644
--- a/virtual-programs/archive/metrics.folk
+++ b/virtual-programs/archive/metrics.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "metrics.folk"
-
When $::nodename has step count /c/ {
Wish $this is labelled [string trim "
step count: $c
diff --git a/virtual-programs/archive/welcome.folk b/virtual-programs/archive/welcome.folk
index 0d9e3f57..6c08ed47 100644
--- a/virtual-programs/archive/welcome.folk
+++ b/virtual-programs/archive/welcome.folk
@@ -1,2 +1 @@
-Wish $this has filename "welcome.folk"
Wish $this is labelled "welcome 2!" \ No newline at end of file
diff --git a/virtual-programs/camera-slice.folk b/virtual-programs/camera-slice.folk
deleted file mode 100644
index 5d36f2f1..00000000
--- a/virtual-programs/camera-slice.folk
+++ /dev/null
@@ -1,11 +0,0 @@
-Wish $this has filename "camera-slice.folk"
-
-return
-Wish $this has camera image
-Wish $this is outlined thick palegoldenrod
-
-When $this has camera image /im/ & $this has region /r/ {
- set coords [lmap n [lindex $r 0 0] {expr $n * 1}]
- Wish display runs [list Display::image {*}$coords $im]
- Wish $this is labelled "$coords $im"
-}
diff --git a/virtual-programs/esc-restart.folk b/virtual-programs/esc-restart.folk
index 02f02c31..01a6dd94 100644
--- a/virtual-programs/esc-restart.folk
+++ b/virtual-programs/esc-restart.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "esc-restart.folk"
-
When the keyboard character log is /k/ {
foreach press $k {
if {$press eq "esc"} {exec sudo systemctl restart folk}
diff --git a/virtual-programs/intersect.folk b/virtual-programs/intersect.folk
index 351a293c..7755acbd 100644
--- a/virtual-programs/intersect.folk
+++ b/virtual-programs/intersect.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "intersect.folk"
-
#Wish $this is outlined white
When $this has neighbor /n/ {
diff --git a/virtual-programs/keyboard.folk b/virtual-programs/keyboard.folk
index 8dc66ceb..a49ac29e 100644
--- a/virtual-programs/keyboard.folk
+++ b/virtual-programs/keyboard.folk
@@ -1,4 +1,3 @@
-Wish $this has filename "keyboard.folk"
return
if {!$::isLaptop} { return }
Wish $this is outlined skyblue
diff --git a/virtual-programs/label.folk b/virtual-programs/label.folk
index 3a5f7f38..30787555 100644
--- a/virtual-programs/label.folk
+++ b/virtual-programs/label.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "label.folk"
-
When /thing/ has region /region/ {
set bbox [regionToBbox $region]
lassign [boxCentroid $bbox] x y
diff --git a/virtual-programs/music.folk b/virtual-programs/music.folk
index 5023a25b..d2c979b6 100644
--- a/virtual-programs/music.folk
+++ b/virtual-programs/music.folk
@@ -1,4 +1,3 @@
-Wish $this has filename "music.folk"
if {$::isLaptop} { return }
if {[catch {exec which sclang}]} { return }
diff --git a/virtual-programs/new-program-web-editor.folk b/virtual-programs/new-program-web-editor.folk
index 67a18832..692b00e0 100644
--- a/virtual-programs/new-program-web-editor.folk
+++ b/virtual-programs/new-program-web-editor.folk
@@ -1,177 +1,179 @@
Wish the web server handles route "/new" with handler {
html {
- <html>
- <head>
- <style>
- body { overflow: hidden; }
- </style>
- </head>
- <body>
- <span id="status">Status</span>
- <div id="dragme" style="cursor: move; position: absolute; user-select: none; background-color: #ccc; padding: 1em">
- <textarea id="code" cols="50" rows="20" style="font-family: monospace">Wish $this is outlined blue</textarea>
- <p><button onclick="handleSave()">Save</button> <button onclick="handlePrint()">Print</button><button id="printback" style="font-size: 50%; display: none" onclick="handlePrintBack()">Print Back</button></p>
- <pre id="error"></pre>
- </div>
-
- <script>
-// The current position of mouse
-let x = 0;
-let y = 0;
-
-// Query the element
-const ele = document.getElementById('dragme');
-const codeEle = document.getElementById("code");
-
-// Handle the mousedown event
-// that's triggered when user drags the element
-const mouseDownHandler = function (e) {
-if (e.target == codeEle) return;
-
-// Get the current mouse position
-x = e.clientX;
-y = e.clientY;
-
-// Attach the listeners to `document`
-document.addEventListener('pointermove', mouseMoveHandler);
-document.addEventListener('pointerup', mouseUpHandler);
-};
-
-const mouseMoveHandler = function (e) {
-if (e.target == codeEle) return;
-
-// How far the mouse has been moved
-const dx = e.clientX - x;
-const dy = e.clientY - y;
-
-// Set the position of element
-const [top, left] = [ele.offsetTop + dy, ele.offsetLeft + dx];
-ele.style.top = `${top}px`;
-ele.style.left = `${left}px`;
-handleDrag();
-
-// Reassign the position of mouse
-x = e.clientX;
-y = e.clientY;
-};
-
-const mouseUpHandler = function () {
-// Remove the handlers of `mousemove` and `mouseup`
-document.removeEventListener('pointermove', mouseMoveHandler);
-document.removeEventListener('pointerup', mouseUpHandler);
-};
-
-// Cmd + S || Ctrl + S => Save
-document.addEventListener('keydown', function(e) {
-if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 83) {
-e.preventDefault();
-handleSave();
-}
-}, false);
-// Cmd + P || Ctrl + P => Print
-document.addEventListener('keydown', function(e) {
-if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 80) {
-e.preventDefault();
-handlePrint();
-}
-}, false);
-
-ele.addEventListener('pointerdown', mouseDownHandler);
-</script>
-
-<script>
-function uuidv4() {
-return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
-(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
-);
-}
-const program = "web-program-" + uuidv4();
-
-let ws;
-let send;
-function wsConnect() {
-ws = new WebSocket(window.location.origin.replace("http", "ws") + "/ws");
-send = function(s) { ws.send(s); }
-
-ws.onopen = () => {
- document.getElementById('status').innerHTML = "<span style=background-color:seagreen;color:white;>Connnected</span>";
-
- handleDrag();
-};
-ws.onclose = window.onbeforeunload = () => {
- document.getElementById('status').innerHTML = "<span style=background-color:red;color:white;>Disconnnected</span>";
-
- send(`Retract web claims {${program}} has region /something/`);
- send(`Retract web claims {${program}} has program code /something/`);
- setTimeout(() => { wsConnect(); }, 1000);
-};
-ws.onerror = (err) => {
- document.getElementById('status').innerText = "Error";
- console.error('Socket encountered error: ', err.message, 'Closing socket');
- ws.close();
-}
-ws.onmessage = (msg) => {
-if (msg.data.startsWith("ERROR:")) {
- const errorEl = document.getElementById("error");
- if (msg.data == "ERROR: {}") {
- errorEl.style.backgroundColor = "";
- errorEl.innerText = "";
- } else {
- errorEl.style.backgroundColor = "#f55";
- errorEl.innerText = msg.data;
+<html>
+ <head>
+ <style>
+ body { overflow: hidden; }
+ </style>
+ </head>
+ <body>
+ <span id="status">Status</span>
+ <div id="dragme" style="cursor: move; position: absolute; user-select: none; background-color: #ccc; padding: 1em">
+ <textarea id="code" cols="50" rows="20" style="font-family: monospace">Wish $this is outlined blue</textarea>
+ <p>
+ <button onclick="handleSave()">Save</button>
+ <button onclick="handlePrint()">Print</button>
+ <button id="printback" style="font-size: 50%; display: none" onclick="handlePrintBack()">Print Back</button>
+ </p>
+ <pre id="error"></pre>
+ </div>
+
+ <script>
+ // The current position of mouse
+ let x = 0;
+ let y = 0;
+
+ // Query the element
+ const ele = document.getElementById('dragme');
+ const codeEle = document.getElementById("code");
+
+ // Handle the mousedown event
+ // that's triggered when user drags the element
+ const mouseDownHandler = function (e) {
+ if (e.target == codeEle) return;
+
+ // Get the current mouse position
+ x = e.clientX;
+ y = e.clientY;
+
+ // Attach the listeners to `document`
+ document.addEventListener('pointermove', mouseMoveHandler);
+ document.addEventListener('pointerup', mouseUpHandler);
+ };
+
+ const mouseMoveHandler = function (e) {
+ if (e.target == codeEle) return;
+
+ // How far the mouse has been moved
+ const dx = e.clientX - x;
+ const dy = e.clientY - y;
+
+ // Set the position of element
+ const [top, left] = [ele.offsetTop + dy, ele.offsetLeft + dx];
+ ele.style.top = `${top}px`;
+ ele.style.left = `${left}px`;
+ handleDrag();
+
+ // Reassign the position of mouse
+ x = e.clientX;
+ y = e.clientY;
+ };
+
+ const mouseUpHandler = function () {
+ // Remove the handlers of `mousemove` and `mouseup`
+ document.removeEventListener('pointermove', mouseMoveHandler);
+ document.removeEventListener('pointerup', mouseUpHandler);
+ };
+
+ // Cmd + S || Ctrl + S => Save
+ document.addEventListener('keydown', function(e) {
+ if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 83) {
+ e.preventDefault();
+ handleSave();
+ }
+ }, false);
+ // Cmd + P || Ctrl + P => Print
+ document.addEventListener('keydown', function(e) {
+ if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 80) {
+ e.preventDefault();
+ handlePrint();
+ }
+ }, false);
+
+ ele.addEventListener('pointerdown', mouseDownHandler);
+
+ function uuidv4() {
+ return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
+ (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
+ );
+ }
+ const program = "web-program-" + uuidv4();
+
+ let ws;
+ let send;
+ function wsConnect() {
+ ws = new WebSocket(window.location.origin.replace("http", "ws") + "/ws");
+ send = function(s) { ws.send(s); }
+
+ ws.onopen = () => {
+ document.getElementById('status').innerHTML = "<span style=background-color:seagreen;color:white;>Connnected</span>";
+
+ handleDrag();
+ };
+ ws.onclose = window.onbeforeunload = () => {
+ document.getElementById('status').innerHTML = "<span style=background-color:red;color:white;>Disconnnected</span>";
+
+ send(`Retract web claims {${program}} has region /something/`);
+ send(`Retract web claims {${program}} has program code /something/`);
+ setTimeout(() => { wsConnect(); }, 1000);
+ };
+ ws.onerror = (err) => {
+ document.getElementById('status').innerText = "Error";
+ console.error('Socket encountered error: ', err.message, 'Closing socket');
+ ws.close();
+ }
+ ws.onmessage = (msg) => {
+ if (msg.data.startsWith("ERROR:")) {
+ const errorEl = document.getElementById("error");
+ if (msg.data == "ERROR: {}") {
+ errorEl.style.backgroundColor = "";
+ errorEl.innerText = "";
+ } else {
+ errorEl.style.backgroundColor = "#f55";
+ errorEl.innerText = msg.data;
+ }
+ }
+ }
+ };
+ wsConnect();
+
+ function handleDrag() {
+ let [top, left, w, h] = [ele.offsetTop, ele.offsetLeft, ele.offsetWidth, ele.offsetHeight];
+ send(`
+ set top [expr {int(double(${(top + (top/window.innerHeight) * h)}) * (double($Display::HEIGHT) / ${window.innerHeight}))}]
+ set left [expr {int(double(${(left + (left/window.innerWidth) * w)}) * (double($Display::WIDTH) / ${window.innerWidth}))}]
+ proc handleConfigure {program x y w h} {
+ set vertices [list [list [expr {$x+$w}] $y] \
+ [list $x $y] \
+ [list $x [expr {$y+$h}]] \
+ [list [expr {$x+$w}] [expr {$y+$h}]]]
+ set edges [list [list 0 1] [list 1 2] [list 2 3] [list 3 0]]
+ Retract web claims $program has region /something/
+ Assert web claims $program has region [list $vertices $edges]
+ }
+ handleConfigure {${program}} $left $top {${w}} {${h}}
+ if {$::isLaptop} { Step }
+ `);
+ }
+ function handleSave() {
+ const code = document.getElementById("code").value;
+ send(`
+ Retract web claims {${program}} has program code /something/
+ Assert web claims {${program}} has program code {${code}}
+ if {$::isLaptop} { Step }
+ `);
+ setTimeout(() => {
+ send(`list ERROR: [Statements::findMatches [list {${program}} has error /err/ with info /errorInfo/]]`);
+ }, 500);
+ }
+ let jobid;
+ function handlePrint() {
+ const code = document.getElementById("code").value;
+ jobid = String(Math.random());
+ send(`Assert web wishes to print {${code}} with job id {${jobid}}`);
+ setTimeout(500, () => {
+ send(`Retract web wishes to print {${code}} with job id {${jobid}}`);
+ });
+ document.getElementById('printback').style.display = '';
+ }
+ function handlePrintBack() {
+ send(`Assert web wishes to print the back of job id {${jobid}}`);
+ setTimeout(500, () => {
+ send(`Retract web wishes to print the back of job id {${jobid}}`);
+ });
+ }
+ </script>
+ </body>
+</html>
}
}
-}
-};
-wsConnect();
-
-function handleDrag() {
-let [top, left, w, h] = [ele.offsetTop, ele.offsetLeft, ele.offsetWidth, ele.offsetHeight];
-send(`
-set top [expr {int(double(${(top + (top/window.innerHeight) * h)}) * (double($Display::HEIGHT) / ${window.innerHeight}))}]
-set left [expr {int(double(${(left + (left/window.innerWidth) * w)}) * (double($Display::WIDTH) / ${window.innerWidth}))}]
-proc handleConfigure {program x y w h} {
- set vertices [list [list $x $y] \
- [list [expr {$x+$w}] $y] \
- [list [expr {$x+$w}] [expr {$y+$h}]] \
- [list $x [expr {$y+$h}]]]
- set edges [list [list 0 1] [list 1 2] [list 2 3] [list 3 0]]
- Retract web claims $program has region /something/
- Assert web claims $program has region [list $vertices $edges]
-}
-handleConfigure {${program}} $left $top {${w}} {${h}}
-if {$::isLaptop} { Step }
-`);
-}
-function handleSave() {
-const code = document.getElementById("code").value;
-send(`
-Retract web claims {${program}} has program code /something/
-Assert web claims {${program}} has program code {${code}}
-if {$::isLaptop} { Step }
-`);
-setTimeout(() => {
- send(`list ERROR: [Statements::findMatches [list {${program}} has error /err/ with info /errorInfo/]]`);
-}, 500);
-}
-let jobid;
-function handlePrint() {
-const code = document.getElementById("code").value;
-jobid = String(Math.random());
-send(`Assert web wishes to print {${code}} with job id {${jobid}}`);
-setTimeout(500, () => {
- send(`Retract web wishes to print {${code}} with job id {${jobid}}`);
-});
-document.getElementById('printback').style.display = '';
-}
-function handlePrintBack() {
-send(`Assert web wishes to print the back of job id {${jobid}}`);
-setTimeout(500, () => {
- send(`Retract web wishes to print the back of job id {${jobid}}`);
-});
-}
-</script>
- </body>
- </html>
- }
-} \ No newline at end of file
diff --git a/virtual-programs/outline.folk b/virtual-programs/outline.folk
index 4b9d31ac..f62ab0ba 100644
--- a/virtual-programs/outline.folk
+++ b/virtual-programs/outline.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "outline.folk"
-
proc loopRegion {edges vertices weight color} {
foreach edge $edges {
set from [lindex $vertices [lindex $edge 0]]
diff --git a/virtual-programs/points-at.folk b/virtual-programs/points-at.folk
new file mode 100644
index 00000000..eb5d942b
--- /dev/null
+++ b/virtual-programs/points-at.folk
@@ -0,0 +1,47 @@
+set pi 3.1415926535897931
+
+When when /rect/ points /direction/ at /someone/ /lambda/ with environment /e/ {
+ Wish $rect points $direction
+}
+
+When /someone/ wishes /rect/ points /direction/ & /rect/ has region /region/ {
+ lassign $region vertices edges
+ lassign $vertices a b c d
+
+ set cx [expr {([lindex $a 0] + [lindex $c 0])/2}]
+ set cy [expr {([lindex $a 1] + [lindex $c 1])/2}]
+
+ set width [vec2 distance $a $b]
+ set height [vec2 distance $a $d]
+
+ set radians [lindex $region 2]
+ if {$radians eq ""} {set radians 0}
+
+ set whisker_radians $radians
+ set fac -1.0
+ set whisker_size [expr {$width * $fac}]
+
+ if {$direction eq "up"} {
+ set whisker_radians [expr {$radians + $pi / 2}]
+ set whisker_size [expr {$height * $fac}]
+ }
+ if {$direction eq "left"} {
+ set whisker_radians [expr {$radians + $pi}]
+ }
+ if {$direction eq "down"} {
+ set whisker_radians [expr {$radians + $pi * 1.5}]
+ set whisker_size [expr {$height * $fac}]
+ }
+
+ set wx [expr {$cx + $whisker_size * [::tcl::mathfunc::cos [expr {-1 * $whisker_radians}]] }]
+ set wy [expr {$cy + $whisker_size * [::tcl::mathfunc::sin [expr {-1 * $whisker_radians}]] }]
+
+ Display::stroke [list [list $cx $cy] [list $wx $wy] ] 2 green
+
+ When /target/ has region /r2/ {
+ if {$target != $rect && \
+ [region contains $r2 [list $wx $wy]]} {
+ Claim $rect points $direction at $target
+ }
+ }
+}
diff --git a/virtual-programs/print.folk b/virtual-programs/print.folk
index 60eb4331..badd191f 100644
--- a/virtual-programs/print.folk
+++ b/virtual-programs/print.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "print.folk"
-
source "pi/cUtils.tcl"
set cc [c create]
diff --git a/virtual-programs/process.folk b/virtual-programs/process.folk
index 520d104b..c08659f1 100644
--- a/virtual-programs/process.folk
+++ b/virtual-programs/process.folk
@@ -1,4 +1,3 @@
-Wish $this has filename "process.folk"
When /p/ is running process /process/ & process /process/ has standard output log /log/ {
Wish $p is labelled [join $log "\n"]
}
diff --git a/virtual-programs/regions.folk b/virtual-programs/regions.folk
index 0f20d260..169af718 100644
--- a/virtual-programs/regions.folk
+++ b/virtual-programs/regions.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "regions.folk"
-
namespace eval ::vec2 {
namespace import ::tcl::mathop::+ ::tcl::mathop::- ::tcl::mathop::*
proc add {a b} {
@@ -54,7 +52,23 @@ namespace eval ::region {
}
set minDist
}
- namespace export distance
+
+ proc contains {r1 p} {
+ lassign $r1 vertices edges
+ lassign $vertices a b c d
+
+ set ab [vec2 sub $b $a]
+ set ap [vec2 sub $p $a]
+ set bc [vec2 sub $c $b]
+ set bp [vec2 sub $p $b]
+ set dot_abap [vec2 dot $ab $ap]
+ set dot_bcbp [vec2 dot $bc $bp]
+
+ expr {0 <= $dot_abap && $dot_abap <= [vec2 dot $ab $ab] && \
+ 0 <= $dot_bcbp && $dot_bcbp <= [vec2 dot $bc $bc]}
+ }
+
+ namespace export distance contains
namespace ensemble create
}
diff --git a/virtual-programs/rfid/rfid-fetcher.folk b/virtual-programs/rfid/rfid-fetcher.folk
deleted file mode 100644
index 4031d26e..00000000
--- a/virtual-programs/rfid/rfid-fetcher.folk
+++ /dev/null
@@ -1,97 +0,0 @@
-Wish $this has filename "rfid/rfid-fetcher.folk"
-
-return
-On process rfid-ib-fetcher {
- set cc [c create]
- $cc include <complex.h>
- $cc include <stdlib.h>
- $cc include <sys/socket.h>
- $cc include <arpa/inet.h>
- $cc include <netinet/tcp.h>
- $cc include <unistd.h>
- $cc include <string.h>
- $cc code {
- typedef struct { int16_t i; int16_t q; } int16_iq_t; // iq format from radio
- typedef float complex iq_t;
- typedef long long freq_t;
- typedef long long counter_t;
- typedef struct {
- char id[100];
- counter_t counter;
- int64_t timestamp_ns;
- freq_t freq;
-
- size_t iqcount;
- iq_t iqs[];
- } signal_t;
-
- counter_t counter_when_syncing_started;
- }
- $cc proc fetcher_fetch {int fd} void {
- // The role of this thread is just to continuously ingest new
- // frames and state updates from the network, not to process them
- // or think too hard about them. It does the same thing regardless
- // of whether we're in syncing mode or not.
-
- counter_t counter_wss;
- recv(fd, &counter_wss, sizeof(counter_wss), 0);
- counter_when_syncing_started = counter_wss;
-
- counter_t counter; recv(fd, &counter, sizeof(counter), 0);
- int64_t timestamp_ns; recv(fd, &timestamp_ns, sizeof(timestamp_ns), 0);
- freq_t freq; recv(fd, &freq, sizeof(freq), 0);
-
- uint32_t len; recv(fd, &len, sizeof(len), 0);
- int16_iq_t *buf = (int16_iq_t *) malloc(len * sizeof(int16_iq_t));
- uint32_t expectedsize = len * sizeof(buf[0]);
- uint32_t recvsize = 0;
- while (recvsize < expectedsize) {
- ssize_t ret = recv(fd, (uint8_t *) buf + recvsize, expectedsize - recvsize, 0);
- if (ret < 0) { perror("recv"); exit(1); }
- if (ret == 0) {
- // Server probably terminated. TODO: handle
- fprintf(stderr, "Server terminated\n"); exit(1);
- }
- recvsize += ret;
- }
-
- signal_t* sig = malloc(sizeof(signal_t) + len * sizeof(int16_iq_t));
- sig->counter = counter;
- sig->timestamp_ns = timestamp_ns;
- sig->freq = freq;
- snprintf(sig->id, sizeof(sig->id), "IB %lld Hz", freq);
-
- // what to do with sig?
- }
- $cc proc fetcher_main {char* host uint16_t port void* buf} void {
- // make TCP connection to radio
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd == -1) { perror("socket"); exit(1); }
-
- int one = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
-
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = inet_addr(host);
- bzero(&addr.sin_zero, 8);
- printf("Trying to connect\n");
- if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
- perror("connect"); close(fd); exit(1);
- }
- printf("Connected\n");
-
- struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; // 1-second timeout
- setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tv, sizeof tv);
- setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char *) &tv, sizeof tv);
-
- while (1) {
- fetcher_fetch(fd);
- }
- }
- $cc compile
-
- # Commit {
- # Claim the buffers are $p
- # }
-}
diff --git a/virtual-programs/rfid/rfid-radios.folk b/virtual-programs/rfid/rfid-radios.folk
deleted file mode 100644
index 10953b4b..00000000
--- a/virtual-programs/rfid/rfid-radios.folk
+++ /dev/null
@@ -1,10 +0,0 @@
-Wish $this has filename "rfid/rfid-radios.folk"
-return
-
-set dir "/home/folk/tag-localization"
-set cc [join [list "/home/folk/gcc-linaro-7.2.1-" \
- "2017.11-x86_64_arm-linux-gnueabihf/bin/" \
- "arm-linux-gnueabihf-gcc"] ""]
-
-Wish $this runs Unix command \
- "make -C $dir CC=$cc -j2 run-ib run-oob"
diff --git a/virtual-programs/shapes.folk b/virtual-programs/shapes.folk
index ce19fb98..b693220e 100644
--- a/virtual-programs/shapes.folk
+++ b/virtual-programs/shapes.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "shapes.folk"
-
set sizeDict [dict create small 1 medium 4 large 10]
proc isSizeWord {word} {
diff --git a/virtual-programs/sounds.folk b/virtual-programs/sounds.folk
index 7719ded4..f127fa58 100644
--- a/virtual-programs/sounds.folk
+++ b/virtual-programs/sounds.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "sounds.folk"
-
When /someone/ wishes /p/ plays sound /sound/ {
if {[file exists "/home/folk/sounds/$sound"]} {
set sound "/home/folk/sounds/$sound"
diff --git a/virtual-programs/tags-and-calibration.folk b/virtual-programs/tags-and-calibration.folk
index 4cbe5e55..fc6a4d44 100644
--- a/virtual-programs/tags-and-calibration.folk
+++ b/virtual-programs/tags-and-calibration.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "tags-and-calibration.folk"
-
if {$::isLaptop} { return }
namespace eval ::Camera {
@@ -68,13 +66,13 @@ proc ::cameraToProjector {cameraPoint} {
set Hy [expr {$Hy / $Hz}]
return [list $Hx $Hy]
}
+
proc ::projectorToCamera {projectorPoint} {
lassign [::math::linearalgebra::matmul $::Hinv [list [lindex $projectorPoint 0] [lindex $projectorPoint 1] 1]] Hinvx Hinvy Hinvz
set Hinvx [expr {$Hinvx / $Hinvz}]
set Hinvy [expr {$Hinvy / $Hinvz}]
return [list $Hinvx $Hinvy]
}
-# Wish $this is highlighted white
When (non-capturing) tag /tag/ has center /c/ size /size/ {
Claim tag $tag is a tag
@@ -94,22 +92,25 @@ When (non-capturing) tag /tag/ is a tag {
Claim $tag has program code $code
}
-
When (non-capturing) tag /tag/ has corners /corners/ {
- set tagcorners [lmap p $corners {::cameraToProjector $p}]
- # foreach tagcorner $tagcorners { Display::text fb {*}$tagcorner 10 "$tag" }
- Display::fillQuad {*}$tagcorners white
+ set tagCorners [lmap p $corners {::cameraToProjector $p}]
+ # foreach tagCorner $tagCorners { Display::text fb {*}$tagCorner 1 $tagCorner }
+ # Display::fillQuad {*}$tagCorners white
- set tagbottom [sub [lindex $tagcorners 1] [lindex $tagcorners 0]]
- set tagright [sub [lindex $tagcorners 2] [lindex $tagcorners 1]]
+ set vecBottom [sub [lindex $tagCorners 1] [lindex $tagCorners 0]]
+ set vecRight [sub [lindex $tagCorners 2] [lindex $tagCorners 1]]
set offsets {{-4.7 -2.6} {1 -2.6} {1 0.8} {-4.7 0.8}}
- set corners [add $tagcorners [matmul $offsets [list $tagbottom $tagright]]]
+ set scales [matmul $offsets [list $vecBottom $vecRight]]
+ set corners [add $tagCorners $scales]
+
set edges [list]
for {set i 0} {$i < [llength $corners]} {incr i} {
if {$i > 0} { lappend edges [list [expr {$i - 1}] $i] }
}
lappend edges [list [expr {[llength $corners] - 1}] 0]
- set region [list $corners $edges [::tcl::mathfunc::atan2 {*}$tagright]]
+
+ set region [list $corners $edges [::tcl::mathfunc::atan2 {*}$vecRight]]
+
Claim $tag has region $region
}
diff --git a/virtual-programs/unix-commands.folk b/virtual-programs/unix-commands.folk
index c79d266c..814fdf3c 100644
--- a/virtual-programs/unix-commands.folk
+++ b/virtual-programs/unix-commands.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "unix-commands.folk"
-
set ::unixjobs [dict create]
set ::nextunixjobid 0
proc ::readline {jobid channel} {
diff --git a/virtual-programs/watchdog.folk b/virtual-programs/watchdog.folk
index e8afb6b5..7316ba08 100644
--- a/virtual-programs/watchdog.folk
+++ b/virtual-programs/watchdog.folk
@@ -1,5 +1,3 @@
-Wish $this has filename "watchdog.folk"
-
# Temporarily disabling watchdog while we work out IPC.
return
diff --git a/virtual-programs/web-editor.folk b/virtual-programs/web-editor.folk
index 5b68746d..6669d9fa 100644
--- a/virtual-programs/web-editor.folk
+++ b/virtual-programs/web-editor.folk
@@ -1,99 +1,117 @@
-Wish the web server handles route {/page/(\d*)$} with handler {
- if {[regexp -all {/page/(\d*)$} $path whole_match pageNumber]} {
- set fp [open "../folk-printed-programs/$pageNumber.folk" r]
+Wish the web server handles route {/page/(.*)$} with handler {
+ if {[regexp -all {/page/(\d*)$} $path whole_match program_id]} {
+ set filename "../folk-printed-programs/$program_id.folk"
+ set fp [open $filename r]
set file_data [read $fp]
close $fp
- html [string map [list file_data [htmlEscape $file_data] my_page_number $pageNumber] {
- <html>
- <body>
- <div>
- <span id="status">Status</span>
- <button onclick="handleSave()">Save</button>
- <button onclick="handlePrint()">Print</button>
- </div>
- <textarea id="code" style="width: 100%;height: 95vh;">file_data</textarea>
- <pre id="error"></pre>
-<script>
-const codeEle = document.getElementById("code");
-function uuidv4() {
- return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
- (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
- );
-}
+ } elseif {[regexp -all {/page/(.*)$} $path whole_match program_id]} {
+ set filename "virtual-programs/$program_id.folk"
+ set fp [open $filename r]
+ set file_data [read $fp]
+ close $fp
+ }
-// Cmd + S || Ctrl + S => Save
-document.addEventListener('keydown', function(e) {
- if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 83) {
- e.preventDefault();
- handleSave();
- }
-}, false);
-// Cmd + P || Ctrl + P => Print
-document.addEventListener('keydown', function(e) {
- if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 80) {
- e.preventDefault();
- handlePrint();
- }
-}, false);
+ html [string map [list file_data [htmlEscape $file_data] program_id $program_id file_name $filename] {
+ <html>
+ <body>
+ <div>
+ <span id="status">Status</span>
+ <button onclick="handleSave()">Save</button>
+ <button id="print" onclick="handlePrint()">Print</button>
+ </div>
+ <textarea id="code" style="width: 100%;height: 95vh;">file_data</textarea>
+ <pre id="error"></pre>
+ <script>
+ const isVirtualProgram = 'file_name'.includes('virtual-programs');
-let ws;
-let send;
-function wsConnect() {
- ws = new WebSocket(window.location.origin.replace("http", "ws") + "/ws");
- send = function(s) { ws.send(s); }
+ if (isVirtualProgram) {
+ document.getElementById("print").disabled = true;
+ }
- ws.onopen = () => {
- document.getElementById('status').innerHTML = "<span style=background-color:seagreen;color:white;>Connnected</span>";
- };
- ws.onclose = window.onbeforeunload = () => {
- document.getElementById('status').innerHTML = "<span style=background-color:red;color:white;>Disconnnected</span>";
+ const codeEle = document.getElementById("code");
+ function uuidv4() {
+ return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
+ (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
+ );
+ }
- setTimeout(() => { wsConnect(); }, 1000);
- };
- ws.onerror = (err) => {
- document.getElementById('status').innerText = "Error";
- console.error('Socket encountered error: ', err.message, 'Closing socket');
- ws.close();
- }
- ws.onmessage = (msg) => {
- if (msg.data.startsWith("ERROR:")) {
- const errorEl = document.getElementById("error");
- if (msg.data == "ERROR: {}") {
- errorEl.style.backgroundColor = "";
- errorEl.innerText = "";
- } else {
- errorEl.style.backgroundColor = "#f55";
- errorEl.innerText = msg.data;
- }
- }
- }
-};
-wsConnect();
+ // Cmd + S || Ctrl + S => Save
+ document.addEventListener('keydown', function(e) {
+ if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 83) {
+ e.preventDefault();
+ handleSave();
+ }
+ }, false);
+ // Cmd + P || Ctrl + P => Print
+ document.addEventListener('keydown', function(e) {
+ if ((window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) && e.keyCode == 80) {
+ e.preventDefault();
+ handlePrint();
+ }
+ }, false);
-function handleSave() {
- const code = document.getElementById("code").value;
- send(`
-set fp [open "../folk-printed-programs/my_page_number.folk" w]
-puts -nonewline $fp {${code}}
-close $fp
-puts "Saved my_page_number.folk"
-`);
- setTimeout(() => {
- send(`list ERROR: [Statements::findMatches [list my_page_number has error /err/ with info /errorInfo/]]`);
- }, 500);
-}
-let jobid;
-function handlePrint() {
- const code = document.getElementById("code").value;
- jobid = String(Math.random());
- send(`Assert web wishes to print program my_page_number with code {${code}} with job id {${jobid}}`);
- setTimeout(500, () => {
- send(`Retract web wishes to print program my_page_number with code {${code}} with job id {${jobid}}`);
- });
+ let ws;
+ let send;
+ function wsConnect() {
+ ws = new WebSocket(window.location.origin.replace("http", "ws") + "/ws");
+ send = function(s) { ws.send(s); }
+
+ ws.onopen = () => {
+ document.getElementById('status').innerHTML = "<span style=background-color:seagreen;color:white;>Connnected</span>";
+ };
+ ws.onclose = window.onbeforeunload = () => {
+ document.getElementById('status').innerHTML = "<span style=background-color:red;color:white;>Disconnnected</span>";
+ setTimeout(() => { wsConnect(); }, 1000);
+ };
+ ws.onerror = (err) => {
+ document.getElementById('status').innerText = "Error";
+ console.error('Socket encountered error: ', err.message, 'Closing socket');
+ ws.close();
+ }
+ ws.onmessage = (msg) => {
+ if (msg.data.startsWith("ERROR:")) {
+ const errorEl = document.getElementById("error");
+ if (msg.data == "ERROR: {}") {
+ errorEl.style.backgroundColor = "";
+ errorEl.innerText = "";
+ } else {
+ errorEl.style.backgroundColor = "#f55";
+ errorEl.innerText = msg.data;
+ }
+ }
+ }
+ };
+ wsConnect();
+
+ function handleSave() {
+ const code = document.getElementById("code").value;
+ send(`
+ set fp [open file_name w]
+ puts -nonewline $fp {${code}}
+ close $fp
+ puts "Saved program_id.folk"
+ `);
+
+ if (isVirtualProgram) {
+ send(`EditVirtualProgram file_name {${code}}`)
+ }
+
+ setTimeout(() => {
+ send(`list ERROR: [Statements::findMatches [list program_id has error /err/ with info /errorInfo/]]`);
+ }, 500);
+ }
+
+ let jobid;
+ function handlePrint() {
+ const code = document.getElementById("code").value;
+ jobid = String(Math.random());
+ send(`Assert web wishes to print program program_id with code {${code}} with job id {${jobid}}`);
+ setTimeout(500, () => {
+ send(`Retract web wishes to print program program_id with code {${code}} with job id {${jobid}}`);
+ });
+ }
+ </script>
+ </body>
+ </html>
+ }]
}
-</script>
- </body>
- </html>
- }]
- }
-} \ No newline at end of file