| #ifdef WITH_RIVE_SCRIPTING |
| #include "rive/lua/rive_lua_libs.hpp" |
| #include "rive/data_bind/data_values/data_value_number.hpp" |
| |
| #include <math.h> |
| #include <stdio.h> |
| |
| using namespace rive; |
| |
| ScriptedDataValue::~ScriptedDataValue() |
| { |
| if (m_dataValue) |
| { |
| delete m_dataValue; |
| } |
| } |
| |
| static int property_namecall_atom(lua_State* L, |
| ScriptedDataValue* scriptedDataValue, |
| uint8_t tag, |
| int atom, |
| bool& error) |
| { |
| switch (atom) |
| { |
| case (int)LuaAtoms::value: |
| { |
| assert(scriptedDataValue->state() == L); |
| switch (tag) |
| { |
| case ScriptedDataValueNumber::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueNumber>(); |
| lua_pushnumber(L, dataValue->value()); |
| return 1; |
| } |
| case ScriptedDataValueString::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueString>(); |
| lua_pushstring(L, dataValue->value().c_str()); |
| return 1; |
| } |
| case ScriptedDataValueBoolean::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueBoolean>(); |
| lua_pushboolean(L, dataValue->value() ? 1 : 0); |
| return 1; |
| } |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueColor>(); |
| lua_pushinteger(L, dataValue->value()); |
| return 1; |
| } |
| } |
| } |
| case (int)LuaAtoms::red: |
| { |
| assert(scriptedDataValue->state() == L); |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueColor>(); |
| lua_pushinteger(L, dataValue->red()); |
| return 1; |
| } |
| } |
| } |
| case (int)LuaAtoms::green: |
| { |
| assert(scriptedDataValue->state() == L); |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueColor>(); |
| lua_pushinteger(L, dataValue->green()); |
| return 1; |
| } |
| } |
| } |
| case (int)LuaAtoms::blue: |
| { |
| assert(scriptedDataValue->state() == L); |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueColor>(); |
| lua_pushinteger(L, dataValue->blue()); |
| return 1; |
| } |
| } |
| } |
| case (int)LuaAtoms::alpha: |
| { |
| assert(scriptedDataValue->state() == L); |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto dataValue = |
| scriptedDataValue->dataValue()->as<DataValueColor>(); |
| lua_pushinteger(L, dataValue->alpha()); |
| return 1; |
| } |
| } |
| } |
| } |
| error = true; |
| return 0; |
| } |
| |
| static int data_value_index(lua_State* L) |
| { |
| int atom; |
| lua_tostringatom(L, 2, &atom); |
| |
| size_t namelen = 0; |
| const char* name = luaL_checklstring(L, 2, &namelen); |
| |
| auto tag = lua_userdatatag(L, 1); |
| auto scriptedDataValue = (ScriptedDataValue*)lua_touserdata(L, 1); |
| |
| bool error = false; |
| int stackChange = |
| property_namecall_atom(L, scriptedDataValue, tag, atom, error); |
| if (!error) |
| { |
| return stackChange; |
| } |
| |
| luaL_error(L, "'%s' is not a valid index of DataValue", name); |
| return 0; |
| } |
| |
| static int data_value_newindex(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 tag = lua_userdatatag(L, 1); |
| auto scriptedDataValue = (ScriptedDataValue*)lua_touserdata(L, 1); |
| switch (atom) |
| { |
| case (int)LuaAtoms::value: |
| { |
| switch (tag) |
| { |
| case ScriptedDataValueNumber::luaTag: |
| { |
| auto val = float(luaL_checknumber(L, 3)); |
| scriptedDataValue->dataValue() |
| ->as<DataValueNumber>() |
| ->value(val); |
| return 1; |
| } |
| case ScriptedDataValueString::luaTag: |
| { |
| auto val = luaL_checkstring(L, 3); |
| scriptedDataValue->dataValue() |
| ->as<DataValueString>() |
| ->value(val); |
| return 1; |
| } |
| case ScriptedDataValueBoolean::luaTag: |
| { |
| auto val = luaL_checkboolean(L, 3); |
| scriptedDataValue->dataValue() |
| ->as<DataValueBoolean>() |
| ->value(val != 0); |
| return 1; |
| } |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto val = luaL_checkinteger(L, 3); |
| scriptedDataValue->dataValue()->as<DataValueColor>()->value( |
| val); |
| return 1; |
| } |
| } |
| } |
| case (int)LuaAtoms::red: |
| { |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto val = luaL_checkinteger(L, 3); |
| scriptedDataValue->dataValue()->as<DataValueColor>()->red( |
| val); |
| return 1; |
| } |
| default: |
| return 1; |
| } |
| } |
| case (int)LuaAtoms::green: |
| { |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto val = luaL_checkinteger(L, 3); |
| scriptedDataValue->dataValue()->as<DataValueColor>()->green( |
| val); |
| return 1; |
| } |
| default: |
| return 1; |
| } |
| } |
| case (int)LuaAtoms::blue: |
| { |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto val = luaL_checkinteger(L, 3); |
| scriptedDataValue->dataValue()->as<DataValueColor>()->blue( |
| val); |
| return 1; |
| } |
| default: |
| return 1; |
| } |
| } |
| case (int)LuaAtoms::alpha: |
| { |
| switch (tag) |
| { |
| case ScriptedDataValueColor::luaTag: |
| { |
| auto val = luaL_checkinteger(L, 3); |
| scriptedDataValue->dataValue()->as<DataValueColor>()->alpha( |
| val); |
| return 1; |
| } |
| default: |
| return 1; |
| } |
| } |
| default: |
| return 0; |
| } |
| |
| return 0; |
| } |
| |
| static int dataValue_number(lua_State* L) |
| { |
| lua_newrive<ScriptedDataValueNumber>(L, L, 0); |
| |
| return 1; |
| } |
| |
| static int dataValue_string(lua_State* L) |
| { |
| lua_newrive<ScriptedDataValueString>(L, L, ""); |
| |
| return 1; |
| } |
| |
| static int dataValue_boolean(lua_State* L) |
| { |
| lua_newrive<ScriptedDataValueBoolean>(L, L, false); |
| |
| return 1; |
| } |
| |
| static int dataValue_color(lua_State* L) |
| { |
| lua_newrive<ScriptedDataValueColor>(L, L, 0); |
| |
| return 1; |
| } |
| |
| static int data_value_namecall(lua_State* L) |
| { |
| int atom; |
| const char* str = lua_namecallatom(L, &atom); |
| if (str != nullptr) |
| { |
| auto dataValue = (ScriptedDataValue*)lua_touserdata(L, 1); |
| switch (atom) |
| { |
| case (int)LuaAtoms::isNumber: |
| { |
| assert(dataValue->state() == L); |
| lua_pushboolean(L, dataValue->isNumber() ? 1 : 0); |
| return 1; |
| } |
| case (int)LuaAtoms::isString: |
| { |
| assert(dataValue->state() == L); |
| lua_pushboolean(L, dataValue->isString() ? 1 : 0); |
| return 1; |
| } |
| case (int)LuaAtoms::isBoolean: |
| { |
| assert(dataValue->state() == L); |
| lua_pushboolean(L, dataValue->isBoolean() ? 1 : 0); |
| return 1; |
| } |
| case (int)LuaAtoms::isColor: |
| { |
| assert(dataValue->state() == L); |
| lua_pushboolean(L, dataValue->isColor() ? 1 : 0); |
| return 1; |
| } |
| default: |
| break; |
| } |
| } |
| |
| luaL_error(L, |
| "%s is not a valid method of %s", |
| str, |
| ScriptedPropertyViewModel::luaName); |
| return 0; |
| } |
| |
| static const luaL_Reg dataValueStaticMethods[] = { |
| {"number", dataValue_number}, |
| {"string", dataValue_string}, |
| {"boolean", dataValue_boolean}, |
| {"color", dataValue_color}, |
| {nullptr, nullptr}}; |
| |
| int luaopen_rive_data_values(lua_State* L) |
| { |
| { |
| |
| luaL_register(L, ScriptedDataValue::luaName, dataValueStaticMethods); |
| } |
| { |
| lua_register_rive<ScriptedDataValueNumber>(L); |
| |
| lua_pushcfunction(L, data_value_index, nullptr); |
| lua_setfield(L, -2, "__index"); |
| |
| lua_pushcfunction(L, data_value_newindex, nullptr); |
| lua_setfield(L, -2, "__newindex"); |
| |
| lua_pushcfunction(L, data_value_namecall, nullptr); |
| lua_setfield(L, -2, "__namecall"); |
| |
| lua_setreadonly(L, -1, true); |
| lua_pop(L, 1); // pop the metatable |
| } |
| { |
| lua_register_rive<ScriptedDataValueString>(L); |
| |
| lua_pushcfunction(L, data_value_index, nullptr); |
| lua_setfield(L, -2, "__index"); |
| |
| lua_pushcfunction(L, data_value_newindex, nullptr); |
| lua_setfield(L, -2, "__newindex"); |
| |
| lua_pushcfunction(L, data_value_namecall, nullptr); |
| lua_setfield(L, -2, "__namecall"); |
| |
| lua_setreadonly(L, -1, true); |
| lua_pop(L, 1); // pop the metatable |
| } |
| { |
| lua_register_rive<ScriptedDataValueBoolean>(L); |
| |
| lua_pushcfunction(L, data_value_index, nullptr); |
| lua_setfield(L, -2, "__index"); |
| |
| lua_pushcfunction(L, data_value_newindex, nullptr); |
| lua_setfield(L, -2, "__newindex"); |
| |
| lua_pushcfunction(L, data_value_namecall, nullptr); |
| lua_setfield(L, -2, "__namecall"); |
| |
| lua_setreadonly(L, -1, true); |
| lua_pop(L, 1); // pop the metatable |
| } |
| { |
| lua_register_rive<ScriptedDataValueColor>(L); |
| |
| lua_pushcfunction(L, data_value_index, nullptr); |
| lua_setfield(L, -2, "__index"); |
| |
| lua_pushcfunction(L, data_value_newindex, nullptr); |
| lua_setfield(L, -2, "__newindex"); |
| |
| lua_pushcfunction(L, data_value_namecall, nullptr); |
| lua_setfield(L, -2, "__namecall"); |
| |
| lua_setreadonly(L, -1, true); |
| lua_pop(L, 1); // pop the metatable |
| } |
| |
| return 1; |
| } |
| #endif |