09/04/15, 04:53 AM | #41 | |
Wandamey
Guest
Posts: n/a
|
thanks, i figured it out with votan example, and everything is uploaded.
I was afraid i wouldn't use properly the "self", but i would have used an addon variable to temporary store it if it hadn't worked. surprisingly, it went so flawlessly that I had to recheck 3 times that i didn't edit in the pts folder instead of the live one that's what i understood from harven's link, but I still dont understand why it doesn't simply replace the previous one when the context is the same. Not that it prevents me from doing what must be done, but it is still cloudy unclear. |
|
Wandamey |
09/04/15, 05:55 AM | #42 |
|
Think about this for a while. The context is not the same on each run, that's the whole point of creating a closure. Outer local variables are different, completely separate from the previous run's local variables.
|
09/04/15, 06:24 AM | #43 | |
Wandamey
Guest
Posts: n/a
|
it's a bit hard to tell i I don't know how it is stored and processed in the first place.
i mean, the handler has an identifier : control/"OnWhatever", i thought what you store in it would replace the old one, and eventually replace the previous results with the new ones when ran again, why would the memory keep the old runs ad vitam aeteram? edit.. well ok, different variables... it doesn't explain why rewriting a stored procedure like in the example you gave me or like votan asked is that bad. (i see it can be better by not running unecessary calls, but it aint the end of the world either, i mean, ZOS_DanB even recommanded to do an update all session long when DerBombo asked for an EVENT that triggers at the end of the session...) re edit : to understand why i'm a bit puzzled, maybe i should add that until now I thought that the interest of having local vars was that (i believed) they were trashed after the function was run Last edited by Wandamey : 09/04/15 at 06:49 AM. |
|
Wandamey |
09/04/15, 07:05 AM | #44 | |
|
Local variables may only exist in registers (i.e. cost virtually nothing) as long as they're not used in any closure. Once you create a closure, they HAVE to be moved to dynamically allocated memory, because the closure typically outlives the block it has been created in. |
|
09/04/15, 07:30 AM | #45 | ||
Wandamey
Guest
Posts: n/a
|
as soon as my head get rif of this picture, it should be way more clear. |
||
Wandamey |
09/04/15, 08:39 AM | #46 |
To see if I understood everything correct about the performance stuff I'd like to show you an example and ask, how I need to change it (including ideas).
Current code: Lua Code:
Optimized code: Lua Code:
I changed the button variable inside the anonymous SetHandler function to use the "self". And I changed the local tooltipText variable usage inside the anonymous SetHandler function to use the self.tooltipText variable now, which was passed to the button control outside the closure. But what about all the other variables used inside the anonymous SetHandler function, like "buttonId" (which is a parameter of the calling function, which is setting the handler), "settingsVars.settings.splitFilters" (which is an addon wide known local variable set as the settings in LAM 2.0 panel get changed), "p_FilterPanelId" (which is a parameter of the calling function too)? Do I need to pass them to the button control too and use the self.variableName inside the anonymouse function then? Last edited by Baertram : 09/04/15 at 08:43 AM. |
|
09/04/15, 08:55 AM | #47 | ||
Wandamey
Guest
Posts: n/a
|
i think you should define : in the first example button.tooltiptext = tooltiptext -- Edit : and define it here, not in the function btw with Lua Code:
elsewhere you define this Code:
local function MyFunction(self) local tooltiptext = self.tooltiptext -- just to keep the same variable and not mix everything up if your function is long like my arm - self here is button, cause it's called from the button blabla all your code from the anonymous function blabla end
Last edited by Wandamey : 09/04/15 at 09:06 AM. |
||
Wandamey |
09/04/15, 09:06 AM | #48 | ||
|
outputFilterState, buttonId, settingsVars... everything that's local above the anonymous function definition goes into the closure's context. I think you don't need to worry about that if you're only doing the whole thing once per user action. I'm saying this because that's what I do. For example here: https://github.com/merlight/eso-merT...window.lua#L52. This function is called once after window creation. There's one closure for savePos and one for resizeStart, and they're used for handlers on lines 58-60. But each time resizeStart is called, it creates a new closure for OnUpdate handler. Does it bother me? I could put self or panel inside control and define that handler outside. But resizeStart is only called once per click on control border, that's not enough to force me to make it a little bit more convoluted. Last edited by merlight : 09/04/15 at 09:11 AM. |
||
09/04/15, 09:25 AM | #49 |
Thanks for the hints. I'll try to change it to local functions instead of the anonymous then too.
Ok maybe it is easier to understand where the current variables are used, and how they are used, if you take a look at the current version of FCOItemSaver and look inside the function "AddOrChangeFilterButton(...)" in source code line 6300. The SetHandler call I described above is in line 6336. The tooltipText could be inside the closure too, yes. I don't know why I defined it outside in the past as it will be overwritten by the outputFilterState(...) function again. I guess I had some reason and need to change and test to find it again (or drop it ). Thanks. But you're right: I'm only setting the handler, and updating the tooltip text, if the user decided to use the tooltip for that button. So if he changes the settings and moves the mouse over the existing button the handler needs to be updated to hide the tooltip instead. I guess I need to NIL the handler then too before changing it. This example here, function AddOrChangeFilterButton(...), is called everytime you open the crafting station, mail panel, player trade panel, guild bank, bank to update the inventory filter buttons. So it is not used constantly but after a user action, right. Last edited by Baertram : 09/04/15 at 09:28 AM. |
|
09/04/15, 09:55 AM | #50 | |
Wandamey
Guest
Posts: n/a
|
shouldn't buttonId be a member of self at some point?
(haven't looked at the whole code yet and i don't know when or how you declare it, but thats why i suggested to define your tooltip text outside btw) |
|
Wandamey |
09/04/15, 10:03 AM | #51 |
Defining it outside won't work as the settings could be changed after the handler was set.
And buttonId is a parameter of the calling function AddOrChangeFilterButton. So I guess, and that is what I asked :-), yes: it should be connected to the button control too. |
|
09/04/15, 10:17 AM | #52 | ||
Wandamey
Guest
Posts: n/a
|
i should look at your code first, just don't listen to me. am just writing out loud. ok, i looked at it... i saw keanu reeves and a colored blob at first but still 2 solutions maybe? either just redefine button.buttonId = buttonId (same with the panelId i suppose) or button.tooltipText = function(blabla) <-- put this outside of your check : if (checkIfButtonexists == nil) , so it's updated when it needs to be. And, the most important here : wait for another advice than mine Last edited by Wandamey : 09/04/15 at 11:43 AM. |
||
Wandamey |
09/11/15, 01:58 AM | #53 | |
It would be enough if we had a function that gave us an updated time inside a function in order to allow us to write our own tools. As far as I have seen all time functions only update between execution, so if I called GetGameTimeMilliseconds() twice with some heavy processing in between I would get the same value from both calls. |
||
09/11/15, 02:05 AM | #54 | |
|
||
09/11/15, 02:19 AM | #55 |
I could, but who knows what happens before that callback gets called. It would make the result pretty much useless IMO.
|
|
09/11/15, 03:57 AM | #56 |
I would make a callback logger and call it whenever I want to log something. Process with many forks can do the callback with a parameter where it can send some essential info. If something and somewhere happens logger might have a clue if it get a sensible info through parameter.
|
|
09/11/15, 04:31 AM | #57 | |
|
GetGameTimeMilliseconds() returns actual time since the game was started, so it basically works for measuring time spent within a function, but the results are not very consistent. They depend on thread scheduling (how much CPU time the Lua VM is given), how it struggles with memory allocations etc. If you want to evaluate whether func1 is more efficient than func2, you'll have to call them hundreds of thousands of times to get some usable averages. |
|
09/11/15, 10:49 AM | #58 | |
What I did was something like this: Lua Code:
Best case we would get a value in UserSettings.txt which enables a profiling event that returns data for each frame. EVENT_FRAME_EXECUTION_TIMES ( integer frameTime, integer cpuPercent, integer memoryAllocation, object callstack, object addonData ) Callstack would contain all calls that happened during the frame in tree form: Lua Code:
Lua Code:
|
||
09/14/15, 01:52 PM | #59 |
Profiling event would certainly help to narrow down the most problematic pieces.
|
|
09/17/15, 01:20 PM | #60 |
|
I just found in MailLooter I was calling SetHandler 4 times in my ZO_ScrollList row setup function. This can be called a lot if your scrolling through the list...
Since ZO_ScrollList uses a row template - the only way to fix this is in XML. Just a heads up for anyone else doing what I did with a ZO_ScrollList. |
ESOUI » Developer Discussions » General Authoring Discussion » 2.1 and SetHandler |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|