LUACN论坛

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
热搜: YJWOW MagicStone BoL
查看: 152|回复: 0

[综合] 【搬运Wowpedia】事件Events(四)

[复制链接]
发表于 2023-7-10 11:13:37 | 显示全部楼层 |阅读模式
本帖最后由 懒动行不行 于 2023-7-10 11:14 AM 编辑

Handling events
事件是魔兽世界客户端发送给UI代码(框架派生的OnEvent脚本处理程序)的消息,主要是对游戏世界中发生的事情的反应。为了处理事件,插件需要创建一个事件处理程序,并为它希望接收的事件注册它。
目录


设置事件处理器
事件是被发送到框架派生的组件;如果插件尚未拥有可用于处理事件的框架,则需要创建一个框架。可以在Lua中使用CreateFrame函数创建框架;或用XML构造(使用<Frame>标签)
一旦创建了一个框架,其OnEvent处理程序就必须设置为代表插件处理事件的函数。OnEvent脚本处理程序可以使用Lua框架:SetScript()函数设置;或者用XML构造(使用<Scripts><OnEvent>函数主体</OnEvent></Scripts>)。

OnEvent 处理器函数接收至少2个参数:
  • self, 对脚本处理程序所属框架的引用
  • event,正在激发的事件的名称
  • 其他的事件参数都可以放置在可变参数表达式中 (...). 您可以从其中提取变量,只需将其分配给局部变量即可:例如从localarg1、arg2、arg3= ...;
插件的OnEvent脚本处理程序函数应该处理该事件,或者调用另一个插件函数来处理该事件。
为了接收事件通知,需要为插件需要处理的事件注册事件处理程序框架;使用frame:RegisterEvent(“eventName”)来实现这一点。RegisterEvent函数可以在框架创建后的任何时间调用;当使用XML时,OnLoad脚本处理程序是注册所需事件的方便位置。
如果您不再希望接收特定事件的事件通知,请使用frame:UnregisterEvent()函数。如果您希望禁用当前传递到框架的所有事件通知,请使用frame:UnregisterAllEvents()。


示例
Hello World

下面的两个实现方法在功能上是相同的:当角色进入世界时,它们将“Hello World!Hello PLAYER_ENTERING_World”打印到默认聊天框中。请注意,事件变量在XML OnEvent处理程序中是隐式的:它由OnEvent闭包签名提供。

使用XML
[Lua] 纯文本查看 复制代码
<Ui>
<Frame name="FooAddonFrame">
 <Scripts>
   <OnLoad> self:RegisterEvent("PLAYER_ENTERING_WORLD"); </OnLoad>
   <OnEvent> print("Hello World! Hello " .. event); </OnEvent>
  </Scripts>
</Frame>
</Ui>

使用 Lua
[Lua] 纯文本查看 复制代码
local frame = CreateFrame("FRAME", "FooAddonFrame");
frame:RegisterEvent("PLAYER_ENTERING_WORLD");
local function eventHandler(self, event, ...)
 print("Hello World! Hello " .. event);
end
frame:SetScript("OnEvent", eventHandler);

XML-相关
您可以将已声明的Lua函数直接绑定到XML中的OnEvent处理程序,而不是通过在<OnEvent></OnEvent>标记中提供函数体来创建另一个函数。这样做可以节省内存:
[Lua] 纯文本查看 复制代码
function FooHandler_OnEvent(self, event, ...)
 --这里插入事件处理器代码
end

FooAddOn.xml
[Lua] 纯文本查看 复制代码
<Ui>
 <Script file="FooAddon.lua"/>
 <Frame name="FooHandler">
  <Scripts>
   <OnEvent function="FooHandler_OnEvent"/>
  </Scripts>
 </Frame>
</Ui>

Lua-相关
如果您的框架注册了大量事件,则可以减少If子句的所需数量,并通常通过以下操作简化设计:
[Lua] 纯文本查看 复制代码
local frame, events = CreateFrame("Frame"), {};
function events:PLAYER_ENTERING_WORLD(...)
 -- handle PLAYER_ENTERING_WORLD here
end
function events:PLAYER_LEAVING_WORLD(...)
 -- handle PLAYER_LEAVING_WORLD here
end
frame:SetScript("OnEvent", function(self, event, ...)
 events[event](self, ...); -- call one of the functions above
end);
for k, v in pairs(events) do
 frame:RegisterEvent(k); -- Register all events for which handlers have been defined
end

请注意,在上面的事件:XXX函数的情况下,通过使用函数表:functionName表示法隐式定义的变量self将指向处理事件的框架,而不是事件表。
可变参数表达式

可变参数表达式(…)可能包含事件提供的其他参数。包含在中的参数…可以通过简单地将它们分配给其他变量来读取,也可以使用select函数跳到列表中的特定参数。
请考虑处理COMBAT_LOG_EVENT的示例:
[Lua] 纯文本查看 复制代码
function eventHandler(self, event, ...)
 if event == "COMBAT_LOG_EVENT" then
  local timestamp, combatEvent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags = 
   ...; -- 这些参数为战斗事件的所有变量.
  local eventPrefix, eventSuffix = combatEvent:match("^(.-)_?([^_]*)$");
  if eventSuffix == "DAMAGE" then
   -- 某事造成了伤害.在 ... 中的后9个参数描述了造成了多少伤害.
   -- 为了提取这些变量, 我们可以使用 select 函数:
   local numArgumentsInVarArg = select("#", ...)
   local amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = 
    select(numArgumentsInVarArg - 8, ...);
   -- 用伤害的细节做些事情 ... 
   if eventPrefix == "RANGE" or eventPrefix:match("^SPELL") then
    -- 这些前缀的前三个参数(出现在所有COMBAT_LOG_EVENT所有的11个参数之后)
    -- 描述法术或者技能造成伤害 . 用 select提取:
    local spellId, spellName, spellSchool = select(12, ...); -- Everything from 12th argument in ... onward
    -- 用技能的细节做些事情 ...
   end
  end
 end
end

备注
全局变量 this, event, 和 argX 在 Patch 4.0.1 版本中移除。替代地, 通过OnEvent脚本处理器使用这些参数。

相关API








回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

小黑屋|手机版|Archiver|LUACN论坛

GMT+8, 2024-5-2 08:19 PM , Processed in 0.035155 second(s), 13 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表