client, extensions/cereal: Binary output

This commit is contained in:
Perttu Ahola 2014-09-19 23:08:09 +03:00
parent ceb8adf65b
commit 5ebde7540b
4 changed files with 86 additions and 1 deletions

View File

@ -4,8 +4,27 @@ local log = buildat.Logger("extension/cereal")
local M = {safe = {}}
function M.safe.binary_input(data, types)
if type(data) ~= 'string' then
error("data not string")
end
if type(types) ~= 'table' then
error("types not table")
end
return __buildat_cereal_binary_input(data, types)
end
function M.safe.binary_output(values, types)
if type(values) ~= 'table' then
error("values not table")
end
if type(types) ~= 'table' then
error("types not table")
end
if #values ~= #types then
error("values and types must have the same length")
end
return __buildat_cereal_binary_output(values, types)
end
return M

View File

@ -285,6 +285,7 @@ struct CApp: public Polycode::EventHandler, public App
DEF_BUILDAT_FUNC(get_path)
DEF_BUILDAT_FUNC(pcall)
DEF_BUILDAT_FUNC(cereal_binary_input)
DEF_BUILDAT_FUNC(cereal_binary_output)
ss_ init_lua_path = g_client_config.share_path+"/client/init.lua";
int error = luaL_dofile(L, init_lua_path.c_str());
@ -546,6 +547,64 @@ struct CApp: public Polycode::EventHandler, public App
// Result table is on top of stack
return 1;
}
// cereal_binary_output(values: table of values, types: table of strings)
// -> data
static int l_cereal_binary_output(lua_State *L)
{
int values_table_L = 1;
int types_table_L = 2;
std::ostringstream os(std::ios::binary);
{
cereal::PortableBinaryOutputArchive ar(os);
int value_index = 1;
lua_pushnil(L);
while(lua_next(L, types_table_L) != 0)
{
ss_ type = lua_tostring(L, -1);
lua_pop(L, 1);
log_t(MODULE, "type=%s", cs(type));
if(type == "byte"){
lua_rawgeti(L, values_table_L, value_index++);
uchar b = lua_tointeger(L, -1);
lua_pop(L, 1);
ar(b);
continue;
}
if(type == "int32"){
lua_rawgeti(L, values_table_L, value_index++);
int32_t i = lua_tointeger(L, -1);
lua_pop(L, 1);
ar(i);
continue;
}
if(type == "double"){
lua_rawgeti(L, values_table_L, value_index++);
double d = lua_tonumber(L, -1);
lua_pop(L, 1);
ar(d);
continue;
}
if(type == "string"){
lua_rawgeti(L, values_table_L, value_index++);
size_t cs_len = 0;
const char *cs = lua_tolstring(L, -1, &cs_len);
lua_pop(L, 1);
ss_ s(cs, cs_len);
ar(s);
continue;
}
throw Exception(ss_()+"Unknown type \""+type+"\""
"; known types are byte, int32, double, string");
}
}
ss_ data = os.str();
lua_pushlstring(L, data.c_str(), data.size());
return 1;
}
};
App* createApp(Polycode::PolycodeView *view)

View File

@ -66,6 +66,7 @@ struct CState: public State
void send_packet(const ss_ &name, const ss_ &data)
{
log_v(MODULE, "send_packet(): name=%s", cs(name));
m_packet_stream.output(name, data, [&](const ss_ & packet_data){
m_socket->send_fd(packet_data);
});
@ -133,7 +134,7 @@ struct CState: public State
void handle_packet(const ss_ &packet_name, const ss_ &data)
{
if(packet_name.substr(0,5) != "core:"){
if(packet_name.substr(0, 5) != "core:"){
m_app->handle_packet(packet_name, data);
return;
}

View File

@ -37,6 +37,12 @@ buildat.sub_packet("test1:add_box", function(data)
box:loadTexture("test1/pink_texture.png")
box:setPosition(x, y, z)
scene:addEntity(box)
data = cereal.binary_output(
{1, "Foo"},
{"byte", "string"}
)
buildat.send_packet("test1:box_added", data)
end)
--[[