Thread Tools Display Modes
03/12/14, 03:30 PM   #1
inDef
Join Date: Mar 2014
Posts: 16
What is LibStub?

Hey All,

I've read the little document on LibStub here, but it doesn't clarify to me at all what it is or what it does.

What exactly is a "versioning library" in terms of add-ons? What is a library in general in terms of add-ons?

I see this in add-ons all the time:

Code:
local LAM = LibStub("LibAddonMenu-1.0")
However I don't see a "LibStub" function defined in either LubStub.lua or LibAddonMenu-1.0.lua. What is that doing?

What are majors and minors?

What does LibAddonMenu-1.0.lua do? It looks like a bunch of functions for creating windows?

Lastly, what is a stub?

Sorry for all these questions. Can't seem to find any documentation anywhere other than what I linked, which only helps if you already know what it's doing (from WoW or something).
  Reply With Quote
03/12/14, 05:27 PM   #2
vasdrakken
Join Date: Mar 2014
Posts: 3
Basically it a group or compilation of scripts and/or code that can be used as the basis for add ons.

You use so that your mods function with other mods, you use it so that it is easier to get started, and similar stuff. Think of it as a dll or dynamic link library for lua.
  Reply With Quote
03/13/14, 10:44 AM   #3
inDef
Join Date: Mar 2014
Posts: 16
What is LibStub?

Hi All,

I asked the question "What is LibStub?" in the wrong forum on accident. Since I asked that question, I went and did some research and actually figured it out myself.

I'd like to post here my findings/conclusions so that it may help other people who have the same question I did. If you see anything wrong here, please feel free to correct me.

The following block of code is the exact code of LibStub.lua with detailed explanations of everything that is happening. I use the addon "LibAddonMenu-1.0" as an example throughout these explanations...thanks to Seerah for unknowingly allowing me to use his addon as an example

Lua Code:
  1. -- LibStub is a simple "version control" stub of code that ensures you are using the latest
  2. -- version of all libraries that are registered with it...including itself.
  3. -- Example: Your ESO client is running 2 different add-ons and both of them use the
  4. --          library "LibAddonMenu-1.0".  However, one of the add-ons uses minor version 2
  5. --          and the other minor version 4.  LibStub will ensure that the latest version
  6. --          (version 4) is used by both add-ons.
  7.  
  8. local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 1
  9.  
  10. -- the _G table is the Lua "environment" where all Global variables are stored.
  11. -- The point of this statement is to see if "LibStub" already exists in memory,
  12. -- or more specifically, was already loaded by another add-on unknown to your add-on.
  13. -- If LibStub has not been loaded yet anywhere, _G[LIBSTUB_MAJOR] will return nil.
  14.  
  15. local LibStub = _G[LIBSTUB_MAJOR]
  16.  
  17. local strformat = string.format
  18. if not LibStub or LibStub.minor < LIBSTUB_MINOR then
  19.  
  20.     --[[
  21.         If you got here, either LibStub was undefined (nil) or the current LibStub in memory has a lesser
  22.         minor revision number than this one.  Assuming LibStub was undefined since this is version 1,
  23.         the following 3 lines create a table titled 'LibStub' which looks like:
  24.        
  25.         LibStub = {
  26.            
  27.             libs = {}
  28.             minors = {}
  29.             minor = 1
  30.        
  31.         }
  32.        
  33.         and sets the global variable "LibStub" equal to this table.  This global table is now the LibStub definition
  34.         for ALL add-ons that use it.
  35.        
  36.         If a newer version of LibStub exists in an add-on somewhere, that version will get used instead since the global
  37.         table "LibStub" will be set there. 
  38.     --]]
  39.  
  40.     LibStub = LibStub or {libs = {}, minors = {} }
  41.     _G[LIBSTUB_MAJOR] = LibStub
  42.     LibStub.minor = LIBSTUB_MINOR
  43.    
  44.    
  45.     -- Register a new library with LibStub
  46.     function LibStub:NewLibrary(major, minor)
  47.    
  48.         assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
  49.         minor = assert(tonumber(zo_strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
  50.        
  51.         -- Example:  major = "LibAddonMenu-1.0" and minor = 4
  52.        
  53.         -- oldminor = LibStub.minors["LibAddonMenu-1.0"]
  54.         -- If a version of LibAddonMenu is already loaded into memory, oldminor will contain it's version number.
  55.         -- Otherwise, oldminor = nil.
  56.         local oldminor = self.minors[major]
  57.        
  58.         -- If a version of LibAddonMenu is already in memory AND it's version number is greater than or equal to
  59.         -- the new library, exit the function and return nil.
  60.         if oldminor and oldminor >= minor then return nil end
  61.        
  62.         -- If you got here, that means either this new library doesn't exist in memory or it's a newer version
  63.         -- Set the minor version number of LibAddonMenu to 4.  If LibStud.libs["LibAddonMenu-1.0"] already exists,
  64.         -- continue to use that library.  Otherwise, set to {}.
  65.         -- LibStub.minors["LibAddonMenu-1.0"] = 4, LibStub.libs["LibAddonMenu-1.0"] = LibStub.libs["LibAddonMenu-1.0"] or {}
  66.         self.minors[major], self.libs[major] = minor, self.libs[major] or {}
  67.        
  68.         -- Return the library table and the oldminor version number.
  69.         -- If this is a brand new library (not in memory already) the library table will be empty.
  70.         return self.libs[major], oldminor
  71.        
  72.     end
  73.    
  74.     -- Grabs a library for you to use.  For example, if you want to use the LibAddonMenu-1.0 library
  75.     -- you would call LAM = LibStub:GetLibrary("LibAddonMenu-1.0").  This returns all definitions
  76.     -- of the library (methods, variables, tables, etc.) into your new object LAM.
  77.     function LibStub:GetLibrary(major, silent)
  78.         if not self.libs[major] and not silent then
  79.             error(("Cannot find a library instance of %q."):strformat(tostring(major)), 2)
  80.         end
  81.         return self.libs[major], self.minors[major]
  82.     end
  83.    
  84.     -- See all libraries currently registered with LibStub in memory
  85.     function LibStub:IterateLibraries() return pairs(self.libs) end
  86.    
  87.     -- Allows a shortcut way to call the GetLibrary function.
  88.     -- These two calls become 100% equivalent:
  89.     --   LAM = LibStub:GetLibrary("LibAddonMenu-1.0")
  90.     --   LAM = LibStub("LibAddonMenu-1.0")
  91.     setmetatable(LibStub, { __call = LibStub.GetLibrary })
  92.    
  93. end

If you have any questions please feel free to ask!

Last edited by inDef : 03/13/14 at 10:56 AM.
  Reply With Quote
03/13/14, 11:14 AM   #4
inDef
Join Date: Mar 2014
Posts: 16
Thanks to mods for moving!
  Reply With Quote
03/13/14, 11:49 AM   #5
Cairenn
Credendo Vides
 
Cairenn's Avatar
Premium Member
WoWInterface Admin
Join Date: Mar 2004
Posts: 437
You're welcome. I just merged the two threads, since there was some information in one that wasn't in the other and vice versa. Figured that'd work best.
  Reply With Quote
03/13/14, 02:32 PM   #6
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Sorry, inDef, I was travelling and wanted to give you the answer and time needed, rather than try to get something out quick on my phone.

Glad you were able to find the answers you were looking for, and thanks so much for posting it here for others as well!


/edit: I would like to point out also that in the top of your library code, you should do this:

Lua Code:
  1. local MAJOR, MINOR = "LibAddonMenu-1.0", 4
  2. local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
  3. if not lam then return end  --the same or newer version of this lib is already loaded into memory
Above, according to inDef's lines 58-60, you can see that LibStub:NewLibrary(major, minor) will return nil if the same or newer version of your library already exists. In this case, you can use my line 3 above. This means that the rest of your library's file will not be parsed into memory (so an older version won't overwrite a newer version).

Last edited by Seerah : 03/13/14 at 02:41 PM.
  Reply With Quote
03/13/14, 08:31 PM   #7
inDef
Join Date: Mar 2014
Posts: 16
Originally Posted by Seerah View Post
Sorry, inDef, I was travelling and wanted to give you the answer and time needed, rather than try to get something out quick on my phone.

Glad you were able to find the answers you were looking for, and thanks so much for posting it here for others as well!


/edit: I would like to point out also that in the top of your library code, you should do this:

Lua Code:
  1. local MAJOR, MINOR = "LibAddonMenu-1.0", 4
  2. local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
  3. if not lam then return end  --the same or newer version of this lib is already loaded into memory
Above, according to inDef's lines 58-60, you can see that LibStub:NewLibrary(major, minor) will return nil if the same or newer version of your library already exists. In this case, you can use my line 3 above. This means that the rest of your library's file will not be parsed into memory (so an older version won't overwrite a newer version).
Thanks for your reply Seerah!

Yeah, after I realized I posted in the wrong place and it'd likely be awhile before getting the response I was looking for... I decided to just dive in and figure it out.

Learned a lot and my understanding is much better now for it. I wish ESO was out so I could start working on my addon! Or if ZOS would at least give you guys permission to post the default UI functions and what they do (the ZO_ ones).
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » What is LibStub?


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