Skip to content

Instantly share code, notes, and snippets.

@brimston3
Created February 10, 2016 16:33
Show Gist options
  • Save brimston3/cbee3b776427e25237ce to your computer and use it in GitHub Desktop.
Save brimston3/cbee3b776427e25237ce to your computer and use it in GitHub Desktop.
#!/usr/bin/lua
--[[
Copyright (C) February 10, 2016, Andrew Domaszek
(MIT License)
Wrote this lua demonstrator for Joe
Show some basics on how to do index-lookup-based function indirection instead
of an if-elseif cascade and keep a table of global state. I suspect the keystate
variable could be declared global instead of manually set in _G, but I've only done
it from C-api before, and this is how I do it.
--]]
-- Replace NILs with b.
function NVL(a,b)
if (a == nil) then
return b
else
return a
end
end
-- Demonstrate loading a table from the global table and toggling the state
function globtoggle ()
-- Create the keystat global if it doesn't already exist.
if rawget(_G, "keystate") == nil then
rawset(_G, "keystate", {})
end
local LTkeystate = _G.keystate -- or if you prefer: _G["keystate"]
local G1=1
local G2=2
local G3=3
-- Using 100 as the "G-key" offset, this is so you could use different keys
-- if, say, you were using family in the OnEvent call (logitech g-series)
-- to switch between multiple devices with the same key nums.
local IncomingEvent=100+G1
local g1_state = NVL(LTkeystate[IncomingEvent], 0)
print("g1_s: " .. g1_state)
-- Toggle the state of g1
-- Note that even though we only update the LOCAL version,
-- the GLOBAL TABLE is pointing at the same table. lua
-- tables are special in this regard.
LTkeystate[IncomingEvent] = (g1_state+1) % 2
end
function globtest()
print("--- Glob Test ---")
for i=1,3 do
globtoggle()
end
print("")
end
-- Demonstrate table initialization, value set, and access methods
function table_demonstrator()
print("--- Table Demonstrator ---")
-- Some declare-and-initialize statements
local t1 = { apple = 1, orange = 2}
local t2 = { ["one key"] = 1, [2] = "two", grape = false}
-- Declare an empty local table
local tTab = {}
-- Can set values in tables. Normally rawset is not used.
rawset(tTab, "dm", "dot-member style")
rawset(tTab, "ar", "associative array style")
-- Normal syntax for setting values
tTab.dms = "dot-member set style"
tTab["ars"] = "associative array set style"
-- Note the concatenation operation with .. here:
print("Accessor: " .. tTab.dm)
print("Accessor: " .. tTab["dms"]) -- can access either way
print("Accessor: " .. tTab["ar"])
print("Accessor: " .. tTab.ars) -- can access either way
print("")
end
-- These four functions are called by the functional_LUT_demonstrator to show
-- different functions are called. Note that all of them have the same
-- call signature; that is a limitation of this method, though the param can
-- be completely ignored or omitted. A return value, if required MUST be provided.
function G1_action(a)
print("G1, ACTION! ("..a..")")
end
function G1m1_action(a)
print("G1-meta1, ACTION! ("..a..")")
end
function G2_action(a)
print("G2, ACTION! ("..a..")")
end
-- Param can be totally omitted and still work.
function G3_action()
print("G3, ACTION! (noparam!)")
end
-- Demonstrate switching between multiple functions stored in a two-tier table
-- based on variables.
function functional_LUT_demonstrator()
-- We only declare and use this table locally, but it
-- could be stored in the globals table _G and referenced
local tLUT = {
[1] = {fn = G1_action, fn_m1 = G1m1_action},
[2] = {fn = G2_action},
[3] = {fn = G3_action}
}
-- Event would be like a keypress
-- Try changing this to 1, 2, or 3
local Event=1
-- Meta would be like the meta state (or maybe keystate from global)
-- Try changing this to 0 or 1
local Meta=1
local eLUT = tLUT[Event]
local E_Action = eLUT.fn
-- Only set the meta-handler if fn_m1 available, otherwise default to fn
if Meta == 1 and not (eLUT.fn_m1 == nil) then
-- print("meta was set")
E_Action = eLUT.fn_m1
end
-- Can create other definitions for Meta == 2, eLUT.fn_m2, etc.
-- Just remember to fail gracefully.
-- If we have retrieved an event, we can call it. There could/should be a type
-- check here to make sure it's actually a callable function.
if not (E_Action == nil) then
E_Action("Passed in stuff!")
else
print("E_Action is nil. Is this event handled?")
end
end
table_demonstrator()
globtest()
functional_LUT_demonstrator()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment