csvdata.lua
4.05 KB
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