- 配置是“<key>=<value>”格式,它以着文本存储在一个叫preferences的文件,存放在小程序的userdata目录根下。
- 在C代码,是用着trose_prefs封装配置。如果要在非主线程读取配置,为和主线程可能的写同步,须要先申请prefs.mutex锁。
C:/Users/ancientcc/我的文档/RoseApp/launcher/aplt_leagor_basic__documents/preferences ------ base_product="wheeltec" base_serial="COM5" base_serial_baudrate=115200 laser_product="N10" laser_serial="COM3" laser_serial_baudrate=230400 moveit_serial="COM5" moveit_serial_baudrate=115200 [signature] [/signature]
以上是一个配置文件示例。signature是个必须存在的空块,trose_prefs要用它判断此个preferences文件是否有效。
一、lua代码
1.1 在main.lua定义preferences_def变量
aplt_leagor_basic = { ... preferences_def = { laser_product = "", laser_serial = "", laser_serial_baudrate = 115200, ... }; };
启动小程序时,首先会从aplt_leagor_basic__documents/preferences文件读出配置,然后加载main.lua,解析当中的preferences_def,来同步配置。这同步表现在几个方面。
- 字段名(key)一样。告知存在哪些配置字段,新版本可以用这功能添加新字段,或删除不用了的字段。如果preferences_def有,preferences文件没有,那要加上,加上时,用的值就是这里指定的值。相应地,preferences_def没有,preferences文件有,那要删除。换句话说,在析解preferences_def后,对已放到内存中的配置,它存储的key和preferences_def一模一样。
- 值(value)类型一样。新版本可以用这功能更改值类型。解析preferences_def时,如果该key两处都存在,除非值类型发生变化,否则不替换。举个例子,laser_serial字段之前存的是string类型,现在改为number,解析preferences_def时,发现前、后类型发生变化,会用此刻的number值替换掉原值。注意,这里不区分number和integer,原因么,preferences文件是以文本存储值,文本“1239”,你无法确定它是number还是integer。
preferences_def中“def”是默认(default)缩写。默认含义体现在两处,1)该字段在preferences_def存在,在preferences文件不存在,用这默认值作为值。2)值类型发生变化时,也将用这默认值。
preferences_def必须写全小程序会用到的所有字段。不论读取(_value)还是设置(_set_value),要是用到一个这里没出现字段,那都会报错。
1.2 读
local laser_product, laser_serial = aplt.preferences:_value("laser_product", "laser_serial");
aplt指的是小程序主表,像aplt_leagor_basic。preferences是C代码为lua环境创建的一个表,lua代码可用这个表中提供的_value方法读取配置值。参数是要读出的key,一次调有可读多个key。
1.3 写
aplt.preferences:_set_value("laser_product", "N10", "laser_serial_baudrate", 115200);
_set_value用于写配置。参数是要写的[key, value]对,一次调可写多个key。
对value,不能是nil。如果想从配置删除该key,用preferences_def机制。
二、C代码
在C代码,是用着trose_prefs封装配置。小程序在运行时,全局变量aplt::curr_aplt指向一个class tapplet,当中就有个类型是trose_prefs字段prefs。
const trose_prefs& aplt_prefs = aplt::curr_aplt->prefs; std::string path = aplt_prefs.get_str("base_serial"); int baudrate aplt_prefs.get_int("base_serial_baudrate", nposm);
上面是一个典型的在C代码读取配置逻辑。get_str用于读取一个string类型的值。get_int读取int类型,第二个参数是当“base_serial_baudrate”这个key不存在时,要返回的值。当然,由于preferences_def机制,理论上不会出现key不存在情况,不过rose处理app配置用的也是trose_prefs,那里就须要第二个参数。
三、多线程同步
不论lua,还是C,归根用的都是class trose_prefs。trose_prefs采用的同步机制就决定了配置的同步要求。
只能在主线程更改配置。在lua,窗口肯定运行在主线程。所以对要更改配置,推荐方式是给用户提供个窗口界面。如果必须要在C代码,那确保在主线程。
若想在非主线程读取配置,为和主线程可能的写同步,须要先申请prefs.mutex锁。至于在主线程中读,因为写肯定在主线程,天然同步,不须要锁。