Thread Tools Display Modes
04/10/14, 04:29 AM   #1
Stormknight
 
Stormknight's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 128
Updating stuff on the Wiki

I'm happy to update stuff on the Wiki here and there, whilst building Add-ons. It only seems fair, as I'm using it a LOT as a reference and it makes it better for everyone moving forward.

I've entered info for a couple of events, including one of the most used ones and it occurred to me that there are clearly many different styles/methods of coding, so I'm looking for some experienced eyes to check for me whether what I've put here makes sense (especially regarding the example). I spent several years creating add-ons for Warcraft, but nothing for the last 3 years, so just getting back into this.

http://wiki.esoui.com/EVENT_ADD_ON_LOADED
  Reply With Quote
04/10/14, 04:41 AM   #2
Cairenn
Credendo Vides
 
Cairenn's Avatar
Premium Member
WoWInterface Admin
Join Date: Mar 2004
Posts: 437
Thank you Stormknight, and everyone else who is helping with adding info to the wiki. It's very much appreciated.
  Reply With Quote
04/11/14, 12:54 PM   #3
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
One thing about events is that the WIKI does not show that events get as first parameter the eventCode, this should be included in the event descriptions, it only leads to the same 'why doesn't this work' questions here.

And imho it's better to link to enumerations already in the parameters, i.e.

EVENT_EXPERIENCE_UPDATE(string unitTag, integer currentExp, integer maxExp, ExperienceReason reason)

Last edited by Iyanga : 04/11/14 at 02:16 PM.
  Reply With Quote
04/11/14, 07:17 PM   #4
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
But the event code *isn't* a return from the event. It's a return from the event handler, saying which event was fired. This is documented in the guides on the wiki. The event code should not be documented as a return from the event. It should be documented in how to use the event handler (RegisterForEvent) function.
  Reply With Quote
04/12/14, 06:49 AM   #5
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
Thumbs up

Originally Posted by Seerah View Post
But the event code *isn't* a return from the event. It's a return from the event handler, saying which event was fired. This is documented in the guides on the wiki. The event code should not be documented as a return from the event. It should be documented in how to use the event handler (RegisterForEvent) function.

I disagree with the conclusion.


function obj.myfunc(param1, param2)
return obj.myfunc2(param3, param1, param2)
end

The signature for obj.myfunc2() is
obj.myfunc2(param3, param1, param2)

It doesn't matter where and how param3 manages it's way onto the stack, it needs to be on the stack for the function call of obj.myfunc2. Therefore param3 is part of its calling signature and trying to use obj.myfunc2 with 2 params will fail, the thing that people experience here.
  Reply With Quote
04/12/14, 10:09 AM   #6
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Of course, anything passed through by the event handler goes straight to the function.

/edit: it works this same exact way in WoW, and no one through the 10 years of programming addons or writing docs for that game thought the event code (name) needed to be documented with the event itself.
  Reply With Quote
04/12/14, 12:58 PM   #7
Stormknight
 
Stormknight's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 128
Guys, Seerah is right and the documentation is correct.

All that's really needed is to make it really obvious that the event handler returns a parameter for the event followed by the event specific parameters.
  Reply With Quote
04/12/14, 05:15 PM   #8
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
Originally Posted by Seerah View Post
Of course, anything passed through by the event handler goes straight to the function.
I don't think you understood the example.

/edit: it works this same exact way in WoW, and no one through the 10 years of programming addons or writing docs for that game thought the event code (name) needed to be documented with the event itself.
So it's not logic that determines what is right and what is wrong, but "how other people do it". Oookay. Then tell me, why does everyone fail to make it right, if it's so obvious and well-known?
  Reply With Quote
04/12/14, 09:44 PM   #9
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
I already explained the logic. What you quoted was not the logic.
  Reply With Quote
04/13/14, 04:23 AM   #10
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
Originally Posted by Seerah View Post
I already explained the logic. What you quoted was not the logic.
I guess there was no logic to quote.


Already "it's a return from the event handler" does not make sense.

LUA functions can only return a value and a function as value has no signature.

That's why there are no overloaded functions in LUA and you can't differentiate between myfunc(int) and myfunc(string), unless you write your own dispatcher, which adds the type of the parameter to the function name and implements myfunc(whatever) like if type(whatever) == "string" then return myfunc.string(whatever) end.
  Reply With Quote
04/13/14, 04:39 AM   #11
Stormknight
 
Stormknight's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 128
The example above is wrong though.

The documentation on the wiki is correct. Sparse, but correct.

Each event returns some event specific parameters.

The event handler function returns an event code parameter PLUS the parameters from the specified event.

It's like asking what sandwich filling you want. The bread will always be there, as it wouldn't be a sandwich without the bread, but you don't need to specify bread because we all know the sandwich starts with bread.

Yes, I'm aware there are different types of bread, but that's not the point.
  Reply With Quote
04/13/14, 05:04 AM   #12
Cr4x
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 11
I guess all of your were right.

However, for "beginner" it is not immediately recognizable that Lua has the ":" operator which causes in this case the eventCode as first Argument.
The list of parameter are correct, however it should be mentioned at the top of the EVENT site, that there will be always the eventCode as first argument.

/edit:
I know there is a thread about a "template" which to use when editing the wiki and which we should discuss soon.

And btw, Stormknight why is your AddonInitialize function, which is mainly your EVENT_ADD_ON_LOADED callback, not a local function instead? Do you want others to be able to initialize your addon manually ?

Last edited by Cr4x : 04/13/14 at 05:09 AM.
  Reply With Quote
04/13/14, 06:15 AM   #13
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
Originally Posted by Cr4x View Post
I guess all of your were right.

However, for "beginner" it is not immediately recognizable that Lua has the ":" operator which causes in this case the eventCode as first Argument.
The list of parameter are correct, however it should be mentioned at the top of the EVENT site, that there will be always the eventCode as first argument.

myfunc(object, param1, param2)

That's the signature.

That LUA allows myfunc to be called in three ways, as:
obj.myfunc(otherobj, param1, param2)
obj.myfunc(obj, param1, param2)
obj:myfunc(param1, param2)

does not suddenly change the signature of myfunc.

The signature for string.len is string.len(string s).
It is not string.len(), just because you can use name:len() as shorthand for name.len(name). And I have never seen a documentation that pretends that string.len(string s) would be string.len(). And LUA documentation is obviously even older than WoW addon documentation.


You can easily see the difference if you take the opposite example and make a function
myfunc(param1, param2)

Calling this function with obj:myfunc(param1, param2) will not work and you would never call this function with obj.myfunc(obj, param1, param2), because you see immediately that it violates the signature.
  Reply With Quote
04/13/14, 06:57 AM   #14
Cr4x
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 11
Originally Posted by Iyanga View Post
myfunc(object, param1, param2)

That's the signature.

That LUA allows myfunc to be called in three ways, as:
obj.myfunc(otherobj, param1, param2)
obj.myfunc(obj, param1, param2)
obj:myfunc(param1, param2)

does not suddenly change the signature of myfunc.
I would say, it depends how it is declared.
because you should always document the declaration and not the "calls"

Originally Posted by Iyanga View Post
The signature for string.len is string.len(string s).
It is not string.len(), just because you can use name:len() as shorthand for name.len(name). And I have never seen a documentation that pretends that string.len(string s) would be string.len(). And LUA documentation is obviously even older than WoW addon documentation.
http://lua-users.org/wiki/StringLibraryTutorial
Just an example

Originally Posted by Iyanga View Post
You can easily see the difference if you take the opposite example and make a function
myfunc(param1, param2)

Calling this function with obj:myfunc(param1, param2) will not work and you would never call this function with obj.myfunc(obj, param1, param2), because you see immediately that it violates the signature.
LOL sorry, but you are comparing apples with pears

So
Declaration: function MyObj.myfunc(self, param1,param2) end
Usage: MyObj.myfunc(MyObj, foo, bar)
or: MyObj:myfunc(foo,bar)

however >
Declaration: function MyObj:myfunc(param1, param2) end
Usage: MyObj.myfunc(MyObj, foo, bar)
or: MyObj:myfunc(foo,bar)

2 declarations using a different parameter list, but on the stack the functions are the same, 3 arguments, doesnt matter how they called.

In other languages you dont have to use such ":" operator, because a "this" reference to the object itselfs exists.
  Reply With Quote
04/13/14, 08:34 AM   #15
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
Originally Posted by Cr4x View Post
I would say, it depends how it is declared.
because you should always document the declaration and not the "calls"
Right.

Exactly what I said:
string.len(s)
not string.len()

They gave the shorthand example if you have an instance of string named s, too.
s:len() (they didn't write string.len() for a reason..)


Declaration: function MyObj.myfunc(self, param1,param2) end
Usage: MyObj.myfunc(MyObj, foo, bar)
or: MyObj:myfunc(foo,bar)

however >
Declaration: function MyObj:myfunc(param1, param2) end
Usage: MyObj.myfunc(MyObj, foo, bar)
or: MyObj:myfunc(foo,bar)

2 declarations using a different parameter list, but on the stack the functions are the same, 3 arguments, doesnt matter how they called.

"The effect of the colon is to add an extra hidden parameter in a method definition and to add an extra argument in a method call. The colon is only a syntactic facility""

MyObj:myfunc(param1, param2)
IS the definition of myfunc(MyObj, param1, param2)

Even the LUA documentation you linked agrees with me that it is part of the argument. How can it NOT be part of the argument list if you can access it as argument...?

Last edited by Iyanga : 04/13/14 at 08:39 AM.
  Reply With Quote
04/13/14, 11:42 AM   #16
Stormknight
 
Stormknight's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 128
Here's a simpler real world example of a restaurant menu.

At the top, "Every order comes with fries"

In the documentation below, of every meal they sell, there is no mention of fries.

There doesn't need to be, as they said above that every order comes with fries.


For the lua code though, it's not even that people are being lazy and don't want to write fries many times.

The event THIS_EVENT returns parameters (string mytext)

The event handler, which is used to interact with the event, returns the object reference PLUS whatever is returned by the event itself.

Documenting the events as returning the object would be incorrect.

Edit: this is feeling a bit silly now, so is my last post on the subject.
  Reply With Quote
04/13/14, 12:00 PM   #17
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
/sigh...

RegisterForEvent is a method defined to the EVENT_MANAGER object. It takes three parameters, the unique identifier for the addon that wants to watch for the event, the event code to watch for, and the function to call when the event fires.

(Optionally, the metatable for CreateControl also adds the RegisterForEvent method to the userdata table of controls that are created. So you could also do MyFrame:RegisterForEvent(eventCode, function) instead of going through EVENT_MANAGER.)

The RegisterForEvent method on EVENT_MANAGER works like this.
Addon A wants me to watch for event B and call function C when event B fires.
Event B fired! I will now send confirmation to Addon A that it was event B that fired, along with all returns from event B that the addon would be looking for.
eventFired = eventCodeB
eventReturns = ...
functionC(eventFired, ...)
The reason WHY the event handler (RegisterForEvent) passes along the event code is this:
Addon A wants me to watch for event B and call function C when event B fires.
Addon A wants me to watch for event D and call function C when event D fires.
Addon A wants me to watch for event E and call function C when event E fires.
Event D fired! I will now send confirmation to Addon A that it was event D that fired, along with all returns from event D that the addon would be looking for.
eventFired = eventCodeD
eventReturns = ...
functionC(eventFired, ...)
This does not make the eventCode part of the the returns list for the event. The event handler takes the event code and prepends it on to the list of returns from the event before sending that along to the function.
  Reply With Quote
04/14/14, 12:16 PM   #18
Iyanga
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 183
Originally Posted by Seerah View Post
The RegisterForEvent method on EVENT_MANAGER works like this.
Addon A wants me to watch for event B and call function C when event B fires.
Event B fired! I will now send confirmation to Addon A that it was event B that fired, along with all returns from event B that the addon would be looking for.
eventFired = eventCodeB
eventReturns = ...
functionC(eventFired, ...)
That's what I've written exactly before:

function obj.myfunc(param1, param2)
return obj.myfunc2(param3, param1, param2)
end

Including the fact that it doesn't matter how param3 makes it way into the argument list - it is there.


The reason WHY the event handler (RegisterForEvent) passes along the event code is this:
So you can have the same function as handler for different events. It's pretty easy without a large example.

This does not make the eventCode part of the the returns list for the event.
Of course it does. Who else does decide which arguments an callback gets, if not the event handler? I'm not the one deciding it, when I'm registering the handler obviously, I can't tell the event handler what I want. So the event handler does decide it. So the event code is no different than every other parameter. And the description how a callback function for an event has to look like must (for me obviously) equal the way the event handler _does_ call the function.


The event handler takes the event code and prepends it on to the list of returns from the event before sending that along to the function.
So the event code is part of the arguments for the function that is called and previously registered. What I said. The event handler might also decide to remove or nil arguments.


I guess we have to agree to disagree.
  Reply With Quote
04/17/14, 09:58 AM   #19
thelegendaryof
 
thelegendaryof's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 161
I agree that the discussion becomes a bit like running in circles.

As a conclusion I would just put an basic explanation of how those work as an introduction to Events including an example like this:

Originally Posted by Cr4x

So
Lua Code:
  1. --Declaration:
  2. function MyObj.myfunc(self, param1,param2) end
  3. --Usage:
  4. MyObj.myfunc(MyObj, foo, bar)
  5. --or:
  6. MyObj:myfunc(foo,bar)

however >
Lua Code:
  1. --Declaration:
  2. function MyObj:myfunc(param1, param2) end
  3. --Usage:
  4. MyObj.myfunc(MyObj, foo, bar)
  5. --or:
  6. MyObj:myfunc(foo,bar)

2 declarations using a different parameter list, but on the stack the functions are the same, 3 arguments, doesnt matter how they called.

In other languages you dont have to use such ":" operator, because a "this" reference to the object itselfs exists.
The rest should stay like it is as it 's correct. However the Events itself need more documentation as to when to use them or how often they fire, when they fire or what values the parameters accept. That 's more important I guess.

Back to the topic, yes the Wiki needs updates badly. I'll try to help if I find time to do so and feel like my knowdlege is good enought for it to be documented. Oh, am I blind? Wasn't there a rule or help page how to properly update the Wiki (not as in how to use a Wiki by itself more like general guidelines or rules)? I guess that would help as well!

Anyway I'll go by the principle that more info is better info. If it 's incorrect feel free to edit it later on (even thought as I said I'll try to keep it quality stuff only there 's always something you could do better or more easily or just different). That 's fine right?

Edit:

@Stormknight: I really like the way how you documented EVENT_ADD_ON_LOADED! That 's actually a good template to start of. :3

Edit 2:

Hm, however wouldn't it be better to go for a general rule to use the best performance as possible for those examples? Meaning defining them as a local function instead of pushing them into a global object? Just speaking from an optimal point of view. See here:

http://stackoverflow.com/questions/6...level-function

Hm, I need to write some tests for this later myself and see how they perform. Especially since localized functions and variables can be a nightmare if you don't keep your code structured and know what you're doing. Globalized ones might be better after all.

Last edited by thelegendaryof : 04/17/14 at 10:14 AM.
  Reply With Quote
04/17/14, 04:17 PM   #20
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Yes, examples on the wiki should be the best example possible. However, having a global variable is better than having no example. But if anyone wants to improve examples, they may - it's a wiki!
  Reply With Quote

ESOUI » Developer Discussions » Wiki » Updating stuff on the Wiki

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