PDA

View Full Version : Me Again. This time my prob is speed...



meathome
December 3rd, 2008, 05:43
So the ptoblem is, when the host and a client open my skills page (the one with a loooong doubly nested windowlist and many scripts to change listitems depending on their type and calculate their values) FG start to slow down to a crawl... Its so bad that you cant even pick up dice or scroll in the list. If only the host or client open the page then it still slows down a little but not so much that it would be unusable.

Does anyone have any tips? If not ,will i have to start that page from scratch with a cleaner script design? Btw any tips for that?

The idea behind the page is the following. I wanted to get all the items that can be upgraded on level up on a single page and have a display to show how many development points ar spent on various subtypes (because theres a point limit) I did go for nested windowlists to have groups of items in a long list.
The group listitem is simply another windowlist and some labels that get set from script (like group name) and a button to hide the list of the items in the group. The second listitem (for the actual items) changes appearance eiher based on the parent groups name or its own name and does calculations based on that. Many values are tied to onUpdate of a lot of DBnodes

(For now i have only done crunchy stuff, no grafics and i used the Foundation ruleset as base. Foundation is very very cool btw )

It looks like this:
https://i408.photobucket.com/albums/pp167/meathome/example.jpg

Foen
December 3rd, 2008, 06:28
There are no particular problems using nested windowlists (the combat tracker is a good example, as each entry is an item in a windowlist, and the effects section is nested within that), so I'm guessing that your problem is more to do with scripts and events.

Try putting print() commands at the start of the likely culprit event handlers, to see if there is massive activity being caused by one or more of them. An example might be onListRearranged being called more frequently than you thought, or onChildUpdate.

Once you have narrowed down the offending events, we can see if there are neater ways to handle them.

I'm glad you find the Foundation ruleset helpful, please let me know if you think it is missing anything.

Foen

meathome
December 3rd, 2008, 07:00
Ok, did that. Got following result:

Each calculated field in the inner windowclass has a sourceUpdate function wich is called once after onInit() is called and every time the source changes.

When the window is created onInit for all fields is called once. A fill function is called once for each group. This essentially checks the listitems in a group against a static data (a list of all entries) and if it finds one that is not there it creates the entry. Its a standard for .. in pairs .

The speed problem is not only present when the sheet is opened or when a value is changed, but as long as it is open. Could it be that the number of listitems is the reason? It looks like th drawing part is the culprit. And the strange part is, that if only the host or client has it open the speed is ok. And it gets much worse if i give elements frames. If i remove frames from elements it gets much faster.

There are roughly 100 entries in the list sorted into 11 groups
1 thing that could be a problem: I get many anchored control warning static height/width ignored messages in the console. Now i noticed hat console output slows down the sheet quite a bit. Could it be that those warnings slow down things even when the console is not visible?

Foen
December 3rd, 2008, 07:05
So there is no repeated calling of onListRearranged, onChildUpdate or onSizeChanged? If not, then I can only think it is the way FG uses DirectX rendering (I seem to recall from another post that it causes high CPU usage even when idle).

Foen

meathome
December 3rd, 2008, 07:17
I think i found something. All seemed ok when only the host was running.

I started another instance of Fg logged in as player switched to the skills page and looked at the console output again.

2 very strange things appeared:

1. The console kept outputting things all the time. Looked like the onUpdate parts were called all the time repeatedly.

2. Lots of Script Warning: A recursive update invoked by setValue() terminated.

So this looks like the problem source. But im quite szumped what the actual cause could be...

This only happens when a client is viewing the sheet the same time the host does. If only one of them is viewing it, this doesnt happen

Foen
December 3rd, 2008, 07:35
With shared data, you have to be very careful not to create recursive loops: the client changes something; it invokes a handler on the host; the host updates something (or in some cases just looks at it); and triggers an event on the client. It can be a real pain to isolate and debug, let alone fix.

Using print liberally in the offending event handlers will help you pin-point the problem.

Foen

meathome
December 3rd, 2008, 15:35
Ok i found the reason or atleast part of it. In the function thats called by the handler a use setValue to change vlaues of nodes to whose onUpdate handler the same function is associated... is there a way to change a value whitout firing the onupdateEvent?

Moon Wizard
December 4th, 2008, 05:24
Yes, I found this happening quite a bit when I was reworking the combat tracker for my rulesets. I think that it also contributes to a problem I see where a windowlist gets into a loop of constantly creating/removing an item when viewed by a host and client at the same time.

In order to eliminate the possible recursion, I actually implemented a semaphore style approach. The linked fields create a hidden custom field that determines whether the linked field should be updated. In this way, it prevents the host/client bouncing on updates. (See the 4E_JPG ruleset in the template_ct*.lua files).

Hope that helps,
JPG

Foen
December 4th, 2008, 06:08
Depending on where the code is located, you can sometimes implement the semaphore using a local Lua variable, rather than having to create a custom field.



local updating = false;

function onUpdate()
if not updating then
updating = true;
... the code that invokes setValue goes here ..
updating = false;
end
end


This only works where the setValue immediately triggers the onUpdate. There are circumstances when the onUpdate event is triggered some time later (which can occur when the recursion happens between client and host), so the semaphore has already been reset and fails to prevent the recursion.

You can try the above method first to see if it fixes it, then fall back to JPG's suggestion (using a db field) if this approach isn't adequate.

Foen

meathome
December 4th, 2008, 06:21
Thanks very much! That did it.