Quantcast Understanding CallbackHandler - WoWInterface
Thread Tools Display Modes
06-28-16, 10:06 AM   #1
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
Understanding CallbackHandler

The documentation for CallbackHandler-1.0 states that the way for mixing it in a library is like that:
lua Code:
  1. local lib = LibStub:NewLibrary("MyLibName", 1)
  2. lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)

The reasoning behind this is that the user could have multiple versions of the lib installed and the lib does not have control over the loading order. So lib.callbacks = lib.callbacks will retain attached callbacks from previously loaded versions.

If this is so, that means I have to always attach the callbacks table to the lib object, which in turn means everybody on the outside can fire my events instead of me. And if I give some event arguments back, then they could use that too to provide false data in my name.

lua Code:
  1. local libToHack = LibStub("MyLibName")
  2. libToHack.callbacks:Fire("MyEventName", "Got you")

And the user can't tell if I passed "Got you" or someone else.

Am I able to prevent this somehow?
  Reply With Quote
06-28-16, 10:26 AM   #2
Lombra
A Scalebane Royal Guard
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 415
Who is "me" here? What is the library and why do you need to prevent others from using it?
__________________
Grab your sword and fight the Horde!
  Reply With Quote
06-28-16, 10:38 AM   #3
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
The library is https://github.com/Rainrider/LibArtifactData-1.0

Me is me. I don't want to prevent using the library, I want to prevent somebody returning data instead of me.

Edit:
Maybe I still expressed myself unclear. I mean "me" like the person who wrote the lib, and "they" like the users. I ask myself what happens if some user decides to tamper with lib.callbacks and how could I prevent this from happening, so that the other users could trust the information they get.

Last edited by Rainrider : 06-28-16 at 11:32 AM.
  Reply With Quote
06-28-16, 11:45 AM   #4
Lombra
A Scalebane Royal Guard
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 415
I understand. While not an answer to your question, in cases like these I'd say you shouldn't be bothering. If a user goes in and deliberately sabotages stuff, that's really a futile thing to try and prevent. Nothing prevents someone from disassembling their computer and putting a screwdriver through their CPU, but why would they do that?

Don't bother protecting the user from themself unless it's something that's easily accessible or may accidentally happen.

Edit: As long as the library is accessible via LibStub and the callback object via the library object I don't believe there's a way to deny anyone access to it, no.
__________________
Grab your sword and fight the Horde!

Last edited by Lombra : 06-28-16 at 11:50 AM.
  Reply With Quote
06-28-16, 03:14 PM   #5
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
So the only way would be to disallow embedding the library and lock the lib object with some meta table magic? And then rawset remains

I will follow your advice and just ignore that then. It seems strange however how much is so open and so accessible.
  Reply With Quote
06-28-16, 03:25 PM   #6
semlar
A Molten Giant
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 991
Originally Posted by Rainrider View Post
It seems strange however how much is so open and so accessible.
I'm not entirely sure what you're afraid of might happen here, someone might make an addon that modifies how yours behaves? The only time that happens is when someone is trying to fix something that's wrong with your addon or augment its behavior.

If you're worried about access through libstub and libcallbackhandler, don't use libstub and libcallbackhandler.

You're making a library, so you have to provide global access to the functions that you expect people to be able to use, which means they can be overwritten by another addon regardless of what you do.
  Reply With Quote
06-29-16, 03:42 AM   #7
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
I'm sorry, I didn't mean to make it sound like it is LibStub's or CallbackHandler's fault. I see it is so by design and there is no real way around and not much harm in it. A part of my learning process is to try to break stuff I made as it helps understanding the system I build upon. And the reason of concern here for me was how to track a problem down if I can't be sure whether someone tries to augment my functionality.
  Reply With Quote
07-05-16, 08:53 AM   #8
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
One further thing I don't quite get about CallbackHandler and LibStub is why it is recommended that they are embedded into the lib that uses them. If the author supports disembedded use and the user installs a no-lib package, then it is up to the user to install all dependencies, isn't it?

What is considered best practice when a library uses another library? The particular case I have is that I'm updating LibSpellbook-1.0 (LSB) to use LibArtifactData-1.0 (LAD). Both of them use LS and CBH. LAD has to be loaded before LSB and thus will load LS and CBH itself. So it makes sense to me to also strip LS and CBH but yet again this is not recommended by their respective documentation.

This leads me to think that I'm missing the big picture here. How am I supposed to do it, when I want to offer disembedded use?
  Reply With Quote
07-05-16, 07:43 PM   #9
myrroddin
A Molten Giant
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 631
While it is not recommended to stip LibStub and CallbackHandler, it is fine to do so if you wish. The reasoning why not to strip them from libraries is that LibStub is required to load libraries, and if you fire your own events (callbacks), a library would require CBH.

Remember that users are dumb. They'll look at their AddOns list, wonder what LibStub and CallbackHandler are, figure they don't need them if they don't know what they are, and disable or delete them. Then libraries will cease to load, which in turn causes AddOns that use said libraries to fail at loading, and then...

Yep, you guessed it: the user will blame the AddOn, and write an incorrect bug report to the AddOn author. It is better to hide the existance of LibStub and CallbackHandler by not using lib-strip.

As for a library that depends on another library (not named LibStub or CallbackHandler), you can modify your folder structure before uploading the zip or committing to the repository.

For example, LibGuildBankComm-1.0 requires both LibCompress and AceSerialize-3.0 to function, along with LS and CBH. In this case, it would be recommended to just bundle the relevant Lua files, rather than the whole of the libary. Come to think about it, I should double check if I did that....

Then, in your ToC, reference each Lua file directly.
Code:
LibStub\LibStub.lua
CallbackHandler-1.0\CallbackHandler.lua -- don't bundle the .xml
LibCompress\LibCompress.lua -- same deal
AceSerialize-3.0\AceSerialize-3.0.lua -- and again

lib.xml -- or LibSomeName-1.0.lua (this is YOUR library)
  Reply With Quote
07-06-16, 02:38 AM   #10
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
But something like:
Code:
assert(LibStub, "MyLib requires LibStub")
local otherLib = LibStub("OtherLib-1.0") -- second argument is nil, so errors are not silenced
should be enough to tell the user why they did not load. Also, I'm fine providing an embedded package for people who don't like or understand disembedded. I just thought there is maybe a chance for some crazy unsolvable load order if you strip LS and CBH and was unsure if this translates to other libs as lib dependencies as well.
  Reply With Quote
07-06-16, 01:57 PM   #11
myrroddin
A Molten Giant
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 631
Don't worry about the load order of libraries. You can't conrol the order in which they are registered with LibStub or CallbackHandler anyway.

What you can do is use your library's ToC fields effiecently. The ## OptionalDeps line, as you probably know, causes YOUR AddOn or library to check for the optional dependencies, and load them before your AddOn or library.
Code:
## OptionalDeps: LibStub, CallbackHandler-1.0, LibOne-1.0, LibTwo-1.0

LibStub\LibStub.lua
CallbackHandler-1.0\CallbackHandler.lua
LibOne-1.0\LibOne-1.0.lua
LibTwo-1.0\LibTwo-1.0.lua

lib.xml -- or Core.lua, Main.lua, LibMyName.lua, etc
  Reply With Quote
07-06-16, 11:18 PM   #12
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,247
I don't think things have changed significantly in this aspect since 2008

There's good arguments for "hard" embedding LibStub and CallbackHandler in that discussion that are still valid.
  Reply With Quote
07-08-16, 12:10 PM   #13
Rainrider
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 361
Both LibStub and CBH have stand-alone versions as of now. Also the post does not provide any reasoning as to why not to strip them and not to include them in the #OptDeps field of the .toc
  Reply With Quote
07-08-16, 12:39 PM   #14
myrroddin
A Molten Giant
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 631
Originally Posted by Rainrider View Post
Both LibStub and CBH have stand-alone versions as of now. Also the post does not provide any reasoning as to why not to strip them and not to include them in the #OptDeps field of the .toc
Because originally, both LS and CBH had no .toc files, and thus could not be loaded like any other AddOn. LibDataBroker-1.1 behaves like this, which is why it must be hard-embedded.

At this point, you could OptDep LS and CBH and strip them out of your lib.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Understanding CallbackHandler

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