Suggestion: would it be possible to roll all the "localized optimizations" into the base file? I know having separate files for each localization is nice for maintenance sake, but its a real pain having to include multiple localizations for a library. I think it would be much simper/nicer for addons to just have to include 1 file in their TOC, instead of the current 4, with the potential for more. I realize all these extra files are optional, but since they do help performance quite a bit I think they could be safely rolled into the main file.
They're just a table so doesn't really matter, I'm fine with combining them into a single file.
But about that FixGlobalStrings.lua : IMO that should be a separate addon, not added to ParserLib.
ParserLib is meant to parse the combat logs, not modify them.
FYI that file modifies the combatlog pattern to attempt to 'fix' some issues which only appears on some localizations: krKR, zhCN and zhTW.
I think fenlis copied that part from SWStats. In fact I had suggested to the author of SWStats to separate such thing into a separate addon, and now my own library is doing the same thing: stealthily modifies the combat logs :\
Anyway, if you want to combine the files into one, feel free do it. I won't do it myself because if I am to modify anything to the current ParserLib, the first thing I would do is to remove the FixGlobalStrings part. But I think I should at least ask fenlis first.
for example: someone called "Rophy's Dog" hits Bob with melee, the result message is :
Rophy's Dog hits Bob for 100.
which has the same pattern with "Rophy's [skill] hits Bob for 100.",
so "Rophy" will be parsed as the name, and "Dog" as the attack.
To fix that issue, the file simply add a space to the %s, so the patterns are changed to:
"_%s_ hits _%s_ for %d." and "_%s_'s _%s_ hits _%s_ for %d.".
so that the two patterns can be distinguished when someone has a name "X's Y".
Anyway, my point is that ParserLib is a combat log parser, not a 'all-on-one mod about combat logs'. "Fixing" combat logs should not be ParserLib's job in anyway so I would like to ask fenlis' permission to remove that file, but he seems to not on the IRC often, I sent him a PM in here but still got no response.
You can for detecting when someone starts to cast a spell and such (instead of parsing "bob starts to cast..."), that is what the new built in enemy casting bars use. But you couldn't use them for normal combat parsing. Those events return nothing about the damage done, resists, etc...
I branched SimpleCombatLog to use a Parser-2.0 to 1.1 wrapper, to test my Parser-2.0 in the branch.
Played a few arena matches, leveled up a bit in the outland and no errors popped out, so may be Parser-2.0 can make it before the release of TBC.
The core hasn't changed (although I tweaked a bit), so the current Parse-1.1 event data for TBC can be directly copied into Parser-2.0 easily, just keep adding missing event data to Parser-1.1 until Parser-2.0 is actually finished.
Now the most important thing if I have to finalize the API, because if the API is finalized then even if someone think ParserLib sucks want to write a kick-ass one, we still can follow a standard API.
Basically Parser-2.0 replaced the old info table approach to AceEvent events. You don't interact with ParserLib directly, instead you register to the Parser_ events:
MyAddon:RegisterEvent("Parser_Hit")
function MyAddon:Parser_Hit(source, victim, skill, amount, element) -- There are more args but they're omitted here.
print( source .. " hits " .. victim .. " for " .. amount )
end
Also in this approach, clients no longer have to manually register to the Blizzard events, ParserLib will register 'hit-related' events when you register to Parser_Hit. This has pro (easier API) and con (possible unnecessary Blizzard events being registered).
That's pretty much it, but Thrae wanted to have more detailed API, i.e. "Parser_SelfHit", "Parser_SelfCast", "Parser_OtherHit", "Parser_OtherCast", basically that doubles the size of events and I think it's unnecessary, but I'd like to ask your guys' idea.
Actually myself liked the table approach more, it has the advantages of dynamic field size, which is more robost for the fact that patterns keep changing, also people don't have to worry about the arg sequence. Passing the info as function args means the args will get longer and longer as Blizzard keep adding new patterns. But I agree table approach also have the main disadvantage that the field can be modified by anyone, just that I personally think dynamic field size is more important, and some people think otherwise. In Parser-1.1 actually every client gets a new copy of the info table to prevent them from modifying the master info table, but that kills performance.
In 2.0, can we still register at the blizzard event level if we want more granularity on what is parsed? My only issue with the "Parser_Hit" hit approach is that there's possibly a ton of events I don't care about there, so potentially a lot of wasted events and overhead parsing them for info that's not needed (for a given mod). Just as an example, SCT only cares about "hit" events that happen to the player and SCTD only cares about "hit" events that the player does.
1. addon A tells ParserLib he wants to listen to CHAT_MSG_COMBAT_SELF_HITS, and registers Parser_Hit to AceEvent.
2. addon B tells ParserLib he wants to litsen to CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS, and registers Parser_Hit to AceEvent.
3. CHAT_MSG_COMBAT_SELF_HITS was fired, ParserLib parsed the event and wants to fire Parser_Hit to addon A.
now how do I fire Parser_Hit only to A, and not B? any ideas?
if addons have to embed ParserLib into themselves, then I might be able to manipulate the unregistration of Parser_Hit for them. but I hope there is a more elegant solution other than having to manipulate clients' AceEvent registration.
You could pass the eventname as an arg to the aceevent.
So the addon can check itself for the event.
You could then also make telling parserlib the exact eventname optional.
So that you could just register Parser_Hit and parserlib then enables all events that can fire Parser_Hit.
I'd like it this way ;)
I still think that using a sequence counter that increnments on each event will solve most if not all of these issues. Each source event CHAT_MSG - gets assigned an ID which can be queried when you get derivative events eg. Parser_Hit.
You can then use some logic to ignore the event based on this ID.
In your case, you would register for CHAT_MSG_COMBAT_SELF_HITS and Parser_Hit. In the CHAT_MSG you would save the ID, and process any subsequent event with that ID.
So if the event CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS generates Parser_Hit, you will not have a matching ID when Parser_Hit fires...so you would ignore it.
Using an ID tied to the source event solves alot of ambiguity issues (with events that fire as a result of the original event) and is extremely cheap to implement.
The problem is that when A only registers to CHAT_MSG_COMBAT_SELF_HITS and Parser_Hit, I think A shouldn't receive a Parser_Hit event at all when CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS was fired. But I can't control who will receive the Parser_Hit event, or ca
IDs and counters only let me know who registered to what Blizzard events, it doesn't solve the problem.
If there isn't any better solution to this, then I think I can only pass Blizzard event as an arg to Parser_Hit, addons should expect to receive Parser events even when they didn't register to the that Blizzard event - that means they may optionally tell ParserLib what Blizzard events they're interested, but expect to receive Parser_Hit from all possible Blizzard events.
In that case the API may look something like this:
-- pass self to ParserLib so when you register to Parser_Hit, ParserLib knows that you have already suggested a Bz event and will not register to all hit-related Bz events.
AceLibrary("Parser-2.0"):SuggestEvent(self, "CHAT_MSG_COMBAT_SELF_HITS")
-- actually registers to Parser_Hit.
myAddon:RegisterEvent("Parser_Hit")
that looks weird to me, but at least it makes the suggestion part completely optional?
At the back of ParserLib it would just store a table of addon reference and their interested Bz events. ParserLib listens to AceEvent_EventRegistered for ParserLib events, when someone registers to ParserLib events, ParserLib registers to all related Bz events if the addon reference doesn't exist in the table, otherwise ParserLib registers to possible Bz events in the suggestion table.
The problem is that when A only registers to CHAT_MSG_COMBAT_SELF_HITS and Parser_Hit, I think A shouldn't receive a Parser_Hit event at all when CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS was fired. But I can't control who will receive the Parser_Hit event, or ca
IDs and counters only let me know who registered to what Blizzard events, it doesn't solve the problem.
If there isn't any better solution to this, then I think I can only pass Blizzard event as an arg to Parser_Hit, addons should expect to receive Parser events even when they didn't register to the that Blizzard event - that means they may optionally tell ParserLib what Blizzard events they're interested, but expect to receive Parser_Hit from all possible Blizzard events.
In that case the API may look something like this:
-- pass self to ParserLib so when you register to Parser_Hit, ParserLib knows that you have already suggested a Bz event and will not register to all hit-related Bz events.
AceLibrary("Parser-2.0"):SuggestEvent(self, "CHAT_MSG_COMBAT_SELF_HITS")
-- actually registers to Parser_Hit.
myAddon:RegisterEvent("Parser_Hit")
that looks weird to me, but at least it makes the suggestion part completely optional?
At the back of ParserLib it would just store a table of addon reference and their interested Bz events. ParserLib listens to AceEvent_EventRegistered for ParserLib events, when someone registers to ParserLib events, ParserLib registers to all related Bz events if the addon reference doesn't exist in the table, otherwise ParserLib registers to possible Bz events in the suggestion table.
Using a unique ID for each event allows the user of parserlib to solve the problem.
event -> parserlib
eventID = eventID+1 (=101)
event --------------------->client
self.eventID=parserlib:GetEventID(). returns 101
parse...
parserHit(eventID, ...) ------>client
if self.eventID != eventID then return end
... otherwise its from an event we want
Even better if the eventID was in AceEvent - since maybe its possible they could get parserHit before the bz event (at least that how i understand it events fired from event handlers create an event stack)
Letting the addons users store information for you prevents you having to maintain tables internally.
This is essentially the "Visitor" design pattern without the OO
But about that FixGlobalStrings.lua : IMO that should be a separate addon, not added to ParserLib.
ParserLib is meant to parse the combat logs, not modify them.
FYI that file modifies the combatlog pattern to attempt to 'fix' some issues which only appears on some localizations: krKR, zhCN and zhTW.
I think fenlis copied that part from SWStats. In fact I had suggested to the author of SWStats to separate such thing into a separate addon, and now my own library is doing the same thing: stealthily modifies the combat logs :\
Anyway, if you want to combine the files into one, feel free do it. I won't do it myself because if I am to modify anything to the current ParserLib, the first thing I would do is to remove the FixGlobalStrings part. But I think I should at least ask fenlis first.
for example: someone called "Rophy's Dog" hits Bob with melee, the result message is :
Rophy's Dog hits Bob for 100.
which has the same pattern with "Rophy's [skill] hits Bob for 100.",
so "Rophy" will be parsed as the name, and "Dog" as the attack.
To fix that issue, the file simply add a space to the %s, so the patterns are changed to:
"_%s_ hits _%s_ for %d." and "_%s_'s _%s_ hits _%s_ for %d.".
so that the two patterns can be distinguished when someone has a name "X's Y".
Anyway, my point is that ParserLib is a combat log parser, not a 'all-on-one mod about combat logs'. "Fixing" combat logs should not be ParserLib's job in anyway so I would like to ask fenlis' permission to remove that file, but he seems to not on the IRC often, I sent him a PM in here but still got no response.
SpellHitSelf add to CHAT_MSG_COMBAT_SELF_HITS
SPELLLOGSCHOOLSELF add to Patternname and SpellHitSelf
PERIODICAURADAMAGESELF add to Patternname and DotSelf
PERIODICAURADAMAGESELFOTHER move from DotSelf to DotOther
This should be changed or removed. "setn" throws errors at german client.
Since there was talk of issues with the FixLogStrings and koKR stuff, I removed it from the TBC branch.
If anyone wants to re-add the files or modify stuff (as long as it will work), go nuts.
Sure it is:
http://www.wowace.com/files/ParserLib/ParserLib-r17187%5BTBC%5D.zip
edit: but toc file is missing :)
edit2: added .toc file to svn
Played a few arena matches, leveled up a bit in the outland and no errors popped out, so may be Parser-2.0 can make it before the release of TBC.
The core hasn't changed (although I tweaked a bit), so the current Parse-1.1 event data for TBC can be directly copied into Parser-2.0 easily, just keep adding missing event data to Parser-1.1 until Parser-2.0 is actually finished.
Now the most important thing if I have to finalize the API, because if the API is finalized then even if someone think ParserLib sucks want to write a kick-ass one, we still can follow a standard API.
Basically Parser-2.0 replaced the old info table approach to AceEvent events. You don't interact with ParserLib directly, instead you register to the Parser_ events:
Also in this approach, clients no longer have to manually register to the Blizzard events, ParserLib will register 'hit-related' events when you register to Parser_Hit. This has pro (easier API) and con (possible unnecessary Blizzard events being registered).
That's pretty much it, but Thrae wanted to have more detailed API, i.e. "Parser_SelfHit", "Parser_SelfCast", "Parser_OtherHit", "Parser_OtherCast", basically that doubles the size of events and I think it's unnecessary, but I'd like to ask your guys' idea.
Actually myself liked the table approach more, it has the advantages of dynamic field size, which is more robost for the fact that patterns keep changing, also people don't have to worry about the arg sequence. Passing the info as function args means the args will get longer and longer as Blizzard keep adding new patterns. But I agree table approach also have the main disadvantage that the field can be modified by anyone, just that I personally think dynamic field size is more important, and some people think otherwise. In Parser-1.1 actually every client gets a new copy of the info table to prevent them from modifying the master info table, but that kills performance.
1. addon A tells ParserLib he wants to listen to CHAT_MSG_COMBAT_SELF_HITS, and registers Parser_Hit to AceEvent.
2. addon B tells ParserLib he wants to litsen to CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS, and registers Parser_Hit to AceEvent.
3. CHAT_MSG_COMBAT_SELF_HITS was fired, ParserLib parsed the event and wants to fire Parser_Hit to addon A.
now how do I fire Parser_Hit only to A, and not B? any ideas?
if addons have to embed ParserLib into themselves, then I might be able to manipulate the unregistration of Parser_Hit for them. but I hope there is a more elegant solution other than having to manipulate clients' AceEvent registration.
So the addon can check itself for the event.
You could then also make telling parserlib the exact eventname optional.
So that you could just register Parser_Hit and parserlib then enables all events that can fire Parser_Hit.
I'd like it this way ;)
You can then use some logic to ignore the event based on this ID.
In your case, you would register for CHAT_MSG_COMBAT_SELF_HITS and Parser_Hit. In the CHAT_MSG you would save the ID, and process any subsequent event with that ID.
So if the event CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS generates Parser_Hit, you will not have a matching ID when Parser_Hit fires...so you would ignore it.
Using an ID tied to the source event solves alot of ambiguity issues (with events that fire as a result of the original event) and is extremely cheap to implement.
IDs and counters only let me know who registered to what Blizzard events, it doesn't solve the problem.
If there isn't any better solution to this, then I think I can only pass Blizzard event as an arg to Parser_Hit, addons should expect to receive Parser events even when they didn't register to the that Blizzard event - that means they may optionally tell ParserLib what Blizzard events they're interested, but expect to receive Parser_Hit from all possible Blizzard events.
In that case the API may look something like this:
that looks weird to me, but at least it makes the suggestion part completely optional?
At the back of ParserLib it would just store a table of addon reference and their interested Bz events. ParserLib listens to AceEvent_EventRegistered for ParserLib events, when someone registers to ParserLib events, ParserLib registers to all related Bz events if the addon reference doesn't exist in the table, otherwise ParserLib registers to possible Bz events in the suggestion table.
Using a unique ID for each event allows the user of parserlib to solve the problem.
event -> parserlib
eventID = eventID+1 (=101)
event --------------------->client
self.eventID=parserlib:GetEventID(). returns 101
parse...
parserHit(eventID, ...) ------>client
if self.eventID != eventID then return end
... otherwise its from an event we want
Even better if the eventID was in AceEvent - since maybe its possible they could get parserHit before the bz event (at least that how i understand it events fired from event handlers create an event stack)
Letting the addons users store information for you prevents you having to maintain tables internally.
This is essentially the "Visitor" design pattern without the OO
i get this error everytime i log in. any ideas how to solve this?
thx
ParserLib\ParserLib.lua:467: unexpected symbol near `#'
---