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"> <meta charset="UTF-8">
<link rel="stylesheet" href="/~entoreor/style.css"> <link rel="stylesheet" href="/~entoreor/style.css">
<link rel="stylesheet" href="documentation.css"> <link rel="stylesheet" href="documentation.css">
<script src="demo.js" defer></script> <script src="documentation.js" defer></script>
</head> </head>
<body> <body>
<h1>Infatuated</h1> <h1>Infatuated</h1>
@ -118,7 +118,7 @@
</tbody> </tbody>
</table> </table>
<h2>API completeness</h2> <h2>API completeness</h2>
<table> <table id="apidoc">
<thead> <thead>
<tr> <tr>
<td>Name</td> <td>Name</td>
@ -642,12 +642,12 @@
</tr> </tr>
<tr> <tr>
<td>love.graphics.print</td> <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> <td><span class="badish">Very incomplete</span></td>
</tr> </tr>
<tr> <tr>
<td>love.graphics.printf</td> <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> <td><span class="badish">Very incomplete</span></td>
</tr> </tr>
<tr> <tr>
@ -1123,7 +1123,7 @@
<tr> <tr>
<td>love.graphics.getDimensions</td> <td>love.graphics.getDimensions</td>
<td></td> <td></td>
<td><span class="bad">Missing</span></td> <td><span class="good">Complete</span></td>
</tr> </tr>
<tr> <tr>
<td>love.graphics.getHeight</td> <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 = { options = {
"View documentation", "View documentation",
"Go to repository", "Go to repository",
"Colors demo" "Colors demo",
"Message box demo"
} }
local function cleanup() local function boot(path)
love.load = nil love.load = nil
love.update = nil love.update = nil
love.draw = nil love.draw = nil
@ -21,6 +22,8 @@ function love.load()
end end
love.graphics.setBackgroundColor(0, 0, 0, 1) love.graphics.setBackgroundColor(0, 0, 0, 1)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
require(path)
if love.load then love.load() end
end end
optionsFunc = { optionsFunc = {
function() function()
@ -29,11 +32,8 @@ function love.load()
function() function()
infatuated.js.global.window:open("https://tildegit.org/entoreor/infatuated", "_self") infatuated.js.global.window:open("https://tildegit.org/entoreor/infatuated", "_self")
end, end,
function() function() boot("demos.colors") end,
cleanup() function() boot("demos.msgbox") end
require "demos.colors"
if love.load then love.load() end
end
} }
end end

View File

@ -10,6 +10,15 @@
</head> </head>
<body> <body>
<!-- Tip: To run your own Lua on the fly, run `fengari.load("your code here")()` in console --> <!-- 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> <canvas id="infatuated-canvas" width="800" height="600"></canvas>
</body> </body>
</html> </html>

142
main.lua
View File

@ -70,6 +70,39 @@ infatuated.canvas = canvas
local ctx = canvas:getContext("2d") local ctx = canvas:getContext("2d")
infatuated.ctx = ctx 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) print("Running game from path %q", path)
local function errorprint(...) local function errorprint(...)
@ -155,60 +188,67 @@ function love.run()
end end
end end
require "modules.data" print("Coroutining now")
require "modules.event" infatuated.thread = coroutine.create(function()
require "modules.filesystem" require "modules.data"
require "modules.graphics" require "modules.event"
require "modules.handlers" require "modules.filesystem"
require "modules.image" require "modules.graphics"
require "modules.math" require "modules.handlers"
require "modules.timer" require "modules.image"
require "modules.window" 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 print("Importing main")
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") local status, errmsg = pcall(oldrequire, infatuated.path..".main")
if not status then infatuated.crash(errmsg) end
local status, errmsg = pcall(oldrequire, infatuated.path..".conf") local status, errmsg = pcall(love.run)
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)
if not status then if not status then
infatuated.crash(errmsg) infatuated.crash(errmsg)
elseif errmsg then else
print("Exited with code %d", errmsg or -1) infatuated.loopGuest = errmsg
return
end end
window:requestAnimationFrame(infatuated.loopMaster)
end print("Starting event loop")
window:requestAnimationFrame(infatuated.loopMaster)
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 if love.handlers.keypressed then
-- TODO: properly implement scancodes -- TODO: properly implement scancodes
if (not love.keyboard or not love.keyboard.getKeyRepeat()) and event["repeat"] then return end 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, key, event["repeat"])
--love.handlers.keypressed(key, event.code, event["repeat"]) --love.handlers.keypressed(key, event.code, event["repeat"])
end end
@ -47,6 +47,7 @@ function love.handlers.keyreleased() end
body:addEventListener("keyup", function(self, event) body:addEventListener("keyup", function(self, event)
if love.handlers.keyreleased and not infatuated.stopDue then if love.handlers.keyreleased and not infatuated.stopDue then
-- TODO: properly implement scancodes -- TODO: properly implement scancodes
local key = keys[event.key] or event.key:lower()
love.handlers.keyreleased(key, key) love.handlers.keyreleased(key, key)
--love.handlers.keyreleased(key, event.code) --love.handlers.keyreleased(key, event.code)
end end

View File

@ -7,3 +7,27 @@ function love.window.fromPixels(pixelvalue)
assert(type(pixelvalue) == "number", "bad argument #1 to fromPixels (expected number)") assert(type(pixelvalue) == "number", "bad argument #1 to fromPixels (expected number)")
return pixelvalue return pixelvalue
end 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 { body {
background-color: #111; background: #111;
color: #ddd; color: #ddd;
font-family: monospace; font-family: monospace;
} }
canvas { #infatuated-canvas,
/*border: 1px solid #777;*/ #infatuated-msgbox {
box-shadow: #7773 0 0 25px;
position: absolute; position: absolute;
left: 50%; left: 50%;
top: 50%; top: 50%;
transform: translateX(-50%) translateY(-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; z-index: 1;
} }