AutoX-对象、图片资源懒加载+Storage持久化

AutoX-对象、图片资源懒加载+Storage持久化

一、使用场景

需要懒加载的场景有很多,我最开始是需要懒加载功能是在编写一个游戏自动化脚本时,需要事先检测某个物品的坐标,才能进行后续的点击操作,该物品在页面中的位置是固定的,我如果确定了其坐标点[x, y],那么以后就可以一直使用。但是考虑到脚本要在不同分辨率的机型上适配,所以这个物品的坐标我不能写死,只能通过找图、找色手段确定后,将其保存到本地缓存中,后续使用时直接加载缓存即可。在同一脚本中,这种先确定物品固定坐标再操作的情况有很多,因此我需要一个能统一处理坐标检测和持久化的方法。

另外,在游戏脚本中通常会涉及大量的找图需求,如果在其中的每个方法中单独加载图片、释放图片资源会使得代码重复部分较多,不够优雅。此时就需要设计一套流程,能够对图片资源按需加载、统一释放资源,并且还可以针对不同分辨率的机型在图片加载后进行统一缩放处理。

二、代码实现

针对我在实际中遇到的以上这两种需求,结合 AutoX 提供的 API 和 Rhino 引擎特性实现了以下懒加载方法:

  • createLazyObject(obj[,saveKey]): 能够对普通对象属性值进行动态获取和Storage持久化,下次启动时可直接加载Storage中的缓存;清理缓存后可重新触发懒加载方法。
  • createImageLazyObject(imagePathMap):对前一方法的进一步封装了,然后就能像 resource.图片1 访问对象属性的方式触发图片加载,再配合退出事件 events.on('exit', xxx) 完成对资源的统一释放。

(后文有测试用例,可直接测试使用)

const isFunction = (val) => typeof val === 'function';/*** 创建一个懒加载对象。动态获取到的属性值可保存在内存中,也可持久化到Storage中,下次运行时从Storage中直接加载* @param {object} obj* @param {string|null} saveKey 为空则只在内存中进行懒加载;如果不为空,表示此对象以saveKey为键存储到Storage。*/
function createLazyObject(obj, saveKey) {let lazyObject = {};let cacheData = saveKey ? getCache(saveKey, {}) : {};for (let key in obj) {if (!obj.hasOwnProperty(key)) {continue;}// 静态值不做处理if (!isFunction(obj[key])) {lazyObject[key] = obj[key];continue;}// 动态加载方法,且有缓存值if (cacheData[key] !== undefined) {lazyObject[key] = cacheData[key];continue;}// 是动态加载方法,但没有缓存值let tempKey = key; // Getter属性值let memoryKey = '_' + key; // 内存中实际存储属性let fetchMethod = obj[key];Object.defineProperty(lazyObject, tempKey, {get: function () {if (!this.hasOwnProperty(memoryKey)) {let value = fetchMethod();if (value === null || value === undefined) {console.warn(`⚠The result of "${tempKey}" lazy loading method is ${value}`);}Object.defineProperty(this, memoryKey, {value: value,writable: true,configurable: true,enumerable: false});// 保存到Storageif (saveKey) {cacheData[tempKey] = value;updateCache(saveKey, cacheData);}}return this[memoryKey];},set: function (value) {if (value === undefined) {delete this[memoryKey];} else {this[memoryKey] = value;}if (saveKey) {cacheData[tempKey] = value;// 更新缓存,值为undefined的属性会被略过,有清除部分缓存的功能updateCache(saveKey, cacheData);}},enumerable: true,configurable: false});}return lazyObject;
}const _myStorage = storages.create('xxx脚本缓存');
/*** 缓存数据* @param {string} key* @param {any} value* @param {number} expire 过期时间戳,ms*/
function updateCache(key, value, expire) {if (!key) {throw new Error('缓存key不能为空');}if (expire) {value.__expire = expire;}_myStorage.put(key, value);delete value.__expire;
}/*** 读取缓存数据,数据不存在或者过期会返回默认值或null* @param {string} key key* @param {any} defaultValue 数据不存在时返回的默认值* @returns 没有缓存会返回null*/
function getCache(key, defaultValue) {if (!key) {return defaultValue;}const value = _myStorage.get(key);if (value === undefined || (value.__expire && value.__expire < Date.now())) {return defaultValue || null;}delete value.__expire;return value;
}/*** 清理缓存,key为空时清理当前Storage全部缓存* @param {string|undefined} key*/
function clearCache(key) {if (key) {_myStorage.remove(key);} else {console.info('清除当前脚本所有缓存\n');_myStorage.clear();}
}// ==================== 图像懒加载 =======================
let _imageCache = {};
events.on('exit', function () {console.log('释放图片资源', Object.values(_imageCache).length);Object.values(_imageCache).forEach((img) => {img.recycle();});
});// 通过闭包保存图片路径参数
function _loadImage(path) {return function () {console.log('加载图片:' + path);let img = images.read(path);if (img == null) {throw new Error('图片资源不存在:' + path);}_imageCache[path] = img;return img;};
}function createImageLazyObject(imagePathMap) {let lazyObject = {};for (let key in imagePathMap) {if (Object.hasOwnProperty.call(imagePathMap, key)) {// 将图片路径转为动态加载图片方法lazyObject[key] = _loadImage(imagePathMap[key]);}}return createLazyObject(lazyObject,undefined // 图片对象不建议保存到Storage,如果需要得先转为base64);
}

三、使用示例

1. 普通懒加载对象

通过 createLazyObject(obj[, saveKey]) 创建一个懒加载对象,obj的每个属性值为 Function 类型的懒加载方法。

若设置了saveKey 参数,在懒加载方法触发后,将方法的返回值存储到 Storage 中,saveKey 作为不同懒加载对象的标识符号;若 saveKey 参数为空,懒加载方法触发后,返回值则仅保存在内存中,下次程序启动后在用到该属性时重新触发其懒加载方法。

注意事项:懒加载方法不要返回 null 或者 undefined

// 定义两个懒加载方法
function fetchName() {console.log('触发name动态方法');return 'John Doe'; // 假设获取到的名称是 'John Doe'
}function fetchAge() {console.log('触发age动态方法');return 30; // 假设获取到的年龄是 30
}let identifier = 'foo';// 定义一个懒加载对象
let lazyObject = createLazyObject({name: fetchName,age: fetchAge,sex: 'male'},identifier // 开启Storage持久化
);

测试属性获取、修改

// 先清理缓存
clearCache(identifier);
console.log(getCache(identifier));console.log(lazyObject);console.log('================测试获取===================');
console.log(lazyObject.name); // 懒加载
console.log(lazyObject.name); // 已获取到
console.log(lazyObject.age); // 懒加载
console.log(getCache(identifier));
console.log(lazyObject);console.log('================测试修改===================');
lazyObject.age = 20; // 懒加载属性被重新赋值,触发Setter方法;保存到Storage
lazyObject.sex = 'female'; // 静态属性被重新赋值,不触发Setter方法;不保存到Storage
console.log(lazyObject.age);
console.log(getCache(identifier));
console.log(lazyObject);console.log('================测试清除缓存===================');
lazyObject.age = undefined;
console.log(lazyObject.age); // 重新触发懒加载
console.log(getCache(identifier));
console.log(lazyObject);

2. 图像资源

// 定义一个图像懒加载对象,值为图片路径
let imgResource = createImageLazyObject({home: '/sdcard/Download/home.jpg',shop: '/sdcard/Download/shop.jpg',
});console.log(imgResource);
console.log(imgResource.icon);
console.log(imgResource.icon.getWidth());
console.log(imgResource.icon2);
console.log(imgResource.icon2.getWidth());

本文持续更新地址:AutoX对象、图片资源懒加载+Storage持久化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/127166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[SpringCloud | Linux] CentOS7 部署 SpringCloud 微服务

目录 一、环境准备 1、工具准备 2、虚拟机环境 3、Docker 环境 二、项目准备 1、配置各个模块&#xff08;微服务&#xff09;的 Dockerfile 2、配置 docker-compose.yml 文件 3、Maven 打包 4、文件整合并传输 三、微服务部署 1、部署至 Docker 2、访问微服务 四…

折纸达珠峰高度(forwhile循环、闭包函数循环)

对折0.1mm厚度的纸张多少次&#xff0c;高度可达珠峰高度8848180mm。 (本笔记适合熟悉循环和列表的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅…

使用 Docker 部署高可用 MongoDB 分片集群

使用 Docker 部署 MongoDB 集群 Mongodb 集群搭建 mongodb 集群搭建的方式有三种&#xff1a; 主从备份&#xff08;Master - Slave&#xff09;模式&#xff0c;或者叫主从复制模式。副本集&#xff08;Replica Set&#xff09;模式。分片&#xff08;Sharding&#xff09;…

vue图书馆书目推荐数据分析与可视化-计算机毕业设计python-django-php

建立本图书馆书目推荐数据分析是为了通过系统对图书数据根据算法进行的分析好推荐&#xff0c;以方便用户对自己所需图书信息的查询&#xff0c;根据不同的算法机制推荐给不同用户不同的图书&#xff0c;用户便可以从系统中获得图书信息信息。 对用户相关数据进行分析&#xff…

C#,数值计算——积分方程与逆理论Quad_matrix的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Quad_matrix : UniVarRealMultiValueFun { private int n { get; set; } private double x { get; set; } public Quad_matrix(double[,] a) { this.n a…

Linux越学越头疼,我要怎么办?

最近&#xff0c;听到一些同学说&#xff0c;“Linux越学越头疼”。其实这句话&#xff0c;在我之前刚接触Linux的时候&#xff0c;也是深有感触。Linux越学越不明所以。最后干脆放弃学习&#xff0c;转而学习其他东西。 其实大家在初学Linux的时候&#xff0c; 有这个感受&am…

ES6对象扩展

ES6对象扩展是指在ES6中新增的一些对象属性和方法&#xff0c;包括对象属性的简写、计算属性名、对象方法的简写、对象的可迭代性、拓展运算符等。 下面是一些常用的ES6对象扩展&#xff1a; 对象属性的简写 ES6中&#xff0c;当对象的属性名和赋值变量名相同时&#xff0c;…

四川达州-全国先进计算创新大赛总结

目录 四川达州-全国先进计算创新大赛 1.三个算法&#xff0c;第三个原创的&#xff1f;&#xff08;国内对比&#xff09; 2.方案的实际落地应用&#xff1f;&#xff08;落地应用&#xff09; 3.农业数据采集有问题&#xff08;数据采集汇总&#xff09;&#xff0c;很难…

应用软件安全编程--03净化传递给 Runtime.exec() 方法的非受信数据

每个 Java 应用都有一个 Runtime 类的实例&#xff0c; 一般需要使用 shell 时调用它&#xff0c;从而可以在 POSIX 中 使用/bin/sh 或者在Windows 平台中使用cmd.exe。 当参数中包含以空格、双引号或者其他以一/开头 的用来表示分支的字符时&#xff0c;就可能发生参数注入攻…

【Tomcat Servlet】如何在idea上部署一个maven项目?

目录 1.创建项目 2.引入依赖 3.创建目录 4.编写代码 5.打包程序 6.部署项目 7.验证程序 什么是Tomcat和Servlet? 以idea2019为例&#xff1a; 1.创建项目 1.1 首先创建maven项目 1.2 项目名称 2.引入依赖 2.1 网址输入mvnrepository.com进入maven中央仓库->地址…

VMware——VMware17设置WindowServer2012R2环境静态IP及关闭防火墙

目录 一、VMware17设置WindowServer2012R2环境静态IP1.1、工具栏虚拟机的设置步骤1.2、工具栏编辑的设置步骤1.3、静态IP的设置步骤 二、VMware17关闭WindowServer2012R2环境防火墙 一、VMware17设置WindowServer2012R2环境静态IP 1.1、工具栏虚拟机的设置步骤 打开VMware虚拟…

CONTAINING_RECORD宏

CONTAINING_RECORD宏的使用 已知类或结构体成员变量的地址&#xff0c;可以取得类或结构体对象的地址。 代码 #include <windows.h> #include <iostream>class MyClass { public:MyClass(){}virtual ~MyClass(){}public:int m_Value1;int m_Value2;int m_Value3; …

线扫相机DALSA--常见问题三:未找到采集卡

“计算机”右键“管理”&#xff0c;选择“设备管理器”&#xff0c;单击打开“图像设备”&#xff0c;即可看到PC上所安装的采集卡型号&#xff0c;采集卡正常状态表现如上图所示&#xff0c;如果采集卡显示黄色叹号&#xff0c;表明驱动存在异常&#xff0c;解决采集卡丢失问…

作物模型--土壤数据制备过程

作物模型–土壤数据制备过程 首先打开FAO网站 下载下面这两个 Arcgis打开.bil文件 .mdb文件在access中转成.xls格式 Arcgis中对.bil文件定义投影

ROS自学笔记二十七:导航中相机消息

深度相机相关消息有:sensor_msgs/Image、sensor_msgs/CompressedImage、sensor_msgs/PointCloud2 sensor_msgs/Image 对应的一般的图像数据&#xff0c;sensor_msgs/CompressedImage 对应压缩后的图像数据&#xff0c;sensor_msgs/PointCloud2 对应的是点云数据(带有深度信息的…

万物皆可“云” 从杭州云栖大会看数智生活的未来

文章目录 前言一、云栖渐进&#xff1a;一个科技论坛的变迁与互联网历史互联网创新创业飞天进化飞天智能驱动数字中国 二、2023云栖大会&#xff1a;云计算人工智能 玩出科技跨界新花样大会亮点重磅嘉宾热门展览算力馆人工智能馆产业创新馆 总结 前言 10月31日&#xff0c;202…

【MATLAB源码-第64期】matlab基于DWA算法的机器人局部路径规划包含动态障碍物和静态障碍物。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 动态窗口法&#xff08;Dynamic Window Approach&#xff0c;DWA&#xff09;是一种局部路径规划算法&#xff0c;常用于移动机器人的导航和避障。这种方法能够考虑机器人的动态约束&#xff0c;帮助机器人在复杂环境中安全、…

论文阅读 - Detecting Social Bot on the Fly using Contrastive Learning

目录 摘要&#xff1a; 引言 3 问题定义 4 CBD 4.1 框架概述 4.2 Model Learning 4.2.1 通过 GCL 进行模型预训练 4.2.2 通过一致性损失进行模型微调 4.3 在线检测 5 实验 5.1 实验设置 5.2 性能比较 5.5 少量检测研究 6 结论 https://dl.acm.org/doi/pdf/10.1145/358…

开发板挂载 Ubuntu 的 NFS 目录

前言 使用的开发板为韦东山老师的 IMX6ULL 目录 什么是 NFS 协议&#xff1f; 为什么要挂载 Ubuntu 的 nfs 目录&#xff1f; 开发板挂载 Ubuntu 的 NFS 目录 步骤 1. 确定 ubuntu 的桥接网卡 IP 2. 判断是否开权限了 3. 判断是否安装并启动 NFS 服务 4. 在开发板上执…

服务器基本命令

nohup python3 ./download-all-2023-11-01_12-08-11.py > T85_download.log & 标准输出重定向到文件 nohup bash test.sh > stdout.txt & 标准错误输出重定向到文件 nohup bash test.sh 2> stderr.txt & 重定向到不同文件 nohup bash test.sh > …