coroutines!! and an almost working love.window.showMessageBox

This commit is contained in:
entoreor 2020-04-02 11:11:06 -06:00
parent c16ef7a38f
commit a81d5d5aa6
8 changed files with 212 additions and 68 deletions

View File

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<link rel="stylesheet" href="/~entoreor/style.css">
<link rel="stylesheet" href="documentation.css">
<script src="demo.js" defer></script>
<script src="documentation.js" defer></script>
</head>
<body>
<h1>Infatuated</h1>
@ -118,7 +118,7 @@
</tbody>
</table>
<h2>API completeness</h2>
<table>
<table id="apidoc">
<thead>
<tr>
<td>Name</td>
@ -642,12 +642,12 @@
</tr>
<tr>
<td>love.graphics.print</td>
<td></td>
<td>r, sx, sy, ox, oy, kx, ky not implemented</td>
<td><span class="badish">Very incomplete</span></td>
</tr>
<tr>
<td>love.graphics.printf</td>
<td>Can't align</td>
<td>Ditto, and "justify" alignment not supported</td>
<td><span class="badish">Very incomplete</span></td>
</tr>
<tr>
@ -1123,7 +1123,7 @@
<tr>
<td>love.graphics.getDimensions</td>
<td></td>
<td><span class="bad">Missing</span></td>
<td><span class="good">Complete</span></td>
</tr>
<tr>
<td>love.graphics.getHeight</td>

25
game/demos/msgbox.lua Normal file
View File

@ -0,0 +1,25 @@
function love.draw()
love.graphics.print("Press A for a boring message box.\nPress B for a message box with options.\nReload the page to go back.", math.max(20, 20+math.sin(love.timer.getTime()*10)*5), 20)
end
function love.handlers.keypressed(key, scan, repeated)
if key == "a" then
print(love.window.showMessageBox("Sample title", "The quick brown fox jumps over the lazy dog.", "info", true))
elseif key == "b" then
print(love.window.showMessageBox(
"Sample title",
"The quick brown fox jumps over the lazy dog.",
{
"Alice",
"Bob",
"Charlie",
"Dan",
"Erin",
enterbutton = 2,
escapebutton = 4
},
"info",
true
))
end
end

View File

@ -10,9 +10,10 @@ function love.load()
options = {
"View documentation",
"Go to repository",
"Colors demo"
"Colors demo",
"Message box demo"
}
local function cleanup()
local function boot(path)
love.load = nil
love.update = nil
love.draw = nil
@ -21,6 +22,8 @@ function love.load()
end
love.graphics.setBackgroundColor(0, 0, 0, 1)
love.graphics.setColor(1, 1, 1, 1)
require(path)
if love.load then love.load() end
end
optionsFunc = {
function()
@ -29,11 +32,8 @@ function love.load()
function()
infatuated.js.global.window:open("https://tildegit.org/entoreor/infatuated", "_self")
end,
function()
cleanup()
require "demos.colors"
if love.load then love.load() end
end
function() boot("demos.colors") end,
function() boot("demos.msgbox") end
}
end

View File

@ -10,6 +10,15 @@
</head>
<body>
<!-- Tip: To run your own Lua on the fly, run `fengari.load("your code here")()` in console -->
<div id="infatuated-msgbox" data-hidden="true">
<span id="infatuated-msgbox-title">Title</span>
<hr>
<span id="infatuated-msgbox-text">Message</span>
<div id="infatuated-msgbox-buttons">
<button>OK</button>
</div>
</div>
<div id="infatuated-overlay" data-hidden="true"></div>
<canvas id="infatuated-canvas" width="800" height="600"></canvas>
</body>
</html>

142
main.lua
View File

@ -70,6 +70,39 @@ infatuated.canvas = canvas
local ctx = canvas:getContext("2d")
infatuated.ctx = ctx
infatuated.overlay = document:getElementById("infatuated-overlay")
infatuated.msgbox = {
root = document:getElementById("infatuated-msgbox"),
title = document:getElementById("infatuated-msgbox-title"),
text = document:getElementById("infatuated-msgbox-text"),
buttons = document:getElementById("infatuated-msgbox-buttons")
}
function infatuated.msgbox:show(title, text, buttons, callback)
self.title.textContent = title
self.text.textContent = text
for k, v in pairs(self.buttons.children) do
v:remove()
end
for i=1, #buttons do
local btn = document:createElement("button")
btn.textContent = buttons[i]
--btn.dataset.id = i
self.buttons:append(btn)
btn:addEventListener("click", function()
self:hide()
callback(i)
end)
end
infatuated.overlay.dataset.hidden = false
self.root.dataset.hidden = false
end
function infatuated.msgbox:hide()
infatuated.canvas:focus()
infatuated.overlay.dataset.hidden = true
self.root.dataset.hidden = true
end
--infatuated.msgbox:show("sample title", "the quick brown fox", {"a", "b", "c"}, oldprint)
print("Running game from path %q", path)
local function errorprint(...)
@ -155,60 +188,67 @@ function love.run()
end
end
require "modules.data"
require "modules.event"
require "modules.filesystem"
require "modules.graphics"
require "modules.handlers"
require "modules.image"
require "modules.math"
require "modules.timer"
require "modules.window"
print("Coroutining now")
infatuated.thread = coroutine.create(function()
require "modules.data"
require "modules.event"
require "modules.filesystem"
require "modules.graphics"
require "modules.handlers"
require "modules.image"
require "modules.math"
require "modules.timer"
require "modules.window"
love.run()
local oldrequire = require
infatuated.require = oldrequire
function require(path)
assert(type(path) == "string", "bad argument #1 to require")
if path == "love" then return love end
return oldrequire(infatuated.path.."."..path)
end
print("Importing conf")
love.run()
local status, errmsg = pcall(oldrequire, infatuated.path..".conf")
if not status and not errmsg:find("^module '.-%.conf' not found:") then
infatuated.crash(errmsg)
end
local status, errmsg = pcall(love.conf, infatuated.conf)
if not status then infatuated.crash(errmsg) end
local oldrequire = require
infatuated.require = oldrequire
function require(path)
assert(type(path) == "string", "bad argument #1 to require")
if path == "love" then return love end
return oldrequire(infatuated.path.."."..path)
end
print("Importing main")
print("Importing conf")
local status, errmsg = pcall(oldrequire, infatuated.path..".conf")
if not status and not errmsg:find("^module '.-%.conf' not found:") then
infatuated.crash(errmsg)
end
local status, errmsg = pcall(love.conf, infatuated.conf)
if not status then infatuated.crash(errmsg) end
print("Importing main")
local status, errmsg = pcall(oldrequire, infatuated.path..".main")
if not status then infatuated.crash(errmsg) end
local status, errmsg = pcall(love.run)
if not status then
infatuated.crash(errmsg)
else
infatuated.loopGuest = errmsg
end
print("Starting event loop")
infatuated.dt1 = window.performance:now()
function infatuated.loopMaster()
local dt2 = window.performance:now()
infatuated.dt = (dt2-infatuated.dt1)/1000
infatuated.dt1 = dt2
local status, errmsg = pcall(infatuated.loopGuest)
local status, errmsg = pcall(oldrequire, infatuated.path..".main")
if not status then infatuated.crash(errmsg) end
local status, errmsg = pcall(love.run)
if not status then
infatuated.crash(errmsg)
elseif errmsg then
print("Exited with code %d", errmsg or -1)
return
else
infatuated.loopGuest = errmsg
end
window:requestAnimationFrame(infatuated.loopMaster)
end
window:requestAnimationFrame(infatuated.loopMaster)
print("Starting event loop")
infatuated.dt1 = window.performance:now()
local function resume()
coroutine.resume(infatuated.thread)
end
while true do
local dt2 = window.performance:now()
infatuated.dt = (dt2-infatuated.dt1)/1000
infatuated.dt1 = dt2
local status, errmsg = pcall(infatuated.loopGuest)
if not status then
infatuated.crash(errmsg)
elseif errmsg then
print("Exited with code %d", errmsg or -1)
return
end
window:requestAnimationFrame(resume)
coroutine.yield()
end
end)
coroutine.resume(infatuated.thread)

View File

@ -38,7 +38,7 @@ body:addEventListener("keydown", function(self, event)
if love.handlers.keypressed then
-- TODO: properly implement scancodes
if (not love.keyboard or not love.keyboard.getKeyRepeat()) and event["repeat"] then return end
local key = keys[event.key] or key
local key = keys[event.key] or event.key:lower()
love.handlers.keypressed(key, key, event["repeat"])
--love.handlers.keypressed(key, event.code, event["repeat"])
end
@ -47,6 +47,7 @@ function love.handlers.keyreleased() end
body:addEventListener("keyup", function(self, event)
if love.handlers.keyreleased and not infatuated.stopDue then
-- TODO: properly implement scancodes
local key = keys[event.key] or event.key:lower()
love.handlers.keyreleased(key, key)
--love.handlers.keyreleased(key, event.code)
end

View File

@ -7,3 +7,27 @@ function love.window.fromPixels(pixelvalue)
assert(type(pixelvalue) == "number", "bad argument #1 to fromPixels (expected number)")
return pixelvalue
end
love.window.getDimensions = love.graphics and love.graphics.getDimensions
function love.window.showMessageBox(title, message, buttonlist, mbtype, attachtowindow)
assert(type(title) == "string", "bad argument #1 to title (string expected)")
assert(type(message) == "string", "bad argument #2 to title (string expected)")
if type(buttonlist) == "string" then
attachtowindow = mbtype
mbtype = buttonlist
buttonlist = {"OK"}
end
buttonlist = buttonlist or {"OK"}
mbtype = mbtype or "info"
attachtowindow = attachtowindow or true
assert(type(buttonlist) == "table", "bad argument #3 to title (table expected)")
assert(type(mbtype) == "string", "bad argument #4 to title (string expected)")
assert(type(attachtowindow) == "boolean", "bad argument #5 to title (boolean expected)")
local co = assert(coroutine.running(infatuated.thread), "must be run in a coroutine")
local ret
infatuated.msgbox:show(title, message, buttonlist, function(i)
ret = i
coroutine.resume(infatuated.thread)
end)
coroutine.yield()
return ret
end

View File

@ -1,14 +1,59 @@
body {
background-color: #111;
background: #111;
color: #ddd;
font-family: monospace;
}
canvas {
/*border: 1px solid #777;*/
box-shadow: #7773 0 0 25px;
#infatuated-canvas,
#infatuated-msgbox {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
#infatuated-msgbox-title {
font-weight: bold;
}
#infatuated-msgbox {
background: #222;
border: 1px solid #777;
box-shadow: #000 0 0 25px;
padding: 2em;
z-index: 3;
}
#infatuated-overlay {
background: #0007;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
}
#infatuated-msgbox,
#infatuated-overlay {
transition: opacity 0.125s;
}
[data-hidden="true"] {
opacity: 0;
pointer-events: none;
}
#infatuated-msgbox-buttons {
display: table;
position: relative;
margin: 1rem auto 0 auto;
}
button {
background: #333;
color: #eee;
border: 1px solid #777;
font-family: monospace;
text-align: center;
}
button:not(:last-child) {
margin-right: 0.5rem;
}
#infatuated-canvas {
/*border: 1px solid #777;*/
box-shadow: #7773 0 0 25px;
z-index: 1;
}