Allow redrawing Lua while multiple scripts are open#4682
Conversation
YoshiRulz
left a comment
There was a problem hiding this comment.
But this clears everything drawn by other scripts as well, without giving them an opportunity to re-draw.
Does that opportunity not come when the script yields? Scripts can clear in a event.onframestart callback then draw in a yield loop.
|
|
||
| public void AddDrawCallback(Action callback) => _displayManager.OnDraw += callback; | ||
|
|
||
| public void RemoveDrawCallback(Action callback) => _displayManager.OnDraw -= callback; |
There was a problem hiding this comment.
ApiHawk already has a draw call batching/scoping method, WithSurface.
There was a problem hiding this comment.
That's completely unrelated. WithSurface(surfaceId, action) is just a wrapper for UseSurface(surfaceId); action(); UseSurface(originalSurfaceId). The new callbacks don't care about which surface is being drawn, it's just a signal to draw.
There was a problem hiding this comment.
I know, I'm saying if you're going to limit draw calls to callbacks, use the callback which already exists and which I've been promoting for this reason. edit: #4799
There was a problem hiding this comment.
I don't understand how WithSurface could be used in a way that is similar to AddDrawCallback.
And if you were to change how WithSurface works, that would be an API change that I think is better done while changing the name, so that existing code will fail at compile time instead of run time. (better yet, have both so existing code keeps working, at least until the old way is deprecated)
EDIT:
if you're going to limit draw calls to callbacks
This PR does not do that. Old Lua scripts should continue to work exactly as they have before.
There was a problem hiding this comment.
You unresolved this conversation. Why? Also I do not see how the PR mention you edited in is relevant to this PR, and I still don't know why you think WithSurface is relevant to this PR.
There was a problem hiding this comment.
My WithSurface PR is relevant because it makes the cited changes redundant.
Do not merge this PR before reverting the changes to IGuiApi.
There was a problem hiding this comment.
Your PR does not address the issue that this PR addresses (the one referred to in the title and the one I explain in OP).
Here's a concrete example of the issue my PR addresses. Take these two Lua scripts that draw on alternating frames:
local y = 100
local function draw()
-- We want to draw something when some condition is met
local dummyCondition = emu.framecount() % 2 == 1
if dummyCondition then
gui.drawRectangle(10, y, 50, 50, "white", "white")
else
-- Since we aren't drawing anything, we have to manually clear.
gui.clearGraphics()
end
end
while true do
draw()
emu.frameadvance()
end
local y = 10
local function draw()
-- We want to draw something when some condition is met
local dummyCondition = emu.framecount() % 2 == 0
if dummyCondition then
gui.drawRectangle(10, y, 50, 50, "white", "white")
else
-- Since we aren't drawing anything, we have to manually clear.
gui.clearGraphics()
end
end
while true do
draw()
emu.frameadvance()
end
If you run both of them, you will only see the rectangle from one script. After my PR, gui.clearGraphics() will not work and is also not necessary, so you'll then be able to see both flashing rectangles.
For another example:
y_manual = 10
function draw_manual()
-- a redraw being triggered by some user action
-- since there's no new frame, we have to clear
gui.clearGraphics()
gui.drawRectangle(100, y_manual, 50, 50, "white", "white")
end
while true do
draw_manual()
emu.frameadvance()
end
Using non-local variable and function so that you can use it with the Lua Console text box. When some user action triggers a re-draw, it'll clear the previous graphics and draw again. You cannot ever see the rectangle of either of the first two scripts after manually calling draw_manual(). This will not be automatically fixed in the PR, but a user would see the deprecation warning pointing them to the method they need to use when updating the scripts.
|
Text written with Drawing in Plus, drawing in a yield loop wastes a bit of CPU while paused. |
…hroughout the years such that the comment accidentally got put with the wrong code and the right code doesn't exist anymore
…awings (except clear APIs, about to be deprecated)
…multiple Lua scripts running at once
…ar more than intended
|
Updated so that other things that cleared graphics also call the new draw event:
|
Currently if a Lua script wants to re-draw it has to do one or more of:
and then draw it's stuff. But this clears everything drawn by other scripts as well, without giving them an opportunity to re-draw.
Having multiple Lua scripts that draw was also made difficult by the fact that some things that Lua draws weren't being cleared on each new frame. This means if any Lua script wants to clear what it drew, it must call
clearGraphicswhich again can interfere with other scripts.So this PR does two things:
DrawString, which makes no sense)EDIT: This now also updates other causes of clearing to also call the new draw event.
A Lua script can now do something like:
and another script can call
gui.draw()to clear its drawings. Thegui.drawcall will end up calling the first Lua'sonDrawfunction so that it isn't affected by the second script's wanting to clear.We could also make it so that the Lua Console calls
IGuiApi.Drawwhen a script is stopped. But this should happen only if the user manually stops it, since a Lua script may want to just draw once and exit, leaving the drawings on screen until the next frame.Check if completed: