Lua: Add on_idle() and on_timer()
This commit is contained in:
parent
528628b233
commit
44233e3897
5 changed files with 134 additions and 11 deletions
|
@ -15,6 +15,8 @@ void push_keygroup_parameters(lua_State* LS, const struct keygroup::parameters&
|
|||
extern lua_render_context* lua_render_ctx;
|
||||
extern controller_frame* lua_input_controllerdata;
|
||||
extern bool lua_booted_flag;
|
||||
extern uint64_t lua_idle_hook_time;
|
||||
extern uint64_t lua_timer_hook_time;
|
||||
|
||||
template<typename T>
|
||||
T get_numeric_argument(lua_State* LS, unsigned argindex, const char* fname)
|
||||
|
|
|
@ -77,6 +77,8 @@ void lua_callback_do_frame_emulated() throw();
|
|||
void lua_callback_do_rewind() throw();
|
||||
void lua_callback_do_readwrite() throw();
|
||||
void lua_callback_startup() throw();
|
||||
void lua_callback_do_idle() throw();
|
||||
void lua_callback_do_timer() throw();
|
||||
void lua_callback_pre_load(const std::string& name) throw();
|
||||
void lua_callback_err_load(const std::string& name) throw();
|
||||
void lua_callback_post_load(const std::string& name, bool was_state) throw();
|
||||
|
@ -87,6 +89,11 @@ void lua_callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index
|
|||
void lua_callback_quit() throw();
|
||||
void lua_callback_keyhook(const std::string& key, const struct keygroup::parameters& p) throw();
|
||||
|
||||
#define LUA_TIMED_HOOK_IDLE 0
|
||||
#define LUA_TIMED_HOOK_TIMER 1
|
||||
|
||||
uint64_t lua_timed_hook(int timer) throw();
|
||||
|
||||
extern bool lua_supported;
|
||||
extern bool lua_requests_repaint;
|
||||
extern bool lua_requests_subframe_paint;
|
||||
|
|
|
@ -13,6 +13,8 @@ void lua_callback_do_rewind() throw() {}
|
|||
void lua_callback_do_frame_emulated() throw() {}
|
||||
void lua_callback_do_readwrite() throw() {}
|
||||
void lua_callback_startup() throw() {}
|
||||
void lua_callback_do_idle() throw() {}
|
||||
void lua_callback_do_timer() throw() {}
|
||||
void lua_callback_pre_load(const std::string& name) throw() {}
|
||||
void lua_callback_err_load(const std::string& name) throw() {}
|
||||
void lua_callback_post_load(const std::string& name, bool was_state) throw() {}
|
||||
|
@ -24,6 +26,9 @@ void lua_callback_quit() throw() {}
|
|||
void lua_callback_keyhook(const std::string& key, const struct keygroup::parameters& p) throw() {}
|
||||
void init_lua() throw() {}
|
||||
void quit_lua() throw() {}
|
||||
uint64_t lua_timed_hook(int timer) throw() { return 0x7EFFFFFFFFFFFFFFULL; }
|
||||
|
||||
|
||||
bool lua_requests_repaint = false;
|
||||
bool lua_requests_subframe_paint = false;
|
||||
bool lua_supported = false;
|
||||
|
@ -45,6 +50,9 @@ extern "C" {
|
|||
#include <lualib.h>
|
||||
}
|
||||
|
||||
uint64_t lua_idle_hook_time = 0x7EFFFFFFFFFFFFFFULL;
|
||||
uint64_t lua_timer_hook_time = 0x7EFFFFFFFFFFFFFFULL;
|
||||
|
||||
namespace
|
||||
{
|
||||
globalwrap<std::map<std::string, lua_function*>> functions;
|
||||
|
@ -405,6 +413,22 @@ void lua_callback_do_rewind() throw()
|
|||
run_lua_cb(0);
|
||||
}
|
||||
|
||||
void lua_callback_do_idle() throw()
|
||||
{
|
||||
lua_idle_hook_time = 0x7EFFFFFFFFFFFFFFULL;
|
||||
if(!callback_exists("on_idle"))
|
||||
return;
|
||||
run_lua_cb(0);
|
||||
}
|
||||
|
||||
void lua_callback_do_timer() throw()
|
||||
{
|
||||
lua_timer_hook_time = 0x7EFFFFFFFFFFFFFFULL;
|
||||
if(!callback_exists("on_timer"))
|
||||
return;
|
||||
run_lua_cb(0);
|
||||
}
|
||||
|
||||
void lua_callback_do_frame_emulated() throw()
|
||||
{
|
||||
if(!callback_exists("on_frame_emulated"))
|
||||
|
@ -552,6 +576,21 @@ void quit_lua() throw()
|
|||
lua_close(lua_initialized);
|
||||
}
|
||||
|
||||
|
||||
#define LUA_TIMED_HOOK_IDLE 0
|
||||
#define LUA_TIMED_HOOK_TIMER 1
|
||||
|
||||
uint64_t lua_timed_hook(int timer) throw()
|
||||
{
|
||||
switch(timer) {
|
||||
case LUA_TIMED_HOOK_IDLE:
|
||||
return lua_idle_hook_time;
|
||||
case LUA_TIMED_HOOK_TIMER:
|
||||
return lua_timer_hook_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool lua_requests_repaint = false;
|
||||
bool lua_requests_subframe_paint = false;
|
||||
bool lua_supported = true;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include "core/command.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
#include "core/lua.hpp"
|
||||
#include "core/misc.hpp"
|
||||
#include "core/render.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
@ -118,6 +120,8 @@ keypress::keypress(modifier_set mod, keygroup& _key, keygroup& _key2, short _val
|
|||
|
||||
namespace
|
||||
{
|
||||
bool queue_function_run = false;
|
||||
|
||||
function_ptr_command<> identify_key("show-plugins", "Show plugins in use",
|
||||
"Syntax: show-plugins\nShows plugins in use.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
|
@ -381,6 +385,7 @@ namespace
|
|||
if(k.key2)
|
||||
k.key2->set_position(k.value, k.modifiers);
|
||||
queue_lock->lock();
|
||||
queue_function_run = true;
|
||||
}
|
||||
//Flush commands.
|
||||
while(!commands.empty()) {
|
||||
|
@ -389,6 +394,7 @@ namespace
|
|||
queue_lock->unlock();
|
||||
command::invokeC(c);
|
||||
queue_lock->lock();
|
||||
queue_function_run = true;
|
||||
}
|
||||
//Flush functions.
|
||||
while(!functions.empty()) {
|
||||
|
@ -398,6 +404,7 @@ namespace
|
|||
f.first(f.second);
|
||||
queue_lock->lock();
|
||||
++functions_executed;
|
||||
queue_function_run = true;
|
||||
}
|
||||
queue_condition->signal();
|
||||
} catch(std::bad_alloc& e) {
|
||||
|
@ -409,28 +416,62 @@ namespace
|
|||
if(!unlocked)
|
||||
queue_lock->unlock();
|
||||
}
|
||||
|
||||
uint64_t on_idle_time;
|
||||
uint64_t on_timer_time;
|
||||
void reload_lua_timers()
|
||||
{
|
||||
on_idle_time = lua_timed_hook(LUA_TIMED_HOOK_IDLE);
|
||||
on_timer_time = lua_timed_hook(LUA_TIMED_HOOK_TIMER);
|
||||
queue_function_run = false;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXWAIT 10000
|
||||
#define MAXWAIT 5000000ULL
|
||||
|
||||
|
||||
void platform::flush_command_queue() throw()
|
||||
{
|
||||
reload_lua_timers();
|
||||
queue_function_run = false;
|
||||
if(modal_pause || normal_pause)
|
||||
freeze_time(get_utime());
|
||||
init_threading();
|
||||
bool run_idle = false;
|
||||
while(true) {
|
||||
uint64_t now = get_utime();
|
||||
if(now >= on_timer_time) {
|
||||
lua_callback_do_timer();
|
||||
reload_lua_timers();
|
||||
}
|
||||
if(run_idle) {
|
||||
lua_callback_do_idle();
|
||||
reload_lua_timers();
|
||||
run_idle = false;
|
||||
}
|
||||
mutex::holder h(*queue_lock);
|
||||
internal_run_queues(true);
|
||||
if(!pausing_allowed)
|
||||
break;
|
||||
uint64_t now = get_utime();
|
||||
if(queue_function_run)
|
||||
reload_lua_timers();
|
||||
now = get_utime();
|
||||
uint64_t waitleft = 0;
|
||||
waitleft = (now < continue_time) ? (continue_time - now) : 0;
|
||||
waitleft = (modal_pause || normal_pause) ? MAXWAIT : waitleft;
|
||||
waitleft = (waitleft > MAXWAIT) ? MAXWAIT : waitleft;
|
||||
if(waitleft > 0)
|
||||
queue_condition->wait(waitleft);
|
||||
else
|
||||
waitleft = min(waitleft, MAXWAIT);
|
||||
if(waitleft > 0) {
|
||||
if(now >= on_idle_time) {
|
||||
run_idle = true;
|
||||
waitleft = 0;
|
||||
}
|
||||
if(on_idle_time >= now)
|
||||
waitleft = min(waitleft, on_idle_time - now);
|
||||
if(on_timer_time >= now)
|
||||
waitleft = min(waitleft, on_timer_time - now);
|
||||
if(waitleft > 0)
|
||||
queue_condition->wait(waitleft);
|
||||
} else
|
||||
break;
|
||||
//If we had to wait, check queues at least once more.
|
||||
}
|
||||
|
@ -445,18 +486,41 @@ void platform::set_paused(bool enable) throw()
|
|||
|
||||
void platform::wait(uint64_t usec) throw()
|
||||
{
|
||||
reload_lua_timers();
|
||||
continue_time = get_utime() + usec;
|
||||
init_threading();
|
||||
bool run_idle = false;
|
||||
while(true) {
|
||||
uint64_t now = get_utime();
|
||||
if(now >= on_timer_time) {
|
||||
lua_callback_do_timer();
|
||||
reload_lua_timers();
|
||||
}
|
||||
if(run_idle) {
|
||||
lua_callback_do_idle();
|
||||
run_idle = false;
|
||||
reload_lua_timers();
|
||||
}
|
||||
mutex::holder h(*queue_lock);
|
||||
internal_run_queues(true);
|
||||
uint64_t now = get_utime();
|
||||
if(queue_function_run)
|
||||
reload_lua_timers();
|
||||
now = get_utime();
|
||||
uint64_t waitleft = 0;
|
||||
waitleft = (now < continue_time) ? (continue_time - now) : 0;
|
||||
waitleft = (waitleft > MAXWAIT) ? MAXWAIT : waitleft;
|
||||
if(waitleft > 0)
|
||||
queue_condition->wait(waitleft);
|
||||
else
|
||||
waitleft = min(MAXWAIT, waitleft);
|
||||
if(waitleft > 0) {
|
||||
if(now >= on_idle_time) {
|
||||
run_idle = true;
|
||||
waitleft = 0;
|
||||
}
|
||||
if(on_idle_time >= now)
|
||||
waitleft = min(waitleft, on_idle_time - now);
|
||||
if(on_timer_time >= now)
|
||||
waitleft = min(waitleft, on_timer_time - now);
|
||||
if(waitleft > 0)
|
||||
queue_condition->wait(waitleft);
|
||||
} else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,4 +58,15 @@ namespace
|
|||
lua_pushnumber(LS, t % 1000000);
|
||||
return 2;
|
||||
});
|
||||
|
||||
function_ptr_luafun lua_idle_time("set_idle_timeout", [](lua_State* LS, const std::string& fname) -> int {
|
||||
lua_idle_hook_time = get_utime() + get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
|
||||
return 0;
|
||||
});
|
||||
|
||||
function_ptr_luafun lua_timer_time("set_timer_timeout", [](lua_State* LS, const std::string& fname) -> int {
|
||||
lua_timer_hook_time = get_utime() + get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
|
||||
return 0;
|
||||
});
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue