forked from VoxeLibre/VoxeLibre
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
e4bf6a546b
commit
11e98e915e
|
@ -100,7 +100,7 @@ if false then
|
||||||
act("test")
|
act("test")
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
local function run_scheduler(dtime)
|
||||||
local start_time = minetest_get_us_time()
|
local start_time = minetest_get_us_time()
|
||||||
local end_time = start_time + 50000
|
local end_time = start_time + 50000
|
||||||
time = time + dtime
|
time = time + dtime
|
||||||
|
@ -129,7 +129,10 @@ minetest.register_globalstep(function(dtime)
|
||||||
local func = functions[task.fid]
|
local func = functions[task.fid]
|
||||||
if func then
|
if func then
|
||||||
--print("Running task "..dump(task)..",func="..dump(func))
|
--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
|
if not ok then
|
||||||
minetest.log("error","Error while running task "..func.name..": "..tostring(ret))
|
minetest.log("error","Error while running task "..func.name..": "..tostring(ret))
|
||||||
end
|
end
|
||||||
|
@ -149,7 +152,9 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
end
|
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))
|
--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
|
return highesti
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
local m_time = 0
|
local m_time = 0
|
||||||
local resumetime = mesecon.setting("resumetime", 4)
|
local resumetime = mesecon.setting("resumetime", 4)
|
||||||
minetest.register_globalstep(function (dtime)
|
minetest.register_globalstep(function (dtime)
|
||||||
|
|
||||||
m_time = m_time + dtime
|
m_time = m_time + dtime
|
||||||
-- don't even try if server has not been running for XY seconds; resumetime = time to wait
|
-- 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
|
-- 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)
|
table.remove(actions_now, hp)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
]]
|
||||||
|
|
||||||
function mesecon.queue:execute(action)
|
function mesecon.queue:execute(action)
|
||||||
if not action.pos then return end
|
if not action.pos then return end
|
||||||
|
|
|
@ -87,7 +87,8 @@ mesecon.queue:add_function("receptor_on", function (pos, rules)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function mesecon.receptor_on(pos, rules)
|
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
|
end
|
||||||
|
|
||||||
mesecon.queue:add_function("receptor_off", function (pos, rules)
|
mesecon.queue:add_function("receptor_off", function (pos, rules)
|
||||||
|
@ -114,7 +115,8 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function mesecon.receptor_off(pos, rules)
|
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
|
end
|
||||||
|
|
||||||
--Services like turnoff receptor on dignode and so on
|
--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."),
|
_doc_items_usagehelp = S("Use the lever to flip it on or off."),
|
||||||
on_rightclick = function(pos, node)
|
on_rightclick = function(pos, node)
|
||||||
minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_on", param2=node.param2})
|
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)
|
minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16}, true)
|
||||||
end,
|
end,
|
||||||
node_placement_prediction = "",
|
node_placement_prediction = "",
|
||||||
|
@ -152,7 +152,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
|
||||||
_doc_items_create_entry = false,
|
_doc_items_create_entry = false,
|
||||||
on_rightclick = function(pos, node)
|
on_rightclick = function(pos, node)
|
||||||
minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_off", param2=node.param2})
|
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)
|
minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16, pitch=0.9}, true)
|
||||||
end,
|
end,
|
||||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
name = mesecons_walllever
|
name = mesecons_walllever
|
||||||
depends = mesecons
|
depends = mesecons, vl_redstone
|
||||||
optional_depends = doc
|
optional_depends = doc
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
description = Redstone implementation
|
||||||
|
name = vl_redstone
|
||||||
|
depends = mcl_sounds, mcl_core, vl_scheduler
|
||||||
|
optional_depends = doc
|
Loading…
Reference in New Issue