Skip to content

Instantly share code, notes, and snippets.

@hugeblank
Last active April 21, 2019 20:12
Show Gist options
  • Save hugeblank/169e7b845d17bf736a3cca52ba1c1d81 to your computer and use it in GitHub Desktop.
Save hugeblank/169e7b845d17bf736a3cca52ba1c1d81 to your computer and use it in GitHub Desktop.
Is this useful? Am I crazy? Tell me please I must know
local this = {}
local function base()
-- Base instance declaration, a template for all elements
local inst = {links = {}, object = {}} -- Template for all interactable elements
inst.object.link = function(...) -- Base and universal function for adding links
local l = {...} -- pack all links given
for i = 1, #l do -- For each link
inst.links[#inst.links+1] = l[i] -- Subscribe it to any emission we provide
end
end
inst.emit = function(...) -- Base function for emitting data to links
for i = 1, #inst.links do -- For each link
inst.links[i](...) -- Run the link function, passing the data
end
end
return inst
end
local function inElement(cx, cy, cb, x, y, w, h, b)
-- Check that the click was within the element and the correct mouse element was clicked if any was given
if cx >= x and cy >= y and cx < x+w and cy < y+h and (b == cb or not b) then
return true
end
return false
end
-- Interfaces are a unique element designed to bundle other elements into one table output
this.interface = function()
local inst = base() -- Get the base instance containing the link and emit functions
inst.elements = {} -- Add a table in the private instance for the element outputs
local object = inst.object -- Public facing API made more accessible
object.getData = function() -- Get the current interface data without the use of a link
return elements
end
object.addElement = function(label, element) -- Add an element to watch. Links to element. Output goes to table
local query = function(...) -- Wrapper function to add as a link
elements[label] = {...} -- Add the states given into a table
inst.emit(elements) -- Emit the current state of elements to anything linked
end
element.link(query) -- Link this function to the element given
end
return object -- Return the public facing API
end
-- Button element. The most simple of all elements, which anything else can pretty much be made off of
this.button = function(x, y, w, h, b)
local inst = base() -- Copy the base instance containing the link and emit functions
local object = inst.object -- Public facing API made more accessible
object.trigger = function(...) -- Trigger function, meant to be given events
local e = {...} -- Packing events
if e[1]:find("mouse") then -- If this is a click interaction
if inElement(e[3], e[4], e[2], x, y, w, h) then -- Verify click was in the right place
if e[1]:find("click") and not inst.locked then -- If the event was a click event and the button isn't locked
inst.emit(true, inst.locked) -- The button is clicked, emit
elseif e[1]:find("up") then -- If the event was a release event
inst.emit(false, inst.locked) -- Emit the button has been unselected
end
end
end
end
object.lock = function(locked) -- Function to toggle locking
inst.locked = locked or true -- Set the state
inst.emit(false, inst.locked) -- The button is locked, emit
end
return object
end
this.toggle = function(...) -- Button that takes 2 clicks in order to cycle on then off
local inst = base() -- Copy the base instance containing the link and emit functions
local button = this.button(...) -- Instantiate a button to wrap around
-- Copy lock and trigger methods, they're identical in this situation
inst.object.lock = button.lock
inst.object.trigger = button.trigger
local toggled = false -- state of toggle, naturally
button.link(function(sel, locked) -- Link a single method to the toggle
if sel == true and not locked then -- If the button is selected and not locked
toggled = not toggled -- Then flip the state of the toggle
end
inst.emit(toggled, lock) -- Emit this change
end)
return inst.object
end
return this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment