OnPluginTick getting blocked by other plugin processing?

Posted by Fiendish on Tue 30 Nov 2010 02:09 AM — 6 posts, 17,543 views.

USA Global Moderator #0
It looks like OnPluginTick isn't getting called at all, let alone 25 times per second, if other plugins are doing a lot of work on a lot of input.

Having, for example,
local reset_on_tick = false

function OnPluginBroadcast (msg, id, name, text)
    if (msg == 999 and text == "repaint") then
        Note("repaint broadcast from "..name)
        reset_on_tick = true
    end
end

function OnPluginTick()
    Note("tick")
    if reset_on_tick then
        reset_on_tick = false
        Note("repainting")
        Repaint()
    end
end
and replacing all calls to repaint in other plugins with related broadcasts results in this...
Quote:

tick
tick
tick
tick
tick
tick
tick
run 6e
tick
tick
tick
tick
Great Andolor Highway (3210)
repaint broadcast from Aardwolf_BigMap_Graphical

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
North of a Great Carnivale (3209)
repaint broadcast from Aardwolf_BigMap_Graphical

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
A dusty field (3208)
repaint broadcast from Aardwolf_BigMap_Graphical

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
Fields near the Dragon River (3207)
repaint broadcast from Aardwolf_BigMap_Graphical

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
The Dragon River (3206)
repaint broadcast from Aardwolf_BigMap_Graphical

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
A Small Village
repaint broadcast from Aardwolf_BigMap_Graphical
There are several small fields filled with crops surrounding a cluster of
log houses here. People dressed in rough woolen clothing are scattered
around doing various activities which keep any small, rural settlement
alive. In the distance, a young boy can be seen watching over a flock of
sheep, and a woman seems to be carrying water back to one of the houses.
Several men seem to be heading for the larger town, and its extensive
forests. There is a very large forest a bit farther to the east, and the
people of this village seem to be avoiding it, almost desperately. The
skyline in that direction seems to give off a bright shimmer, almost as if
the trees themselves glitter softly.

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
[Exits: north east south west]
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars

< 3039/3039hp 2324/2324mp 3191/3211mv 3341tnl 820737g Quest=0 Dbl: 10 > < -2470 >

INFO: Zodiac raises a level. Now up to level 195.
INFO: Bladedge raises a level. Now up to level 12.

tick
repainting
tick
tick
tick
tick
tick
tick


If this is expected behavior, something in the helps should indicate it. Currently forum posts and the very limited documentation on OnPluginTick indicates that we can expect 25 updates per second, not 25 or 0 updates per second. It doesn't even fire in between other plugin events.
Amended on Tue 30 Nov 2010 02:13 AM by Fiendish
Australia Forum Administrator #1
Hmmmmm.

http://msdn.microsoft.com/en-us/library/ms644902%28VS.85%29.aspx


The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions post this message only when no other higher-priority messages are in the thread's message queue.


OnPluginTick uses WM_TIMER messages.
Australia Forum Administrator #2
Fiendish said:

repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_Ascii_Mapper
repaint broadcast from Aardwolf_GMCP_Mapper
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars
repaint broadcast from Aardwolf_Statmon
repaint broadcast from Aardwolf_Health_Bars


What's all this then? Simulating Redraw?
Australia Forum Administrator #3
Fiendish said:

If this is expected behavior, something in the helps should indicate it.


I've updated the documentation. There is no real way of guaranteeing a firing of 25 times a second, because an individual script might take more than 40 milliseconds to run.

In your particular case, you might check for elapsed time in the repaint broadcast message, and do whatever you are planning to do if 40 milliseclonds have elapsed.
USA Global Moderator #4
Nick Gammon said:

What's all this then? Simulating Redraw?

I was experimenting with a way to batch calls to repaint. Essentially I want something sort of like Redraw, in that it doesn't do something expensive every single call, but that actually still forces painting periodically like repaint does.

Quote:
There is no real way of guaranteeing a firing of 25 times a second, because an individual script might take more than 40 milliseconds to run.
That much I expected, but it wasn't even firing in between function calls because it's getting co-opted by processing new mud output. The WM_TIMER explanation makes sense.

Quote:
In your particular case, you might check for elapsed time in the repaint broadcast message, and do whatever you are planning to do if 40 milliseclonds have elapsed.

An excellent suggestion. I'll try that.
Amended on Tue 30 Nov 2010 02:44 AM by Fiendish
USA Global Moderator #5
FYI, Nick, my current solution is this:
local repaint_on_tick = false
local last_repaint_time = utils.timer()
function OnPluginBroadcast (msg, id, name, text)
    if (msg == 999 and text == "repaint") then
        repaint_on_tick = true
        if (utils.timer() - last_repaint_time > .1) then
            repaint_on_tick = false        
            Repaint()
            last_repaint_time = utils.timer()
        end
    end
end

-- if ticks are coming through, then we have enough time to repaint again
function OnPluginTick()
    if repaint_on_tick == true then
        repaint_on_tick = false        
        Repaint()
        last_repaint_time = utils.timer()
    end
end

I *think* this allows me to get deferred drawing for better performance when running a lot of plugins at once like Redraw and also the higher priority of Repaint that causes it to happen at all instead of never when under load.