info-beamer/ffnord-con-2015-2/room/node.lua
2015-09-12 18:34:28 +02:00

324 lines
8.4 KiB
Lua

gl.setup(1280, 720)
font = resource.load_font("Oswald-Medium.ttf")
node.alias("room")
local json = require "json"
-- Configure room here
local SAAL = "attraktor"
util.auto_loader(_G)
util.file_watch("schedule.json", function(content)
print("reloading schedule")
talks = json.decode(content)
end)
util.file_watch("config.json", function(content)
local config = json.decode(content)
if sys.get_env then
saal = config.devices[sys.get_env("SERIAL")]
end
if not saal then
print("using statically configured saal identifier")
saal = SAAL
end
print(saal)
rooms = config.rooms
room = config.rooms[saal]
end)
local base_time = N.base_time or 0
local current_talk
local all_talks = {}
local day = 0
function get_now()
return base_time + sys.now()
end
function check_next_talk()
local now = get_now()
local room_next = {}
for idx, talk in ipairs(talks) do
if rooms[talk.place] and not room_next[talk.place] and talk.unix + 25 * 60 > now then
room_next[talk.place] = talk
end
end
for room, talk in pairs(room_next) do
talk.lines = wrap(talk.title, 40)
end
if room_next[saal] then
current_talk = room_next[saal]
else
current_talk = nil
end
all_talks = {}
for room, talk in pairs(room_next) do
if current_talk and room ~= current_talk.place then
all_talks[#all_talks + 1] = talk
end
end
table.sort(all_talks, function(a, b)
if a.unix < b.unix then
return true
elseif a.unix > b.unix then
return false
else
return a.place < b.place
end
end)
end
function wrap(str, limit, indent, indent1)
limit = limit or 72
local here = 1
local wrapped = str:gsub("(%s+)()(%S+)()", function(sp, st, word, fi)
if fi-here > limit then
here = st
return "\n"..word
end
end)
local splitted = {}
for token in string.gmatch(wrapped, "[^\n]+") do
splitted[#splitted + 1] = token
end
return splitted
end
local clock = (function()
local base_time = N.base_time or 0
local function set(time)
base_time = tonumber(time) - sys.now()
end
util.data_mapper{
["clock/midnight"] = function(since_midnight)
set(since_midnight)
end;
}
local left = 0
local function get()
local time = (base_time + sys.now()) % 86400
return string.format("%d:%02d", math.floor(time / 3600), math.floor(time % 3600 / 60))
end
return {
get = get;
set = set;
}
end)()
check_next_talk()
util.data_mapper{
["clock/set"] = function(time)
base_time = tonumber(time) - sys.now()
N.base_time = base_time
check_next_talk()
print("UPDATED TIME", base_time)
end;
["clock/day"] = function(new_day)
print("DAY", new_day)
day = new_day
end;
}
function switcher(screens)
local current_idx = 1
local current = screens[current_idx]
local switch = sys.now() + current.time
local switched = sys.now()
local blend = 0.5
local function draw()
local now = sys.now()
local percent = ((now - switched) / (switch - switched)) * 3.14129 * 2 - 3.14129
progress:use{percent = percent}
white:draw(WIDTH-50, HEIGHT-50, WIDTH-10, HEIGHT-10)
progress:deactivate()
if now - switched < blend then
local delta = (switched - now) / blend
gl.pushMatrix()
gl.translate(WIDTH/2, 0)
gl.rotate(270-90 * delta, 0, 1, 0)
gl.translate(-WIDTH/2, 0)
current.draw()
gl.popMatrix()
elseif now < switch - blend then
current.draw(now - switched)
elseif now < switch then
local delta = 1 - (switch - now) / blend
gl.pushMatrix()
gl.translate(WIDTH/2, 0)
gl.rotate(90 * delta, 0, 1, 0)
gl.translate(-WIDTH/2, 0)
current.draw()
gl.popMatrix()
else
current_idx = current_idx + 1
if current_idx > #screens then
current_idx = 1
end
current = screens[current_idx]
switch = now + current.time
switched = now
end
end
return {
draw = draw;
}
end
content = switcher{
{
--[[
time = 20;
draw = function()
redU(400, 200, "Other rooms", 80)
white:draw(0, 300, WIDTH, 302, 0.6)
y = 320
local time_sep = false
if #all_talks > 0 then
for idx, talk in ipairs(all_talks) do
if not time_sep and talk.unix > get_now() then
if idx > 1 then
y = y + 5
white:draw(0, y, WIDTH, y+2, 0.6)
y = y + 20
end
time_sep = true
end
local alpha = 1
if not time_sep then
alpha = 0.3
end
blueU(30, y, talk.start, 50)
redU(190, y, talk.place, 50)
yellow(450, y, talk.lines[math.floor((sys.now()/2) % #talk.lines)+1], 50)
y = y + 60
end
else
yellow(400, 330, "No other talks.", 50, 1,1,1,1)
end
end
}, {
time = 30;
draw = function()
if not current_talk then
redU(400, 200, "Next session...", 80, 1,1,1,1)
white:draw(0, 300, WIDTH, 302, 0.6)
redU(400, 330, "Nope. That's it.", 80)
else
local delta = current_talk.unix - get_now()
if delta > 0 then
redU(400, 200, "Next session", 80)
else
redU(400, 200, "This session", 80)
end
white:draw(0, 300, WIDTH, 302, 0.6)
blue(130, 330, current_talk.start, 50, 1,1,1,1)
if delta > 0 then
blue(130, 330 + 60, string.format("in %d min", math.floor(delta/60)+1), 50)
end
for idx, line in ipairs(current_talk.lines) do
if idx >= 5 then
break
end
yellow(400, 330 - 60 + 60 * idx, line, 50)
end
for i, speaker in ipairs(current_talk.speakers) do
blue(400, 510 + 50 * i, speaker, 50)
end
end
end
}, {
time = 10;
draw = function(t)
redU(400, 200, "Info", 80)
white:draw(0, 300, WIDTH, 302, 0.6)
blueU(30, 320, "WC", 50)
yellow(400, 320, "Im Keller", 50)
blueU(30, 380, "Spenden", 50)
yellow(400, 380, "Box am Tresen - Kosten noch nicht gedeckt", 50)
blueU(30, 480, "IRC", 50)
yellow(400, 480, room.irc, 50)
blueU(30, 540, "Twitter", 50)
yellow(400, 540, room.twitter, 50)
end
}, {
--]]
time = 10;
draw = function(t)
redU(110, 200, "PUBLIC SERVICE ANNOUNCEMENT", 80)
white:draw(0, 300, WIDTH, 302, 0.6)
yellowU(380, 400, "BESTELLT MEHR PIZZA!!1ELF", 50)
yellowU(300, 500, "SPENDET MEHR FÜR'S FRÜHSTÜCK!", 50)
end
},
}
function redU(x, y, text, size)
red(x, y, string.upper(text), size)
end
function red(x, y, text, size)
font:write(x, y, text, size, 0.894, 0.251, 0.506, 1)
end
function yellowU(x, y, text, size)
yellow(x, y, string.upper(text), size)
end
function yellow(x, y, text, size)
font:write(x, y, text, size, 1.0, 0.776, 0.251, 1)
end
function blueU(x, y, text, size)
blue(x, y, string.upper(text), size)
end
function blue(x, y, text, size)
font:write(x, y, text, size, 0.251, 0.714, 0.906, 1)
end
function node.render()
gl.clear(0.1, 0.1, 0.1, 1)
if base_time == 0 then
return
end
util.draw_correct(logo, 20, 20, 300, 120)
yellowU(310, 20, saal, 80)
blueU(730, 20, clock.get(), 80)
redU(WIDTH-300, 20, string.format("Day %d", day), 80)
local fov = math.atan2(HEIGHT, WIDTH*2) * 360 / math.pi
gl.perspective(fov, WIDTH/2, HEIGHT/2, -WIDTH,
WIDTH/2, HEIGHT/2, 0)
content.draw()
end