Skip to content
Snippets Groups Projects
Commit 41424146 authored by dg's avatar dg
Browse files

Changed lua table.sort() function to accept any index as a second parameter,...

Changed lua table.sort() function to accept any index as a second parameter, if not a function it will assume the items to sort are tables and sort them by the given index
Improved the integrated lua profiler (only works when luajit is disabled)
Greatly improved performance when moving around the map. Map:checkAllEntities() is now much faster, FOV code is also faster


git-svn-id: http://svn.net-core.org/repos/t-engine4@1092 51575b47-30f0-44d4-a5cc-537603b46e54
parent d392f18d
No related branches found
No related tags found
No related merge requests found
......@@ -211,6 +211,8 @@ end
--- Serialization
function _M:save()
return class.save(self, {
_check_entities = true,
_check_entities_store = true,
_map = true,
_fovcache = true,
surface = true,
......@@ -309,6 +311,9 @@ function _M:loaded()
setmetatable(self.remembers, {__call = mapremember})
setmetatable(self.attrs, {__call = mapattrs})
self._check_entities = {}
self._check_entities_store = {}
self.surface = core.display.newSurface(self.viewport.width, self.viewport.height)
self.changed = true
self.finished = true
......@@ -397,6 +402,18 @@ function _M:updateMap(x, y)
p:getMapObjects(self.tiles, mos, 13)
end
-- Update entities checker for this spot
-- This is to improve speed, we create a function for each spot that checks entities it knows are there
-- This avoid a costly for iteration over a pairs() and this allows luajit to compile only code that is needed
local ce = {}
local fstr = [[p = m[%s]:check(what, x, y, ...) if p then return p end ]]
ce[#ce+1] = [[return function(self, x, y, what, ...) local p local m = self.map[x + y * self.w] ]]
for idx, e in pairs(self.map[x + y * self.w]) do ce[#ce+1] = fstr:format(idx) end
ce[#ce+1] = [[end]]
local ce = table.concat(ce)
self._check_entities[x + y * self.w] = self._check_entities_store[ce] or loadstring(ce)()
self._check_entities_store[ce] = self._check_entities[x + y * self.w]
-- Cache the map objects in the C map
self._map:setGrid(x, y, mm, mos)
......@@ -562,10 +579,7 @@ end
function _M:checkAllEntities(x, y, what, ...)
if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
if self.map[x + y * self.w] then
for _, e in pairs(self.map[x + y * self.w]) do
local p = e:check(what, x, y, ...)
if p then return p end
end
return self._check_entities[x + y * self.w](self, x, y, what, ...)
end
end
......
......@@ -80,14 +80,16 @@ function _M:computeFOV(radius, block, apply, force, no_store, cache)
local t = {x=x,y=y, dx=dx, dy=dy, sqdist=sqdist}
fov.actors[a] = t
fov.actors_dist[#fov.actors_dist+1] = a
a.__sqdist = sqdist
a:check("seen_by", self)
a:updateFOV(self, t.sqdist)
end
end, cache and game.level.map._fovcache[block])
-- Sort actors by distance (squared but we do not care)
table.sort(fov.actors_dist, function(a, b) return fov.actors[a].sqdist < fov.actors[b].sqdist end)
for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end
table.sort(fov.actors_dist, "__sqdist")
-- table.sort(fov.actors_dist, function(a, b) return a.__sqdist < b.__sqdist end)
-- for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end
-- print("Computed FOV for", self.uid, self.name, ":: seen ", #fov.actors_dist, "actors closeby")
self.fov = fov
......
......@@ -39,7 +39,12 @@ function _M:act()
-- print("lite", self.name, self.lite)
-- self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true)
-- end
self:computeFOV(self.sight or 20)
-- If the actor has no special vision we can use the default cache
if not self.special_vision then
self:computeFOV(self.sight or 20, "block_sight", nil, nil, nil, true)
else
self:computeFOV(self.sight or 20, "block_sight")
end
-- Let the AI think .... beware of Shub !
-- If AI did nothing, use energy anyway
......
......@@ -182,22 +182,28 @@ function _M:act()
end
end
-- Precompute FOV form
local fovdist = {}
for i = 0, 30 * 30 do
fovdist[i] = math.max((20 - math.sqrt(i)) / 14, 0.6)
end
function _M:playerFOV()
-- Clean FOV before computing it
game.level.map:cleanFOV()
-- Compute ESP FOV, using cache
if not game.zone.wilderness then self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true) end
if not game.zone.wilderness then self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true, true) end
if not self:attr("blind") then
-- Compute both the normal and the lite FOV, using cache
if game.zone.wilderness_see_radius then
self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist)
game.level.map:apply(x, y, math.max((20 - math.sqrt(sqdist)) / 14, 0.6))
game.level.map:apply(x, y, fovdist[sqdist])
end, true, false, true)
self:computeFOV(game.zone.wilderness_see_radius, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true)
else
self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist)
game.level.map:apply(x, y, math.max((20 - math.sqrt(sqdist)) / 14, 0.6))
game.level.map:apply(x, y, fovdist[sqdist])
end, true, false, true)
if self.lite <= 0 then game.level.map:applyLite(self.x, self.y)
else self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true) end
......
......@@ -170,14 +170,14 @@ static int lua_fov_calc_circle(lua_State *L)
}
fov.apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
fov.opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
// int i= SDL_GetTicks();
fov_settings_init(&(fov.fov_settings));
fov_settings_set_opacity_test_function(&(fov.fov_settings), map_opaque);
fov_settings_set_apply_lighting_function(&(fov.fov_settings), map_seen);
fov_circle(&(fov.fov_settings), &fov, NULL, x, y, radius+1);
map_seen(&fov, x, y, 0, 0, radius, NULL);
fov_settings_free(&(fov.fov_settings));
// printf("map display ticks %d\n",SDL_GetTicks()-i);
luaL_unref(L, LUA_REGISTRYINDEX, fov.apply_ref);
luaL_unref(L, LUA_REGISTRYINDEX, fov.opaque_ref);
if (fov.cache_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, fov.cache_ref);
......
......@@ -169,6 +169,27 @@ static int tconcat (lua_State *L) {
** Addison-Wesley, 1993.)
*/
static void stackDump (lua_State *L) {
int i=lua_gettop(L);
printf(" ---------------- Stack Dump ----------------\n" );
while( i ) {
int t = lua_type(L, i);
switch (t) {
case LUA_TSTRING:
printf("%d:`%s'\n", i, lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf("%d: %s\n",i,lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER:
printf("%d: %g\n", i, lua_tonumber(L, i));
break;
default: printf("%d: %s\n", i, lua_typename(L, t)); break;
}
i--;
}
printf("--------------- Stack Dump Finished ---------------\n" );
}
static void set2 (lua_State *L, int i, int j) {
lua_rawseti(L, 1, i);
......@@ -176,7 +197,7 @@ static void set2 (lua_State *L, int i, int j) {
}
static int sort_comp (lua_State *L, int a, int b) {
if (!lua_isnil(L, 2)) { /* function? */
if (lua_isfunction(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
......@@ -186,6 +207,17 @@ static int sort_comp (lua_State *L, int a, int b) {
lua_pop(L, 1);
return res;
}
else if (!lua_isnil(L, 2)) { /* index? */
int res;
lua_pushvalue(L, 2);
lua_gettable(L, a-1);
lua_pushvalue(L, 2);
lua_gettable(L, b-2);
res = lua_lessthan(L, -2, -1);
lua_pop(L, 2);
return res;
}
else /* a < b? */
return lua_lessthan(L, a, b);
}
......@@ -257,7 +289,9 @@ static int sort (lua_State *L) {
int n = aux_getn(L, 1);
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
{
// if (luaL_checktype(L, 2, LUA_TFUNCTION);
}
lua_settop(L, 2); /* make sure there is two arguments */
auxsort(L, 1, n);
return 0;
......
......@@ -176,7 +176,7 @@ static void set2 (lua_State *L, int i, int j) {
}
static int sort_comp (lua_State *L, int a, int b) {
if (!lua_isnil(L, 2)) { /* function? */
if (lua_isfunction(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
......@@ -186,6 +186,17 @@ static int sort_comp (lua_State *L, int a, int b) {
lua_pop(L, 1);
return res;
}
else if (!lua_isnil(L, 2)) { /* index? */
int res;
lua_pushvalue(L, 2);
lua_gettable(L, a-1);
lua_pushvalue(L, 2);
lua_gettable(L, b-2);
res = lua_lessthan(L, -2, -1);
lua_pop(L, 2);
return res;
}
else /* a < b? */
return lua_lessthan(L, a, b);
}
......@@ -257,7 +268,9 @@ static int sort (lua_State *L) {
int n = aux_getn(L, 1);
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
{
// if (luaL_checktype(L, 2, LUA_TFUNCTION);
}
lua_settop(L, 2); /* make sure there is two arguments */
auxsort(L, 1, n);
return 0;
......
......@@ -79,7 +79,7 @@ static void formats(char *s) {
/* computes new stack and new timer */
void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedefined, int currentline) {
void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedefined, int currentline) {
S->stack_level++;
lprofM_enter_function(S, file, func_name, linedefined, currentline);
}
......@@ -103,8 +103,8 @@ int lprofP_callhookOUT(lprofP_STATE* S) {
info->total_time += function_call_time;
formats(info->file_defined);
formats(info->function_name);
output("%d\t%s\t%s\t%d\t%d\t%f\t%f\n", S->stack_level, info->file_defined,
info->function_name,
output("%d\t%s\t%s:%d:%s\t%d\t%d\t%f\t%f\n", S->stack_level, info->file_defined,
info->function_name, info->line_defined, info->file_defined,
info->line_defined, info->current_line,
info->local_time, info->total_time);
/* ... now it's ok to resume the timer */
......@@ -128,7 +128,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin
function_call_time = _function_call_time;
out_filename = (_out_filename) ? (_out_filename):(OUT_FILENAME);
/* the random string to build the logname is extracted */
/* from 'tmpnam()' (the '/tmp/' part is deleted) */
randstr = tmpnam(NULL);
......@@ -155,7 +155,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin
fclose(outf);
return 0;
}
return S;
}
......@@ -174,7 +174,7 @@ lprofP_STATE* lprofP_create_profiler(float _function_call_time) {
if(!S) {
return 0;
}
return S;
}
......@@ -42,7 +42,7 @@ static void callhook(lua_State *L, lua_Debug *ar) {
lua_getinfo(L, "l", &previous_ar);
currentline = previous_ar.currentline;
}
lua_getinfo(L, "nS", ar);
if (!ar->event) {
......@@ -90,7 +90,7 @@ static int coroutine_create(lua_State *L) {
lua_pushlightuserdata(L, S);
lua_settable(L, LUA_REGISTRYINDEX);
lua_sethook(NL, (lua_Hook)callhook, LUA_MASKCALL | LUA_MASKRET, 0);
return 1;
return 1;
}
#endif
......@@ -134,7 +134,7 @@ static int profiler_init(lua_State *L) {
lua_pushlightuserdata(L, &profstate_id);
lua_pushlightuserdata(L, S);
lua_settable(L, LUA_REGISTRYINDEX);
/* use our own exit function instead */
lua_getglobal(L, "os");
lua_pushlightuserdata(L, &exit_id);
......@@ -158,7 +158,7 @@ static int profiler_init(lua_State *L) {
/* as a library. */
lprofP_callhookIN(S, "profiler_init", "(C)", -1, -1);
lua_pushboolean(L, 1);
return 1;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment