Skip to content

Instantly share code, notes, and snippets.

@Adrodoc
Last active January 14, 2018 13:50
Show Gist options
  • Save Adrodoc/de04f5a740a59a598a294c7f4a93dbbf to your computer and use it in GitHub Desktop.
Save Adrodoc/de04f5a740a59a598a294c7f4a93dbbf to your computer and use it in GitHub Desktop.
SharedVar.lua
require 'adrodoc55.wol.EventQueue'
local requestEventName = 'SharedVarRequest-'
local updateEventName = 'SharedVarUpdate-'
declare('SharedVar')
local function createSharedVar(name)
Check.isString(name, 1)
local result = {
name = name,
requestQueue = Events.connect(requestEventName..name),
updateQueue = Events.connect(updateEventName..name)
}
setmetatable(result, SharedVar)
return result
end
function SharedVar.new(name, value)
local result = createSharedVar(name)
result:fireUpdate(value)
return result
end
Help.on(SharedVar.new) [[Creates a new SharedVar with the specified name and value. A
SharedVar is used to share memory between multiple spells.
SharedVars with the same name always contain the same value,
even across different spells. Note that modifying the content
of a shared table does not update the content for other
SharedVars.
This constructor updates the shared value regardless of a
potential previous value. If you don't want to override the
shared value use 'SharedVar.connect()' instead.
Parameters:
- name: the public name for the new SharedVar
- value: the new shared value (defaults to nil)
]]
function SharedVar.connect(name)
local result = createSharedVar(name)
result.connecting = true
Events.fire(requestEventName..name)
return result
end
Help.on(SharedVar.connect) [[Creates a new SharedVar with the specified name and value. A
SharedVar is used to share memory between multiple spells.
SharedVars with the same name always contain the same value,
even across different spells. Note that modifying the content
of a shared table does not update the content for other
SharedVars.
This constructor does not update the shared value. This has
the negative side effect that the first call to
'SharedVar:getValue()' may block indefinately if there is no
other SharedVar with the same name, because the SharedVar
is stuck waiting for the previous value. To avoid this risk
consider using 'SharedVar.new' instead.
Parameters:
- name: the public name for the new SharedVar
]]
function SharedVar:respondToNewConnections()
if self.connecting then
return
end
local queue = self.requestQueue
local event = queue:pop(0)
if event then
queue:clear()
self:fireUpdate(self.value)
end
end
function SharedVar:getValue()
local queue = self.updateQueue
if self.connecting then
local event = queue:pop() -- blocking on first read
self.value = event.data
self.connecting = nil
end
while not queue:isEmpty() do
local event = queue:pop(0)
if queue:isEmpty() then
self.value = event.data
end
end
return self.value
end
function SharedVar:setValue(value)
self:fireUpdate(value)
end
function SharedVar:fireUpdate(newValue)
Events.fire(updateEventName..self.name, newValue)
end
function SharedVar:close()
self.requestQueue:disconnect()
self.updateQueue:disconnect()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment