Commit 0ac3b4862dec9b14e74849c3fc49da64b64bd239

Authored by DarkGod
2 parents 4b5509bb 8862c1b1

Merge branch 'cache_for_particles' into 'master'

Faster!

This merge request consists of several independent commits which aim at making ToME4 faster:
1. Add cache for particles & shaders to avoid loadfile & loadstring in game;
2. Adjust the record of recent logs, making it faster and takes less space under extreme situation; 
3. Add cache for ShowChatLog dialog, making the scrolling smoother;
4. Reduce the frequency of player's 'hit_warning' particle effects, which might spam too much (each damage number may create a particle effect).

See merge request !749
... ... @@ -24,6 +24,7 @@ require "engine.class"
24 24 -- @classmod engine.Particles
25 25 module(..., package.seeall, class.make)
26 26
  27 +_M.loaded_particles = {}
27 28 local __particles_gl = {}
28 29 setmetatable(__particles_gl, {__mode="v"})
29 30
... ... @@ -62,8 +63,20 @@ function _M:loaded()
62 63 print("[PARTICLES] system"..self.def.." does not exist, replacing with dummy")
63 64 self.def = "dummy"
64 65 end
65   -
66   - local f, err = loadfile("/data/gfx/particles/"..self.def..".lua")
  66 +
  67 + local f, err
  68 + do local file = "/data/gfx/particles/"..self.def..".lua"
  69 + if config.settings.cheat then
  70 + f, err = loadfile(file)
  71 + else
  72 + local cached = _M.loaded_particles[file]
  73 + if not cached then
  74 + cached = { loadfile(file) }
  75 + _M.loaded_particles[file] = cached
  76 + end
  77 + f, err = unpack(cached)
  78 + end
  79 + end
67 80 if not f and err then error(err) end
68 81 local t = self.args or {}
69 82 local _
... ...
... ... @@ -37,7 +37,6 @@ _M.current_save = false
37 37 _M.hotkeys_file = "/save/quick_hotkeys"
38 38 _M.md5_types = {}
39 39
40   -_M.TRUNCATE_PRINTLOG_TO = 5000
41 40
42 41 --- Init a savefile
43 42 -- @param savefile the name of the savefile, usually the player's name. It will be sanitized so dont bother doing it
... ... @@ -272,7 +271,6 @@ function _M:saveGame(game, no_dialog)
272 271 savefile_pipe:pushGeneric("saveGame_md5", function() self:md5Upload("game", self:nameSaveGame(game)) end)
273 272
274 273 local f = fs.open(self.save_dir.."last_log.txt", "w")
275   - truncate_printlog(self.TRUNCATE_PRINTLOG_TO)
276 274 local log = get_printlog()
277 275 for _, line in ipairs(log) do
278 276 local max = 1
... ...
... ... @@ -24,6 +24,7 @@ require "engine.class"
24 24 -- @classmod engine.Shader
25 25 module(..., package.seeall, class.make)
26 26
  27 +_M.loaded_shaders = {}
27 28 _M.verts = {}
28 29 _M.frags = {}
29 30 _M.progsperm = {}
... ... @@ -176,13 +177,31 @@ function _M:loaded()
176 177 end
177 178 else
178 179 print("[SHADER] Loading from /data/gfx/shaders/"..self.name..".lua")
179   - local f, err = loadfile("/data/gfx/shaders/"..self.name..".lua")
180   - if not f and err then
  180 + local f, err
  181 + do local file = "/data/gfx/shaders/" .. self.name .. ".lua"
181 182 if config.settings.cheat then
182   - error(err)
  183 + f, err = loadfile(file)
183 184 else
184   - print("[SHADER] "..self.name.." not found, using fallback")
185   - f, err = loadfile("/data/gfx/shaders/fallback.lua")
  185 + local cached = _M.loaded_shaders[file]
  186 + if not cached then
  187 + cached = { loadfile(file) }
  188 + _M.loaded_shaders[file] = cached
  189 + end
  190 + f, err = unpack(cached)
  191 + end
  192 + if not f and err then
  193 + if config.settings.cheat then
  194 + error(err)
  195 + else
  196 + print("[SHADER] "..self.name.." not found, using fallback")
  197 + file = "/data/gfx/shaders/fallback.lua"
  198 + local cached = _M.loaded_shaders[file]
  199 + if not cached then
  200 + cached = { loadfile(file) }
  201 + _M.loaded_shaders[file] = cached
  202 + end
  203 + f, err = unpack(cached)
  204 + end
186 205 end
187 206 end
188 207 setfenv(f, setmetatable(self.args or {}, {__index=_G}))
... ...
... ... @@ -81,7 +81,6 @@ function _M:init(errs)
81 81 fs.mkdir(errlogdir)
82 82 local errfile = errlogdir.."/"..os.date("%Y-%m-%d_%H-%M-%S")..".txt"
83 83 local f = fs.open(errfile, "w")
84   - truncate_printlog(5000)
85 84 local log = get_printlog()
86 85 for _, line in ipairs(log) do
87 86 local max = 1
... ...
... ... @@ -65,19 +65,26 @@ end
65 65
66 66 local printlog = {}
67 67 local oprint = print
  68 +local cur_index = 0
  69 +local recent_print_log_max_size = 5000
  70 +
68 71 function print(...)
69 72 local t = {}
70 73 for k, e in pairs{...} do t[k] = tostring(e) end
71   - printlog[#printlog+1] = t
72 74 oprint(...)
  75 + cur_index = math.max(1, (cur_index + 1) % recent_print_log_max_size)
  76 + printlog[cur_index] = t
73 77 end
74 78
75 79 function get_printlog()
76   - return printlog
77   -end
78   -
79   -function truncate_printlog(nb)
80   - while #printlog > nb do table.remove(printlog, 1) end
  80 + local log_sequence = { }
  81 + for index = cur_index + 1, #printlog do
  82 + log_sequence[#log_sequence + 1] = printlog[index]
  83 + end
  84 + for index = 1, cur_index do
  85 + log_sequence[#log_sequence + 1] = printlog[index]
  86 + end
  87 + return log_sequence
81 88 end
82 89
83 90 local rngavg = rng.avg
... ...
... ... @@ -1818,7 +1818,6 @@ function _M:onTurn()
1818 1818
1819 1819 if self.turn % 500 ~= 0 then return end
1820 1820 self:dieClonesDie()
1821   - truncate_printlog(Savefile.TRUNCATE_PRINTLOG_TO)
1822 1821 end
1823 1822
1824 1823 function _M:updateFOV()
... ...
... ... @@ -791,9 +791,10 @@ function _M:onTakeHit(value, src, death_note)
791 791 end
792 792
793 793 -- Hit direction warning
794   - if src.x and src.y and (self.x ~= src.x or self.y ~= src.y) then
  794 + if not self.turn_procs.__hit_warning and src.x and src.y and (self.x ~= src.x or self.y ~= src.y) then
795 795 local range = core.fov.distance(src.x, src.y, self.x, self.y)
796 796 if range > 1 then
  797 + self.turn_procs.__hit_warning = true
797 798 local angle = math.atan2(src.y - self.y, src.x - self.x)
798 799 game.level.map:particleEmitter(self.x, self.y, 1, "hit_warning", {angle=math.deg(angle)})
799 800 end
... ...
... ... @@ -62,7 +62,8 @@ function _M:init(title, shadow, log, chat)
62 62
63 63 self.scrollbar = Slider.new{size=self.h - 20, max=0}
64 64 self.line_size = setmetatable({}, {__mode='k'})
65   -
  65 + self.cache = {}
  66 + setmetatable(self.cache, {__mode="v"})
66 67 self:switchTo(self.last_tab or "__log")
67 68 end
68 69
... ... @@ -256,7 +257,15 @@ function _M:setScroll(i, do_shifty_thing)
256 257 local str = self.lines[i].str
257 258 local size = self.line_size[str] or 1
258 259 if cur + size > self.scroll then
259   - local gen = self.font:draw(str, self.iw - 10, 255, 255, 255, false, true)
  260 + local gen
  261 + if config.settings.cheat then
  262 + gen = self.font:draw(str, self.iw - 10, 255, 255, 255, false, true)
  263 + elseif self.cache[str] then
  264 + gen = self.cache[str]
  265 + else
  266 + gen = self.font:draw(str, self.iw - 10, 255, 255, 255, false, true)
  267 + self.cache[str] = gen
  268 + end
260 269 if size ~= #gen then
261 270 self.line_size[str] = #gen
262 271 shift = shift + #gen - size
... ...