extensions/cereal, client/app: Allow repeating values of the same type without specifying type for each value separately

This commit is contained in:
Perttu Ahola 2014-09-20 00:25:54 +03:00
parent 8aefb1c4d8
commit f36e5af4de
4 changed files with 97 additions and 41 deletions

View File

@ -20,9 +20,6 @@ function M.safe.binary_output(values, types)
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

View File

@ -558,35 +558,54 @@ struct CApp: public Polycode::EventHandler, public App
lua_pushnil(L);
while(lua_next(L, types_table_L) != 0)
{
ss_ type = lua_tostring(L, -1);
ss_ type;
int repeat = 1;
if(lua_istable(L, -1)){
lua_rawgeti(L, -1, 1);
type = lua_tostring(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, -1, 2);
repeat = lua_tointeger(L, -1);
lua_pop(L, 1);
} else {
type = lua_tostring(L, -1);
}
lua_pop(L, 1);
log_t(MODULE, "type=%s", cs(type));
if(type == "byte"){
uchar b;
ar(b);
lua_pushinteger(L, b);
lua_rawseti(L, result_table_L, output_index++);
for(int i = 0; i < repeat; i++){
uchar b;
ar(b);
lua_pushinteger(L, b);
lua_rawseti(L, result_table_L, output_index++);
}
continue;
}
if(type == "int32"){
int32_t i;
ar(i);
lua_pushinteger(L, i);
lua_rawseti(L, result_table_L, output_index++);
for(int i = 0; i < repeat; i++){
int32_t d;
ar(d);
lua_pushinteger(L, d);
lua_rawseti(L, result_table_L, output_index++);
}
continue;
}
if(type == "double"){
double d;
ar(d);
lua_pushnumber(L, d);
lua_rawseti(L, result_table_L, output_index++);
for(int i = 0; i < repeat; i++){
double d;
ar(d);
lua_pushnumber(L, d);
lua_rawseti(L, result_table_L, output_index++);
}
continue;
}
if(type == "string"){
ss_ s;
ar(s);
lua_pushlstring(L, s.c_str(), s.size());
lua_rawseti(L, result_table_L, output_index++);
for(int i = 0; i < repeat; i++){
ss_ s;
ar(s);
lua_pushlstring(L, s.c_str(), s.size());
lua_rawseti(L, result_table_L, output_index++);
}
continue;
}
throw Exception(ss_()+"Unknown type \""+type+"\""
@ -613,37 +632,56 @@ struct CApp: public Polycode::EventHandler, public App
lua_pushnil(L);
while(lua_next(L, types_table_L) != 0)
{
ss_ type = lua_tostring(L, -1);
ss_ type;
int repeat = 1;
if(lua_istable(L, -1)){
lua_rawgeti(L, -1, 1);
type = lua_tostring(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, -1, 2);
repeat = lua_tointeger(L, -1);
lua_pop(L, 1);
} else {
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);
for(int i = 0; i < repeat; i++){
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);
for(int i = 0; i < repeat; i++){
lua_rawgeti(L, values_table_L, value_index++);
int32_t d = lua_tointeger(L, -1);
lua_pop(L, 1);
ar(d);
}
continue;
}
if(type == "double"){
lua_rawgeti(L, values_table_L, value_index++);
double d = lua_tonumber(L, -1);
lua_pop(L, 1);
ar(d);
for(int i = 0; i < repeat; i++){
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);
for(int i = 0; i < repeat; i++){
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+"\""

View File

@ -42,8 +42,8 @@ buildat.sub_packet("test1:add_box", function(data)
the_box = box
data = cereal.binary_output(
{1, "Foo"},
{"byte", "string"}
{1, "Foo", "Bar"},
{"byte", {"string", 2}}
)
buildat.send_packet("test1:box_added", data)
end)
@ -72,6 +72,18 @@ mouseinput.sub_up(function(button, x, y)
--log:info("mouse up: "..button..", "..x..", "..y..")")
end)
buildat.sub_packet("test1:array", function(data)
values = cereal.binary_input(data, {"int32"})
values = cereal.binary_input(data, {"int32", {"int32", values[1]}})
log:info("test1:array: "..dump(values))
data = cereal.binary_output(
values,
{"int32", {"int32", values[1]}}
)
buildat.send_packet("test1:array_response", data)
end)
--[[
-- Temporary test
require "Polycode/Core"

View File

@ -86,6 +86,15 @@ struct Module: public interface::Module
}
inetwork->send(event.recipient, "test1:add_box", os.str());
});
network::access(m_server, [&](network::Interface * inetwork){
std::ostringstream os(std::ios::binary);
{
cereal::PortableBinaryOutputArchive ar(os);
ar((int32_t)5, (int32_t)1, (int32_t)4, (int32_t)6, (int32_t)8, (int32_t)10);
}
inetwork->send(event.recipient, "test1:array", os.str());
});
}
void on_packet_received(const network::Packet &packet)