From e7c5fd79d2caa6fbf7c4f71c28095ff3ddb615e3 Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine \" Monoids" Date: Fri, 23 Sep 2022 16:21:23 +0300 Subject: [PATCH 1/7] help --- actorsTest.xml | 6 +++ main.xml | 115 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 actorsTest.xml diff --git a/actorsTest.xml b/actorsTest.xml new file mode 100644 index 0000000..ce7fb36 --- /dev/null +++ b/actorsTest.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main.xml b/main.xml index 01991ac..c1a72e1 100644 --- a/main.xml +++ b/main.xml @@ -266,8 +266,29 @@ -- actors local actorQueue = {} + local actorAssociationQueue = {} + + local actorTree = {} + local currentPath + local pastPaths = {} 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 = {} function oat._actor.next() @@ -315,14 +336,17 @@ function oat._actor.init(self) currentActor.init(self) + currentActor = nil -- shouldn't be needed from now on end function oat._actor.initFrame(self) - local nextChild = self(2) + print('initiating an actorframe') + --local nextChild = self(2) self:SetDrawFunction(function() - if nextChild then - nextChild:Draw() - end + --if nextChild then + -- nextChild:Draw() + --end + -- TODO end) end @@ -330,6 +354,7 @@ local queue = {} local initCommands = {} local lockedActor + local queueRepresentation return setmetatable({}, { __index = function(self, key) @@ -343,8 +368,17 @@ end return val end + if key == '__queue' then + return queueRepresentation + end + if key == '__queueRepresentation' then + return function(q) + queueRepresentation = q + end + end if key == '__lock' then return function(actor) + if lockedActor then return end for _, v in ipairs(queue) do local func = actor[v[1]] if not func then @@ -384,6 +418,7 @@ end end initCommands = {} + queueRepresentation = nil -- to make mr. Garbage Collector's job easier end else return function(...) @@ -398,7 +433,7 @@ __newindex = function() error('uranium: cannot set properties on actors!', 2) end, - __tostring = function() return name end, + __tostring = function() return 'Proxy of ' .. name end, __name = name }) end @@ -409,11 +444,11 @@ local actor = createProxyActor(type) table.insert(actorQueue, { type = type, - file = nil, init = function(a) actor.__lock(a) end }) + actor.__queueRepresentation(actorQueue[#actorQueue]) return actor end end @@ -436,6 +471,20 @@ actor.__lock(a) 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 end @@ -474,6 +523,7 @@ end end }) + actor.__queueRepresentation(actorQueue[#actorQueue]) return actor end @@ -488,6 +538,7 @@ actor.__lock(a) end }) + actor.__queueRepresentation(actorQueue[#actorQueue]) return actor end @@ -502,6 +553,7 @@ actor.__lock(a) end }) + actor.__queueRepresentation(actorQueue[#actorQueue]) return actor end @@ -516,16 +568,62 @@ actor.__lock(a) end }) + actor.__queueRepresentation(actorQueue[#actorQueue]) return actor 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() - require('main') + --require('main') + --require('stdlib.util') end) if success then luaobj = result + --local queue = actorQueue + --actorQueue = deepcopy(actorQueue) + --transformQueueToTree() + --Trace(fullDump(actorTree)) + --currentPath = actorTree + self:addcommand('On', onCommand) self:addcommand('Ready', screen_ready_command) self:addcommand('Off', exit) @@ -548,6 +646,7 @@ -- By removing the command after it's done, it can only ever run once self:removecommand('Init') end"> - + + \ No newline at end of file From 3c4e04574cb8722991c52bd213d00c29f9fff5da Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Fri, 23 Sep 2022 19:22:23 +0300 Subject: [PATCH 2/7] GHAHAHAAAAAAAAAA IT WORKS --- actors.xml | 44 ++++++++++++++++++++---- actorsTest.xml | 6 ++-- main.xml | 93 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 107 insertions(+), 36 deletions(-) diff --git a/actors.xml b/actors.xml index 7cf954c..6eadda9 100644 --- a/actors.xml +++ b/actors.xml @@ -1,7 +1,37 @@ - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/actorsTest.xml b/actorsTest.xml index ce7fb36..5ae04ee 100644 --- a/actorsTest.xml +++ b/actorsTest.xml @@ -1,6 +1,6 @@ - + - - + + \ No newline at end of file diff --git a/main.xml b/main.xml index c1a72e1..586d026 100644 --- a/main.xml +++ b/main.xml @@ -145,6 +145,9 @@ if hasExited then return end hasExited = true uranium:call('exit') + -- good templates clean up after themselves + _G.oat = nil + _main:hidden(1) end local actorsInitialized = false -- if true, no new actors can be created @@ -218,16 +221,20 @@ local errored = false local firstrun = true + local playersLoaded = false self:addcommand('Update', function() - if not P1 and not P2 then -- sora exit hack - exit() - end - if errored then return 0 end 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() b = GAMESTATE:GetSongBeat() local dt = t - lastt @@ -291,17 +298,41 @@ oat._actor = {} - function oat._actor.next() - local actor = actorQueue[1] - if actor then - table.remove(actorQueue, 1) - currentActor = actor + local function nextActor() + local new, idx = findFirstActor(currentPath) + if not new then + print('no actor!') + currentActor = nil + else + print('adding new actor') + currentActor = new + table.remove(currentPath, idx) + end + end + + function oat._actor.recurse() + local newFrame, idx = findFirstActorFrame(currentPath) + if newFrame then + table.insert(pastPaths, currentPath) + currentPath = currentPath[idx] + table.remove(pastPaths[#pastPaths], idx) + print('recursing: ' .. #pastPaths) + return true + elseif currentActor then + table.insert(pastPaths, currentPath) + print('recursing (actor): ' .. #pastPaths) return true else + print('no actor or actorframe!') return false end end + function oat._actor.endRecurse() + print('heading back: ' .. #pastPaths) + currentPath = table.remove(pastPaths, #pastPaths) + end + function oat._actor.cond() return currentActor ~= nil end @@ -311,6 +342,7 @@ end function oat._actor.noShader() + nextActor() return oat._actor.cond() and not oat._actor.hasShader() end @@ -336,18 +368,27 @@ function oat._actor.init(self) currentActor.init(self) - currentActor = nil -- shouldn't be needed from now on + self:removecommand('Init') + currentActor = nil -- to prevent any weirdness end function oat._actor.initFrame(self) - print('initiating an actorframe') - --local nextChild = self(2) + print('initializing an actorframe') + self:removecommand('Init') self:SetDrawFunction(function() - --if nextChild then - -- nextChild:Draw() - --end - -- TODO + for i = 1, self:GetNumChildren() do + local a = self(i) + if a.fov then -- actorframe + a:Draw() + end + end end) + + if currentPath.init then + print('found init function, calling') + currentPath.init(self) + currentPath.init = nil + end end local function createProxyActor(name) @@ -575,7 +616,7 @@ function addChild(frame, actor) actorAssociationQueue[actor.__queue] = frame.__queue end - + local function transformQueueToTree() local tree = {} local paths = {} @@ -611,18 +652,19 @@ end local success, result = pcall(function() - --require('main') - --require('stdlib.util') + require('main') + require('stdlib.util') end) if success then luaobj = result - --local queue = actorQueue - --actorQueue = deepcopy(actorQueue) - --transformQueueToTree() - --Trace(fullDump(actorTree)) - --currentPath = actorTree + print('---') + + transformQueueToTree() + Trace(fullDump(actorTree)) + currentPath = actorTree + nextActor() self:addcommand('On', onCommand) self:addcommand('Ready', screen_ready_command) @@ -646,7 +688,6 @@ -- By removing the command after it's done, it can only ever run once self:removecommand('Init') end"> - - + \ No newline at end of file From 6a03dc3ebf09bdceaf47ccd6cbdcadd74889c21e Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Fri, 23 Sep 2022 19:26:31 +0300 Subject: [PATCH 3/7] cleanup, add typings --- actorsTest.xml | 6 ------ typings.lua | 9 +++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) delete mode 100644 actorsTest.xml diff --git a/actorsTest.xml b/actorsTest.xml deleted file mode 100644 index 5ae04ee..0000000 --- a/actorsTest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/typings.lua b/typings.lua index 230ad3f..9eabd49 100644 --- a/typings.lua +++ b/typings.lua @@ -50,11 +50,20 @@ function ActorFrameTexture() end ---@return RageShaderProgram --- Defines a shader. `frag` and `vert` can either be filenames or shader code. function Shader(frag, vert) end +---@return ActorFrame +---@see addChild +--- Defines an ActorFrame. Add children to it with `addChild`. +function ActorFrame() end ---@param actor Actor --- Resets an actor to its initial state function reset(actor) end +---@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 --- A simple timer. Ticks upwards at a rate of 1/sec. --- From 0521ba40f065818cdd59badea033f8663d1629b8 Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Fri, 23 Sep 2022 20:27:52 +0300 Subject: [PATCH 4/7] further actorframe cleanup --- actors.xml | 2 +- main.xml | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/actors.xml b/actors.xml index 6eadda9..c4386bd 100644 --- a/actors.xml +++ b/actors.xml @@ -32,6 +32,6 @@ - + \ No newline at end of file diff --git a/main.xml b/main.xml index 586d026..7141202 100644 --- a/main.xml +++ b/main.xml @@ -301,35 +301,33 @@ local function nextActor() local new, idx = findFirstActor(currentPath) if not new then - print('no actor!') currentActor = nil else - print('adding new actor') currentActor = new table.remove(currentPath, idx) end end - function oat._actor.recurse() + function oat._actor.recurse(forceActor) local newFrame, idx = findFirstActorFrame(currentPath) - if newFrame then + if newFrame and not (currentActor and forceActor) then table.insert(pastPaths, currentPath) currentPath = currentPath[idx] table.remove(pastPaths[#pastPaths], idx) - print('recursing: ' .. #pastPaths) return true elseif currentActor then table.insert(pastPaths, currentPath) - print('recursing (actor): ' .. #pastPaths) return true else - print('no actor or actorframe!') return false end end + function oat._actor.recurseLast() + return oat._actor.recurse(true) + end + function oat._actor.endRecurse() - print('heading back: ' .. #pastPaths) currentPath = table.remove(pastPaths, #pastPaths) end @@ -373,7 +371,6 @@ end function oat._actor.initFrame(self) - print('initializing an actorframe') self:removecommand('Init') self:SetDrawFunction(function() for i = 1, self:GetNumChildren() do @@ -385,7 +382,6 @@ end) if currentPath.init then - print('found init function, calling') currentPath.init(self) currentPath.init = nil end From 81775b8ae8f915004ea0655f7d271f9e94adb669 Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Fri, 23 Sep 2022 20:35:11 +0300 Subject: [PATCH 5/7] quick bugfix --- main.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.xml b/main.xml index 7141202..c345f9f 100644 --- a/main.xml +++ b/main.xml @@ -658,9 +658,8 @@ print('---') transformQueueToTree() - Trace(fullDump(actorTree)) + --Trace(fullDump(actorTree)) currentPath = actorTree - nextActor() self:addcommand('On', onCommand) self:addcommand('Ready', screen_ready_command) From e6c2867aed653b0bf35475a53c620cba2f386dab Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Fri, 23 Sep 2022 21:44:37 +0300 Subject: [PATCH 6/7] tiiny fixes!! almost there!! almost stable!! --- main.xml | 143 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 55 deletions(-) diff --git a/main.xml b/main.xml index 08758e4..2c1c001 100644 --- a/main.xml +++ b/main.xml @@ -167,8 +167,11 @@ hasExited = true uranium:call('exit') -- good templates clean up after themselves + uranium = nil _G.oat = nil + oat = nil _main:hidden(1) + collectgarbage() end local actorsInitialized = false -- if true, no new actors can be created @@ -236,62 +239,20 @@ end end - local lastt = GAMESTATE:GetSongTime() - local function screen_ready_command(self) - hideThemeActors() - self:hidden(0) + GAMESTATE:ApplyModifiers('clearall') - local errored = false - local firstrun = true - local playersLoaded = false - self:addcommand('Update', function() - if errored then - return 0 - end - 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() - b = GAMESTATE:GetSongBeat() - local dt = t - lastt - lastt = t - - if firstrun then - firstrun = false - dt = 0 - self:GetChildren()[2]:hidden(1) - uranium:call('ready') - end - - for _, q in ipairs(globalQueue) do - local actor = q[1] - local v = q[2] - - local func = actor[v[1]] - if not func then - -- uhmmm ??? hm. what do we do?? - else - patchFunction(func, actor)(unpack(v[2])) + function setDrawFunction(frame, func) + frame:SetDrawFunction(function() + for i = 1, frame:GetNumChildren() do + local a = frame:GetChildAt(i - 1) + if a.fov then -- actorframe + a:Draw() end end - - uranium:call('update', dt) - - errored = false - - return 0 + func() end) - self:luaeffect('Update') end - GAMESTATE:ApplyModifiers('clearall') - -- actors local actorQueue = {} @@ -332,12 +293,15 @@ function oat._actor.recurse(forceActor) local newFrame, idx = findFirstActorFrame(currentPath) - if newFrame and not (currentActor and forceActor) then + local newActor = findFirstActor(currentPath) + if newFrame and not (newActor and forceActor) then + print('creating frame') table.insert(pastPaths, currentPath) currentPath = currentPath[idx] table.remove(pastPaths[#pastPaths], idx) return true - elseif currentActor then + elseif newActor then + print('creating actor') table.insert(pastPaths, currentPath) return true else @@ -346,6 +310,7 @@ end function oat._actor.recurseLast() + print('recurselast: hi!') return oat._actor.recurse(true) end @@ -396,7 +361,7 @@ self:removecommand('Init') self:SetDrawFunction(function() for i = 1, self:GetNumChildren() do - local a = self(i) + local a = self:GetChildAt(i - 1) if a.fov then -- actorframe a:Draw() end @@ -476,11 +441,14 @@ ) end end + -- to make mr. Garbage Collector's job easier initCommands = {} - queueRepresentation = nil -- to make mr. Garbage Collector's job easier + queueRepresentation = nil + queue = {} end else return function(...) + if actorsInitialized then return end if key == 'addcommand' and arg[2] == 'Init' then table.insert(initCommands, {arg[3], debug.getinfo(2, 'Sl')}) else @@ -669,6 +637,71 @@ actorTree = tree end + local lastt = GAMESTATE:GetSongTime() + local function screenReadyCommand(self) + hideThemeActors() + self:hidden(0) + oat._actor = {} + + actorQueue = {} + actorAssociationQueue = {} + + actorTree = {} + currentPath = nil + pastPaths = {} + currentActor = nil + + collectgarbage() + + local errored = false + local firstrun = true + local playersLoaded = false + self:addcommand('Update', function() + if errored then + return 0 + end + 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() + b = GAMESTATE:GetSongBeat() + local dt = t - lastt + lastt = t + + if firstrun then + firstrun = false + dt = 0 + self:GetChildren()[2]:hidden(1) + uranium:call('ready') + end + + for _, q in ipairs(globalQueue) do + local actor = q[1] + local v = q[2] + + local func = actor[v[1]] + if not func then + -- uhmmm ??? hm. what do we do?? + else + patchFunction(func, actor)(unpack(v[2])) + end + end + + uranium:call('update', dt) + + errored = false + + return 0 + end) + self:luaeffect('Update') + end + local success, result = pcall(function() require('main') require('stdlib.util') @@ -684,7 +717,7 @@ currentPath = actorTree self:addcommand('On', onCommand) - self:addcommand('Ready', screen_ready_command) + self:addcommand('Ready', screenReadyCommand) self:addcommand('Off', exit) self:addcommand('SaltyReset', exit) self:addcommand('WindowFocus', function() From 7c486e896a106595f64a15fd3aa5717fa149b59c Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Fri, 23 Sep 2022 22:30:22 +0300 Subject: [PATCH 7/7] drawfunction fixes (this might be stable now??) --- main.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/main.xml b/main.xml index 2c1c001..e5e38eb 100644 --- a/main.xml +++ b/main.xml @@ -241,11 +241,13 @@ GAMESTATE:ApplyModifiers('clearall') + local specialActorFrames = {} -- ones defined specifically; here for drawfunction jank + function setDrawFunction(frame, func) frame:SetDrawFunction(function() for i = 1, frame:GetNumChildren() do local a = frame:GetChildAt(i - 1) - if a.fov then -- actorframe + if specialActorFrames[a] == false then a:Draw() end end @@ -362,7 +364,7 @@ self:SetDrawFunction(function() for i = 1, self:GetNumChildren() do local a = self:GetChildAt(i - 1) - if a.fov then -- actorframe + if specialActorFrames[a] == false then a:Draw() end end @@ -371,6 +373,9 @@ if currentPath.init then currentPath.init(self) currentPath.init = nil + specialActorFrames[self] = true + else + specialActorFrames[self] = false end end