GetWorld, GetWorldByID from plugin... returns plugin 'world' object.

Posted by Worstje on Tue 08 Jan 2008 09:33 PM — 18 posts, 75,145 views.

Netherlands #0
I wanted to loop through the triggers and aliases of the world my plugin is running in. However, I -always- get the same world object returned from GetWorld and GetWorldByID as the plugin itself 'lives' in, which means I can't find out about this information in any way. I can however request this info from any other world fine.

I'm using Lua btw, in case it may be a bug with the Lua specific implementation.
Australia Forum Administrator #1
I don't quite understand the problem. Are you specifying a different world to the one the plugin runs in?

Judging by the code, the Lua function should return a userdatum which is the world matching the name, not the calling world.

You said you want the "triggers and aliases of the world my plugin is running in" - in that case don't you want the world object the plugin lives in?
Australia Forum Administrator #2
The other thing to check is how you are using the world object. In Lua, you should be doing something like this:


w = GetWorld ("someworld")

w:Note ("hi there")   -- do note to someworld's window


http://www.gammon.com.au/scripts/doc.php?function=GetWorld

Check the world userdatum is not nil, or it is likely to simply refer to the current world.

Netherlands #3
Actually, I use Function(w, param1, param2, ...). But that doesn't matter, so I'll use the w: notation for clarity here.

Say my plugin was loaded in the world with name 'myworld'. I use w = world.GetWorld("myworld") to get a reference to this world in my plugin. If I then try to use w:GetTriggerList, w:GetTriggerInfo etc. I get exactly the same responses as if I'd called world.GetTriggerList() and world.GetTriggerInfo() -- the trigger information of the plugin itself. However, if I try to do the exact same thing for a world with name 'anotherworld', I get the trigger data belonging to the world.

Same thing goes for aliases.

> You said you want the "triggers and aliases of the world my
> plugin is running in" - in that case don't you want the
> world object the plugin lives in?

That's one confusing sentence. But aye, I think that is correct. I want the world object of the main script file, rather than the world object of the plugin. Similarly to how it works for other unrelated worlds.
Amended on Wed 09 Jan 2008 09:54 AM by Worstje
Russia #4
That's not a bug - it works just as documented.

From documentation for GetTriggerList:

Quote:
If GetTriggerList is called from within a plugin, the triggers for the current plugin are used, not the "global" MUSHclient triggers.

If you want to find the list of triggers in another plugin, or the global MUSHclient triggers, use "GetPluginTriggerList".


When your plugin gets the world object for the world it is loaded in it receives just that - the same thing as what is bound to the global 'world' object, and calling methods on this returned object should behave in exactly the same way as calling them on the "default" world object. Which it does.
Netherlands #5
That is.. silly. I could have sworn I read that help file, too. Thanks for pointing that out, Ked.

On another note, it still feels mightily odd to me. GetWorld() is what I always considered a scope changer - get the world object as it would look like for that worlds scriptfile, minus the oddities with GetTriggerList() and all pointing to the plugin specific stuff.

/me goes to write exceptions for when the current world-object is passed.

Edit: Yay, next problem. There is no GetPlugin(Alias|Trigger|Timer)Option function, so I can't check whether something of my own world is enabled. Or plugins for that matter, assuming this script ever gets expanded upon.
Amended on Wed 09 Jan 2008 03:07 PM by Worstje
Russia #6
There's the GetPluginTriggerInfo(), which is pretty much the same thing.
Netherlands #7
Stop making me feel like an idiot. :( This just is not my set of days.

However.. I recall an issue I had ages ago with needing *Option over *Info because I couldn't get to it with *Info. And now that I'm writing about it, I remember again. The multi_line and lines_to_match options were what I was looking for, and unless I'm totally out my league reading through the list in GetTriggerInfo(), I'd still be unable to find out whether my worlds triggers are multi_lines. Right now, I don't need it... but who knows about the future? :)
Australia Forum Administrator #8
Quote:

On another note, it still feels mightily odd to me. GetWorld() is what I always considered a scope changer - get the world object as it would look like for that worlds scriptfile, minus the oddities with GetTriggerList() and all pointing to the plugin specific stuff.


If you use:


w = GetWorld ("someworld")
l = w:GetTriggerList ()


Then you should get the trigger list for the nominated world, and if the nominated world has a current plugin, then that plugin's trigger list. If the nominated world is the current world, then overriding with the w: does not change the way GetTriggerList works - it still checks if there is a current plugin.

Quote:

There is no GetPlugin(Alias|Trigger|Timer)Option function ...


I suppose that could be added without too much trouble if it was required.

However considering that GetPluginTriggerInfo will answer *most* of your questions, the requirement to find exactly how many lines (say) a multi-line trigger uses, in a different plugin, seems a bit obscure. Plugins are really supposed to be self-contained "black boxes".
Netherlands #9
Quote:

However considering that GetPluginTriggerInfo will answer *most* of your questions, the requirement to find exactly how many lines (say) a multi-line trigger uses, in a different plugin, seems a bit obscure. Plugins are really supposed to be self-contained "black boxes".


It's for a 'yours-is-bigger-than-mine' contest. Or to be precise, I'm a numbers freak. I like the idea of loading a plugin, enter a command, and have a pretty table of how highly taxed an actual world is, by showing all the plugins, triggers and other statistics that could negatively impact performance.

Of course, this only became interesting after I wrote a bunch of scripts to add 1390 triggers to one of my plugins, bringing its triggercount 2090, of which 1950 are enabled by default. Multi-line, checks for welformedness of triggers and other stuff to optimize performance are a good plus now.
Australia Forum Administrator #10
I have added those 3 script routines to version 4.21.
Australia Forum Administrator #11
Quote:

I wrote a bunch of scripts to add 1390 triggers to one of my plugins, bringing its triggercount 2090, of which 1950 are enabled by default.


How *is* performance, BTW?
Netherlands #12
Strangely decent. :D

Biggest problem is the fact I only have 512MB of RAM on a 2.5 years old Athlon64, which means a lot of swapping combined with the fact I tend to have three worlds open at once (two of which have that mega-plugin) and memoryhogger Firefox and Trillian.

I guess it takes around 0.1-0.2s to process an incoming line, but it is hard to say. I just ran a test with my prompt repeated 20 times using test trigger, and these are the results (timestamps from a plugin). Given that my prompt is the most heavily triggered, I figure it should be the best benchmark:

[4000] [3000] E100 W100 [db eb] 44:3.29 -
[4000] [3000] E100 W100 [db eb] 44:3.64 -
[4000] [3000] E100 W100 [db eb] 44:3.89 -
[4000] [3000] E100 W100 [db eb] 44:3.113 -
[4000] [3000] E100 W100 [db eb] 44:3.154 -
[4000] [3000] E100 W100 [db eb] 44:3.208 -
[4000] [3000] E100 W100 [db eb] 44:3.249 -
[4000] [3000] E100 W100 [db eb] 44:3.273 -
[4000] [3000] E100 W100 [db eb] 44:3.290 -
[4000] [3000] E100 W100 [db eb] 44:3.326 -
[4000] [3000] E100 W100 [db eb] 44:3.343 -
[4000] [3000] E100 W100 [db eb] 44:3.387 -
[4000] [3000] E100 W100 [db eb] 44:3.416 -
[4000] [3000] E100 W100 [db eb] 44:3.433 -
[4000] [3000] E100 W100 [db eb] 44:3.512 -
[4000] [3000] E100 W100 [db eb] 44:3.529 -
[4000] [3000] E100 W100 [db eb] 44:3.550 -
[4000] [3000] E100 W100 [db eb] 44:3.567 -
[4000] [3000] E100 W100 [db eb] 44:3.586 -
[4000] [3000] E100 W100 [db eb] 44:3.603 -

But even then, I am not sure how reliable the results are since this input is rather predictable.

Edit1: Oh, and clearly it is less than what I thought. Woo.

Edit2: I completely missed your first message. Thanks, that's going to be useful! If I ever finish this statistics thing, I'll send it your way. For now though, it needs a lot of cleaning up and adding features, since its core is pretty much an ugly version translated from Python when I started scripting... but I am lazy too, and it works. Hrm...
Amended on Wed 09 Jan 2008 11:01 PM by Worstje
Australia Forum Administrator #13
I have added some extra debugging stuff in version 4.21, available from GetInfo (see release notes) that will let you see how many triggers/aliases are being evaluated. This could be interesting, as you might have 2000 triggers, but it evaluates 1000 before one fires.

This version is now available.
Netherlands #14
Whoa, that's awesome. I guess I'm not the only numbers freak then, eh? :D

(That and I guess it makes this time for another benchmarking spree? The most recent benchmarks I've found of mud clients in general are old to say the least.. :) More stuff to compare, yay!)
#15
On the topic, as I understand it ExportXML and ImportXML are only applicable to the world triggers/timers/aliases so addxml.lua can't be used in a plugin to modify the plugins own triggers/timers/aliases?

Does this leave an opening for an ExportPluginXML/ImportPluginXML function pair?
Australia Forum Administrator #16
You are probably right, however I am inclined to think that actually having one plugin exporting another plugin's triggers is going too far. Why would you want to do that? You can always find the plugin's source file name, and then simply read the plugin in (as XML) which gives you effectively the same thing (except for dynamically-generated items).

Quote:

I guess I'm not the only numbers freak then, eh?


Well I *do* like to measure things. :)

As you will have noticed, MUSHclient provides all sorts of timers and counters.

They help to evaluate the performance of scripts, trigger evaluation and so on.

An interesting thing is that the worst-case scenario for triggers (and aliases too) is if *none* match, as that means they all have to be evaluated, before you are sure that none will match.

There is an argument for disabling groups of triggers, where possible, if you don't expect them to fire at certain times, to improve speed. For example, if you know you aren't in combat, you could disable combat-oriented triggers.

However having said that, MUSHclient has pretty fast trigger evaluation. A test I did a while ago (http://www.gammon.com.au/mushclient/benchmarks.htm) shows that it processed over 5,000 lines of incoming text with ANSI colours, with 10 triggers which didn't match, in 3.8 seconds. In practice you wouldn't receive text that fast, as it would be difficult to read.
Netherlands #17
Isthiriel: I seem to recall ImportXML couldn't be used in a plugin, however that certainly isn't the case anymore as I have used it heavily in my runtime addition of 1300 triggers.

Nick Gammon: What harm can it do to have the information available anyhow? While I mean absolutely no offense, if it is leaks or people with bad plugin-writing intents, they'll find far more destructive ways to go about their thing. In the meanwhile, having the feature(tm) to check the data during runtime only opens up possibilities.