blob: e4598d1aa3c6ca0db68d6637229dfba5033fc863 [file]
#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "lualib.h"
using namespace rive;
static const char* hit_listener_type_string(int raw)
{
switch (static_cast<ListenerType>(raw))
{
case ListenerType::enter:
return "pointerEnter";
case ListenerType::exit:
return "pointerExit";
case ListenerType::down:
return "pointerDown";
case ListenerType::up:
return "pointerUp";
case ListenerType::move:
return "pointerMove";
case ListenerType::click:
return "click";
case ListenerType::drag:
return "pointerDrag";
default:
return "unknown";
}
return "unknown";
}
static void pointer_event_direct_id(void* udata, void* result)
{
lua_userdatadirectfield_setnumber(
result,
(double)((ScriptedPointerEvent*)udata)->m_id);
}
static void pointer_event_direct_position(void* udata, void* result)
{
auto* self = (ScriptedPointerEvent*)udata;
lua_userdatadirectfield_setvector(
result,
self->m_position.x,
self->m_position.y,
0.0f
#if LUA_VECTOR_SIZE == 4
,
0.0f
#endif
);
}
static void pointer_event_direct_previousPosition(void* udata, void* result)
{
auto* self = (ScriptedPointerEvent*)udata;
lua_userdatadirectfield_setvector(
result,
self->m_previousPosition.x,
self->m_previousPosition.y,
0.0f
#if LUA_VECTOR_SIZE == 4
,
0.0f
#endif
);
}
static void pointer_event_direct_timeStamp(void* udata, void* result)
{
lua_userdatadirectfield_setnumber(
result,
((ScriptedPointerEvent*)udata)->m_timeStamp);
}
static int pointer_event_index(lua_State* L)
{
int atom;
const char* key = lua_tostringatom(L, 2, &atom);
if (!key)
{
luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
return 0;
}
auto pointerEvent = lua_torive<ScriptedPointerEvent>(L, 1);
switch (atom)
{
case (int)LuaAtoms::id:
lua_pushunsigned(L, (unsigned)pointerEvent->m_id);
return 1;
case (int)LuaAtoms::position:
rive_lua_pushvector2(
L,
pointerEvent->m_position.x,
pointerEvent->m_position.y);
return 1;
case (int)LuaAtoms::previousPosition:
rive_lua_pushvector2(
L,
pointerEvent->m_previousPosition.x,
pointerEvent->m_previousPosition.y);
return 1;
case (int)LuaAtoms::type:
lua_pushstring(
L,
hit_listener_type_string(pointerEvent->m_hitListenerType));
return 1;
case (int)LuaAtoms::timeStamp:
lua_pushnumber(L, pointerEvent->m_timeStamp);
return 1;
}
luaL_error(
L,
"%s is not a valid field of %s",
luaL_checkstring(L, 1),
ScriptedPointerEvent::luaName);
return 0;
}
static int pointer_event_hit(lua_State* L)
{
auto pointerEvent = lua_torive<ScriptedPointerEvent>(L, 1);
if (lua_isboolean(L, 2))
{
pointerEvent->m_hitResult = lua_toboolean(L, 2) ? HitResult::hit
: HitResult::hitOpaque;
}
else
{
pointerEvent->m_hitResult = HitResult::hitOpaque;
}
return 0;
}
static int pointer_event_namecall(lua_State* L)
{
int atom;
const char* str = lua_namecallatom(L, &atom);
if (str != nullptr)
{
switch (atom)
{
case (int)LuaAtoms::hit:
return pointer_event_hit(L);
}
}
luaL_error(
L,
"%s is not a valid method of %s",
luaL_checkstring(L, 1),
ScriptedPointerEvent::luaName);
return 0;
}
static int pointer_event_new(lua_State* L)
{
int id = luaL_checkinteger(L, 1);
auto vec = lua_checkvec2d(L, 2);
lua_newrive<ScriptedPointerEvent>(L, id, Vec2D(vec->x, vec->y));
return 1;
}
// Indexed by ScrollPhase, null terminated for luaL_checkoption.
static const char* const scrollPhaseNames[] =
{"begin", "update", "end", "momentum", "inertiaCancel", nullptr};
static const char* scroll_phase_string(ScrollPhase phase)
{
auto index = (size_t)phase;
return index < std::size(scrollPhaseNames) - 1 ? scrollPhaseNames[index]
: "update";
}
static int scroll_event_new(lua_State* L)
{
int id = luaL_checkinteger(L, 1);
Vec2D position = *lua_checkvec2d(L, 2);
ScrollEvent event;
event.delta = *lua_checkvec2d(L, 3);
event.phase = (ScrollPhase)luaL_checkoption(L, 4, "update", scrollPhaseNames);
event.precise = luaL_optboolean(L, 5, false);
lua_newrive<ScriptedScrollEvent>(
L,
id,
position,
event,
(float)luaL_optnumber(L, 6, 0));
return 1;
}
static int scroll_event_index(lua_State* L)
{
int atom;
const char* key = lua_tostringatom(L, 2, &atom);
if (!key)
{
luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
return 0;
}
auto scrollEvent = lua_torive<ScriptedScrollEvent>(L, 1);
switch (atom)
{
case (int)LuaAtoms::id:
lua_pushinteger(L, scrollEvent->m_id);
return 1;
case (int)LuaAtoms::position:
rive_lua_pushvector2(
L,
scrollEvent->m_position.x,
scrollEvent->m_position.y);
return 1;
case (int)LuaAtoms::delta:
rive_lua_pushvector2(
L,
scrollEvent->m_event.delta.x,
scrollEvent->m_event.delta.y);
return 1;
case (int)LuaAtoms::phase:
lua_pushstring(L, scroll_phase_string(scrollEvent->m_event.phase));
return 1;
case (int)LuaAtoms::precise:
lua_pushboolean(L, scrollEvent->m_event.precise);
return 1;
case (int)LuaAtoms::timeStamp:
lua_pushnumber(L, scrollEvent->m_timeStamp);
return 1;
}
luaL_error(
L,
"%s is not a valid field of %s",
key,
ScriptedScrollEvent::luaName);
return 0;
}
static int scroll_event_namecall(lua_State* L)
{
int atom;
const char* str = lua_namecallatom(L, &atom);
if (str != nullptr && atom == (int)LuaAtoms::hit)
{
lua_torive<ScriptedScrollEvent>(L, 1)->m_hitResult = HitResult::hitOpaque;
return 0;
}
luaL_error(
L,
"%s is not a valid method of %s",
str,
ScriptedScrollEvent::luaName);
return 0;
}
static const luaL_Reg pointerEventsStaticMethods[] = {
{"new", pointer_event_new},
{nullptr, nullptr}};
static const luaL_Reg scrollEventsStaticMethods[] = {
{"new", scroll_event_new},
{nullptr, nullptr}};
int luaopen_rive_input(lua_State* L)
{
{
luaL_register(L, ScriptedPointerEvent::luaName, pointerEventsStaticMethods);
}
{
lua_register_rive<ScriptedPointerEvent>(L);
lua_pushcfunction(L, pointer_event_index, nullptr);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, pointer_event_namecall, nullptr);
lua_setfield(L, -2, "__namecall");
lua_setreadonly(L, -1, true);
lua_pop(L, 1); // pop the metatable
lua_registeruserdatadirectfieldget(
L,
ScriptedPointerEvent::luaTag,
"id",
pointer_event_direct_id);
lua_registeruserdatadirectfieldget(
L,
ScriptedPointerEvent::luaTag,
"position",
pointer_event_direct_position);
lua_registeruserdatadirectfieldget(
L,
ScriptedPointerEvent::luaTag,
"previousPosition",
pointer_event_direct_previousPosition);
lua_registeruserdatadirectfieldget(
L,
ScriptedPointerEvent::luaTag,
"timeStamp",
pointer_event_direct_timeStamp);
}
{
luaL_register(L, ScriptedScrollEvent::luaName, scrollEventsStaticMethods);
}
{
lua_register_rive<ScriptedScrollEvent>(L);
lua_pushcfunction(L, scroll_event_index, nullptr);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, scroll_event_namecall, nullptr);
lua_setfield(L, -2, "__namecall");
lua_setreadonly(L, -1, true);
lua_pop(L, 1); // pop the metatable
}
rive_lua_register_listener_invocation_types(L);
return 1;
}
#endif