Initial version - 1.2.0.60
EN: 1.2.0.60 CN: 1.2.0.61 JP: 1.2.0.63 KR: 1.2.0.67
This commit is contained in:
+216
@@ -0,0 +1,216 @@
|
||||
local Luvent = {}
|
||||
Luvent.__index = Luvent
|
||||
function Luvent.newEvent()
|
||||
local event = {}
|
||||
event.actions = {}
|
||||
return setmetatable(event, Luvent)
|
||||
end
|
||||
function Luvent.__eq(e1, e2)
|
||||
if getmetatable(e1) ~= Luvent or getmetatable(e2) ~= Luvent then
|
||||
return false
|
||||
end
|
||||
if #e1.actions ~= #e2.actions then
|
||||
return false
|
||||
end
|
||||
for _, a1 in ipairs(e1.actions) do
|
||||
local found = false
|
||||
for _, a2 in ipairs(e2.actions) do
|
||||
if a1 == a2 then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if found == false then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
Luvent.Action = {}
|
||||
Luvent.Action.__index = Luvent.Action
|
||||
local isActionCallable = function(callable)
|
||||
if type(callable) == "table" then
|
||||
if type(getmetatable(callable).__call) == "function" then
|
||||
return true
|
||||
end
|
||||
elseif type(callable) == "function" then
|
||||
return true
|
||||
elseif type(callable) == "thread" and coroutine.status(callable) ~= "dead" then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
local newAction = function(callable)
|
||||
local action = {}
|
||||
assert(isActionCallable(callable))
|
||||
action.callable = callable
|
||||
action.id = tostring(callable)
|
||||
action.enabled = true
|
||||
action.priority = 0
|
||||
action.limit = -1
|
||||
action.numberOfInvocations = 0
|
||||
action.interval = 0
|
||||
action.timeOfLastInvocation = os.time()
|
||||
return setmetatable(action, Luvent.Action)
|
||||
end
|
||||
function Luvent.Action.__eq(a1, a2)
|
||||
if getmetatable(a1) ~= Luvent.Action or getmetatable(a2) ~= Luvent.Action then
|
||||
return false
|
||||
end
|
||||
return a1.id == a2.id
|
||||
end
|
||||
local findAction = function(event, actionToFind)
|
||||
local key
|
||||
if type(actionToFind) == "string" then
|
||||
key = "id"
|
||||
elseif isActionCallable(actionToFind) then
|
||||
key = "callable"
|
||||
else
|
||||
error("Invalid action parameter: " .. tostring(actionToFind))
|
||||
end
|
||||
for index, action in ipairs(event.actions) do
|
||||
if action[key] == actionToFind then
|
||||
return true, index
|
||||
end
|
||||
end
|
||||
return false, nil
|
||||
end
|
||||
local sortActionsByPriority = function(event)
|
||||
table.sort(event.actions, function(a1, a2)
|
||||
return a1.priority > a2.priority
|
||||
end)
|
||||
end
|
||||
function Luvent:addAction(actionToAdd)
|
||||
assert(isActionCallable(actionToAdd) == true)
|
||||
if self:hasAction(actionToAdd) then
|
||||
return
|
||||
end
|
||||
local new = newAction(actionToAdd)
|
||||
table.insert(self.actions, new)
|
||||
return new.id
|
||||
end
|
||||
function Luvent:removeAction(actionToRemove)
|
||||
local exists, index = findAction(self, actionToRemove)
|
||||
if exists == true then
|
||||
table.remove(self.actions, index)
|
||||
end
|
||||
end
|
||||
function Luvent:removeAllActions()
|
||||
self.actions = {}
|
||||
end
|
||||
function Luvent:getActionCount()
|
||||
return #self.actions
|
||||
end
|
||||
function Luvent:hasAction(actionToFind)
|
||||
return (findAction(self, actionToFind))
|
||||
end
|
||||
local invokeAction = function(action, ...)
|
||||
if action.enabled == false then
|
||||
return true
|
||||
end
|
||||
if type(action.callable) == "thread" then
|
||||
coroutine.resume(action.callable, ...)
|
||||
if coroutine.status(action.callable) == "dead" then
|
||||
return false
|
||||
end
|
||||
else
|
||||
action.callable(...)
|
||||
end
|
||||
action.numberOfInvocations = action.numberOfInvocations + 1
|
||||
if action.limit >= 0 and action.numberOfInvocations >= action.limit then
|
||||
action.enabled = false
|
||||
end
|
||||
return true
|
||||
end
|
||||
function Luvent:trigger(...)
|
||||
local call = function(action, ...)
|
||||
local keep = invokeAction(action, ...)
|
||||
if keep == false then
|
||||
self:removeAction(action.id)
|
||||
end
|
||||
end
|
||||
sortActionsByPriority(self)
|
||||
for _, action in ipairs(self.actions) do
|
||||
if action.interval > 0 then
|
||||
if os.difftime(os.time(), action.timeOfLastInvocation) >= action.interval then
|
||||
call(action, ...)
|
||||
action.timeOfLastInvocation = os.time()
|
||||
end
|
||||
else
|
||||
call(action, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
local createActionSetter = function(property, valueType, default)
|
||||
return function(event, actionToFind, newValue)
|
||||
local propertyValue = newValue or default
|
||||
local propertyValueType = type(propertyValue)
|
||||
local exists, index = findAction(event, actionToFind)
|
||||
assert(exists)
|
||||
assert(propertyValueType == valueType)
|
||||
if propertyValueType == "number" then
|
||||
assert(0 <= propertyValue)
|
||||
end
|
||||
event.actions[index][property] = propertyValue
|
||||
end
|
||||
end
|
||||
local createActionGetter = function(property)
|
||||
return function(event, action)
|
||||
local exists, index = findAction(event, action)
|
||||
assert(exists)
|
||||
assert(event.actions[index][property])
|
||||
return event.actions[index][property]
|
||||
end
|
||||
end
|
||||
Luvent.setActionInterval = createActionSetter("interval", "number")
|
||||
Luvent.getActionInterval = createActionGetter("interval")
|
||||
Luvent.removeActionInterval = createActionSetter("interval", "number", 0)
|
||||
Luvent.setActionPriority = createActionSetter("priority", "number")
|
||||
Luvent.getActionPriority = createActionGetter("priority")
|
||||
Luvent.removeActionPriority = createActionSetter("priority", "number", 0)
|
||||
Luvent.enableAction = createActionSetter("enabled", "boolean", true)
|
||||
Luvent.disableAction = createActionSetter("enabled", "boolean", false)
|
||||
function Luvent:isActionEnabled(actionToFind)
|
||||
local exists, index = findAction(self, actionToFind)
|
||||
assert(exists)
|
||||
return self.actions[index].enabled
|
||||
end
|
||||
function Luvent:setActionTriggerLimit(actionToFind, limit)
|
||||
local exists, index = findAction(self, actionToFind)
|
||||
assert(exists)
|
||||
assert(type(limit) == "number" and 0 <= limit)
|
||||
self.actions[index].limit = limit
|
||||
self.actions[index].numberOfInvocations = 0
|
||||
if limit == 0 then
|
||||
self.actions[index].enabled = false
|
||||
end
|
||||
end
|
||||
function Luvent:getActionTriggerLimit(actionToFind)
|
||||
local exists, index = findAction(self, actionToFind)
|
||||
assert(exists)
|
||||
assert(self.actions[index].limit)
|
||||
return self.actions[index].limit
|
||||
end
|
||||
function Luvent:removeActionTriggerLimit(actionToFind)
|
||||
local exists, index = findAction(self, actionToFind)
|
||||
assert(exists)
|
||||
self.actions[index].limit = -1
|
||||
self.actions[index].numberOfInvocations = 0
|
||||
self.actions[index].enabled = true
|
||||
end
|
||||
function Luvent:allActions()
|
||||
local index = 0
|
||||
return function()
|
||||
index = index + 1
|
||||
local action = self.actions[index]
|
||||
if action then
|
||||
return action.id
|
||||
end
|
||||
end
|
||||
end
|
||||
function Luvent:forEachAction(f)
|
||||
for action in self:allActions() do
|
||||
f(self, action)
|
||||
end
|
||||
end
|
||||
return Luvent
|
||||
Reference in New Issue
Block a user