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

Some player profile rpc calls can be asynchronous to not delay gameplay

git-svn-id: http://svn.net-core.org/repos/t-engine4@985 51575b47-30f0-44d4-a5cc-537603b46e54
parent edaecdc1
No related branches found
No related tags found
No related merge requests found
...@@ -42,6 +42,8 @@ function _M:init(keyhandler) ...@@ -42,6 +42,8 @@ function _M:init(keyhandler)
self.mouse:setCurrent() self.mouse:setCurrent()
self.uniques = {} self.uniques = {}
self.__threads = {}
end end
function _M:loaded() function _M:loaded()
...@@ -208,3 +210,27 @@ end ...@@ -208,3 +210,27 @@ end
--- Requests the game to save --- Requests the game to save
function _M:saveGame() function _M:saveGame()
end end
--- Save a thread into the thread pool
-- Threads will be auto join'ed when the module exits or when it can<br/>
-- ALL THREADS registered *MUST* return true when they exit
function _M:registerThread(th, linda)
print("[THREAD] registering", th, linda, #self.__threads+1)
self.__threads[#self.__threads+1] = {th=th, linda=linda}
return #self.__threads
end
--- Try to join all registered threads
-- @param timeout the time in seconds to wait for each thread
function _M:joinThreads(timeout)
for i = #self.__threads, 1, -1 do
local th = self.__threads[i].th
print("[THREAD] Thread join", i, th)
local v, err = th:join(timeout)
if err then print("[THREAD] error", th) error(err) end
if v then
print("[THREAD] Thread result", i, th, "=>", v)
table.remove(self.__threads, i)
end
end
end
...@@ -45,6 +45,11 @@ function _M:tick() ...@@ -45,6 +45,11 @@ function _M:tick()
engine.GameEnergyBased.tick(self) engine.GameEnergyBased.tick(self)
self.turn = self.turn + 1 self.turn = self.turn + 1
self:onTurn() self:onTurn()
-- Try to join threads if any, every hundred turns
if self.turn % 100 == 0 then
self:joinThreads(0)
end
end end
end end
......
...@@ -95,6 +95,8 @@ function _M:loadDefinition(dir, team) ...@@ -95,6 +95,8 @@ function _M:loadDefinition(dir, team)
end end
profile:loadModuleProfile(mod.short_name) profile:loadModuleProfile(mod.short_name)
local m = require(mod.starter) local m = require(mod.starter)
m[1].__session_time_played_start = os.time()
m[1].__mod_info = mod
print("[MODULE LOADER] loading module", mod.long_name, "["..mod.starter.."]", "::", m[1] and m[1].__CLASSNAME, m[2] and m[2].__CLASSNAME) print("[MODULE LOADER] loading module", mod.long_name, "["..mod.starter.."]", "::", m[1] and m[1].__CLASSNAME, m[2] and m[2].__CLASSNAME)
return m[1], m[2] return m[1], m[2]
end end
......
...@@ -21,6 +21,7 @@ require "engine.class" ...@@ -21,6 +21,7 @@ require "engine.class"
local http = require "socket.http" local http = require "socket.http"
local url = require "socket.url" local url = require "socket.url"
local ltn12 = require "ltn12" local ltn12 = require "ltn12"
local lanes = require "lanes"
require "Json2" require "Json2"
------------------------------------------------------------ ------------------------------------------------------------
...@@ -187,10 +188,33 @@ end ...@@ -187,10 +188,33 @@ end
----------------------------------------------------------------------- -----------------------------------------------------------------------
function _M:rpc(data) function _M:rpc(data)
print("[ONLINE PROFILE] rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action) -- We can work in asynchronous mode, to not delay the main game execution
local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data))) if data.async and game and type(game) == "table" and not game.refuse_threads then
if not body then return end data.async = nil
return json.decode(body) local l = lanes.linda()
function handler(data)
local http = require "socket.http"
local url = require "socket.url"
require "Json2"
print("[ONLINE PROFILE] async rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action)
local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data)))
if not body then l:send("final", nil)
else l:send("final", json.decode(body))
end
return true
end
local th = lanes.gen("*", handler)(data)
-- Tell the game to monitor this thread and end it when it's done
game:registerThread(th, l)
else
print("[ONLINE PROFILE] rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action)
local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data)))
if not body then return end
return json.decode(body)
end
end end
function _M:tryAuth() function _M:tryAuth()
...@@ -229,7 +253,7 @@ function _M:setConfigs(module, name, val) ...@@ -229,7 +253,7 @@ function _M:setConfigs(module, name, val)
if type(val) ~= "string" then val = serialize(val) end if type(val) ~= "string" then val = serialize(val) end
local data = self:rpc{action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data={[name] = val}} local data = self:rpc{async=true, action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data={[name] = val}}
if not data then return end if not data then return end
print("[ONLINE PROFILE] saved ", module, name, val) print("[ONLINE PROFILE] saved ", module, name, val)
end end
...@@ -243,7 +267,7 @@ function _M:syncOnline(module) ...@@ -243,7 +267,7 @@ function _M:syncOnline(module)
local data = {} local data = {}
for k, v in pairs(sync) do if k ~= "online" then data[k] = serialize(v) end end for k, v in pairs(sync) do if k ~= "online" then data[k] = serialize(v) end end
local data = self:rpc{action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data=data} local data = self:rpc{async=true, action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data=data}
if not data then return end if not data then return end
print("[ONLINE PROFILE] saved ", module) print("[ONLINE PROFILE] saved ", module)
end end
......
...@@ -489,6 +489,15 @@ function util.findFreeGrid(sx, sy, radius, block, what) ...@@ -489,6 +489,15 @@ function util.findFreeGrid(sx, sy, radius, block, what)
end end
function util.showMainMenu(no_reboot) function util.showMainMenu(no_reboot)
if game and type(game) == "table" and game.__session_time_played_start then
profile.generic.modules_played = profile.generic.modules_played or {}
profile.generic.modules_played[game.__mod_info.short_name] = (profile.generic.modules_played[game.__mod_info.short_name] or 0) + (os.time() - game.__session_time_played_start)
profile:saveGenericProfile("modules_played", profile.generic.modules_played)
end
-- Join threads
if game and type(game) == "table" then game:joinThreads(30) end
if no_reboot then if no_reboot then
local Menu = require("special.mainmenu.class.Game") local Menu = require("special.mainmenu.class.Game")
game = Menu.new() game = Menu.new()
......
...@@ -35,6 +35,7 @@ function _M:init() ...@@ -35,6 +35,7 @@ function _M:init()
engine.Game.init(self, engine.KeyBind.new()) engine.Game.init(self, engine.KeyBind.new())
self.background = core.display.loadImage("/data/gfx/mainmenu/background.png") self.background = core.display.loadImage("/data/gfx/mainmenu/background.png")
self.refuse_threads = true
end end
function _M:run() function _M:run()
......
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