Quantcast
XML vs Lua for GUI Best Practices - Page 3 - ESOUI
Thread Tools Display Modes
05/11/14, 12:00 PM   #41
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 651
Proper OnUpdate usage is certainly acceptable. Using the second return from the OnUpdate handler to create a buffer is the way to do this.

Also, static memory usage does not matter. My system has 8GB of RAM. If an addon takes up even 5MB, it's merely a drop in the bucket.

I do prefer using Lua over XML, and encourage its usage for frame creation, but you don't need to bite the heads off of people who prefer it the other way. This is a game community - this is a hobby. If you want to help people learn, then fine. If you just want to yell at them, maybe this isn't the right place for you.
  Reply With Quote
05/11/14, 12:43 PM   #42
Harven
 
Harven's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 137
Agree with Seerah, let people do as they wish. If the XML created controls are soo bad, why ZO team made the whole UI that way? I'm really grateful to them, because now we can mod almost every control. If you don't like addons with XML control just don't install them. This is a game, not the linux kernel.
  Reply With Quote
05/11/14, 01:19 PM   #43
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Sometimes Lua programmers, like myself, have had to switch to XML because of limitations within the ESO API. Some of the functionality I need will only work with XML created frames. Such as the Update routine for frames. I also had problems implementing the combo boxes in pure Lua. It was at that point *I* decided to simply put all my UI in XML and just use Lua for functionality. Maybe in a later update ESO will change things again so that I can do what I initially wanted to do.

That aside, people will always see different pro's and con's of XML vs Lua. I posted my comments way way back in the thread so I won't mention them again. But I am not going to let such a debate decide how I write my addon as I feel it needs to be written. Of course, if there is a blatant problem with some of my code, that is a different matter entirely. But then that is what wrong information/display, error messages and crashing of game is for, to tell you that something is wrong.
  Reply With Quote
05/11/14, 02:17 PM   #44
Klingo
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 14
Originally Posted by Shinni View Post
Lua Code:
  1. local b = WINDOW_MANAGER:CreateControlFromVirtual("asd", GuiRoot, "ZO_StatsDropdownRow")
  2. local a = WINDOW_MANAGER:CreateControl("asd2", GuiRoot, CT_CONTROL )
  3. b:SetHandler("OnUpdate", function(...) d(123) end )
  4. a:SetHandler("OnUpdate", function(...) d(456) end )
hmm the control from CreateControlFromVirtual works, but the other one doesn't...
Is there a difference between CreateControl and CreateControlFromVirtual?
  Reply With Quote
05/11/14, 03:13 PM   #45
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Outside of the fact you use the virtual one when inheriting from a template control, nothing. Of course the template control may have had it's own update function set up in it's initialisation. Most likely from within XML which is where we usually have to do it.

Although I seemed to have missed Shinni's post. But not sure if that would have resolved my problem as it is usually the top level control that has the update routine set up in it.
  Reply With Quote
05/11/14, 06:15 PM   #46
CatoTheElder
Join Date: May 2014
Posts: 44
Originally Posted by Seerah View Post
Proper OnUpdate usage is certainly acceptable. Using the second return from the OnUpdate handler to create a buffer is the way to do this.

Also, static memory usage does not matter. My system has 8GB of RAM. If an addon takes up even 5MB, it's merely a drop in the bucket.

I do prefer using Lua over XML, and encourage its usage for frame creation, but you don't need to bite the heads off of people who prefer it the other way. This is a game community - this is a hobby. If you want to help people learn, then fine. If you just want to yell at them, maybe this isn't the right place for you.
Please note, my post was directed at another "professional". Instead of getting butt-hurt about my stance on the issue, which is well explained and based on years of experience, and hundreds of thousands of dollars of training, perhaps you should show some empathy.

Can you provide an example where you require to run a function 60 times a second, regardless of what happens in that time? I've never heard of one, but I'm willing to listen.

Static memory usage does matter. First of all, no matter how much RAM you have, even the smallest leak will add up over time, and become a huge problem. Second, unless you have a custom written kernel, your OS controls memory management. Modern OS's tend to hold huge amounts of memory in reserve (pre-fetched), and a memory intensive add-on will increase that amount.

For example, this is how my gaming machine (Windows 8 x64) memory is being used atm:
89MB - hardware reserved
3303MB - in use
93MB - modified
4272MB - standby
408MB - free

So, that 5MB you mentioned as a drop in the bucket (which is a conservative estimation), is over 1% of free memory on an 8GB system, without the game running. (the free pool usually drops to under 10 MB when it is).

If this (software development) is a hobby for you, that's fine. It is a lifelong career for me. I really don't care what your preference is. I prefer XML too, because it is faster and easier. Sometimes I use it for very small addons, despite the drawbacks. However, I discourage other people from doing so, and in all fairness, I never should. You'll see a similar post in the addon request section from me. That thread serves as perfect evidence to back my point.

Cheers!
Cato

P.S. Can we get a /thread soon? People have argued over this for years, I expect things will only get worse.

P.P.S. ZO uses XML, because they are APPLICATION DEVELOPERS, not API SCRIPTERS. If you were programming a game engine, or even a simple application, by all means, use XML for EVERYTHING.
  Reply With Quote
05/12/14, 09:28 AM   #47
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Cato, I like your discussions and thoughts from being a profession programmer, but I agree with others that you tend to be a little terse when disagreeing with others who also claim to be professionals. With what little software development I was able to learn (since I never made it my profession), even I noticed that people do things in different ways for a variety of different reasons. And they all have their preferred methods of doing things. I would have the same attitude if someone insulted how you coded (which I believe someone did in another thread and I was a little more supportive of your response).

You talk about the problem of using OnUpdate because everything in it is called so much. The problem I ran into is that there are many functions in ESO that aren't associated with an event. Take location updates. When you run around there is nothing that can tell an addon that the player's location has changed. So, to update something that can be constantly changing like this I need to call my update function through OnUpdate. Yes, I understand that this could drain resources, but is necessary for the functionality of the addon. What would be your suggestion in such cases?
  Reply With Quote
05/12/14, 09:48 AM   #48
Roupine
Join Date: May 2014
Posts: 18
I've found that zo_callLater(fn,delay) works well for most of the things I used to use OnUpdate for. Especially if you're buffering OnUpdate to only run every so often, just replace it with a zo_callLater loop for the same length of time.

Code:
zo_callLater( MyMod:UpdateHandler, TIME_IN_MILLISECONDS )
Just add a zo_callLater() at the end of the UpdateHandler function to call itself again. It's still constantly looping a function, but it's a lot less often than 30-60 times a second.

TBH, the only reason I use OnUpdate anymore is to quickly run through a recursive set of functions that run too deep for the game to allow without external activation.
  Reply With Quote
05/12/14, 10:24 AM   #49
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 185
Originally Posted by CatoTheElder View Post
For example, this is how my gaming machine (Windows 8 x64) memory is being used atm:
89MB - hardware reserved
3303MB - in use
93MB - modified
4272MB - standby
408MB - free

So, that 5MB you mentioned as a drop in the bucket (which is a conservative estimation), is over 1% of free memory on an 8GB system, without the game running.
5MB of 4680MB is 0.11%.
  Reply With Quote
05/12/14, 11:42 AM   #50
Harven
 
Harven's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 137
Originally Posted by Roupine View Post
I've found that zo_callLater(fn,delay) works well for most of the things I used to use OnUpdate for. Especially if you're buffering OnUpdate to only run every so often, just replace it with a zo_callLater loop for the same length of time.

Code:
zo_callLater( MyMod:UpdateHandler, TIME_IN_MILLISECONDS )
Just add a zo_callLater() at the end of the UpdateHandler function to call itself again. It's still constantly looping a function, but it's a lot less often than 30-60 times a second.

TBH, the only reason I use OnUpdate anymore is to quickly run through a recursive set of functions that run too deep for the game to allow without external activation.
Hey, there is also another useful pair of functions: EVENT_MANAGER:RegisterForUpdate and EVENT_MANAGER:UnregisterForUpdate. You can find more info in the following threads: http://www.esoui.com/forums/showthread.php?t=1228, http://www.esoui.com/forums/showthread.php?t=906 and http://www.esoui.com/forums/showthread.php?t=603
  Reply With Quote
05/12/14, 11:50 AM   #51
Roupine
Join Date: May 2014
Posts: 18
Originally Posted by Harven View Post
Hey, there is also another useful pair of functions: EVENT_MANAGER:RegisterForUpdate and EVENT_MANAGER:UnregisterForUpdate. You can find more info in the following threads: http://www.esoui.com/forums/showthread.php?t=1228, http://www.esoui.com/forums/showthread.php?t=906 and http://www.esoui.com/forums/showthread.php?t=603
Woah, that's a much better solution!
Thanks a billions!
  Reply With Quote
05/12/14, 11:53 AM   #52
CatoTheElder
Join Date: May 2014
Posts: 44
Originally Posted by skyraker View Post
Cato, I like your discussions and thoughts from being a profession programmer, but I agree with others that you tend to be a little terse when disagreeing with others who also claim to be professionals. With what little software development I was able to learn (since I never made it my profession), even I noticed that people do things in different ways for a variety of different reasons. And they all have their preferred methods of doing things. I would have the same attitude if someone insulted how you coded (which I believe someone did in another thread and I was a little more supportive of your response).

You talk about the problem of using OnUpdate because everything in it is called so much. The problem I ran into is that there are many functions in ESO that aren't associated with an event. Take location updates. When you run around there is nothing that can tell an addon that the player's location has changed. So, to update something that can be constantly changing like this I need to call my update function through OnUpdate. Yes, I understand that this could drain resources, but is necessary for the functionality of the addon. What would be your suggestion in such cases?
Thanks Sky. I am quite touchy when disagreeing with others who claim to be professionals, extremely so on this particular topic. There are a few reasons for my "terseness", I'll list quickly (please don't take my brevity for rudeness.) Hopefully this clears things up, and we can move on.

1) A professional programmer should know to review empirical data and reference material.
2) Programming, compilers etc. operate solely on classic logic. Typo one character, and the compiler will throw an error at you. Do what you want on your own system, but please don't publish code that will be problematic for others, and especially encourage others to do the same because "they want to". 20+ years of debugging and error testing makes it hard to be polite about programming inefficiency and errors. I do try, believe it or not.
3) This thread is about "... best practices", not "prefered methods".
4) I was banned over this topic a few years back from this site's "sister" (WoW) by the same community of admins. A few years later, the same argument is still going on. It is fairly easy to measure performance metrics for oneself. This shouldn't have lasted a month, never mind years. Which is why I asked for the end of the thread.

As for your question regarding OnUpdate() usage. This turns out to be a fairly common thing, which is quite difficult to implement. Usually, this is intentional, as it opens up a lot of potential abuse for botting. As long as zo_CallLater is available, that should be used. This will let the timing function be done in the engine, as a general rule of thumb, the more you can pass to the engine, the better.

Without that, I'd create a separate thread for the function (preventing the main thread from getting blocked), and use a time comparison to run a recursive function once every half second or so. (tweak time for performance/addon latency). Still a bit of a dirty hack though; use EVENT_PLAYER_STATUS_CHANGED and whatever other tricks you can to keep the usage as low as possible (Don't need to spam updates when the player is afk, do we?)

Hope this helps!
Cheers!
  Reply With Quote
05/12/14, 12:11 PM   #53
Aiiane
 
Aiiane's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 19
Originally Posted by CatoTheElder View Post
As for your question regarding OnUpdate() usage. This turns out to be a fairly common thing, which is quite difficult to implement. Usually, this is intentional, as it opens up a lot of potential abuse for botting. As long as zo_CallLater is available, that should be used. This will let the timing function be done in the engine, as a general rule of thumb, the more you can pass to the engine, the better.
FWIW, zo_callLater is just a wrapper around an OnUpdate check. The zo_callLater function is implemented in Lua as part of the base game's Lua UI modules.

Specifically, zo_callLater is a wrapper around a function that calls EVENT_MANAGER:RegisterForUpdate to register a function which then calls EVENT_MANAGER:UnregisterForUpdate the first time it runs. EVENT_MANAGER:RegisterForUpdate in turn is a wrapper around OnUpdate which checks to see if it's time to fire various callbacks after each frame.

Last edited by Aiiane : 05/12/14 at 12:18 PM.
  Reply With Quote
05/12/14, 12:25 PM   #54
CatoTheElder
Join Date: May 2014
Posts: 44
Originally Posted by Aiiane View Post
FWIW, zo_callLater is just a wrapper around an OnUpdate check. The zo_callLater function is implemented in Lua as part of the base game's Lua UI modules.

Specifically, zo_callLater is a wrapper around a function that calls EVENT_MANAGER:RegisterForUpdate to register a function which then calls EVENT_MANAGER:UnregisterForUpdate the first time it runs. EVENT_MANAGER:RegisterForUpdate in turn is a wrapper around OnUpdate which checks to see if it's time to fire various callbacks after each frame.


*CENSORED*
  Reply With Quote
05/12/14, 12:31 PM   #55
Aiiane
 
Aiiane's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 19
In addition, due to the way it is implemented, if the callback supplied to zo_callLater contains an error which causes it to not successfully finish running (e.g. a restricted function call, a nil that is expected to be non-nil, etc), the callback will continue to fire for each subsequent frame, because the call to EVENT_MANAGER:UnregisterForUpdate is done after the callback is fired, so if the Lua callstack bombs out, the unregistration never happens.
  Reply With Quote
05/12/14, 12:58 PM   #56
Roupine
Join Date: May 2014
Posts: 18
Originally Posted by Aiiane View Post
FWIW, zo_callLater is just a wrapper around an OnUpdate check. The zo_callLater function is implemented in Lua as part of the base game's Lua UI modules.

Specifically, zo_callLater is a wrapper around a function that calls EVENT_MANAGER:RegisterForUpdate to register a function which then calls EVENT_MANAGER:UnregisterForUpdate the first time it runs. EVENT_MANAGER:RegisterForUpdate in turn is a wrapper around OnUpdate which checks to see if it's time to fire various callbacks after each frame.
Where do you find out such things?
  Reply With Quote
05/12/14, 01:03 PM   #57
Harven
 
Harven's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 137
Originally Posted by Aiiane View Post
...EVENT_MANAGER:RegisterForUpdate in turn is a wrapper around OnUpdate...
How you know that? EVENT_MANAGER = GetEventManager(), and the function GetEventManager() seems to be defined inside the game (not in lua). Is this a knowledge acquired with trial and error method?
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » XML vs Lua for GUI Best Practices

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off