Blame view

src/shared/csvdata.lua 4.05 KB
a5486ede   zhouhaihai   csvdata 修改为 share...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  -- 对sharetable 的一层封装 实现热更新
  
  local skynet = require "skynet"
  local service = require "skynet.service"
  local sharetable = require "skynet.sharetable"
  
  local function sharetable_service()
  	local skynet = require "skynet"
  	local sharetable = require "skynet.sharetable"
  
  	local files = {}	-- filename
  	local csvdata = {}
  
  	local initfile = {
  		["src/csvdata/init.lua"] = {},
  		["src/csvdata/init_adv.lua"] = {},
  	}
  
  	function csvdata.query(source, filename)
  		files[filename] = files[filename] or {}
  		files[filename][source] = 1
  	end
  
  	function csvdata.close(source)
  		for filename, info in pairs(files) do
  			info[source] = nil
  		end
  	end
  
  	function csvdata.realName(file)
  		if string.match(file, "Csv$") then
  			if initfile["src/csvdata/init.lua"] and initfile["src/csvdata/init.lua"][file] then
  				file = initfile["src/csvdata/init.lua"][file]
  			elseif initfile["src/csvdata/init_adv.lua"] and initfile["src/csvdata/init_adv.lua"][file] then
  				file = initfile["src/csvdata/init_adv.lua"][file]
  			end
  			file = "src/" .. file .. ".lua"
  		end
  		return file
  	end
  
  	function csvdata.hotfix(_, ...)
  		local now = skynet.timex()
  
  		local filenames = {...}
  
  		local needHotfix = {}
  		for _, filename in ipairs(filenames) do
  			-- 更新下
  			skynet.error(string.format("hotfix_csvdata time: %s, file: %s", now, filename))
  
  			if initfile[filename] then
  				sharetable.loadfile(filename)
  				sharetable.update(filename)
  			else
  				sharetable.loadfile(csvdata.realName(filename))
  			end
  
  			if files[filename] then
  				for source, _ in pairs(files[filename]) do
  					needHotfix[source] = needHotfix[source] or {}
  					table.insert(needHotfix[source], filename)
  				end
  			end
  		end
  
  		for source, files in pairs(needHotfix) do
  			skynet.send(source, "csvdata", "hotfix", table.unpack(files))
  		end
  	end
  
  	skynet.dispatch("lua", function(_,source,cmd,...)
  		skynet.ignoreret()
  		csvdata[cmd](source,...)
  	end)
  
  	skynet.register_protocol {
  		name = "csvdata",
  		id = 102,
  		pack = skynet.pack,
  		unpack = skynet.unpack,
  	}
  
  	-- 初始化csvdata
  	skynet.start(function()
  		for file, _ in pairs(initfile) do
  			sharetable.loadfile(file)
  			local init = sharetable.query(file)
  			if not init then
  				error("csvdata load init file error " .. file)
  				return
  			end
  			initfile[file] = init
  			for _, one in pairs(init) do
  				sharetable.loadfile("src/" .. one .. ".lua")
  			end
  		end
  	end)
  end
  
  
  local cache = {}
  local csvdata
  
  local function load_csvdata(t, key)
  	if key == "address" then
  		t.address = service.new("csvdata", sharetable_service)
  		return t.address
  	else
  		if cache[key] then return cache[key] end
  
  		local realName = csvdata.realName(key)
  
  		local tab = sharetable.query(realName)
  		if not tab then
  			error("dont have csvdata :  " .. realName)
  			return
  		end
  		cache[key] = tab
  		-- 增加引用
  		skynet.send(csvdata.address, "lua", "query", key)
  		return tab
  	end
  end
  
  local function close_hotfix(t)
  	local addr = rawget(t, "address")
  	if addr then
  		skynet.send(addr, "lua", "close")
  	end
  end
  
  csvdata = setmetatable ( {} , {
  	__index = load_csvdata,
  	__gc = close_hotfix,
  })
  
  function csvdata.init()
  	return csvdata.address
  end
  
  function csvdata.hotfix(...)
  	skynet.send(csvdata.address, "lua", "hotfix", ...)
  end
  
  function csvdata.realName(file)
  	if string.match(file, "Csv$") then
  		if csvdata["src/csvdata/init.lua"] and csvdata["src/csvdata/init.lua"][file] then
  			file = csvdata["src/csvdata/init.lua"][file]
  		elseif csvdata["src/csvdata/init_adv.lua"] and csvdata["src/csvdata/init_adv.lua"][file] then
  			file = csvdata["src/csvdata/init_adv.lua"][file]
  		end
  		file = "src/" .. file .. ".lua"
  	end
  	return file
  end
  
  local function update(file)
  	-- 更新一下
  	if cache[file] then
  		sharetable.update(csvdata.realName(file))
  	end
  end
  
  skynet.register_protocol {
  	name = "csvdata",
  	id = 102,
  	pack = skynet.pack,
  	unpack = skynet.unpack,
  	dispatch = function(_, _, cmd, ...)
  		skynet.ignoreret()
  		if cmd == "hotfix" then
  			-- skynet.error("csvdara hotfix update", ...)
  			local files = {...}
  			for _, file in ipairs(files) do
  				update(file)
  			end
  			return
  		end
  	end,
  }
  
  return csvdata