client: Packet handling in Lua; extensions/cereal
This commit is contained in:
parent
e41f7ad8b8
commit
0c7d5602bb
@ -1,18 +1,25 @@
|
||||
local log = buildat.Logger("__client/packet")
|
||||
|
||||
__buildat_packet_subs = {}
|
||||
local packet_subs = {}
|
||||
|
||||
function buildat:sub_packet(name, cb)
|
||||
__buildat_packet_subs[name] = cb
|
||||
function __buildat_handle_packet(name, data)
|
||||
local cb = packet_subs[name]
|
||||
if cb then
|
||||
cb(data)
|
||||
end
|
||||
function buildat:unsub_packet(cb)
|
||||
end
|
||||
|
||||
function buildat.sub_packet(name, cb)
|
||||
packet_subs[name] = cb
|
||||
end
|
||||
function buildat.unsub_packet(cb)
|
||||
for name, cb1 in pairs(buildat.packet_subs) do
|
||||
if cb1 == cb then
|
||||
__buildat_packet_subs[cb] = nil
|
||||
packet_subs[cb] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function buildat:send_packet(name, data)
|
||||
function buildat.send_packet(name, data)
|
||||
__buildat_send_packet(name, data)
|
||||
end
|
||||
|
11
extensions/cereal/init.lua
Normal file
11
extensions/cereal/init.lua
Normal file
@ -0,0 +1,11 @@
|
||||
-- Buildat: extension/cereal/init.lua
|
||||
local polybox = require("buildat/extension/polycode_sandbox")
|
||||
local log = buildat.Logger("extension/cereal")
|
||||
local M = {safe = {}}
|
||||
|
||||
function M.safe.binary_input(data, types)
|
||||
return __buildat_cereal_binary_input(data, types)
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <OSBasics.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#include <c55/getopt.h>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
#include <core/log.h>
|
||||
#include <signal.h>
|
||||
#define MODULE "__main"
|
||||
@ -283,6 +285,7 @@ struct CApp: public Polycode::EventHandler, public App
|
||||
DEF_BUILDAT_FUNC(get_file_path)
|
||||
DEF_BUILDAT_FUNC(get_path)
|
||||
DEF_BUILDAT_FUNC(pcall)
|
||||
DEF_BUILDAT_FUNC(cereal_binary_input)
|
||||
|
||||
ss_ init_lua_path = g_client_config.share_path+"/client/init.lua";
|
||||
int error = luaL_dofile(L, init_lua_path.c_str());
|
||||
@ -332,6 +335,16 @@ struct CApp: public Polycode::EventHandler, public App
|
||||
}
|
||||
}
|
||||
|
||||
void handle_packet(const ss_ &name, const ss_ &data)
|
||||
{
|
||||
log_v(MODULE, "handle_packet(): %s", cs(name));
|
||||
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "__buildat_handle_packet");
|
||||
lua_pushlstring(L, name.c_str(), name.size());
|
||||
lua_pushlstring(L, data.c_str(), data.size());
|
||||
lua_call(L, 2, 0);
|
||||
}
|
||||
|
||||
// Non-public methods
|
||||
|
||||
// send_packet(name: string, data: string)
|
||||
@ -474,6 +487,66 @@ struct CApp: public Polycode::EventHandler, public App
|
||||
lua_pushvalue(L, error_stack_i);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// cereal_binary_input(data: string, types: table of strings)
|
||||
// -> table of values
|
||||
static int l_cereal_binary_input(lua_State *L)
|
||||
{
|
||||
size_t data_len = 0;
|
||||
const char *data_c = lua_tolstring(L, 1, &data_len);
|
||||
ss_ data(data_c, data_len);
|
||||
|
||||
int types_table_L = 2;
|
||||
|
||||
lua_newtable(L);
|
||||
int result_table_L = lua_gettop(L);
|
||||
|
||||
std::istringstream is(data, std::ios::binary);
|
||||
{
|
||||
cereal::PortableBinaryInputArchive ar(is);
|
||||
|
||||
int output_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"){
|
||||
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++);
|
||||
continue;
|
||||
}
|
||||
if(type == "double"){
|
||||
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++);
|
||||
continue;
|
||||
}
|
||||
throw Exception(ss_()+"Unknown type \""+type+"\""
|
||||
"; known types are byte, int32, double, string");
|
||||
}
|
||||
}
|
||||
// Result table is on top of stack
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
App* createApp(Polycode::PolycodeView *view)
|
||||
|
@ -19,6 +19,7 @@ namespace app
|
||||
virtual bool update() = 0;
|
||||
virtual void shutdown() = 0;
|
||||
virtual void run_script(const ss_ &script) = 0;
|
||||
virtual void handle_packet(const ss_ &name, const ss_ &data) = 0;
|
||||
};
|
||||
|
||||
App* createApp(Polycode::PolycodeView *view);
|
||||
|
@ -133,6 +133,11 @@ struct CState: public State
|
||||
|
||||
void handle_packet(const ss_ &packet_name, const ss_ &data)
|
||||
{
|
||||
if(packet_name.substr(0,5) != "core:"){
|
||||
m_app->handle_packet(packet_name, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if(packet_name == "core:run_script"){
|
||||
log_i(MODULE, "Asked to run script:\n----\n%s\n----", cs(data));
|
||||
if(m_app)
|
||||
|
@ -1,17 +1,9 @@
|
||||
-- Buildat: test1/client_lua/init.lua
|
||||
local log = buildat.Logger("test1")
|
||||
local dump = buildat.dump
|
||||
log:info("test1/init.lua loaded")
|
||||
|
||||
--[[
|
||||
-- Temporary test
|
||||
require "Polycode/Core"
|
||||
scene = Scene(Scene.SCENE_2D)
|
||||
scene:getActiveCamera():setOrthoSize(640, 480)
|
||||
label = SceneLabel("Hello from remote module!", 32)
|
||||
label:setPosition(0, -100, 0)
|
||||
scene:addChild(label)
|
||||
--]]
|
||||
|
||||
-- Test extension interface safety
|
||||
local test = require("buildat/extension/test")
|
||||
|
||||
test.f()
|
||||
@ -24,10 +16,35 @@ ground = g3d.ScenePrimitive(g3d.ScenePrimitive.TYPE_PLANE, 5,5)
|
||||
ground:loadTexture("test1/green_texture.png")
|
||||
scene:addEntity(ground)
|
||||
|
||||
box = g3d.ScenePrimitive(g3d.ScenePrimitive.TYPE_BOX, 1,1,1)
|
||||
box:loadTexture("test1/pink_texture.png")
|
||||
box:setPosition(0.0, 0.5, 0.0)
|
||||
scene:addEntity(box)
|
||||
|
||||
scene:getDefaultCamera():setPosition(7,7,7)
|
||||
scene:getDefaultCamera():lookAt(g3d.Vector3(0,0,0), g3d.Vector3(0,1,0))
|
||||
|
||||
local cereal = require("buildat/extension/cereal")
|
||||
|
||||
buildat.sub_packet("test1:add_box", function(data)
|
||||
values = cereal.binary_input(data, {
|
||||
"double", "double", "double",
|
||||
"double", "double", "double"
|
||||
})
|
||||
local w = values[1]
|
||||
local h = values[2]
|
||||
local d = values[3]
|
||||
local x = values[4]
|
||||
local y = values[5]
|
||||
local z = values[6]
|
||||
log:info("values="..dump(values))
|
||||
box = g3d.ScenePrimitive(g3d.ScenePrimitive.TYPE_BOX, w,h,d)
|
||||
box:loadTexture("test1/pink_texture.png")
|
||||
box:setPosition(x, y, z)
|
||||
scene:addEntity(box)
|
||||
end)
|
||||
|
||||
--[[
|
||||
-- Temporary test
|
||||
require "Polycode/Core"
|
||||
scene = Scene(Scene.SCENE_2D)
|
||||
scene:getActiveCamera():setOrthoSize(640, 480)
|
||||
label = SceneLabel("Hello from remote module!", 32)
|
||||
label:setPosition(0, -100, 0)
|
||||
scene:addChild(label)
|
||||
--]]
|
||||
|
@ -2,10 +2,10 @@
|
||||
#include "interface/server.h"
|
||||
#include "interface/event.h"
|
||||
#include "test1/api.h"
|
||||
//#include "client_lua/api.h"
|
||||
#include "client_file/api.h"
|
||||
#include "network/api.h"
|
||||
#include "core/log.h"
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
|
||||
using interface::Event;
|
||||
|
||||
@ -71,10 +71,21 @@ struct Module: public interface::Module
|
||||
void on_files_transmitted(const client_file::FilesTransmitted &event)
|
||||
{
|
||||
log_v(MODULE, "on_files_transmitted(): recipient=%zu", event.recipient);
|
||||
|
||||
network::access(m_server, [&](network::Interface * inetwork){
|
||||
inetwork->send(event.recipient, "core:run_script",
|
||||
"buildat:run_script_file(\"test1/init.lua\")");
|
||||
});
|
||||
|
||||
network::access(m_server, [&](network::Interface * inetwork){
|
||||
std::ostringstream os(std::ios::binary);
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive ar(os);
|
||||
ar(1.0, 1.0, 1.0);
|
||||
ar(0.0, 0.5, 0.0);
|
||||
}
|
||||
inetwork->send(event.recipient, "test1:add_box", os.str());
|
||||
});
|
||||
}
|
||||
|
||||
void on_packet_received(const network::Packet &packet)
|
||||
|
Loading…
x
Reference in New Issue
Block a user