mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
add sharemap , an example of stm
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "rwlock.h"
|
#include "rwlock.h"
|
||||||
#include "skynet_malloc.h"
|
#include "skynet_malloc.h"
|
||||||
@@ -126,8 +127,16 @@ lcopy(lua_State *L) {
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
lnewwriter(lua_State *L) {
|
lnewwriter(lua_State *L) {
|
||||||
void * msg = lua_touserdata(L, 1);
|
void * msg;
|
||||||
uint32_t sz = (uint32_t)luaL_checkinteger(L, 2);
|
size_t sz;
|
||||||
|
if (lua_isuserdata(L,1)) {
|
||||||
|
msg = lua_touserdata(L, 1);
|
||||||
|
sz = (size_t)luaL_checkinteger(L, 2);
|
||||||
|
} else {
|
||||||
|
const char * tmp = luaL_checklstring(L,1,&sz);
|
||||||
|
msg = skynet_malloc(sz);
|
||||||
|
memcpy(msg, tmp, sz);
|
||||||
|
}
|
||||||
struct boxstm * box = lua_newuserdata(L, sizeof(*box));
|
struct boxstm * box = lua_newuserdata(L, sizeof(*box));
|
||||||
box->obj = stm_new(msg,sz);
|
box->obj = stm_new(msg,sz);
|
||||||
lua_pushvalue(L, lua_upvalueindex(1));
|
lua_pushvalue(L, lua_upvalueindex(1));
|
||||||
@@ -148,8 +157,16 @@ ldeletewriter(lua_State *L) {
|
|||||||
static int
|
static int
|
||||||
lupdate(lua_State *L) {
|
lupdate(lua_State *L) {
|
||||||
struct boxstm * box = lua_touserdata(L, 1);
|
struct boxstm * box = lua_touserdata(L, 1);
|
||||||
void * msg = lua_touserdata(L, 2);
|
void * msg;
|
||||||
uint32_t sz = (uint32_t)luaL_checkinteger(L, 3);
|
size_t sz;
|
||||||
|
if (lua_isuserdata(L, 2)) {
|
||||||
|
msg = lua_touserdata(L, 2);
|
||||||
|
sz = (size_t)luaL_checkinteger(L, 3);
|
||||||
|
} else {
|
||||||
|
const char * tmp = luaL_checklstring(L,2,&sz);
|
||||||
|
msg = skynet_malloc(sz);
|
||||||
|
memcpy(msg, tmp, sz);
|
||||||
|
}
|
||||||
stm_update(box->obj, msg, sz);
|
stm_update(box->obj, msg, sz);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -186,6 +203,7 @@ static int
|
|||||||
lread(lua_State *L) {
|
lread(lua_State *L) {
|
||||||
struct boxreader * box = lua_touserdata(L, 1);
|
struct boxreader * box = lua_touserdata(L, 1);
|
||||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||||
|
|
||||||
struct stm_copy * copy = stm_copy(box->obj);
|
struct stm_copy * copy = stm_copy(box->obj);
|
||||||
if (copy == box->lastcopy) {
|
if (copy == box->lastcopy) {
|
||||||
// not update
|
// not update
|
||||||
@@ -197,10 +215,13 @@ lread(lua_State *L) {
|
|||||||
stm_releasecopy(box->lastcopy);
|
stm_releasecopy(box->lastcopy);
|
||||||
box->lastcopy = copy;
|
box->lastcopy = copy;
|
||||||
if (copy) {
|
if (copy) {
|
||||||
|
lua_settop(L, 3);
|
||||||
|
lua_replace(L, 1);
|
||||||
lua_settop(L, 2);
|
lua_settop(L, 2);
|
||||||
lua_pushlightuserdata(L, copy->msg);
|
lua_pushlightuserdata(L, copy->msg);
|
||||||
lua_pushinteger(L, copy->sz);
|
lua_pushinteger(L, copy->sz);
|
||||||
lua_call(L, 2, LUA_MULTRET);
|
lua_pushvalue(L, 1);
|
||||||
|
lua_call(L, 3, LUA_MULTRET);
|
||||||
lua_pushboolean(L, 1);
|
lua_pushboolean(L, 1);
|
||||||
lua_replace(L, 1);
|
lua_replace(L, 1);
|
||||||
return lua_gettop(L);
|
return lua_gettop(L);
|
||||||
|
|||||||
69
lualib/sharemap.lua
Normal file
69
lualib/sharemap.lua
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
local stm = require "stm"
|
||||||
|
local sprotoloader = require "sprotoloader"
|
||||||
|
local sproto = require "sproto"
|
||||||
|
local setmetatable = setmetatable
|
||||||
|
|
||||||
|
local sharemap = {}
|
||||||
|
|
||||||
|
function sharemap.register(protofile)
|
||||||
|
-- use global slot 0 for type define
|
||||||
|
sprotoloader.register(protofile, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local sprotoobj
|
||||||
|
local function loadsp()
|
||||||
|
if sprotoobj == nil then
|
||||||
|
sprotoobj = sprotoloader.load(0)
|
||||||
|
end
|
||||||
|
return sprotoobj
|
||||||
|
end
|
||||||
|
|
||||||
|
function sharemap:commit()
|
||||||
|
self.__obj(sprotoobj:encode(self.__typename, self.__data))
|
||||||
|
end
|
||||||
|
|
||||||
|
function sharemap:copy()
|
||||||
|
return stm.copy(self.__obj)
|
||||||
|
end
|
||||||
|
|
||||||
|
function sharemap.writer(typename, obj)
|
||||||
|
local sp = loadsp()
|
||||||
|
obj = obj or {}
|
||||||
|
local stmobj = stm.new(sp:encode(typename,obj))
|
||||||
|
obj.__typename = typename
|
||||||
|
obj.__obj = stmobj
|
||||||
|
obj.__data = obj
|
||||||
|
obj.commit = sharemap.commit
|
||||||
|
obj.copy = sharemap.copy
|
||||||
|
return setmetatable(obj, { __index = obj.__data, __newindex = obj.__data })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function decode(msg, sz, self)
|
||||||
|
local data = self.__data
|
||||||
|
for k in pairs(data) do
|
||||||
|
data[k] = nil
|
||||||
|
end
|
||||||
|
return sprotoobj:decode(self.__typename, msg, sz, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function sharemap:update()
|
||||||
|
return self.__obj(decode, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function sharemap.reader(typename, stmcpy)
|
||||||
|
local sp = loadsp()
|
||||||
|
local stmobj = stm.newcopy(stmcpy)
|
||||||
|
local _, data = stmobj(function(msg, sz)
|
||||||
|
return sp:decode(typename, msg, sz)
|
||||||
|
end)
|
||||||
|
|
||||||
|
local obj = {
|
||||||
|
__typename = typename,
|
||||||
|
__obj = stmobj,
|
||||||
|
__data = data,
|
||||||
|
update = sharemap.update,
|
||||||
|
}
|
||||||
|
return setmetatable(obj, { __index = obj.__data, __newindex = error })
|
||||||
|
end
|
||||||
|
|
||||||
|
return sharemap
|
||||||
@@ -53,9 +53,9 @@ function sproto:encode(typename, tbl)
|
|||||||
return core.encode(st, tbl)
|
return core.encode(st, tbl)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sproto:decode(typename, bin)
|
function sproto:decode(typename, ...)
|
||||||
local st = querytype(self, typename)
|
local st = querytype(self, typename)
|
||||||
return core.decode(st, bin)
|
return core.decode(st, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sproto:pencode(typename, tbl)
|
function sproto:pencode(typename, tbl)
|
||||||
|
|||||||
5
test/sharemap.sp
Normal file
5
test/sharemap.sp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.foobar {
|
||||||
|
x 0 : integer
|
||||||
|
y 1 : integer
|
||||||
|
s 2 : string
|
||||||
|
}
|
||||||
48
test/testsm.lua
Normal file
48
test/testsm.lua
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local sharemap = require "sharemap"
|
||||||
|
|
||||||
|
local mode = ...
|
||||||
|
|
||||||
|
if mode == "slave" then
|
||||||
|
--slave
|
||||||
|
|
||||||
|
local function dump(reader)
|
||||||
|
reader:update()
|
||||||
|
print("x=", reader.x)
|
||||||
|
print("y=", reader.y)
|
||||||
|
print("s=", reader.s)
|
||||||
|
end
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
local reader
|
||||||
|
skynet.dispatch("lua", function(_,_,cmd,...)
|
||||||
|
if cmd == "init" then
|
||||||
|
reader = sharemap.reader(...)
|
||||||
|
else
|
||||||
|
assert(cmd == "ping")
|
||||||
|
dump(reader)
|
||||||
|
end
|
||||||
|
skynet.ret()
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
else
|
||||||
|
-- master
|
||||||
|
skynet.start(function()
|
||||||
|
-- register share type schema
|
||||||
|
sharemap.register("./test/sharemap.sp")
|
||||||
|
local slave = skynet.newservice(SERVICE_NAME, "slave")
|
||||||
|
local writer = sharemap.writer("foobar", { x=0,y=0,s="hello" })
|
||||||
|
skynet.call(slave, "lua", "init", "foobar", writer:copy())
|
||||||
|
writer.x = 1
|
||||||
|
writer:commit()
|
||||||
|
skynet.call(slave, "lua", "ping")
|
||||||
|
writer.y = 2
|
||||||
|
writer:commit()
|
||||||
|
skynet.call(slave, "lua", "ping")
|
||||||
|
writer.s = "world"
|
||||||
|
writer:commit()
|
||||||
|
skynet.call(slave, "lua", "ping")
|
||||||
|
end)
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user