]> hydra-www.ietfng.org Git - acmetensortoys-esp-lua_lamp/commitdiff
lamp: revise remote protocol
authorNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Fri, 16 Dec 2016 07:12:03 +0000 (02:12 -0500)
committerNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Fri, 16 Dec 2016 07:12:03 +0000 (02:12 -0500)
A new, improved lamp-remote.lua.  The protocol herein is backwards
compatible with everything ever automatically generated by earlier
versions, but is not in general compatible with the old scheme.  I
think I like this one better.

init2.lua
lamp-remote.lua

index 7278d24654abfdd753ade2cbebeb2c40fa658ade..2228b18b0a3351d880d56eefc64fd2ffe74725a1 100644 (file)
--- a/init2.lua
+++ b/init2.lua
@@ -58,7 +58,7 @@ mqtt_revert = nil
 nwfnet.onmqtt["lamp"] = function(c,t,m) if t and m and t:find("^lamp/[^/]+/out") then dofile("lamp-remote.lc")(m) end end
 
 -- TODO: messages to specific lamps?  Multiple brokers?
-function lamp_announce(fn,g,r,b) mqc:publish(mqttBcastPfx,string.format("0 %s %x %x %x ;",fn,r,g,b),1,1) end
+function lamp_announce(fn,g,r,b) mqc:publish(mqttBcastPfx,string.format("new; draw %s %x %x %x;",fn,r,g,b),1,1) end
 
 -- mqtt setup
 local mqtt_beat_cancel
index 8ebfcbfff11f0d06adbfe34f90d40fda4e0de83a..e780a127921d32a23d2e37b01961803cbbc677ad 100644 (file)
@@ -1,23 +1,59 @@
--- GLOBAL: tq, remotefb, doremotedraw, remotetmr, loaddrawfn, remotetqh
+-- GLOBAL: tq, remotefb, doremotedraw, remotetmr, loaddrawfn, remotetqh, remotefifo
+
+if not remotefifo then remotefifo = (require "fifo")() end
+
+-- dequeue from remotefifo; if nothing to dequeue, clean up
+local function fdq()
+  if not remotefifo:dequeue(function(k) k() end)
+   then remotetqh = nil; remotefifo = nil
+  end
+end
+
+-- queue to remotefifo; if fifo has emptied, fire callback immediately,
+-- otherwise, let the functions manage their own timeline
+local function fq(what)
+  remotefifo:queue(what,fdq)
+end
 
 return function(msg)
-  if remotetqh then tq:dequeue(remotetqh) end
 
-  local fifo = (require "fifo")()
-  local function fdq() if not fifo:dequeue(function(k) k() end) then remotetqh = nil end end
+  local vt = {
+    ['new'] = function(_)
+      -- really only sensible at the start of a message; throw out
+      -- the existing fifo, if any, and stop whatever time event is
+      -- pending
+      remotefifo = (require "fifo")()
+      tq:dequeue(remotetqh)
+     end,
+    ['wait'] = function(s)
+      -- step the fifo in d milliseconds
+      local d = tonumber(s) 
+      if d and d > 0 then fq(function() remotetqh = tq:queue(d,fdq) end) end
+     end,
+    ['draw'] = function(s)
+      -- engage a drawing function and post a time event to pop the fifo
+      -- on the next tick (for, e.g., delay's use).  This is done on a
+      -- callback to prevent deep stacks.
+      local m,r,g,b = s:match("^(%w+)%s+(%x+)%s+(%x+)%s+(%x+)%s*$")
+      g = tonumber(g,16); r = tonumber(r,16); b = tonumber(b,16)
+      if m then
+        fq(function()
+          remotetmr:unregister()
+          loaddrawfn(m)(remotetmr,remotefb,g,r,b); doremotedraw()
+          remotetqh = tq:queue(1,fdq)
+         end)
+      end
+    end,
+  }
 
-  local d,m,r,g,b
+  vt["0"] = vt.draw -- XXX hack for backwards compatibility
 
-  for d,m,r,g,b in msg:gmatch("(%d+)%s+(%w+)%s+(%x+)%s+(%x+)%s+(%x+)%s*;") do
-    g = tonumber(g,16); r = tonumber(r,16); b = tonumber(b,16); d = tonumber(d)
-    if d and d > 0 then
-      fifo:queue(function() remotetqh = tq:queue(d,fdq) end)
-    end
-    fifo:queue(function()
-      remotetmr:unregister()
-      loaddrawfn(m)(remotetmr,remotefb,g,r,b); doremotedraw()
-      remotetqh = tq:queue(1,fdq) -- run on callback to avoid stack problems
-    end)
+  -- loop over all ;-delimited statements in the message and fire
+  -- them off.  Note that by default this will *append* to the fifo,
+  -- making messages not entirely idempotent (unless they start with
+  -- "new").
+  local c,as
+  for c,as in msg:gmatch("(%w*)%s*([^;]*);%s*") do
+    if c then vt[c](as) end
   end
-  fdq() -- start party
 end