blob: bce924f3c01fc06341158d4276d74c0f50aef075 [file] [log] [blame] [edit]
#ifdef WITH_RIVE_SCRIPTING
#include "lualib.h"
#include "rive/math/vec2d.hpp"
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/factory.hpp"
#include <math.h>
#include <stdio.h>
using namespace rive;
static int vertex_buffer_construct(lua_State* L)
{
lua_newrive<ScriptedVertexBuffer>(L);
return 1;
}
static int vertex_buffer_reset(lua_State* L)
{
auto vertexBuffer = lua_torive<ScriptedVertexBuffer>(L, 1);
vertexBuffer->values.clear();
vertexBuffer->vertexBuffer = nullptr;
return 0;
}
static int vertex_buffer_add(lua_State* L)
{
auto vertexBuffer = lua_torive<ScriptedVertexBuffer>(L, 1);
int nargs = lua_gettop(L) - 1;
for (int i = 0; i < nargs; i++)
{
auto vec = lua_checkvec2d(L, 2 + i);
vertexBuffer->values.push_back(*vec);
}
vertexBuffer->vertexBuffer = nullptr;
return 0;
}
static int vertex_buffer_namecall(lua_State* L)
{
int atom;
const char* str = lua_namecallatom(L, &atom);
if (str != nullptr)
{
switch (atom)
{
case (int)LuaAtoms::reset:
return vertex_buffer_reset(L);
case (int)LuaAtoms::add:
return vertex_buffer_add(L);
}
}
luaL_error(L,
"%s is not a valid method of %s",
str,
ScriptedVertexBuffer::luaName);
return 0;
}
static int index_buffer_construct(lua_State* L)
{
lua_newrive<ScriptedTriangleBuffer>(L);
return 1;
}
static int index_buffer_reset(lua_State* L)
{
auto indexBuffer = lua_torive<ScriptedTriangleBuffer>(L, 1);
indexBuffer->values.clear();
indexBuffer->max = 0;
indexBuffer->indexBuffer = nullptr;
return 0;
}
static int index_buffer_add(lua_State* L)
{
auto indexBuffer = lua_torive<ScriptedTriangleBuffer>(L, 1);
for (int i = 0; i < 3; i++)
{
auto index = luaL_checkunsigned(L, 2 + i);
if (index > std::numeric_limits<uint16_t>::max())
{
luaL_error(L,
"index %i exceeds %i",
index,
std::numeric_limits<uint16_t>::max());
}
if (index > indexBuffer->max)
{
indexBuffer->max = index;
}
indexBuffer->values.push_back((uint16_t)index);
}
indexBuffer->indexBuffer = nullptr;
return 0;
}
static int index_buffer_namecall(lua_State* L)
{
int atom;
const char* str = lua_namecallatom(L, &atom);
if (str != nullptr)
{
switch (atom)
{
case (int)LuaAtoms::reset:
return index_buffer_reset(L);
case (int)LuaAtoms::add:
return index_buffer_add(L);
}
}
luaL_error(L,
"%s is not a valid method of %s",
str,
ScriptedTriangleBuffer::luaName);
return 0;
}
static const luaL_Reg empty[] = {
{NULL, NULL},
};
static void register_vertex_buffer(lua_State* L)
{
luaL_register(L, ScriptedVertexBuffer::luaName, empty);
lua_register_rive<ScriptedVertexBuffer>(L);
lua_pushcfunction(L, vertex_buffer_namecall, nullptr);
lua_setfield(L, -2, "__namecall");
// Create metatable for the metatable (so we can call it).
lua_createtable(L, 0, 1);
lua_pushcfunction(L, vertex_buffer_construct, nullptr);
lua_setfield(L, -2, "__call");
// -3 as it's the library (Path) that we're setting this metatable on.
lua_setmetatable(L, -3);
lua_setreadonly(L, -1, true);
lua_pop(L, 1); // pop the metatable
}
static void register_index_buffer(lua_State* L)
{
luaL_register(L, ScriptedTriangleBuffer::luaName, empty);
lua_register_rive<ScriptedTriangleBuffer>(L);
lua_pushcfunction(L, index_buffer_namecall, nullptr);
lua_setfield(L, -2, "__namecall");
// Create metatable for the metatable (so we can call it).
lua_createtable(L, 0, 1);
lua_pushcfunction(L, index_buffer_construct, nullptr);
lua_setfield(L, -2, "__call");
// -3 as it's the library (Path) that we're setting this metatable on.
lua_setmetatable(L, -3);
lua_setreadonly(L, -1, true);
lua_pop(L, 1); // pop the metatable
}
void ScriptedVertexBuffer::update(Factory* factory)
{
// still valid?
if (vertexBuffer)
{
return;
}
auto buffer =
factory->makeRenderBuffer(RenderBufferType::vertex,
RenderBufferFlags::mappedOnceAtInitialization,
values.size() * sizeof(Vec2D));
if (buffer)
{
float* pos = static_cast<float*>(buffer->map());
memcpy(pos, values.data(), buffer->sizeInBytes());
buffer->unmap();
}
vertexBuffer = buffer;
}
void ScriptedTriangleBuffer::update(Factory* factory)
{
// still valid?
if (indexBuffer)
{
return;
}
auto buffer =
factory->makeRenderBuffer(RenderBufferType::index,
RenderBufferFlags::mappedOnceAtInitialization,
values.size() * sizeof(uint16_t));
if (buffer)
{
void* indexData = buffer->map();
memcpy(indexData, values.data(), buffer->sizeInBytes());
buffer->unmap();
}
indexBuffer = buffer;
}
int luaopen_rive_mesh(lua_State* L)
{
register_vertex_buffer(L);
register_index_buffer(L);
return 2;
}
#endif