210 lines
6.0 KiB
C
210 lines
6.0 KiB
C
/*************************************************************************
|
|
> File Name: lua_plugin_data.c
|
|
> Author:
|
|
> Created Time: 2024-08
|
|
> Encoding : UTF-8
|
|
************************************************************************/
|
|
|
|
/*************************************************************************
|
|
* version
|
|
* [ v0.1 ]
|
|
* 08-06
|
|
* 1. 实现函数
|
|
* int lua_cdata_push_stack;
|
|
* int lua_cdata_pop_stack;
|
|
* void lua_cdata_destory;
|
|
* struct lua_context * lua_context_new;
|
|
* int lua_context_push_stack;
|
|
* void lua_context_free;
|
|
************************************************************************/
|
|
#include "lua_plugin_manage_internal.h"
|
|
|
|
/*
|
|
* Function: lua_cdata_push_stack
|
|
* Input: | lua_State * | state | 入栈数据使用的状态机
|
|
* | struct lua_cdata * | cdata | 需要入栈的数据
|
|
* Output:
|
|
* Return: | -1 | 参数错误
|
|
* | 1 | 入栈数据类型有误
|
|
* | 0 | 入栈成功
|
|
* Description: 将一个数据元素入栈
|
|
*/
|
|
int lua_cdata_push_stack(
|
|
lua_State *state,
|
|
struct lua_cdata *cdata)
|
|
{
|
|
if (__glibc_unlikely(!state || !cdata))
|
|
return -1;
|
|
|
|
switch (cdata->cdata_type)
|
|
{
|
|
case DATATYPE_NIL:
|
|
lua_pushnil(state);
|
|
return 0;
|
|
case DATATYPE_BOOL:
|
|
lua_pushboolean(state, cdata->cdata_bool);
|
|
return 0;
|
|
case DATATYPE_INT:
|
|
lua_pushinteger(state, cdata->cdata_int);
|
|
return 0;
|
|
case DATATYPE_NUM:
|
|
lua_pushnumber(state, cdata->cdata_num);
|
|
return 0;
|
|
case DATATYPE_STRING:
|
|
lua_pushstring(state, cdata->cdata_string);
|
|
return 0;
|
|
case DATATYPE_TABLE:
|
|
lua_rawgeti(state, LUA_REGISTRYINDEX, cdata->cdata_table);
|
|
return 0;
|
|
case DATATYPE_POINTER:
|
|
lua_pushlightuserdata(state, (void *)cdata->cdata_pointer);
|
|
return 0;
|
|
case DATATYPE_CONTEXT:
|
|
lua_context_push_stack(cdata->cdata_context);
|
|
return 0;
|
|
default:
|
|
LOGERROR("can't recorgnize data type %d", cdata->cdata_type);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Function: lua_cdata_pop_stack
|
|
* Input: | lua_State * | state | 出栈数据使用的状态机
|
|
* | struct lua_cdata * | cdata | 保存出栈的元素
|
|
* Output:
|
|
* Return: | -1 | 参数错误
|
|
* | -2 | 出栈数据类型有误
|
|
* | 0 | 出栈成功
|
|
* Description: 将一个数据元素出栈, 出栈过程中无法出栈context与table类型
|
|
* TODO: 扩展类型, 支持更多数据类型
|
|
*/
|
|
int lua_cdata_pop_stack(
|
|
lua_State *state,
|
|
struct lua_cdata *cdata)
|
|
{
|
|
if (__glibc_unlikely(!state || !cdata))
|
|
return -1;
|
|
if (!lua_gettop(state))
|
|
return 0;
|
|
|
|
switch (lua_type(state, -1))
|
|
{
|
|
case LUA_TNIL:
|
|
cdata->cdata_type = DATATYPE_NIL;
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
cdata->cdata_type = DATATYPE_BOOL;
|
|
cdata->cdata_bool = lua_toboolean(state, -1);
|
|
break;
|
|
case LUA_TNUMBER:
|
|
cdata->cdata_type = DATATYPE_NUM;
|
|
cdata->cdata_num = lua_tonumber(state, -1);
|
|
int try_int = (int)cdata->cdata_num;
|
|
if ((double)try_int == cdata->cdata_num)
|
|
{
|
|
cdata->cdata_type = DATATYPE_INT;
|
|
cdata->cdata_int = lua_tointeger(state, -1);
|
|
}
|
|
break;
|
|
case LUA_TSTRING:
|
|
cdata->cdata_type = DATATYPE_STRING;
|
|
cdata->cdata_string = (char *)strdup(lua_tostring(state, -1));
|
|
break;
|
|
case LUA_TLIGHTUSERDATA:
|
|
cdata->cdata_type = DATATYPE_POINTER;
|
|
cdata->cdata_pointer = (void *)lua_topointer(state, -1);
|
|
break;
|
|
default:
|
|
/* 其他数据类型之后处理 */
|
|
LOGERROR("other lua type can't pop out, %d", lua_type(state, -1));
|
|
return -2;
|
|
}
|
|
|
|
lua_pop(state, 1);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Function: lua_cdata_destory
|
|
* Input: | struct lua_cdata * | cdata | 待销毁的data结构
|
|
* Output:
|
|
* Return:
|
|
* Description: 销毁是一个data结构, 释放内部占用内存
|
|
* 目前该函数仅数据类型为string的时候需要调用一次
|
|
*/
|
|
void lua_cdata_destory(struct lua_cdata *cdata)
|
|
{
|
|
if (__glibc_unlikely(!cdata))
|
|
return;
|
|
if (cdata->cdata_type == DATATYPE_STRING && cdata->cdata_string)
|
|
free(cdata->cdata_string);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Function: lua_context_new
|
|
* Input: | lua_State * | state | 创建context使用的状态机
|
|
* Output:
|
|
* Return: | NULL | 创建失败
|
|
* | pointer | 创建成功, 返回创建的context指针
|
|
* Description: 创建一个context结构, 由于context结构使用需要在状态机中生成引用值, 单独重写一个new函数
|
|
*/
|
|
struct lua_context *lua_context_new(lua_State *state)
|
|
{
|
|
if (__glibc_unlikely(!state))
|
|
return NULL;
|
|
|
|
lua_newtable(state);
|
|
int ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
|
lua_settop(state, 0);
|
|
if (ref_id == LUA_REFNIL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
struct lua_context *new_context = (struct lua_context *)calloc(1, sizeof(struct lua_context));
|
|
if (__glibc_unlikely(!new_context))
|
|
{
|
|
luaL_unref(state, LUA_REGISTRYINDEX, ref_id);
|
|
return NULL;
|
|
}
|
|
new_context->context_state = state;
|
|
new_context->context_ref_id = ref_id;
|
|
return new_context;
|
|
}
|
|
|
|
/*
|
|
* Function: lua_context_push_stack
|
|
* Input: | struct lua_context * | context | 待入栈的context结构
|
|
* Output:
|
|
* Return: | 0 | 入栈成功
|
|
* | -1 | 参数错误
|
|
* Description: 将一个context入栈, 实际入栈流程与table一致
|
|
*/
|
|
int lua_context_push_stack(struct lua_context *context)
|
|
{
|
|
if (luai_unlikely(!context))
|
|
return -1;
|
|
|
|
lua_rawgeti(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Function: lua_context_free
|
|
* Input: | struct lua_context * | context | 释放一个context
|
|
* Output:
|
|
* Return:
|
|
* Description: 释放一个context
|
|
*/
|
|
void lua_context_free(struct lua_context *context)
|
|
{
|
|
if (__glibc_unlikely(!context))
|
|
return;
|
|
luaL_unref(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
|
|
free(context);
|
|
return;
|
|
} |