配置(preferences)

  • 配置是“<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,来同步配置。这同步表现在几个方面。

  1. 字段名(key)一样。告知存在哪些配置字段,新版本可以用这功能添加新字段,或删除不用了的字段。如果preferences_def有,preferences文件没有,那要加上,加上时,用的值就是这里指定的值。相应地,preferences_def没有,preferences文件有,那要删除。换句话说,在析解preferences_def后,对已放到内存中的配置,它存储的key和preferences_def一模一样。
  2. 值(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锁。至于在主线程中读,因为写肯定在主线程,天然同步,不须要锁。

全部评论: 0

    写评论: