WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Understanding CallbackHandler (https://www.wowinterface.com/forums/showthread.php?t=53790)

Rainrider 06-28-16 10:06 AM

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?

Lombra 06-28-16 10:26 AM

Who is "me" here? What is the library and why do you need to prevent others from using it?

Rainrider 06-28-16 10:38 AM

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.

Lombra 06-28-16 11:45 AM

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.

Rainrider 06-28-16 03:14 PM

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.

semlar 06-28-16 03:25 PM

Quote:

Originally Posted by Rainrider (Post 316046)
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.

Rainrider 06-29-16 03:42 AM

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.

Rainrider 07-05-16 08:53 AM

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?

myrroddin 07-05-16 07:43 PM

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)


Rainrider 07-06-16 02:38 AM

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.

myrroddin 07-06-16 01:57 PM

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


Dridzt 07-06-16 11:18 PM

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.

Rainrider 07-08-16 12:10 PM

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

myrroddin 07-08-16 12:39 PM

Quote:

Originally Posted by Rainrider (Post 316271)
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.


All times are GMT -6. The time now is 09:45 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI