mirror of
https://github.com/joe7575/techpack.git
synced 2024-11-26 09:03:46 +01:00
Stopwatch function to SmartLine Controller added
This commit is contained in:
parent
58ed780c13
commit
9a1ad7349f
@ -182,10 +182,15 @@ function lcdlib.make_multiline_texture(font_name, text, width, height,
|
|||||||
local lines = {}
|
local lines = {}
|
||||||
local textheight = 0
|
local textheight = 0
|
||||||
local y, w, h
|
local y, w, h
|
||||||
|
h = get_font(font_name).height
|
||||||
|
|
||||||
for num, line in pairs(split_lines(text, maxlines)) do
|
for num, line in pairs(split_lines(text, maxlines)) do
|
||||||
|
if line:byte(1) == 60 then -- '<'
|
||||||
|
lines[num] = { text = line:sub(2,-1), width = width - 4, height = h, }
|
||||||
|
else
|
||||||
w, h = lcdlib.get_text_size(font_name, line)
|
w, h = lcdlib.get_text_size(font_name, line)
|
||||||
lines[num] = { text = line, width = w, height = h, }
|
lines[num] = { text = line, width = w, height = h, }
|
||||||
|
end
|
||||||
textheight = textheight + h
|
textheight = textheight + h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## V1.16.4 (2018-09-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Additions
|
||||||
|
- Stopwatch function to SmartLine Controller added
|
||||||
|
- Display supports now left oriented text outputs via prefix '<'
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Owner bugfix for the SmartLine Controller
|
||||||
|
|
||||||
|
|
||||||
## V1.16.3 (2018-09-26)
|
## V1.16.3 (2018-09-26)
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ local function integer(s, min, max)
|
|||||||
return min
|
return min
|
||||||
end
|
end
|
||||||
|
|
||||||
local sOUTPUT = "Edit commands"
|
local sOUTPUT = "Edit commands (see help)"
|
||||||
local Cache = {}
|
local Cache = {}
|
||||||
local FS_DATA = gen_table(smartline.NUM_RULES, {})
|
local FS_DATA = gen_table(smartline.NUM_RULES, {})
|
||||||
|
|
||||||
@ -71,6 +71,22 @@ end
|
|||||||
-- env.blocked[1] = false
|
-- env.blocked[1] = false
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
|
-- -- Callback variant
|
||||||
|
-- if env.blocked[1] == false and env.ticks % <cycle> == 0 then
|
||||||
|
-- env.result[1], env.blocked[1] = <callback>
|
||||||
|
-- if env.blocked[1] then
|
||||||
|
-- env.timer[1] = env.ticks + <after>
|
||||||
|
-- end
|
||||||
|
-- env.conditions[1] = env.blocked[1]
|
||||||
|
-- else
|
||||||
|
-- env.conditions[1] = false
|
||||||
|
-- end
|
||||||
|
-- if env.blocked[1] and env.timer[1] == env.ticks then
|
||||||
|
-- <action>
|
||||||
|
-- env.blocked[1] = false
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
-- cyclic execution
|
-- cyclic execution
|
||||||
local TemplCyc = [[
|
local TemplCyc = [[
|
||||||
-- Rule #
|
-- Rule #
|
||||||
@ -109,6 +125,24 @@ if env.blocked[#] and env.timer[#] == env.ticks then
|
|||||||
end
|
end
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
-- event based execution of callback function
|
||||||
|
local TemplEvtClbk = [[
|
||||||
|
-- Rule #
|
||||||
|
if env.blocked[#] == false and env.event then
|
||||||
|
env.result[#], env.blocked[#] = %s(env, %s)
|
||||||
|
if env.blocked[#] then
|
||||||
|
env.timer[#] = env.ticks + %s
|
||||||
|
end
|
||||||
|
env.condition[#] = env.blocked[#]
|
||||||
|
else
|
||||||
|
env.condition[#] = false
|
||||||
|
end
|
||||||
|
if env.blocked[#] and env.timer[#] == env.ticks then
|
||||||
|
%s
|
||||||
|
env.blocked[#] = false
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
-- generate the Lua code from the NUM_RULES rules
|
-- generate the Lua code from the NUM_RULES rules
|
||||||
local function generate(pos, meta, environ)
|
local function generate(pos, meta, environ)
|
||||||
local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA
|
local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA
|
||||||
@ -124,7 +158,12 @@ local function generate(pos, meta, environ)
|
|||||||
-- add rule number
|
-- add rule number
|
||||||
local s
|
local s
|
||||||
if cycle == 0 then -- event?
|
if cycle == 0 then -- event?
|
||||||
|
if result then
|
||||||
s = string.format(TemplEvt, cond, result, after, actn)
|
s = string.format(TemplEvt, cond, result, after, actn)
|
||||||
|
else -- callback function
|
||||||
|
local data = dump(fs_data[idx].cond)
|
||||||
|
s = string.format(TemplEvtClbk, cond, data, after, actn)
|
||||||
|
end
|
||||||
else -- cyclic
|
else -- cyclic
|
||||||
s = string.format(TemplCyc, cycle, cond, result, after, actn)
|
s = string.format(TemplCyc, cycle, cond, result, after, actn)
|
||||||
end
|
end
|
||||||
@ -216,7 +255,8 @@ local function start_controller(pos, meta)
|
|||||||
if compile(pos, meta, number) then
|
if compile(pos, meta, number) then
|
||||||
meta:set_int("state", tubelib.RUNNING)
|
meta:set_int("state", tubelib.RUNNING)
|
||||||
minetest.get_node_timer(pos):start(1)
|
minetest.get_node_timer(pos):start(1)
|
||||||
meta:set_string("formspec", smartline.formspecOutput(meta))
|
local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA
|
||||||
|
meta:set_string("formspec", smartline.formspecRules(meta, fs_data, sOUTPUT))
|
||||||
meta:set_string("infotext", "Controller "..number..": running")
|
meta:set_string("infotext", "Controller "..number..": running")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -280,7 +320,9 @@ local function on_receive_fields(pos, formname, fields, player)
|
|||||||
if not player or not player:is_player() then
|
if not player or not player:is_player() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local readonly = player:get_player_name() ~= owner
|
if player:get_player_name() ~= owner then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
--print("fields", dump(fields))
|
--print("fields", dump(fields))
|
||||||
if fields.quit then -- cancel button
|
if fields.quit then -- cancel button
|
||||||
@ -290,18 +332,14 @@ local function on_receive_fields(pos, formname, fields, player)
|
|||||||
meta:set_string("notes", fields.notes)
|
meta:set_string("notes", fields.notes)
|
||||||
end
|
end
|
||||||
if fields.go then
|
if fields.go then
|
||||||
if not readonly then
|
|
||||||
local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA
|
local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA
|
||||||
local output = smartline.edit_command(fs_data, fields.cmnd)
|
local output = smartline.edit_command(fs_data, fields.cmnd)
|
||||||
stop_controller(pos, meta)
|
stop_controller(pos, meta)
|
||||||
meta:set_string("formspec", smartline.formspecRules(meta, fs_data, output))
|
meta:set_string("formspec", smartline.formspecRules(meta, fs_data, output))
|
||||||
meta:set_string("fs_data", minetest.serialize(fs_data))
|
meta:set_string("fs_data", minetest.serialize(fs_data))
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if fields._type_ == "main" then
|
if fields._type_ == "main" then
|
||||||
if not readonly then
|
|
||||||
smartline.store_main_form_data(meta, fields)
|
smartline.store_main_form_data(meta, fields)
|
||||||
end
|
|
||||||
local key = smartline.main_form_button_pressed(fields)
|
local key = smartline.main_form_button_pressed(fields)
|
||||||
if key then
|
if key then
|
||||||
-- store data before going into sub-menu
|
-- store data before going into sub-menu
|
||||||
@ -438,9 +476,10 @@ minetest.register_craft({
|
|||||||
local function set_input(pos, own_number, rmt_number, val)
|
local function set_input(pos, own_number, rmt_number, val)
|
||||||
if rmt_number then
|
if rmt_number then
|
||||||
if Cache[own_number] and Cache[own_number].env.input then
|
if Cache[own_number] and Cache[own_number].env.input then
|
||||||
Cache[own_number].env.input[rmt_number] = val
|
|
||||||
-- only two events per second
|
|
||||||
local t = minetest.get_us_time()
|
local t = minetest.get_us_time()
|
||||||
|
Cache[own_number].env.input[rmt_number] = val
|
||||||
|
Cache[own_number].env.last_event = t
|
||||||
|
-- only two events per second
|
||||||
if not Cache[own_number].last_event or Cache[own_number].last_event < t then
|
if not Cache[own_number].last_event or Cache[own_number].last_event < t then
|
||||||
minetest.after(0.01, on_timer, pos, -1)
|
minetest.after(0.01, on_timer, pos, -1)
|
||||||
Cache[own_number].last_event = t + 500000 -- add 500 ms
|
Cache[own_number].last_event = t + 500000 -- add 500 ms
|
||||||
@ -453,10 +492,11 @@ tubelib.register_node("smartline:controller2", {}, {
|
|||||||
on_recv_message = function(pos, topic, payload)
|
on_recv_message = function(pos, topic, payload)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local number = meta:get_string("number")
|
local number = meta:get_string("number")
|
||||||
|
local state = meta:get_int("state")
|
||||||
|
|
||||||
if topic == "on" then
|
if state == tubelib.RUNNING and topic == "on" then
|
||||||
set_input(pos, number, payload, topic)
|
set_input(pos, number, payload, topic)
|
||||||
elseif topic == "off" then
|
elseif state == tubelib.RUNNING and topic == "off" then
|
||||||
set_input(pos, number, payload, topic)
|
set_input(pos, number, payload, topic)
|
||||||
elseif topic == "state" then
|
elseif topic == "state" then
|
||||||
local state = meta:get_int("state")
|
local state = meta:get_int("state")
|
||||||
|
130
smartline/icta/stopwatch.lua
Normal file
130
smartline/icta/stopwatch.lua
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
ICTA Controller
|
||||||
|
===============
|
||||||
|
|
||||||
|
Part of the SmartLine mod
|
||||||
|
|
||||||
|
Copyright (C) 2018 Joachim Stolberg
|
||||||
|
|
||||||
|
LGPLv2.1+
|
||||||
|
See LICENSE.txt for more information
|
||||||
|
|
||||||
|
stopwatch.lua
|
||||||
|
Start/stop the watch with an on/off commands.
|
||||||
|
The player name clicking the stop is stored in addition.
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local sl = smartline
|
||||||
|
|
||||||
|
local function retrieve_clicker_name(number)
|
||||||
|
local pos = tubelib.get_node_info(number).pos
|
||||||
|
if pos then
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
return meta:get_string("clicker_name") or "<unknown>"
|
||||||
|
end
|
||||||
|
return "<error>"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- env = {
|
||||||
|
-- event = <bool>,
|
||||||
|
-- last_event = <number> -- last event time
|
||||||
|
-- ticks = <number,
|
||||||
|
-- pos = <pos>,
|
||||||
|
-- timer = gen_table(8, 0),
|
||||||
|
-- blocked = gen_table(8, false),
|
||||||
|
-- result = gen_table(8, false),
|
||||||
|
-- condition = gen_table(8, false),
|
||||||
|
-- input = <table>, -- node number is key
|
||||||
|
-- number = <number>,
|
||||||
|
-- owner = <string>,
|
||||||
|
-- },
|
||||||
|
--
|
||||||
|
-- return cond_result, trigger_action
|
||||||
|
function smartline.stopwatch(env, data)
|
||||||
|
if env.input[data.number] == "on" then
|
||||||
|
env.time = env.last_event
|
||||||
|
if not env.highscore then
|
||||||
|
env.highscore = 99999
|
||||||
|
end
|
||||||
|
return nil, false
|
||||||
|
else
|
||||||
|
local time = (env.last_event - env.time) / 1000000
|
||||||
|
local name = retrieve_clicker_name(data.number)
|
||||||
|
env.highscore = math.min(time, env.highscore)
|
||||||
|
local s1 = string.format("%2.1f s", time)
|
||||||
|
local s2 = string.format("%2.1f s", env.highscore)
|
||||||
|
env.stopwatch_result = {s1, s2, name}
|
||||||
|
return nil, true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
smartline.icta_register_condition("stopwatch", {
|
||||||
|
title = "stopwatch",
|
||||||
|
formspec = {
|
||||||
|
{
|
||||||
|
type = "numbers",
|
||||||
|
name = "number",
|
||||||
|
label = "Switch number",
|
||||||
|
default = "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "label",
|
||||||
|
name = "lbl",
|
||||||
|
label = "Hint: Stop the time between switching on\nand switching off of the connected switch.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
code = function(data, environ)
|
||||||
|
return "smartline.stopwatch"
|
||||||
|
end,
|
||||||
|
button = function(data, environ)
|
||||||
|
return 'stopwatch('..sl.fmt_number(data.number)..')'
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
smartline.icta_register_action("stopwatch", {
|
||||||
|
title = "stopwatch",
|
||||||
|
formspec = {
|
||||||
|
{
|
||||||
|
type = "numbers",
|
||||||
|
name = "number",
|
||||||
|
label = "Display number",
|
||||||
|
default = "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "textlist",
|
||||||
|
name = "row",
|
||||||
|
label = "Display line",
|
||||||
|
choices = "1,2,3,4,5,6,7,8,9",
|
||||||
|
default = "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "ascii",
|
||||||
|
name = "text",
|
||||||
|
label = "label",
|
||||||
|
default = "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "textlist",
|
||||||
|
name = "type",
|
||||||
|
label = "type",
|
||||||
|
choices = "time,highscore,name",
|
||||||
|
default = "time",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "label",
|
||||||
|
name = "lbl",
|
||||||
|
label = "Hint: Display number for the output\nof time, highscore and player name.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
button = function(data, environ)
|
||||||
|
return "lcd("..sl.fmt_number(data.number)..","..data.row..","..data.type..')'
|
||||||
|
end,
|
||||||
|
code = function(data, environ)
|
||||||
|
local idx = ({time=1, highscore= 2, name=3})[data.type]
|
||||||
|
local s1 = string.format('local payload = {row = %s, str = "%s "..env.stopwatch_result['..idx..']}', data.row, smartline.escape(data.text))
|
||||||
|
local s2 = string.format('tubelib.send_message("%s", "%s", nil, "row", payload)', data.number, environ.owner)
|
||||||
|
return s1.."\n\t"..s2
|
||||||
|
end,
|
||||||
|
})
|
@ -33,3 +33,4 @@ dofile(MP.."/icta/commands.lua")
|
|||||||
dofile(MP.."/icta/edit.lua")
|
dofile(MP.."/icta/edit.lua")
|
||||||
dofile(MP.."/icta/battery.lua")
|
dofile(MP.."/icta/battery.lua")
|
||||||
dofile(MP.."/icta/balancer.lua")
|
dofile(MP.."/icta/balancer.lua")
|
||||||
|
dofile(MP.."/icta/stopwatch.lua")
|
||||||
|
Loading…
Reference in New Issue
Block a user