mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-28 05:21:05 +01:00
Disable mesecons processing, create initial redstone power propigation code, change wall lever to use new code, modify scheduler to provide backtraces when tasks error
This commit is contained in:
parent
a958fbbf71
commit
6107bba52f
7 changed files with 167 additions and 9 deletions
|
@ -100,7 +100,7 @@ if false then
|
|||
act("test")
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local function run_scheduler(dtime)
|
||||
local start_time = minetest_get_us_time()
|
||||
local end_time = start_time + 50000
|
||||
time = time + dtime
|
||||
|
@ -129,7 +129,10 @@ minetest.register_globalstep(function(dtime)
|
|||
local func = functions[task.fid]
|
||||
if func then
|
||||
--print("Running task "..dump(task)..",func="..dump(func))
|
||||
local ok,ret = pcall(func.func, task, unpack(task.args or {}))
|
||||
local function caller()
|
||||
return func.func(task, unpack(task.args or {}))
|
||||
end
|
||||
local ok,ret = xpcall(caller, debug.traceback)
|
||||
if not ok then
|
||||
minetest.log("error","Error while running task "..func.name..": "..tostring(ret))
|
||||
end
|
||||
|
@ -149,7 +152,9 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
end
|
||||
end
|
||||
print("Total scheduler time: "..tostring(minetest_get_us_time() - start_time).." microseconds")
|
||||
--print("Total scheduler time: "..tostring(minetest_get_us_time() - start_time).." microseconds")
|
||||
--print("priority_queue="..dump(priority_queue))
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime) run_scheduler(dtime) end)
|
||||
|
||||
|
|
|
@ -58,9 +58,11 @@ local function get_highest_priority(actions)
|
|||
return highesti
|
||||
end
|
||||
|
||||
--[[
|
||||
local m_time = 0
|
||||
local resumetime = mesecon.setting("resumetime", 4)
|
||||
minetest.register_globalstep(function (dtime)
|
||||
|
||||
m_time = m_time + dtime
|
||||
-- don't even try if server has not been running for XY seconds; resumetime = time to wait
|
||||
-- after starting the server before processing the ActionQueue, don't set this too low
|
||||
|
@ -87,6 +89,7 @@ minetest.register_globalstep(function (dtime)
|
|||
table.remove(actions_now, hp)
|
||||
end
|
||||
end)
|
||||
]]
|
||||
|
||||
function mesecon.queue:execute(action)
|
||||
if not action.pos then return end
|
||||
|
|
|
@ -87,7 +87,8 @@ mesecon.queue:add_function("receptor_on", function (pos, rules)
|
|||
end)
|
||||
|
||||
function mesecon.receptor_on(pos, rules)
|
||||
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
|
||||
print("receptor_on(pos="..vector.to_string(pos)..",rules="..dump(rules))
|
||||
--mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
|
||||
end
|
||||
|
||||
mesecon.queue:add_function("receptor_off", function (pos, rules)
|
||||
|
@ -114,7 +115,8 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
|
|||
end)
|
||||
|
||||
function mesecon.receptor_off(pos, rules)
|
||||
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
|
||||
print("receptor_off(pos="..vector.to_string(pos)..",rules="..dump(rules))
|
||||
--mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
|
||||
end
|
||||
|
||||
--Services like turnoff receptor on dignode and so on
|
||||
|
|
|
@ -52,7 +52,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
|
|||
_doc_items_usagehelp = S("Use the lever to flip it on or off."),
|
||||
on_rightclick = function(pos, node)
|
||||
minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_on", param2=node.param2})
|
||||
mesecon.receptor_on(pos, lever_get_output_rules(node))
|
||||
vl_redstone.set_power(pos, 15)
|
||||
minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16}, true)
|
||||
end,
|
||||
node_placement_prediction = "",
|
||||
|
@ -152,7 +152,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
|
|||
_doc_items_create_entry = false,
|
||||
on_rightclick = function(pos, node)
|
||||
minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_off", param2=node.param2})
|
||||
mesecon.receptor_off(pos, lever_get_output_rules(node))
|
||||
vl_redstone.set_power(pos, 0)
|
||||
minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16, pitch=0.9}, true)
|
||||
end,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
name = mesecons_walllever
|
||||
depends = mesecons
|
||||
depends = mesecons, vl_redstone
|
||||
optional_depends = doc
|
||||
|
|
144
mods/ITEMS/REDSTONE/vl_redstone/init.lua
Normal file
144
mods/ITEMS/REDSTONE/vl_redstone/init.lua
Normal file
|
@ -0,0 +1,144 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
vl_redstone = {}
|
||||
local mod = vl_redstone
|
||||
|
||||
local REDSTONE_POWER_META = modname .. ".power"
|
||||
local REDSTONE_POWER_META_LAST_STATE = modname .. ".last-power"
|
||||
local REDSTONE_POWER_META_SOURCE = REDSTONE_POWER_META.."."
|
||||
|
||||
local function update_sink(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local nodedef = minetest.registered_nodes[node.name]
|
||||
|
||||
-- Only do this processing of signal sinks
|
||||
if not nodedef.mesecons then return end
|
||||
local sink = nodedef.mesecons.effector
|
||||
if not sink then return end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
-- Calculate the maximum power feeding into this node
|
||||
local strength = 0
|
||||
local meta_tbl = meta:to_table()
|
||||
for k,v in pairs(meta_tbl.fields) do
|
||||
if string.sub(k,1,#REDSTONE_POWER_META_SOURCE) == REDSTONE_POWER_META_SOURCE then
|
||||
--local source_pos_str = string.sub(k,#REDSTONE_POWER_META_SOURCE+1)
|
||||
--print("\tsource_pos_str="..source_pos_str)
|
||||
local source_strength = tonumber(v)
|
||||
--print("\tstrength="..source_strength)
|
||||
if source_strength > strength then
|
||||
strength = source_strength
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local last_strength = meta:get_int(REDSTONE_POWER_META_LAST_STATE)
|
||||
|
||||
if last_strength ~= strength then
|
||||
-- Inform the node of changes
|
||||
if strength > 0 then
|
||||
-- Handle activation
|
||||
if sink.action_on then
|
||||
sink.action_on(pos, node)
|
||||
end
|
||||
|
||||
else
|
||||
-- Handle deactivation
|
||||
if sink.action_off then
|
||||
sink.action_off(pos, node)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: handle signal level change notification
|
||||
|
||||
-- Update the state as the last thing in case there is a crash in the above code
|
||||
meta:set_int(REDSTONE_POWER_META_LAST_STATE, strength)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_positions_from_node_rules(pos, rules_type, list)
|
||||
list = list or {}
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
local nodedef = minetest.registered_nodes[node.name]
|
||||
if not nodedef.mesecons then return list end
|
||||
|
||||
-- Get mesecons rules
|
||||
if not nodedef.mesecons[rules_type] then
|
||||
minetest.log("info","Node "..node.name.." has no mesecons."..rules_type.." rules")
|
||||
return list
|
||||
end
|
||||
local rules = nodedef.mesecons[rules_type].rules
|
||||
if type(rules) == "function" then rules = rules(node) end
|
||||
|
||||
--print("rules="..dump(rules))
|
||||
|
||||
-- Convert to absolute positions
|
||||
for i=1,#rules do
|
||||
local next_pos = vector.add(pos, rules[i])
|
||||
local next_pos_str = vector.to_string(next_pos)
|
||||
list[next_pos_str] = true
|
||||
end
|
||||
|
||||
return list
|
||||
end
|
||||
|
||||
vl_scheduler.register_function("vl_redstone:flow_power",function(task, source_pos, strength, distance)
|
||||
print("Flowing lv"..tostring(strength).." power from "..vector.to_string(source_pos).." for "..tostring(distance).." blocks")
|
||||
local processed = {}
|
||||
local source_pos_str = vector.to_string(source_pos)
|
||||
|
||||
-- Update the source node's redstone power
|
||||
local meta = minetest.get_meta(source_pos)
|
||||
meta:set_int(REDSTONE_POWER_META, strength)
|
||||
|
||||
-- Get rules
|
||||
local list = {}
|
||||
get_positions_from_node_rules(source_pos, "receptor", list)
|
||||
print("initial list="..dump(list))
|
||||
|
||||
for i=1,distance do
|
||||
local next_list = {}
|
||||
local strength = strength - (i - 1)
|
||||
if strength < 0 then strength = 0 end
|
||||
|
||||
for pos_str,dir in pairs(list) do
|
||||
print("Processing "..pos_str)
|
||||
|
||||
if not processed[pos_str] then
|
||||
processed[pos_str] = true
|
||||
|
||||
local pos = vector.from_string(pos_str)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
-- Update node power directly
|
||||
meta:set_int(REDSTONE_POWER_META.."."..source_pos_str, strength)
|
||||
print("pos="..vector.to_string(pos)..", strength="..tostring(strength))
|
||||
|
||||
-- handle spread
|
||||
local spread_to = get_positions_from_node_rules(pos, "conductor")
|
||||
for j=1,#spread_to do
|
||||
next_list[vector.to_string(spread_to[j])] = true
|
||||
end
|
||||
|
||||
-- Update the position
|
||||
update_sink(pos)
|
||||
end
|
||||
end
|
||||
|
||||
-- Continue onto the next set of nodes to process
|
||||
list = next_list
|
||||
end
|
||||
end)
|
||||
|
||||
function vl_redstone.set_power(pos, strength)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local distance = meta:get_int(REDSTONE_POWER_META)
|
||||
if distance < strength then
|
||||
distance = strength
|
||||
end
|
||||
|
||||
vl_scheduler.add_task(0, "vl_redstone:flow_power", 2, {pos, strength, distance})
|
||||
end
|
||||
|
4
mods/ITEMS/REDSTONE/vl_redstone/mod.conf
Normal file
4
mods/ITEMS/REDSTONE/vl_redstone/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
description = Redstone implementation
|
||||
name = vl_redstone
|
||||
depends = mcl_sounds, mcl_core, vl_scheduler
|
||||
optional_depends = doc
|
Loading…
Reference in a new issue