|
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 |