红点迁移
首先来了解红点模块的各个函数的作用,然后再讲如何使用这些函数达成红点传递的目的,以及一些使用时候的注意事项。
1.首先来看表,新红点将红点名和依赖项的关系都放在了表里面,如下图:
上图表的依赖项对应关系使用下列代码进行了实现:
name2Rules[依赖项名] = 依赖项类
这里保持了依赖项名和依赖类名的一致,所以可以直接通过前者来创建一个类
module("RedDotHintM", package.seeall)
require("game/misc/red_dot_rule/RedDotRuleBase")
local name2Rules = {};
-- 载入配置表
local function loadCsv()
name2Rules = {};
require("game/config/red_dot_rule")
for _, ruleCfg in ipairs(CONFIG.red_dot_rule) do
local name = ruleCfg.name;
local ruleClass = require(string.format("game/misc/red_dot_rule/%s", name));
name2Rules[name] = ruleClass.new(name);
end
-- 设置依赖
for _, ruleCfg in ipairs(CONFIG.red_dot_rule) do
if type(ruleCfg.deps) == "table" then
local deps = {};
for _, ruleName in ipairs(ruleCfg.deps) do
local rule = name2Rules[ruleName];
assert(nil ~= rule, tostring(ruleName) .. "规则不存在");
table.insert(deps, rule);
end
local rule = name2Rules[ruleCfg.name];
rule:setDeps(deps);
end
end
CONFIG.red_dot_rule = nil;
package.loaded["game.config.red_dot_rule"] = nil;
end
2.接下来是RedDotRuleBase文件各个函数的作用和解析
首先是变量的初始化,这里重点说明一下依赖项和被依赖项。
一般来说外层红点依赖内层红点,所以外层红点是否显示需要判断依赖的内层红点是否显示。所以需要依赖项,这个不难理解。
而当红点变化的时候,一般需要监听某些数据变化,而这个监听数据变化是在内层红点进行的,外层红点并不知道要监听哪些数据,这个时候内层红点已经发生了变化,但是外层红点并不知道内层发生了变化,所以很多时候你会发现内层已经有红点了,外层还是憨憨的没有红点,得退出去重新进来之后才有(也就是常见的红点刷新不及时的问题)
解决这个问题有两个方法,第一就是在外层红点监听处,把所有的内层红点的监听函数全复制一遍,这样只要内层红点发生变化,外层一定能及时跟上。
第二就是这里使用的被依赖项,当内层红点数据变化时,调用一下被依赖项(也就是外层红点)的onQuery来达到及时改变红点的效果。
两种方法本质是一样的,就是第二种会更简洁一点,这里采用的就是第二种。所以我们在写代码的时候不必在外层红点上监听一堆数据,做好分内之事就行了
RedDotRuleBase = Class();
function RedDotRuleBase:ctor(name)
self.name = name;
self.rely = {}; -- 依赖项(依赖项的红点变化会影响到自己)
self.relied = {}; -- 被依赖项(被依赖项的监听会影响到自己)
self.callbacks = {}; -- 回调函数,一般储存onQuery函数,也就是判断是否显示红点的那个函数
self:reset();
end
-- 清空重置
function RedDotRuleBase:reset()
self.isViewed = false;
if self.enabled then
self:onDisable();
end
self.enabled = false;
self.isShow = false; -- 是否显示红点,仅对整体规则有效
self.isDirty = true;
end