mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-22 15:39:52 +00:00
[lua] Add Timer() type (fix #3251)
This commit is contained in:
parent
835aa3f83d
commit
c2f8335891
@ -209,6 +209,7 @@ if(ENABLE_SCRIPTING)
|
|||||||
script/tile_class.cpp
|
script/tile_class.cpp
|
||||||
script/tileset_class.cpp
|
script/tileset_class.cpp
|
||||||
script/tilesets_class.cpp
|
script/tilesets_class.cpp
|
||||||
|
script/timer_class.cpp
|
||||||
script/tool_class.cpp
|
script/tool_class.cpp
|
||||||
script/values.cpp
|
script/values.cpp
|
||||||
script/version_class.cpp
|
script/version_class.cpp
|
||||||
|
@ -192,6 +192,7 @@ void register_theme_classes(lua_State* L);
|
|||||||
void register_tile_class(lua_State* L);
|
void register_tile_class(lua_State* L);
|
||||||
void register_tileset_class(lua_State* L);
|
void register_tileset_class(lua_State* L);
|
||||||
void register_tilesets_class(lua_State* L);
|
void register_tilesets_class(lua_State* L);
|
||||||
|
void register_timer_class(lua_State* L);
|
||||||
void register_tool_class(lua_State* L);
|
void register_tool_class(lua_State* L);
|
||||||
void register_version_class(lua_State* L);
|
void register_version_class(lua_State* L);
|
||||||
void register_websocket_class(lua_State* L);
|
void register_websocket_class(lua_State* L);
|
||||||
@ -472,6 +473,7 @@ Engine::Engine()
|
|||||||
register_tile_class(L);
|
register_tile_class(L);
|
||||||
register_tileset_class(L);
|
register_tileset_class(L);
|
||||||
register_tilesets_class(L);
|
register_tilesets_class(L);
|
||||||
|
register_timer_class(L);
|
||||||
register_tool_class(L);
|
register_tool_class(L);
|
||||||
register_version_class(L);
|
register_version_class(L);
|
||||||
#if ENABLE_WEBSOCKET
|
#if ENABLE_WEBSOCKET
|
||||||
|
171
src/app/script/timer_class.cpp
Normal file
171
src/app/script/timer_class.cpp
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2022-2023 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "app/script/engine.h"
|
||||||
|
#include "app/script/luacpp.h"
|
||||||
|
#include "ui/timer.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class Timer : public ui::Timer {
|
||||||
|
public:
|
||||||
|
Timer() : ui::Timer(100) { }
|
||||||
|
|
||||||
|
int runningRef() const {
|
||||||
|
return m_runningRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refTimer(lua_State* L) {
|
||||||
|
if (m_runningRef == LUA_REFNIL) {
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
m_runningRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrefTimer(lua_State* L) {
|
||||||
|
if (m_runningRef != LUA_REFNIL) {
|
||||||
|
luaL_unref(L, LUA_REGISTRYINDEX, m_runningRef);
|
||||||
|
m_runningRef = LUA_REFNIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Reference used to keep the timer alive (so it's not garbage
|
||||||
|
// collected) when it's running.
|
||||||
|
int m_runningRef = LUA_REFNIL;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Timer_new(lua_State* L)
|
||||||
|
{
|
||||||
|
auto timer = push_new<Timer>(L);
|
||||||
|
|
||||||
|
if (lua_istable(L, 1)) {
|
||||||
|
auto type = lua_getfield(L, 1, "interval");
|
||||||
|
if (type != LUA_TNIL)
|
||||||
|
timer->setInterval(std::max(1, int(lua_tonumber(L, -1) * 1000.0)));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
type = lua_getfield(L, 1, "ontick");
|
||||||
|
if (type == LUA_TFUNCTION) {
|
||||||
|
lua_pushvalue(L, -1); // Copy the function in the stack
|
||||||
|
lua_setuservalue(L, -3); // Put the function as uservalue of the timer
|
||||||
|
|
||||||
|
timer->Tick.connect(
|
||||||
|
[timer, L]() {
|
||||||
|
if (timer->runningRef() == LUA_REFNIL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get the timer, and get the function that is inside the
|
||||||
|
// timer uservalue
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, timer->runningRef());
|
||||||
|
lua_getuservalue(L, -1);
|
||||||
|
if (lua_isfunction(L, -1)) {
|
||||||
|
if (lua_pcall(L, 0, 0, 0)) {
|
||||||
|
if (const char* s = lua_tostring(L, -1))
|
||||||
|
App::instance()
|
||||||
|
->scriptEngine()
|
||||||
|
->consolePrint(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_pop(L, 1); // Pop the value which should have been a function
|
||||||
|
}
|
||||||
|
lua_pop(L, 1); // Pop timer
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex) {
|
||||||
|
App::instance()
|
||||||
|
->scriptEngine()
|
||||||
|
->consolePrint(ex.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timer_gc(lua_State* L)
|
||||||
|
{
|
||||||
|
auto obj = get_obj<Timer>(L, 1);
|
||||||
|
obj->~Timer();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timer_start(lua_State* L)
|
||||||
|
{
|
||||||
|
auto obj = get_obj<Timer>(L, 1);
|
||||||
|
obj->start();
|
||||||
|
obj->refTimer(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timer_stop(lua_State* L)
|
||||||
|
{
|
||||||
|
auto obj = get_obj<Timer>(L, 1);
|
||||||
|
obj->stop();
|
||||||
|
obj->unrefTimer(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timer_get_interval(lua_State* L)
|
||||||
|
{
|
||||||
|
const auto timer = get_obj<Timer>(L, 1);
|
||||||
|
lua_pushnumber(L, double(timer->interval()) / 1000.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timer_set_interval(lua_State* L)
|
||||||
|
{
|
||||||
|
const auto timer = get_obj<Timer>(L, 1);
|
||||||
|
int interval = int(lua_tonumber(L, 2) * 1000.0);
|
||||||
|
timer->setInterval(std::max(1, interval));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timer_get_isRunning(lua_State* L)
|
||||||
|
{
|
||||||
|
const auto timer = get_obj<Timer>(L, 1);
|
||||||
|
lua_pushboolean(L, timer->isRunning());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const luaL_Reg Timer_methods[] = {
|
||||||
|
{ "__gc", Timer_gc },
|
||||||
|
{ "start", Timer_start },
|
||||||
|
{ "stop", Timer_stop },
|
||||||
|
{ nullptr, nullptr }
|
||||||
|
};
|
||||||
|
|
||||||
|
const Property Timer_properties[] = {
|
||||||
|
{ "interval", Timer_get_interval, Timer_set_interval },
|
||||||
|
{ "isRunning", Timer_get_isRunning, nullptr },
|
||||||
|
{ nullptr, nullptr, nullptr }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
DEF_MTNAME(Timer);
|
||||||
|
|
||||||
|
void register_timer_class(lua_State* L)
|
||||||
|
{
|
||||||
|
REG_CLASS(L, Timer);
|
||||||
|
REG_CLASS_NEW(L, Timer);
|
||||||
|
REG_CLASS_PROPERTIES(L, Timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace script
|
||||||
|
} // namespace app
|
Loading…
x
Reference in New Issue
Block a user