Compare commits

...

5 Commits

Author SHA1 Message Date
Jill 0933b25ae4 quick bugfix 2022-09-23 23:07:36 +03:00
Jill d8056408f4 further actorframe cleanup 2022-09-23 23:07:36 +03:00
Jill e7d49fa562 cleanup, add typings 2022-09-23 23:07:36 +03:00
Jill f6638b8f3e GHAHAHAAAAAAAAAA IT WORKS 2022-09-23 23:07:36 +03:00
Jill 441ca0facc help 2022-09-23 23:07:36 +03:00
3 changed files with 196 additions and 22 deletions

View File

@ -1,7 +1,37 @@
<ActorFrame InitCommand="%oat._actor.initFrame"> <ActorFrame InitCommand="%oat._actor.initFrame"><children>
<children>
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/> <!-- help -->
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.next()" File="actors.xml" /> <Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
</children> <Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
</ActorFrame> <Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.noShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init"/>
<Layer Condition="oat._actor.hasShader()" Type="@oat._actor.type()" File="@oat._actor.file()" Font="@oat._actor.font()" InitCommand="%oat._actor.init" Frag="@oat._actor.frag()" Vert="@oat._actor.vert()" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurse()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
<Layer Condition="oat._actor.recurseLast()" File="actors.xml" InitCommand="%oat._actor.endRecurse" />
</children></ActorFrame>

165
main.xml
View File

@ -166,6 +166,9 @@
if hasExited then return end if hasExited then return end
hasExited = true hasExited = true
uranium:call('exit') uranium:call('exit')
-- good templates clean up after themselves
_G.oat = nil
_main:hidden(1)
end end
local actorsInitialized = false -- if true, no new actors can be created local actorsInitialized = false -- if true, no new actors can be created
@ -240,16 +243,20 @@
local errored = false local errored = false
local firstrun = true local firstrun = true
local playersLoaded = false
self:addcommand('Update', function() self:addcommand('Update', function()
if not P1 and not P2 then -- sora exit hack
exit()
end
if errored then if errored then
return 0 return 0
end end
errored = true errored = true
if P1 and P2 then
playersLoaded = true
end
if playersLoaded and not P1 and not P2 then -- sora exit hack
exit()
end
t = os.clock() t = os.clock()
b = GAMESTATE:GetSongBeat() b = GAMESTATE:GetSongBeat()
local dt = t - lastt local dt = t - lastt
@ -288,21 +295,64 @@
-- actors -- actors
local actorQueue = {} local actorQueue = {}
local actorAssociationQueue = {}
local actorTree = {}
local currentPath
local pastPaths = {}
local currentActor = nil local currentActor = nil
local function findFirstActor(path)
for i, v in ipairs(path) do
if v.type or v.file then
return v, i
end
end
end
local function findFirstActorFrame(path)
for i, v in ipairs(path) do
if not v.type and not v.file then
return v, i
end
end
end
oat._actor = {} oat._actor = {}
function oat._actor.next() local function nextActor()
local actor = actorQueue[1] local new, idx = findFirstActor(currentPath)
if actor then if not new then
table.remove(actorQueue, 1) currentActor = nil
currentActor = actor else
currentActor = new
table.remove(currentPath, idx)
end
end
function oat._actor.recurse(forceActor)
local newFrame, idx = findFirstActorFrame(currentPath)
if newFrame and not (currentActor and forceActor) then
table.insert(pastPaths, currentPath)
currentPath = currentPath[idx]
table.remove(pastPaths[#pastPaths], idx)
return true
elseif currentActor then
table.insert(pastPaths, currentPath)
return true return true
else else
return false return false
end end
end end
function oat._actor.recurseLast()
return oat._actor.recurse(true)
end
function oat._actor.endRecurse()
currentPath = table.remove(pastPaths, #pastPaths)
end
function oat._actor.cond() function oat._actor.cond()
return currentActor ~= nil return currentActor ~= nil
end end
@ -312,6 +362,7 @@
end end
function oat._actor.noShader() function oat._actor.noShader()
nextActor()
return oat._actor.cond() and not oat._actor.hasShader() return oat._actor.cond() and not oat._actor.hasShader()
end end
@ -337,21 +388,32 @@
function oat._actor.init(self) function oat._actor.init(self)
currentActor.init(self) currentActor.init(self)
self:removecommand('Init')
currentActor = nil -- to prevent any weirdness
end end
function oat._actor.initFrame(self) function oat._actor.initFrame(self)
local nextChild = self(2) self:removecommand('Init')
self:SetDrawFunction(function() self:SetDrawFunction(function()
if nextChild then for i = 1, self:GetNumChildren() do
nextChild:Draw() local a = self(i)
if a.fov then -- actorframe
a:Draw()
end
end end
end) end)
if currentPath.init then
currentPath.init(self)
currentPath.init = nil
end
end end
local function createProxyActor(name) local function createProxyActor(name)
local queue = {} local queue = {}
local initCommands = {} local initCommands = {}
local lockedActor local lockedActor
local queueRepresentation
return setmetatable({}, { return setmetatable({}, {
__index = function(self, key) __index = function(self, key)
@ -365,8 +427,17 @@
end end
return val return val
end end
if key == '__queue' then
return queueRepresentation
end
if key == '__queueRepresentation' then
return function(q)
queueRepresentation = q
end
end
if key == '__lock' then if key == '__lock' then
return function(actor) return function(actor)
if lockedActor then return end
for _, v in ipairs(queue) do for _, v in ipairs(queue) do
local func = actor[v[1]] local func = actor[v[1]]
if not func then if not func then
@ -406,6 +477,7 @@
end end
end end
initCommands = {} initCommands = {}
queueRepresentation = nil -- to make mr. Garbage Collector's job easier
end end
else else
return function(...) return function(...)
@ -420,7 +492,7 @@
__newindex = function() __newindex = function()
error('uranium: cannot set properties on actors!', 2) error('uranium: cannot set properties on actors!', 2)
end, end,
__tostring = function() return name end, __tostring = function() return 'Proxy of ' .. name end,
__name = name __name = name
}) })
end end
@ -431,11 +503,11 @@
local actor = createProxyActor(type) local actor = createProxyActor(type)
table.insert(actorQueue, { table.insert(actorQueue, {
type = type, type = type,
file = nil,
init = function(a) init = function(a)
actor.__lock(a) actor.__lock(a)
end end
}) })
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor return actor
end end
end end
@ -458,6 +530,20 @@
actor.__lock(a) actor.__lock(a)
end end
}) })
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor
end
function ActorFrame()
if actorsInitialized then error('uranium: cannot create an actor during runtime!!', 2) end
local actor = createProxyActor('ActorFrame')
table.insert(actorQueue, {
type = 'ActorFrame',
init = function(a)
actor.__lock(a)
end
})
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor return actor
end end
@ -496,6 +582,7 @@
end end
end end
}) })
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor return actor
end end
@ -510,6 +597,7 @@
actor.__lock(a) actor.__lock(a)
end end
}) })
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor return actor
end end
@ -524,6 +612,7 @@
actor.__lock(a) actor.__lock(a)
end end
}) })
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor return actor
end end
@ -538,16 +627,62 @@
actor.__lock(a) actor.__lock(a)
end end
}) })
actor.__queueRepresentation(actorQueue[#actorQueue])
return actor return actor
end end
function addChild(frame, actor)
actorAssociationQueue[actor.__queue] = frame.__queue
end
local function transformQueueToTree()
local tree = {}
local paths = {}
local iter = 0
while #actorQueue > 0 do
iter = iter + 1
if iter > 999999 then
error('uranium: failed to transform queue to tree: reached maximum iteration limit! is there an actor with an invalid actorframe?')
end
for i = #actorQueue, 1, -1 do
v = actorQueue[i]
local insertInto
if not actorAssociationQueue[v] then
insertInto = tree
else
if paths[actorAssociationQueue[v]] then
insertInto = paths[actorAssociationQueue[v]]
end
end
if insertInto then
if v.type == 'ActorFrame' then
table.insert(insertInto, {init = v.init})
table.remove(actorQueue, i)
paths[v] = insertInto[#insertInto]
else
table.insert(insertInto, v)
table.remove(actorQueue, i)
end
end
end
end
actorTree = tree
end
local success, result = pcall(function() local success, result = pcall(function()
require('main') require('main')
require('stdlib.util')
end) end)
if success then if success then
luaobj = result luaobj = result
print('---')
transformQueueToTree()
--Trace(fullDump(actorTree))
currentPath = actorTree
self:addcommand('On', onCommand) self:addcommand('On', onCommand)
self:addcommand('Ready', screen_ready_command) self:addcommand('Ready', screen_ready_command)
self:addcommand('Off', exit) self:addcommand('Off', exit)
@ -570,6 +705,6 @@
-- By removing the command after it's done, it can only ever run once -- By removing the command after it's done, it can only ever run once
self:removecommand('Init') self:removecommand('Init')
end"><children> end"><children>
<Layer Condition="oat._actor.next()" File="actors.xml"/> <Layer File="actors.xml" />
<Layer Type="Quad" InitCommand="xywh,SCREEN_CENTER_X,SCREEN_CENTER_Y,SCREEN_WIDTH,SCREEN_HEIGHT;diffuse,#000000;sleep,9e9"/> <Layer Type="Quad" InitCommand="xywh,SCREEN_CENTER_X,SCREEN_CENTER_Y,SCREEN_WIDTH,SCREEN_HEIGHT;diffuse,#000000;sleep,9e9"/>
</children></Layer> </children></Layer>

View File

@ -50,12 +50,21 @@ function ActorFrameTexture() end
---@return RageShaderProgram ---@return RageShaderProgram
--- Defines a shader. `frag` and `vert` can either be filenames or shader code. --- Defines a shader. `frag` and `vert` can either be filenames or shader code.
function Shader(frag, vert) end function Shader(frag, vert) end
---@return ActorFrame
---@see addChild
--- Defines an ActorFrame. Add children to it with `addChild`.
function ActorFrame() end
---@param actor Actor ---@param actor Actor
--- Resets an actor to its initial state --- Resets an actor to its initial state
function reset(actor) end function reset(actor) end
resetActor = reset resetActor = reset
---@param frame ActorFrame
---@param actor Actor
--- Adds a child to an ActorFrame. **Please be aware of the side-effects!**
function addChild(frame, actor) end
---@type number ---@type number
--- A simple timer. Ticks upwards at a rate of 1/sec. --- A simple timer. Ticks upwards at a rate of 1/sec.
--- ---