nvm.lua 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. --- 模块功能:参数管理
  2. -- @module nvm
  3. -- @author openLuat
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2017.11.9
  7. require"log"
  8. module(...,package.seeall)
  9. package.path = "/?.lua;".."/?.luae;"..package.path
  10. --默认参数配置存储在configname文件中
  11. --实时参数配置存储在paraname文件中
  12. --para:实时参数表
  13. --config:默认参数表
  14. paraname,paranamebak = "/nvm_para.lua","/nvm_para_bak.lua"
  15. local para,libdftconfig,configname,econfigname = {}
  16. --[[
  17. 函数名:serialize
  18. 功能 :根据不同的数据类型,按照不同的格式,写格式化后的数据到文件中
  19. 参数 :
  20. pout:文件句柄
  21. o:数据
  22. 返回值:无
  23. ]]
  24. local function serialize(pout,o)
  25. if type(o) == "number" then
  26. --number类型,直接写原始数据
  27. pout:write(o)
  28. elseif type(o) == "string" then
  29. --string类型,原始数据左右各加上双引号写入
  30. pout:write(string.format("%q", o))
  31. elseif type(o) == "boolean" then
  32. --boolean类型,转化为string写入
  33. pout:write(tostring(o))
  34. elseif type(o) == "table" then
  35. --table类型,加换行,大括号,中括号,双引号写入
  36. pout:write("{\n")
  37. for k,v in pairs(o) do
  38. pout:write(" [")
  39. serialize(pout, k)
  40. pout:write("] = ")
  41. serialize(pout, v)
  42. pout:write(",\n")
  43. end
  44. pout:write("}\n")
  45. else
  46. error("cannot serialize a " .. type(o))
  47. end
  48. end
  49. --[[
  50. 函数名:upd
  51. 功能 :更新实时参数表
  52. 参数 :
  53. overide:是否用默认参数强制更新实时参数
  54. 返回值:无
  55. ]]
  56. function upd(overide)
  57. for k,v in pairs(libdftconfig) do
  58. if k ~= "_M" and k ~= "_NAME" and k ~= "_PACKAGE" then
  59. if overide or para[k] == nil then
  60. para[k] = v
  61. end
  62. end
  63. end
  64. end
  65. --[[
  66. 函数名:load
  67. 功能 :初始化参数
  68. 参数 :无
  69. 返回值:无
  70. ]]
  71. local function load()
  72. local f,fBak,fExist,fBakExist
  73. f = io.open(paraname,"rb")
  74. fBak = io.open(paranamebak,"rb")
  75. if f then
  76. fExist = f:read("*a")~=""
  77. f:close()
  78. end
  79. if fBak then
  80. fBakExist = fBak:read("*a")~=""
  81. fBak:close()
  82. end
  83. print("load fExist fBakExist",fExist,fBakExist)
  84. local fResult,fBakResult
  85. if fExist then
  86. fResult,para = pcall(require,string.match(paraname,"/(.+)%.lua"))
  87. end
  88. print("load fResult",fResult)
  89. if fResult then
  90. os.remove(paranamebak)
  91. upd()
  92. return
  93. end
  94. if fBakExist then
  95. fBakResult,para = pcall(require,string.match(paranamebak,"/(.+)%.lua"))
  96. end
  97. print("load fBakResult",fBakResult)
  98. if fBakResult then
  99. os.remove(paraname)
  100. upd()
  101. return
  102. else
  103. para = {}
  104. restore()
  105. end
  106. end
  107. --[[
  108. 函数名:save
  109. 功能 :保存参数文件
  110. 参数 :
  111. s:是否真正保存,true保存,false或者nil不保存
  112. 返回值:无
  113. ]]
  114. local function save(s)
  115. if not s then return end
  116. local f = {}
  117. f.write = function(self, s) table.insert(self, s) end
  118. f:write("module(...)\n")
  119. for k,v in pairs(para) do
  120. if k ~= "_M" and k ~= "_NAME" and k ~= "_PACKAGE" then
  121. f:write(k .. " = ")
  122. serialize(f,v)
  123. f:write("\n")
  124. end
  125. end
  126. local fparabak = io.open(paranamebak, 'wb')
  127. fparabak:write(table.concat(f))
  128. fparabak:close()
  129. os.remove(paraname)
  130. os.rename(paranamebak,paraname)
  131. end
  132. --- 初始化参数存储模块
  133. -- @string defaultCfgFile 默认配置文件名
  134. -- @return nil
  135. -- @usage nvm.init("config.lua")
  136. function init(defaultCfgFile)
  137. local f
  138. f,libdftconfig = pcall(require,string.match(defaultCfgFile,"(.+)%.lua"))
  139. configname,econfigname = "/lua/"..defaultCfgFile,"/lua/"..defaultCfgFile.."e"
  140. --初始化配置文件,从文件中把参数读取到内存中
  141. load()
  142. end
  143. --- 设置某个参数的值
  144. -- @string k 参数名
  145. -- @param v,可以是任意类型,参数的新值
  146. -- @param r,设置原因,如果传入了非nil的有效参数,并且v值和旧值相比发生了改变,会产生一个PARA_CHANGED_IND消息,携带 k,v,r 3个参数
  147. -- @param s,是否立即写入到文件系统中,false不写入,其余的都写入
  148. -- @return bool或者nil,成功返回true,失败返回nil
  149. -- @usage nvm.set("name","Luat"),参数name赋值为Luat,立即写入文件系统
  150. -- @usage nvm.set("age",12,"SVR"),参数age赋值为12,立即写入文件系统,如果旧值不是12,会产生一个PARA_CHANGED_IND消息,携带 "age",12,"SVR" 3个参数
  151. -- @usage nvm.set("class","Class2",nil,false),参数class赋值为Class2,不写入文件系统
  152. -- @usage nvm.set("score",{chinese=100,math=99,english=98}),参数score赋值为{chinese=100,math=99,english=98},立即写入文件系统
  153. function set(k,v,r,s)
  154. local bchg = true
  155. if type(v) ~= "table" then
  156. bchg = (para[k] ~= v)
  157. end
  158. log.info("nvm.set",bchg,k,v,r,s)
  159. if bchg then
  160. para[k] = v
  161. save(s or s==nil)
  162. if r then sys.publish("PARA_CHANGED_IND",k,v,r) end
  163. end
  164. return true
  165. end
  166. --- 设置某个table类型参数的某一个索引的值
  167. -- @string k table类型的参数名
  168. -- @param kk table类型参数的某一个索引名
  169. -- @param v,table类型参数的某一个索引的新值
  170. -- @param r,设置原因,如果传入了非nil的有效参数,并且v值和旧值相比发生了改变,会产生一个TPARA_CHANGED_IND消息,携带 k,kk,v,r 4个参数
  171. -- @param s,是否立即写入到文件系统中,false不写入,其余的都写入
  172. -- @return bool或者nil,成功返回true,失败返回nil
  173. -- @usage nvm.sett("score","chinese",100),参数score["chinese"]赋值为100,立即写入文件系统
  174. -- @usage nvm.sett("score","chinese",100,"SVR"),参数score["chinese"]赋值为100,立即写入文件系统,
  175. -- 如果旧值不是100,会产生一个TPARA_CHANGED_IND消息,携带 "score","chinese",100,"SVR" 4个参数
  176. -- @usage nvm.sett("score","chinese",100,nil,false),参数class赋值为Class2,不写入文件系统
  177. function sett(k,kk,v,r,s)
  178. local bchg = true
  179. if type(v) ~= "table" then
  180. bchg = (para[k][kk] ~= v)
  181. end
  182. if bchg then
  183. para[k][kk] = v
  184. save(s or s==nil)
  185. if r then sys.publish("TPARA_CHANGED_IND",k,kk,v,r) end
  186. end
  187. return true
  188. end
  189. --- 所有参数立即写入文件系统
  190. -- @return nil
  191. -- @usage nvm.flush()
  192. function flush()
  193. save(true)
  194. end
  195. --- 读取某个参数的值
  196. -- @string k 参数名
  197. -- @return 参数值
  198. -- @usage nameValue = nvm.get("name")
  199. function get(k)
  200. return para[k]
  201. end
  202. --- 读取某个table类型参数的某一个索引的值
  203. -- @string k table类型的参数名
  204. -- @param kk table类型参数的某一个索引名
  205. -- @usage nvm.gett("score","chinese")
  206. function gett(k,kk)
  207. return para[k][kk]
  208. end
  209. --- 参数恢复出厂设置
  210. -- @return nil
  211. -- @usage nvm.restore()
  212. function restore()
  213. os.remove(paraname)
  214. os.remove(paranamebak)
  215. local fpara,fconfig = io.open(paraname,"wb"),io.open(configname,"rb")
  216. if not fconfig then fconfig = io.open(econfigname,"rb") end
  217. fpara:write(fconfig:read("*a"))
  218. fpara:close()
  219. fconfig:close()
  220. upd(true)
  221. end
  222. --- 请求删除参数文件.
  223. -- 此接口一般用在远程升级时,需要用新的config.lua覆盖原来的参数文件的场景,在此场景下,远程升级包下载成功后,在确定要重启前调用此接口
  224. -- 下次开机执行nvm.init("config.lua")时,会用新的config.lua文件自动覆盖参数文件;以后再开机就不会自动覆盖了
  225. -- 也就是说"nvm.remove()->重启->nvm.init("config.lua")"是一个仅执行一次的完整操作
  226. -- @return nil
  227. -- @usage nvm.remove()
  228. function remove()
  229. os.remove(paraname)
  230. os.remove(paranamebak)
  231. end