unity lua属性绑定刷新
我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候,我们需要刷新界面显示等级信息,通常我们是在收到等级升级成功的协议的时候,发送一个事件,UI界面接受到这个事件的时候,刷新一下等级信息,如果不采用全局事件的方式,该怎么处理呢
我们能不能监听HeroModel的level这个属性,给这个属性绑定一个监听方法,当这个属性发生变化的时候,自动执行这个监听方法执行一些刷新操作。
local heroModel = {id = 1001,star = 1,level = 1, life = 1000,atk = 100,def = 10,}
我们知道,lua有两个比较常见的原方法 __index 和 __newindex,__index是 元表提供的表对象内部数据获取元方法,__newindex是当对表中不存在的元素进行赋值时会被调用。当我们从heroModel中获取某一个属性值的时候,会先从heroModel中取值,如果heroModel中不存在该值,则会从原表中取值,同样当我们给heroModel赋值的时候,会先判断heroModel是否存在该属性,如果存在,直接赋值,不存在则从原方法 __newindex中进行赋值。加入heroModel中不存在level这个属性,那么我们给它赋值的时候,肯定会调用原方法__newindex ,这个时候我们就可以在这个原方法里面赋值的时候进行判断,属性level是否发生变化,如果发生了变化, 则执行一个回调方法
简单演示如下
local heroModel = {id = 1001, star = 1, level=1}---创建原表local metaTable = {}metaTable.newInfo = {} --保存新创建的属性值metaTable.bindDataList = {} --存储回调方法metaTable.__index = function(t , k)printError("get " .. k)local res = metaTable.newInfo[k]return resendmetaTable.__newindex = function(t, k, v)printError("set " .. k .. " = " .. tostring(v))if (not metaTable.newInfo[k] or metaTable.newInfo[k] ~= v) and metaTable.bindDataList[k] ~= nil thenlocal callback = metaTable.bindDataList[k]callback()endmetaTable.newInfo[k] = vreturn vend-- 将heroModel中的属性赋值到原表,并清空heroModel,这样操作之后,只要给heroModel进行赋值就会执行它的原方法 __newindexfor k, v in pairs(heroModel) dometaTable.newInfo[k] = vheroModel[k] = nilend-- 设置元表setmetatable(heroModel, metaTable)-- 绑定回调方法metaTable.bindDataList["level"] = function()printError("level 值发生了变化")end--测试printError("----test---")printError("level 初始值 = "..tostring(heroModel.level)) --没有更新赋值时候进行调用heroModel.level = 10 --通过__newindex 刷新属性值,并执行回调heroModel.level = 11local b = heroModel.level --通关__index 获取新属性值printError("level新值 = " .. b)heroModel.kkk = 111 --通过__newindex 创建新属性值printError(heroModel.kkk) --通关__index 获取新属性值
输出结果

完整代码
DataBindModel = {}---@class DataBindModel:nil
local DataBindModel = DataBindModel---给实例添加绑定 内部方法 不要手动调用
---@param target dataBindInfo
function DataBindModel:__bindIns(target)if (target.dataBindvars) thenreturnendlocal dataBindvars = {}local mateTable = getmetatable(target)setmetatable(dataBindvars, mateTable)for k, v in pairs(target) dodataBindvars[k] = vtarget[k] = nilendtarget.dataBindvars = dataBindvarstarget.bindInfo__ = {}target.isBind = falsetarget.oldMateTable = mateTablelocal settable = { __index = function(t, key)return dataBindvars[key]end }settable.__newindex = DataBindModel.__newindexsetmetatable(target, settable)
endfunction DataBindModel:unBindIns(target)if (not target.dataBindvars) thenreturnendlocal dataBindvars = target.dataBindvarslocal mateTable = target.oldMateTabletarget.oldMateTable = niltarget.bindInfo__ = niltarget.isBind = niltarget.dataBindvars = nilsetmetatable(target, mateTable)for k, v in pairs(dataBindvars) dotarget[k] = vend
endfunction DataBindModel:newIndex(key)return self.dataBindvars[key]
endfunction DataBindModel:__newindex(key, var)local vars = self.dataBindvarslocal oldValue = vars[key]vars[key] = varif (self.isBind) thenif (oldValue ~= var) thenlocal bindInfo__ = self.bindInfo__local bindData = bindInfo__[key]if (bindData) thenlocal tempBindData = {}for i, bdata in ipairs(bindData) dotable.insert(tempBindData, bdata)endfor i, bdata in ipairs(tempBindData) dobdata.callBack(var, bdata, self)endtempBindData = nilendendendend---@param target any @model
---@param bindInfo dataBindInfo
function DataBindModel:bindKey(target, bindInfo)if not target thenprintWarningColor("FFB500FF", "dataModel is nil")returnendif (not target.dataBindvars) thenself:__bindIns(target)endlocal bindInfo__ = target.bindInfo__local bindData = bindInfo__[bindInfo.key]if (not bindData) thenbindData = {}bindInfo__[bindInfo.key] = bindDataendtarget.isBind = truelocal uiNode = bindInfo.uiNodeif (uiNode and not tolua.isnull(uiNode)) then---@type CS.NodeEventListenerlocal nodeEventListener = uiNode:GetComponent(typeof(CS.NodeEventListener))if not nodeEventListener thennodeEventListener = uiNode.gameObject:AddComponent(typeof(CS.NodeEventListener))bindInfo.nodeEventHandle = function()self:unBindKey(target, bindInfo)endif nodeEventListener.destroyCallback thennodeEventListener.destroyCallback = nodeEventListener.destroyCallback + bindInfo.nodeEventHandleelsenodeEventListener.destroyCallback = bindInfo.nodeEventHandleendendendtable.insert(bindData, bindInfo)
end---@param target any
---@param bindInfo dataBindInfo
function DataBindModel:unBindKey(target, bindInfo)if (not target.dataBindvars) thenreturnendlocal bindInfo__ = target.bindInfo__local bindData = bindInfo__[bindInfo.key]if (bindData) thenlocal index = table.indexof(bindData, bindInfo)if (index) thentable.remove(bindData, index)local uiNode = bindInfo.uiNodeif (uiNode and not tolua.isnull(uiNode)) thenlocal nodeEventHandle = uiNode:GetComponent(typeof(CS.NodeEventListener))if nodeEventHandle thennodeEventHandle.destroyCallback = nodeEventHandle.destroyCallback - bindInfo.nodeEventHandleendendendif (#bindData == 0) thenbindInfo__[bindInfo.key] = nilendendlocal count = 0;for k, v in pairs(bindInfo__) docount = count + 1;break ;endif (count <= 0) thenself:unBindIns(target)end
end---@param bindDataInfos dataBindInfo
function DataBindModel:bindKeys(target, bindDataInfos)for i, data in ipairs(bindDataInfos) doself:bindKey(target, data)end
end---@param bindDataInfos dataBindInfo
function DataBindModel:unBindKeys(target, bindDataInfos)for i, data in ipairs(bindDataInfos) doself:unBindKey(target, data)end
endreturn DataBindModel
调用
注:DataBindModel 是一个全局table
local heroModel = {id = 1001, star = 1, level=1}
local bindDatas = {key = "level", callBack = function(value, bindInfo, model)-- 执行刷新逻辑self:checkRed()end
}
DataBindModel:bindKeys(heroModel, bindDatas)
相关文章:
unity lua属性绑定刷新
我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候,我们需要刷新界面显示等级信息,通常我们是在收到等级升级成功的协议的时候,发送一个事件,UI界面接受到这个事件的时候,刷新一下等级…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_t
ngx_conf_t 定义在src/core/ngx_core.h typedef struct ngx_conf_s ngx_conf_t;ngx_conf_s 定义在 src/core/ngx_conf_file.h struct ngx_conf_s {char *name;ngx_array_t *args;ngx_cycle_t *cycle;ngx_pool_t *po…...
gtest 和 gmock讲解
Google Test(gtest)和 Google Mock(gmock)是 Google 开发的用于 C 的测试框架和模拟框架,以下是对它们的详细讲解: Google Test(gtest) 简介 Google Test 是一个用于 C 的单元测试框…...
Ubuntu20.04安装Redis
目录 切换到root用户 使用 apt install redis 安装redis 修改配置文件 编辑 重新启动服务器 使用Redis客户端连接服务器 切换到root用户 如果没有切换到root用户的,切换到root用户。 使用 apt install redis 安装redis 遇到y/n直接y即可。 redis安装好之…...
利用 DeepSeek 总结运维知识库的总结报告
一、背景 在运维工作中,知识库是重要的知识沉淀与共享工具。随着公司业务的发展,运维涉及的系统、设备和技术日益复杂,原有的运维知识库内容繁杂、缺乏条理,难以高效检索和利用。为了提升知识库的可用性,我尝试借助 D…...
Go基于协程池的延迟任务调度器
原理 通过用一个goroutine以及堆来存储要待调度的延迟任务,当达到调度时间后,将其添加到协程池中去执行。 主要是使用了chan、Mutex、atomic及ants协程池来实现。 用途 主要是用于高并发及大量定时任务要处理的情况,如果使用Go协程来实现每…...
一个原教旨的多路径 TCP
前面提到过 ECMP 和 TCP 之间的互不友好,pacing 收益和中断开销的互斥,在事实上阻碍了 packet-based LB 的部署,也限制了交换机,服务器的并发性能,同时潜在增加了 bufferbloat 的概率,而适用 packet-based …...
OSPF BIT 类型说明
注:本文为 “OSPF BIT 类型 | LSA 类型 ” 相关文章合辑。 机翻,未校。 15 OSPF BIT Types Explained 15 种 OSPF BIT 类型说明 Rashmi Bhardwaj Distribution of routing information within a single autonomous system in larger networks is per…...
如何获取mac os 安装盘
发现虚拟机VirtualBox支持Mac虚拟,就想尝试一下。但是发现Mac的安装盘特别难拿到,因此留档。 第一种方法 在mac环境下,使用softwareupdate命令来获取mac安装,能获得当前设备支持的系统。 使用这个命令:/usr/sbin/soft…...
【深度学习】强化学习(RL)-A3C(Asynchronous Advantage Actor-Critic)
A3C(Asynchronous Advantage Actor-Critic)详解 A3C(Asynchronous Advantage Actor-Critic) 是 深度强化学习(Deep Reinforcement Learning, DRL) 领域的重要算法,由 DeepMind 在 2016 年提出。…...
vue的双向绑定是怎么实现的
Vue.js 的双向绑定是通过 数据劫持(Data Observation) 和 发布-订阅模式(Publish-Subscribe Pattern) 实现的。具体来说,Vue 使用了以下核心技术: 数据劫持:通过 Object.defineProperty 或 Prox…...
在 Mac mini M2 上本地部署 DeepSeek-R1:14B:使用 Ollama 和 Chatbox 的完整指南
随着人工智能技术的飞速发展,本地部署大型语言模型(LLM)已成为许多技术爱好者的热门选择。本地部署不仅能够保护隐私,还能提供更灵活的使用体验。本文将详细介绍如何在 Mac mini M2(24GB 内存)上部署 DeepS…...
docker-compose部署onlyoffice8.3.0并支持ssl,且支持通过nginx代理,关闭JWT配置
编写docker-compose文件 mkdir -p /data/onlyoffice && echo "version: 3services:onlyoffice:container_name: OnlyOfficeimage: onlyoffice/documentserver:8.3.0restart: alwaysports:- 8088:80- 64431:443environment:TZ: Asia/ShanghaiJWT_ENABLED: falsevol…...
如何配置虚拟机的IP上网
要配置虚拟机的IP地址以便上网,你可以按照以下步骤操作: 打开虚拟机软件,确保虚拟机的网络设置为“桥接模式”或“NAT模式”,这样虚拟机可以与物理网络连接。 在虚拟机操作系统中,打开网络设置界面,一般在…...
【tplink】校园网接路由器如何单独登录自己的账号,wan-lan和lan-lan区别
老式路由器TPLINK,接入校园网后一人登录,所有人都能通过连接此路由器上网,无法解决遂上网搜索,无果,幸而偶然看到一个帖子说要把信号源网线接入路由器lan口,开启新世界。 一、wan-lan,lan-lan区…...
Python--内置模块和开发规范(下)
2. 开发规范 2.1 单文件应用 文件结构示例 # 文件注释 import os import jsonDB_PATH "data.json" # 常量放顶部def load_data():"""函数注释:加载数据"""if os.path.exists(DB_PATH):with open(DB_PATH, "r"…...
DeepSeek开源周Day5压轴登场:3FS与Smallpond,能否终结AI数据瓶颈之争?
2025年2月28日,DeepSeek开源周迎来了第五天,也是本次活动的收官之日。自2月24日启动以来,DeepSeek团队以每天一个开源项目的节奏,陆续向全球开发者展示了他们在人工智能基础设施领域的最新成果。今天,他们发布了Fire-F…...
[密码学实战]Java实现SM2数字信封(结合SM4对称加密)生成与解析
一、代码运行结果 二、什么是数字信封 2.1 基本概念 数字信封(Digital Envelope) 是一种结合对称加密与非对称加密的混合加密技术,通过以下步骤实现高效安全的数据传输: 对称加密:使用SM4算法加密原始数据,处理速度快,适合大数据量。非对称加密:使用SM2公钥加密SM4密…...
redis序列化设置
redis序列化设置 redis序列化设置序列化对象里有org.joda.time.DateTime1)、报错内容如下2)、解决方案:分别自定义时间的序列化和反序列化,以对象形式关联到redisTemplate redis序列化设置 redis序列化设置,通过自定义…...
Sqlserver安全篇之_TLS的证书概念
证书的理解 参考Sqlserver的官方文档https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/certificate-overview?viewsql-server-ver16 TLS(Transport Layer Security)传输层安全和SSL(Secure Sockets Layer)安全套接字层协议位于应用程序协议层和TCP/…...
【HarmonyOS Next】 鸿蒙应用useNormalizedOHMUrl详解
【HarmonyOS Next】 鸿蒙应用useNormalizedOHMUrl详解 一、useNormalizedOHMUrl是什么? useNormalizedOHMUrl指的是是否使用标准化OHMUrl拼接。 在开发过程中,需要根据不同的环境或配置动态生成 URL。例如,在加载一些远程模块或者资源时,…...
Oracle 查询表空间使用情况及收缩数据文件
本文介绍Oracle收缩数据文件的相关操作,运维工作中有时会需要通过收缩数据文件来释放磁盘空间。 数据文件初始化方式: 1.我们创建表空间一般有两种方式初始化其数据文件,即指定初始大小为32G(很大的值)或指定初始大小为…...
怎么进行mysql的优化?
MySQL 的优化是一个系统性的工作,涉及多个层面,包括查询优化、索引优化、配置优化、架构优化等。以下是一些常见的 MySQL 优化方法: 查询优化 避免全表扫描:确保查询能够使用索引,避免 SELECT *,只选择需要…...
docker-compose方式启动Kafka Sasl加密认证(无zk)
首先参考文档,思考过程可以进行参考https://juejin.cn/post/7294556533932884020#heading-3 用的镜像是Bitnami,对SASL配置进行了简化,需要按照特定格式去配置jass验证 完整配置如下 镜像版本参考:https://hub.docker.com/r/bitn…...
Grafana接入Zabbix数据源
1. 对接 Zabbix 1.1 安装 Zabbix 插件 在线安装: 1.2 配置 Zabbix 数据源 点击 Configuration > Data Sources > Add data source。选择 Zabbix,填写: URL:http://<zabbix-server>/api_jsonrpc.phpUsername&#x…...
华为在不同发展时期的战略选择(节选)
华为在不同发展时期的战略选择(节选) 添加图片注释,不超过 140 字(可选) 来源:谢宁专著《华为战略管理法:DSTE实战体系》。本文有节选修改。 导言 从目前所取得的成就往回看,华为…...
【计算机网络】TCP协议相关总结,TCP可靠性的生动讲解
TCP 可靠性 确保快递不丢、不乱、不过载 机制作用(快递类比)防止的问题检验和检查包裹是否损坏,损坏就重新发数据出错序列号给每个包裹编号,按顺序整理乱序、重复确认应答每送到一件,就让收件人签收丢失滑动窗口控制…...
lua基础语法学习
lua基础语法学习 文章目录 lua基础语法学习1. 基础2. 输入输出3. 分支结构与循环结构4. 函数5. 元表与元方法6. 面向对象 1. 基础 注释 --单行注释--[[ 多行注释 --]]标识符 标识符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上 0 个或多个字母,下划线&…...
【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调【完整教程】
文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-1微调2.2.3.2 zero-2微调2.2.3.3 zero-3微调2.2.3.4 单卡Lora微调 2.2.4 实验2.2.4.1 实验1:多GPU微调-zero12.2.4.2 实验2:…...
【SpringBoot】数据访问技术spring Data、 JDBC、MyBatis、JSR-303校验
Spring Boot 数据访问技术及特性 目录标题 Spring Boot 数据访问技术及特性摘要1. 引言2. Spring Data架构与原理2.1 Spring Data概述2.2 Spring Data核心组件2.3 Spring Boot与Spring Data的集成机制 3. Spring Boot与JDBC的整合3.1 JDBC整合流程3.2 数据源自动配置3.3 JdbcTe…...
