Custom InvRef implementation for in-memory cache
This commit is contained in:
parent
dfc8e4adcc
commit
109f6e1aa6
@ -66,7 +66,7 @@ if quartz then
|
|||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
type = "cooking",
|
type = "cooking",
|
||||||
output = "holostorage:silicon",
|
output = "holostorage:silicon",
|
||||||
recipe = "holostorage:quartz_iron"
|
recipe = "quartz:quartz_crystal"
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
3
init.lua
3
init.lua
@ -7,6 +7,9 @@ holostorage.modpath = modpath
|
|||||||
|
|
||||||
holostorage.devices = {}
|
holostorage.devices = {}
|
||||||
|
|
||||||
|
-- Memory Storage
|
||||||
|
dofile(modpath.."/masscache.lua")
|
||||||
|
|
||||||
-- Network
|
-- Network
|
||||||
dofile(modpath.."/network.lua")
|
dofile(modpath.."/network.lua")
|
||||||
|
|
||||||
|
@ -1,29 +1,6 @@
|
|||||||
-- Storage disks
|
-- Storage disks
|
||||||
|
|
||||||
holostorage.disks = {}
|
holostorage.disks = {}
|
||||||
holostorage.disks.memcache = {}
|
|
||||||
|
|
||||||
local function inv_to_table(inv)
|
|
||||||
local t = {}
|
|
||||||
for listname, list in pairs(inv:get_lists()) do
|
|
||||||
local size = inv:get_size(listname)
|
|
||||||
if size then
|
|
||||||
t[listname] = {}
|
|
||||||
for i = 1, size, 1 do
|
|
||||||
t[listname][i] = inv:get_stack(listname, i):to_table()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return t
|
|
||||||
end
|
|
||||||
|
|
||||||
local function table_to_inv(inv, t)
|
|
||||||
for listname, list in pairs(t) do
|
|
||||||
for i, stack in pairs(list) do
|
|
||||||
inv:set_stack(listname, i, stack)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function holostorage.disks.register_disk(index, desc, capacity)
|
function holostorage.disks.register_disk(index, desc, capacity)
|
||||||
local mod = minetest.get_current_modname()
|
local mod = minetest.get_current_modname()
|
||||||
@ -40,88 +17,12 @@ function holostorage.disks.register_disk(index, desc, capacity)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local function create_invref(ptr, capacity)
|
|
||||||
local inv = minetest.create_detached_inventory(ptr, {})
|
|
||||||
inv:set_size("main", capacity)
|
|
||||||
return inv
|
|
||||||
end
|
|
||||||
|
|
||||||
function holostorage.disks.ensure_disk_inventory(stack, pstr)
|
|
||||||
local meta = stack:get_meta()
|
|
||||||
local tag = meta:get_string("storage_tag")
|
|
||||||
local cap = minetest.registered_items[stack:get_name()].holostorage_capacity
|
|
||||||
|
|
||||||
if not tag or tag == "" then
|
|
||||||
local rnd = PseudoRandom(os.clock())
|
|
||||||
local rndint = rnd.next(rnd)
|
|
||||||
local diskid = "d"..pstr.."-"..rndint
|
|
||||||
meta:set_string("storage_tag", diskid)
|
|
||||||
holostorage.disks.memcache[diskid] = create_invref(diskid, cap)
|
|
||||||
end
|
|
||||||
|
|
||||||
return stack
|
|
||||||
end
|
|
||||||
|
|
||||||
function holostorage.disks.load_disk_from_file(stack, diskptr)
|
|
||||||
local world = minetest.get_worldpath()
|
|
||||||
local directory = world.."/holostorage"
|
|
||||||
local cap = minetest.registered_items[stack:get_name()].holostorage_capacity
|
|
||||||
local inv = create_invref(diskptr, cap)
|
|
||||||
minetest.mkdir(directory)
|
|
||||||
|
|
||||||
local filetag = minetest.sha1(diskptr)..".invref"
|
|
||||||
local file = io.open(directory.."/"..filetag)
|
|
||||||
|
|
||||||
if not file then
|
|
||||||
holostorage.disks.memcache[diskptr] = inv
|
|
||||||
return diskptr
|
|
||||||
end
|
|
||||||
|
|
||||||
local str = ""
|
|
||||||
for line in file:lines() do
|
|
||||||
str = str..line
|
|
||||||
end
|
|
||||||
|
|
||||||
file:close()
|
|
||||||
|
|
||||||
table_to_inv(inv, minetest.deserialize(str))
|
|
||||||
holostorage.disks.memcache[diskptr] = inv
|
|
||||||
return diskptr
|
|
||||||
end
|
|
||||||
|
|
||||||
function holostorage.disks.save_disk_to_file(diskptr)
|
|
||||||
if not holostorage.disks.memcache[diskptr] then return nil end
|
|
||||||
|
|
||||||
local world = minetest.get_worldpath()
|
|
||||||
local directory = world.."/holostorage"
|
|
||||||
local filetag = minetest.sha1(diskptr)..".invref"
|
|
||||||
|
|
||||||
minetest.mkdir(directory)
|
|
||||||
|
|
||||||
local inv = holostorage.disks.memcache[diskptr]
|
|
||||||
local data = minetest.serialize(inv_to_table(inv))
|
|
||||||
|
|
||||||
minetest.safe_file_write(directory.."/"..filetag, data)
|
|
||||||
return diskptr
|
|
||||||
end
|
|
||||||
|
|
||||||
function holostorage.disks.save_disks_to_file()
|
|
||||||
for diskptr in pairs(holostorage.disks.memcache) do
|
|
||||||
holostorage.disks.save_disk_to_file(diskptr)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Make sure stack is disk
|
-- Make sure stack is disk
|
||||||
function holostorage.disks.is_valid_disk(stack)
|
function holostorage.disks.is_valid_disk(stack)
|
||||||
local stack_name = stack:get_name()
|
local stack_name = stack:get_name()
|
||||||
return minetest.get_item_group(stack_name, "holostorage_disk") > 0
|
return minetest.get_item_group(stack_name, "holostorage_disk") > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Save disks on shutdown
|
|
||||||
minetest.register_on_shutdown(function ()
|
|
||||||
holostorage.disks.save_disks_to_file()
|
|
||||||
end)
|
|
||||||
|
|
||||||
local capacities = {1000, 8000, 16000, 32000, 64000}
|
local capacities = {1000, 8000, 16000, 32000, 64000}
|
||||||
local descriptions = {"1K Disk", "8K Disk", "16K Disk", "32K Disk", "64K Disk"}
|
local descriptions = {"1K Disk", "8K Disk", "16K Disk", "32K Disk", "64K Disk"}
|
||||||
for i = 1, 5 do
|
for i = 1, 5 do
|
||||||
|
233
masscache.lua
Normal file
233
masscache.lua
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
|
||||||
|
-- INVENTORY CACHE
|
||||||
|
holostorage.server_inventory = {
|
||||||
|
cache = {},
|
||||||
|
new = function (size)
|
||||||
|
local system = {
|
||||||
|
size = size,
|
||||||
|
stacks = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function system:get_size(abs)
|
||||||
|
return system.size
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:get_stack(abs, index)
|
||||||
|
if not index then index = abs end
|
||||||
|
|
||||||
|
if system.stacks[index] then
|
||||||
|
return system.stacks[index]
|
||||||
|
end
|
||||||
|
|
||||||
|
return ItemStack(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:set_stack(abs, index, stack)
|
||||||
|
if not stack then
|
||||||
|
stack = index
|
||||||
|
index = abs
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(stack) == "table" or type(stack) == "string" then
|
||||||
|
stack = ItemStack(stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
system.stacks[index] = stack
|
||||||
|
return stack
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:get_list(abs)
|
||||||
|
return system.stacks
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:set_list(abs, list)
|
||||||
|
if not list then list = abs end
|
||||||
|
|
||||||
|
system.stacks = list
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:get_width(abs)
|
||||||
|
local size = 0
|
||||||
|
for _,v in pairs(system.stacks) do
|
||||||
|
if v and not v:is_empty() then
|
||||||
|
size = size + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return size
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:first_empty_index()
|
||||||
|
local index = 0
|
||||||
|
local last = 0
|
||||||
|
for inx, stack in pairs(system.stacks) do
|
||||||
|
if stack:is_empty() then
|
||||||
|
index = inx
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if last ~= inx - 1 then
|
||||||
|
index = inx - 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
last = inx
|
||||||
|
end
|
||||||
|
|
||||||
|
if index == 0 then
|
||||||
|
return #system.stacks + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return index
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:room_for_item(abs, stack)
|
||||||
|
if not stack then stack = abs end
|
||||||
|
local matching = false
|
||||||
|
|
||||||
|
if system:get_width() < system.size then return true end
|
||||||
|
|
||||||
|
for _,stc in pairs(system.stacks) do
|
||||||
|
if not stc or stc:is_empty() then
|
||||||
|
matching = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if stc:get_name() == stack:get_name() and
|
||||||
|
stc:get_meta() == stack:get_meta() then
|
||||||
|
if stc:item_fits(stack) then
|
||||||
|
matching = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return matching
|
||||||
|
end
|
||||||
|
|
||||||
|
function system:add_item(abs, stack)
|
||||||
|
if not stack then stack = abs end
|
||||||
|
local leftover = nil
|
||||||
|
for i,stc in pairs(system.stacks) do
|
||||||
|
if not stc or stc:is_empty() then
|
||||||
|
system[i] = stack
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if stc:get_name() == stack:get_name() and stc:get_meta() == stack:get_meta() then
|
||||||
|
if stc:get_count() == stack:get_stack_max() then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
leftover = system.stacks[i]:add_item(stack)
|
||||||
|
if leftover and not leftover:is_empty() and system:room_for_item(leftover) then
|
||||||
|
leftover = system:add_item(leftover)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not leftover then
|
||||||
|
system.stacks[system:first_empty_index()] = stack
|
||||||
|
leftover = ItemStack(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
return leftover
|
||||||
|
end
|
||||||
|
|
||||||
|
return system
|
||||||
|
end,
|
||||||
|
from_table = function (inv, table)
|
||||||
|
if table["main"] then
|
||||||
|
table = table["main"]
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, stack in pairs(table) do
|
||||||
|
inv:set_stack(i, stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
return inv
|
||||||
|
end,
|
||||||
|
to_table = function (inv)
|
||||||
|
local t = {}
|
||||||
|
local size = inv:get_size()
|
||||||
|
if size then
|
||||||
|
for i = 1, size, 1 do
|
||||||
|
t[i] = inv:get_stack(i):to_table()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
local function create_invref(capacity)
|
||||||
|
return holostorage.server_inventory.new(capacity)
|
||||||
|
end
|
||||||
|
|
||||||
|
function holostorage.server_inventory.ensure_disk_inventory(stack, pstr)
|
||||||
|
local meta = stack:get_meta()
|
||||||
|
local tag = meta:get_string("storage_tag")
|
||||||
|
local cap = minetest.registered_items[stack:get_name()].holostorage_capacity
|
||||||
|
|
||||||
|
if not tag or tag == "" then
|
||||||
|
local rnd = PseudoRandom(os.clock())
|
||||||
|
local rndint = rnd.next(rnd)
|
||||||
|
local diskid = "d"..pstr.."-"..rndint
|
||||||
|
meta:set_string("storage_tag", diskid)
|
||||||
|
holostorage.server_inventory.cache[diskid] = create_invref(cap)
|
||||||
|
end
|
||||||
|
|
||||||
|
return stack
|
||||||
|
end
|
||||||
|
|
||||||
|
function holostorage.server_inventory.load_disk_from_file(stack, diskptr)
|
||||||
|
local world = minetest.get_worldpath()
|
||||||
|
local directory = world.."/holostorage"
|
||||||
|
local cap = minetest.registered_items[stack:get_name()].holostorage_capacity
|
||||||
|
local inv = create_invref(cap)
|
||||||
|
minetest.mkdir(directory)
|
||||||
|
|
||||||
|
local filetag = minetest.sha1(diskptr)..".invref"
|
||||||
|
local file = io.open(directory.."/"..filetag)
|
||||||
|
|
||||||
|
if not file then
|
||||||
|
holostorage.server_inventory.cache[diskptr] = inv
|
||||||
|
return diskptr
|
||||||
|
end
|
||||||
|
|
||||||
|
local str = ""
|
||||||
|
for line in file:lines() do
|
||||||
|
str = str..line
|
||||||
|
end
|
||||||
|
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
holostorage.server_inventory.from_table(inv, minetest.deserialize(str))
|
||||||
|
holostorage.server_inventory.cache[diskptr] = inv
|
||||||
|
return diskptr
|
||||||
|
end
|
||||||
|
|
||||||
|
function holostorage.server_inventory.save_disk_to_file(diskptr)
|
||||||
|
if not holostorage.server_inventory.cache[diskptr] then return nil end
|
||||||
|
|
||||||
|
local world = minetest.get_worldpath()
|
||||||
|
local directory = world.."/holostorage"
|
||||||
|
local filetag = minetest.sha1(diskptr)..".invref"
|
||||||
|
|
||||||
|
minetest.mkdir(directory)
|
||||||
|
|
||||||
|
local inv = holostorage.server_inventory.cache[diskptr]
|
||||||
|
local data = minetest.serialize(holostorage.server_inventory.to_table(inv))
|
||||||
|
|
||||||
|
minetest.safe_file_write(directory.."/"..filetag, data)
|
||||||
|
return diskptr
|
||||||
|
end
|
||||||
|
|
||||||
|
function holostorage.server_inventory.save_disks_to_file()
|
||||||
|
for diskptr in pairs(holostorage.server_inventory.cache) do
|
||||||
|
holostorage.server_inventory.save_disk_to_file(diskptr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Save disks on shutdown
|
||||||
|
minetest.register_on_shutdown(function ()
|
||||||
|
holostorage.server_inventory.save_disks_to_file()
|
||||||
|
end)
|
@ -197,7 +197,6 @@ minetest.register_node("holostorage:export_bus", {
|
|||||||
meta:set_string("infotext", "Inventory full")
|
meta:set_string("infotext", "Inventory full")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
meta:set_string("infotext", "Exporting to Inventory at "..front_pos)
|
meta:set_string("infotext", "Exporting to Inventory at "..front_pos)
|
||||||
|
|
||||||
if can_take then
|
if can_take then
|
||||||
|
@ -53,7 +53,7 @@ function holostorage.stack_list(pos)
|
|||||||
local tabl = {}
|
local tabl = {}
|
||||||
|
|
||||||
for _,diskptr in pairs(invs) do
|
for _,diskptr in pairs(invs) do
|
||||||
local invref = holostorage.disks.memcache[diskptr]
|
local invref = holostorage.server_inventory.cache[diskptr]
|
||||||
local inv_n = "main"
|
local inv_n = "main"
|
||||||
local inv_p
|
local inv_p
|
||||||
if diskptr:find("chest/") then
|
if diskptr:find("chest/") then
|
||||||
@ -86,7 +86,7 @@ function holostorage.insert_stack(pos, stack)
|
|||||||
local leftover
|
local leftover
|
||||||
|
|
||||||
for _,diskptr in pairs(invs) do
|
for _,diskptr in pairs(invs) do
|
||||||
local invref = holostorage.disks.memcache[diskptr]
|
local invref = holostorage.server_inventory.cache[diskptr]
|
||||||
local inv_n = "main"
|
local inv_n = "main"
|
||||||
local inv_p
|
local inv_p
|
||||||
if diskptr:find("chest/") then
|
if diskptr:find("chest/") then
|
||||||
@ -116,7 +116,7 @@ function holostorage.take_stack(pos, stack)
|
|||||||
local success = false
|
local success = false
|
||||||
|
|
||||||
for _,diskptr in pairs(invs) do
|
for _,diskptr in pairs(invs) do
|
||||||
local invref = holostorage.disks.memcache[diskptr]
|
local invref = holostorage.server_inventory.cache[diskptr]
|
||||||
local inv_n = "main"
|
local inv_n = "main"
|
||||||
local inv_p
|
local inv_p
|
||||||
if diskptr:find("chest/") then
|
if diskptr:find("chest/") then
|
||||||
|
@ -111,7 +111,7 @@ local function register_disk_drive(index)
|
|||||||
minetest.get_node_timer(pos):start(0.02)
|
minetest.get_node_timer(pos):start(0.02)
|
||||||
end,
|
end,
|
||||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
stack = holostorage.disks.ensure_disk_inventory(stack, minetest.pos_to_string(pos))
|
stack = holostorage.server_inventory.ensure_disk_inventory(stack, minetest.pos_to_string(pos))
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
@ -149,9 +149,9 @@ minetest.register_abm({
|
|||||||
local meta = stack:get_meta()
|
local meta = stack:get_meta()
|
||||||
local tag = meta:get_string("storage_tag")
|
local tag = meta:get_string("storage_tag")
|
||||||
if tag and tag ~= "" then
|
if tag and tag ~= "" then
|
||||||
if not holostorage.disks.memcache[tag] then
|
if not holostorage.server_inventory.cache[tag] then
|
||||||
print("loading drive",tag)
|
print("loading drive",tag)
|
||||||
holostorage.disks.load_disk_from_file(stack, tag)
|
holostorage.server_inventory.load_disk_from_file(stack, tag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
BIN
textures/holostorage_external.png
Normal file
BIN
textures/holostorage_external.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 472 B |
Loading…
Reference in New Issue
Block a user