+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 15 of 18
Like Tree1Likes

Thread: Namespace Cleanup: Addon.*, SavedVariables.*

  1. #1
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default Namespace Cleanup: Addon.*, SavedVariables.*

    Just thinking ahead:

    Addon identifiers are already uniqueness-enforced identifier-like names.

    I suggest that:

    1. Addon.foo == Inspect.Addon.Detail('foo')
    2. SavedVariables should be stored in that table, not in _G.

    I basically propose this now because if the namespace becomes a problem, it will become a problem when there are way too many addons to change anything.

    This way, we could use more intuitive (and shorter) names for our saved variables, and not worry about clashes.

    For extra credit, addon source could be executed in the scope of Addon.foo, so the saved variables would be locals.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  2. #2
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    I doubt we'll see any conflicts soon so long people use a format like this for saved variables:

    Youraddonanme_<savedvariablename>

    I think people should stop worrying about 'namespace collisions' and what not, everyone seems to be freaked out about it, but it never really posed a problem in World of Warcraft so I doubt it will pose a problem in Rift.

    That said, I would like to see a different implementation of saved variables.

    The problem is that changing it now would mean a lot of addons would have to change their code, they'd have to look up every occurance of their saved variables in the code and change them to the new format.

    Which is a lot of work for a change that solves a problem that doesn't exist.
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  3. #3
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    I seem to recall having gotten bitten by it in the past. Not much, and it's relatively easy to solve, but... Well, yeah, it can be work. But I'd rather do that work to 200 addons than 2000.

    The Rift API has a nice starting point in that Utility.*, Inspect.*, and so on mean that new Rift features can't clash with addons.

    The thing about namespace problems is that they are nearly always insanely hard to fix when you are actually encountering them, but easy to fix if they haven't happened yet. Also, in Lua at least, they can be hell to debug, because there's no diagnostics as such; you can't have a type clash in a declaration. So...

    Code:
    math = {}
    Whoops.

    Thing is, this can result in really, really, strange behaviors if you happen to stumble on a name. And while in theory we could all just use names like Addon_Foo for our saved variables... Why not just do it automatically and avoid a point-of-failure?

    I don't think I've got so much as a line of code that would have to be changed if saved variables were addon-local and accessible through Addon.* instead of global.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  4. #4
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    A matter of good practices, the only time you should define a global in an addon is, for example, if your addon is called DPSMeter:

    DPSMeter = {}

    And you just tie anything else to it, the only problem would be if there was another addon with the same name, but that would clash before the addon was even loaded.

    Aside from that, you should only ever use local
    Last edited by Verea; 03-05-2012 at 02:06 PM.
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  5. #5
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    Hmm.

    To put it another way:

    "Should" is not a robust design principle. I try to be good about declaring things local, although I'm sure I sometimes forget. (Hmm. I should totally make an addon which checks for _G pollution.)
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  6. #6
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    One easy way to avoid "forgetting" local is by using the Lua method "setfenv"
    Code:
    MyAddonTable = { }
    setfenv(1, MyAddonTable)
    
    x = { } -- Becomes MyAddonTable.x
    Any global you define after setfenv(1, table) is automatically stored inside table and any global you reference is searched in table. The second point is important as it means that after setfenv you cannot access any globals if you do not redeclare them as local upvalues:
    Code:
    MyAddonTable = { }
    setfenv(1, MyAddonTable)
    
    -- This line throws an error (trying to call a nil value)
    print("Hello World")
    There are two solutions:
    Code:
    local print = print -- Make a local copy of the global, this is always accessible despite setfenv
    
    MyAddonTable = { }
    setfenv(1, MyAddonTable)
    
    print("Hello World")
    or
    Code:
    local _G = _G -- Make a local reference to the global environment
    
    MyAddonTable = { }
    setfenv(1, MyAddonTable)
    
    _G.print("Hello World")
    I put setfenv on top of all my Lua files after redefining all the necessary globals as locals so I don't accidentally replace a global variable. This makes it also possible to use any method names you want without risking name clashes with global symbols. A neat side effect: the redeclared locals are accessed faster than globals.

    setfenv and getfenv can be useful for other situations. By setting a function's environment you can control which "global" variables are visible to the function. This comes in handy for embedded scripts (e.g. when the user can type its own function in some text field and you want to provide additional globals).
    Last edited by Imhothar; 03-05-2012 at 06:06 PM.

  7. #7
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    Oooh. I'd thought about an environment thing like that, and concluded "gee, I bet that'd be handy, I bet Lua has a way to do that", but then I forgot about it.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  8. #8
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    You should use setfenv sparingly.
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  9. #9
    Champion Lorandii's Avatar
    Join Date
    Jun 2011
    Posts
    516

    Default

    Quote Originally Posted by Verea View Post
    You should use setfenv sparingly.
    ^^ This. It can be abused to no good end, and ultimately, if used incorrectly, can and will cause all sorts of problems. I am not saying it should not be used; if you need it, use it. Just be careful. Very, very careful.

  10. #10
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    Quote Originally Posted by Lorandii View Post
    ^^ This. It can be abused to no good end, and ultimately, if used incorrectly, can and will cause all sorts of problems. I am not saying it should not be used; if you need it, use it. Just be careful. Very, very careful.
    Someone that understands me for a change. :P

    It is sometimes rather worrying, when I look around in other addon's their source code, I sometimes see some very worrying things like upvalue-ing every function there is when they are only used once (or sometimes not at all).

    Last time I installed an unitframe mod, to see how it works, and it consumed well over 3MB of memory in an idle state. It also crippled my framerate in combat.
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  11. #11
    Champion Lorandii's Avatar
    Join Date
    Jun 2011
    Posts
    516

    Default

    Quote Originally Posted by Verea View Post
    Someone that understands me for a change. :P
    I'm trying! LOL

    Quote Originally Posted by Verea View Post
    It is sometimes rather worrying, when I look around in other addon's their source code, I sometimes see some very worrying things like upvalue-ing every function there is when they are only used once (or sometimes not at all).
    Over-optimization can sometimes have the opposite desired effect, making things worse.

    Quote Originally Posted by Verea View Post
    Last time I installed an unitframe mod, to see how it works, and it consumed well over 3MB of memory in an idle state. It also crippled my framerate in combat.
    Considering computers have RAM measuring in gigabytes, 3 megabytes won't even be noticed. Memory isn't an issue, but CPU cycles are. And if an addon is crippling framerates, that is usually a sign of bad code, but not always. An addon that deals heavily with the combat log events will eat compute cycles in a huge way. Just one example.

    But there is no excuse for a unit frame addon to hog the CPU. That's just horrid design.

  12. #12
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    Quote Originally Posted by Lorandii View Post
    Considering computers have RAM measuring in gigabytes, 3 megabytes won't even be noticed.
    And here is where we will disagree. It is funny cause I wrote a theses about this for my studies when I still did my bachelor in Computer Science.

    It is this typical 'lax' attitude towards memory management which is a rather rampant problem. It results in software bloat because programmers badly make usage of all the memory they get. While 3MB might not be a problem, it could very well be. For example, why would an addon need all that memory? It seems to be storing way more information than is realistic, to compare:

    Timelapse, a combat meter which consumes tons of data and keeps track of pretty much all combat events and saves them into amalgamations, consumes only 800KB of memory after a fight of 4 minutes long involving 20 players.

    How can it be that an UnitFrame mod is eating up 3MB? No clue, but it definitely displays that something is wrong with the code. It also appeared to be full of leaks, with memory usage peaking from 3MB to 4MB rapidly for no reason.

    This again would suggest in sloppy code. Sloppy code often tends to be poor code. And poor code tends to run pretty badly.

    So why is this a problem? Because it happens everywhere, my OS (Win7) consumes almost 800 MB when idle, which is a ridiculous amount. Linux and Mac OS X are equally bad, consuming 300 to 400 MB depending on your linux distribution.

    My BSD box downstairs with a Gnome2 shell, runs comfortably on 90 to 110 MB.

    A worse example? How about web browsers. Even having just 1 page open sometimes means my browser is happily eating away 100-120 MB memory. That is almost 4 times the amount to run a freshly installed FreeBSD installation. MY GOD.

    The list goes on.
    Last edited by Verea; 03-06-2012 at 07:03 AM.
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  13. #13
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    Quote Originally Posted by Verea View Post
    You should use setfenv sparingly.
    As with all tools, it's knwoing when to use the right tool for the right job. You can try to hammer a nail with a sledgehammer but you won't like the result.

    When you know how the Lua environment works and what exactly setfenv does on the virtual machine level it is save to use setfenv. It is one of the suggested ways to implement packages in the "Programming in Lua" book, which is written by the Lua authors. You might think of Rift Addons to be a sort of package. The section I'm referring to is http://www.lua.org/pil/15.4.html#package-env

    And a side note about memory consumption:
    People tend to forget the garbage collector. The more memory there is and the more heavy values exist the more data structures the garbage collector needs to traverse per mark cycle. Creating tons of little temporary tables makes it even worse as it is often the cause of GC pressure and slowdowns. That means: re-use tables if you can.

    Local upvalues do not increase memory usage by a significant amount (8 bytes per value in the default implementation), but they avoid the reclamation of the referenced values, which is not really a problem with global functions. Considering there may be like 10 or so upvalues in a file the memory and traversal increase in this case is negligible. One can be paranoid about memory consumption or one can be realistic.

    Quote Originally Posted by Verea View Post
    A worse example? How about web browsers. Even having just 1 page open sometimes means my browser is happily eating away 100-120 MB memory. That is almost 4 times the amount to run a freshly installed FreeBSD installation. MY GOD.
    The thing with most algorithms is: the fast ones need large caches and more memory. Do not underestimate the effort required to parse and correctly render modern web pages.
    Sloppy code will always be the root of much evil, but sometimes event he best code needs lots of memory.

    But I fear this is going offtopic.

  14. #14
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    Quote Originally Posted by Imhothar View Post
    When you know how the Lua environment works and what exactly setfenv does on the virtual machine level it is save to use setfenv. It is one of the suggested ways to implement packages in the "Programming in Lua" book, which is written by the Lua authors. You might think of Rift Addons to be a sort of package
    They are not the same in any way, please understand the difference before posting such nonsense. :P
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  15. #15
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    Quote Originally Posted by Verea View Post
    They are not the same in any way, please understand the difference before posting such nonsense. :P
    Really? Care to elaborate?
    Refer to chapter 15 of "Programming in Lua" (ignoring the parts about file access and package loading as Rift is controlling that for good reasons) and tell me the difference, please.
    I hope we aren't going to argue about terminology.

+ Reply to Thread
Page 1 of 2 1 2 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts