Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ Suggestions
➜ A Hide Trigger/Alias/Timer Option and Another group level
|
A Hide Trigger/Alias/Timer Option and Another group level
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1
2 3
| Posted by
| David Haley
USA (3,881 posts) Bio
|
| Date
| Reply #15 on Thu 03 Jun 2004 08:55 AM (UTC) |
| Message
| | You do know that Nick's suggestion is similar to how OSes often implement event handlers, don't you? It's not quite as 'stupid' as you think. :) |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | | Top |
|
| Posted by
| Shadowfyr
USA (1,792 posts) Bio
|
| Date
| Reply #16 on Thu 03 Jun 2004 05:34 PM (UTC) |
| Message
| | Hmm. True, in an OS you can capture an event and then remove it, so other applications don't recieve it. In general though, this is not usually done, since a message like "close all" could then be itercepted and disabled, before the OS successfully shuts down all the applications. This is frankly a bad thing. In the case of this idea, you may end up with some clown always returning true whenever his plugin recognizes an event, then wondering why the heck his new plugin or someone elses, which just happens to use the same event name, doesn't work. Or worse, they could stupidly return true for every event, and prevent all other plugins from working when theirs happens by chance to be the first one to recieve it. I think one that you can't intercept and cancel is much better in this environment imho. | | Top |
|
| Posted by
| David Haley
USA (3,881 posts) Bio
|
| Date
| Reply #17 on Thu 03 Jun 2004 09:36 PM (UTC) |
| Message
|
Quote: since a message like "close all" could then be itercepted and disabled, before the OS successfully shuts down all the applications. This is frankly a bad thing.
No it's not. There are many times when you might want to have a program intercept the close-all and cancel it under some circumstances. If the OS really wants things to die it can just kill the process.
Same for a plugin - there might be really good reasons for a plugin to cancel the close-all (or whatever) event and not let other people see it.
Basically what it comes down to is that yes, if programmers do something stupid then stupid things happen; but isn't that always the case? :) In any event it would seem that you're removing a lot of power and simplicity for the sake of making something fool-proof. If somebody writes a plugin and does something stupid like that, do you really want to be using the rest of their plugin? |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | | Top |
|
| Posted by
| Nick Gammon
Australia (23,173 posts) Bio
Forum Administrator |
| Date
| Reply #18 on Fri 04 Jun 2004 03:19 AM (UTC) |
| Message
|
Quote:
Boolean = FireEvent(Type, Data)
If true, something responded to it.
Do I sense an implication that as soon as a plugin handles the event, that event's propagation is stopped? If so then it wouldn't be very consistent with the idea of events.
I don't see how the FireEvent call can return "true" to indicate the event was handled if the event handler doesn't return true (I handled it) or false (I didn't).
Merely having an event handler hardly guarantees the event is handled, especially if every plugin has a OnPluginHandleEvent function in it.
Then the question arises, once an event is handled, do you keep trying other plugins? It seems to me the answer would be "no", because "handled" implies "dealt with". This is actually quite consistent with the way a lot of Windows event handlers work. Events are passed to various places in the hierarchy (eg. child window, parent window, document, application) until something says it has handled it.
Say you had an event handler for "I am poisoned". Once a plugin deals with it (eg. "drink green potion") you don't want it re-handled.
*However* a plugin can always "do something" but still return false. eg. Plugin A might log to a file that you had drunk poison (and returns false), but Plugin B actually drinks the antidote.
Quote:
In general though, this is not usually done, since a message like "close all" could then be itercepted and disabled, before the OS successfully shuts down all the application
No, this is not true. For instance, if you shutdown MUSHclient, and a world asks you to save your changes, but you cancel the save then the shutdown itself is cancelled. In effect you have changed your mind.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | | Top |
|
| Posted by
| Ked
Russia (524 posts) Bio
|
| Date
| Reply #19 on Fri 04 Jun 2004 04:57 AM (UTC) |
| Message
|
Quote: Then the question arises, once an event is handled, do you keep trying other plugins? It seems to me the answer would be "no", because "handled" implies "dealt with".
That's exactly the contrary of how I use events currently. If I wanted to have a plugin as a container for a large number of triggers that almost never get modified and only exist for the sole purpose of tracking a number of certain boolean states, and use that plugin to notify others about those states changing then I would want the "StateChangeNotify" event to propagate as long as there are still plugins left which want to hear it. That unties my hands, since I've dealt with the problem of saving states once and for all and from now on I don't have to worry about them when adding plugins which require state information - I just add the plugin with the event handler, implement the processing and storage of the states locally (using a dict, array, list, struct - whatever) and go on my way of doing something productive. If events would block however, I would need to either do what Magnum suggests - duplicate the state saving mechanism (with over 200 triggers, and multiple scripts) in every plugin, bundle everything into a single plugin (in which case it would make more sense to just keep it in the world), or go through every existing plugin which handles the "StateChangeNotify" event and make sure it doesn't block. Another example is the prompt - I have a small plugin for the sole purpose of capturing the prompt using OnPluginPartialLine and don't have to worry about it anywhere else. However, if blocking events is just something that can be done optionally, then I suppose it wouldn't be such a big problem. I see it as something that would have few uses, since the possibility of screwing up later by blocking something now is likely to keep most people from using that option, but if it would provide something useful in at least one case of a few hundred then I suppose you might as well have it, actually - you probably should have it. | | Top |
|
| Posted by
| Nick Gammon
Australia (23,173 posts) Bio
Forum Administrator |
| Date
| Reply #20 on Fri 04 Jun 2004 05:46 AM (UTC) |
| Message
| That's agreement then?
It is really a semantic issue. "Handled" means in this context "completely handled".
So, if a plugin wants to indicate that it is to be "the end of the chain", then it returns true.
Something like your "state change" would go to handlers that would return false, so the state change goes to other handlers. This is simply a convention you would expect them to follow, in much the same way that you are expecting the handler to be called in the first place.
This all follows on from the original idea that a "fireevent" calls gets told whether or not the event was handled. I think for this to have any real meaning you need to indicate that the event was handled, and I think in this context, "completely handled". |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | | Top |
|
| Posted by
| Shadowfyr
USA (1,792 posts) Bio
|
| Date
| Reply #21 on Fri 04 Jun 2004 06:05 AM (UTC) |
| Message
| Umm. Well Nick, the only major issue with having it return anything at all is that some events you may 'want' to have all available plugins respond to. For instance, while the plugin counter one was silly, lets say I have a plugin that allows you to set a global 'theme' in all plugins I create. This would set the default colors to be used by errors and various types of output. I could have my master plugin send out an event FireEvent("ChangeErrorColor", "Gold"). All plugins that recognize this 'need' to handle it, not just the first one that happens to see it.
However, it is likely useless for saving execution time. For two plugins, there is no certainty as to which one Mushclient will call first, so only 1/2 of the time will it actually save time. For 3, 4, 10, 20.... The more plugins, the less often you can be sure that it will stop execution and save time. After all, there are no priority options for plugins, they get called more or less randomly and there is no guarentee that the right one to kill the event won't be the very last one called.
However.. After some thought, there may be some cases where it would be helpful. A notice about the plugin and who made it for instance.. You may want to generate an ANSI graphic when the first plugin loads, along with a notice of what it is called, but also fire an event to tell all following plugins to respond with their names. However, this would mean that the event must fire 'after' all autoloaded plugins are installed, but 'before' any other plugins have a chance to generate a timer delayed message of their own for it to work. But.. Another method could have all plugins respond to an event to inform the first one that it needs their names. Then its own timed delay to send the needed info to the screen, including the names. This still requires that the very first event only happen 'after' mushclient has completed startup procedures, since the event needs to be recieved by all other plugins, so they know to fire back their names and disable their own output of the notice.
So.. Ok, I agree, there is a valid use for it. Though it isn't really quite the same as if you where in an OS, where you have multiple priorities, several execution layers and something on a higher level has to respond 'before' the lowest one deals with it instead. Everything in plugins will be the same priority and layer, with no certain order in which the are called. | | Top |
|
| Posted by
| David Haley
USA (3,881 posts) Bio
|
| Date
| Reply #22 on Fri 04 Jun 2004 06:09 AM (UTC) |
| Message
|
Quote: All plugins that recognize this 'need' to handle it, not just the first one that happens to see it.
No problem... you just don't mark it as handled. And if a plugin is 'gobbling' events, either that is intentional for the plugin or is a mistake.
Quote: Everything in plugins will be the same priority and layer, with no certain order in which the are called.
Just because YOU don't think you will have layers doesn't mean that other people will want layers. Besides, I suspect that if there weren't layers, then at some point you would start complaining about plugins not being able to intercept and halt events. :-) |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | | Top |
|
| Posted by
| Ked
Russia (524 posts) Bio
|
| Date
| Reply #23 on Fri 04 Jun 2004 06:10 AM (UTC) |
| Message
| | Sure, only how about doing it as with OnPluginLineRecieved - you set it to false if you don't want the line displayed, and if you don't set it to anything it displays the line. That makes omitting the line an option, rather than an equal possibility to the one of displaying the line. Since plugins are likely to allow the events to "fall through" more often than block them, I think it would make sense to have the "fall through" behaviour as default, and "blocking" as optional for them. | | Top |
|
| Posted by
| Shadowfyr
USA (1,792 posts) Bio
|
| Date
| Reply #24 on Fri 04 Jun 2004 08:21 AM (UTC) |
| Message
| Umm. Do you know something I don't Ksilyan? lol As they stand there is no priorities for plugins. And even if there was, it isn't like an OS, there can't be a layer lower than that of the plugins themselves, unless it is mushclient. Mushclient won't be responding to or interpretting such events. As for execution priority, that works for triggers within a plugin, where the order they execute can be predefined, but how exactly do you correctly set the priority for someone elses plugin? You can't. Therefor the idea of halting an event, unless all plugins involved know it and what they should do with it is total nonsense. It isn't unbelievable that someone may define a set of stadard events for plugins to respond to. If you tried to intercept and stop one of those, it would never work unless you as the plugin designer could be 100% certain that someone elses plugin wasn't assigned a higher (or even the highest) priority.
Frankly, it makes a lot more sense to work around the issue by not messing with interception in the first place, save in specific cases like my example, where it is not intercepted and stopped, but sent 'in the first place' as a "halt your normal task" type message. I see no practical way to layer plugins that won't break the feature. For instance, if you placed plugins in groups, then only allowed priority and the reception of events to that group, you could produce a layer system, but it breaks the ability to send out universal events based on a standard that *doesn't* require them to be in that group, but only using some accepted standard for the event. Letting someone add their plugin to the group then potentially breaks things too, since they may incorrectly choose the wrong priority and end up responding to the command, even though it was supposed to be intercepted and blocked.
Of course, a possible solution to this is to have both FireEvent and FireGroupEvent. Both types could still be recieved through the same sub, but the second one would allow the priority within the group itself to determine which one reieved it first. Priority in this case is irrelevant and unrealiable for FireEvent though, since the actually sequence they are expected to be checked in could be vitually anything in the global list. One person could set them to run from 0 to 5, someone else from 10-50, stepping up by tens. The result would be totally unpredictable, so I would suggest under such a design that returning True or False be totally ignored in the global FireEvent system, but halt farther attempts in the Group layer, where it serves a real purpose.
Unless you can describe some way Ksilyan, to make the behavior predictable in a global scope? I don't see how, since unlike triggers, you can't just pop into the editor and adjust the sequence number if the XML someone gave you breaks something. Plugins or groups of them should behave predictably the moment installed, without the need to tweak them. The most predictible behaviour is to ignore the True/False value in a global event imo. Anything else will break and require the poor guy that just downloaded it to edit the plugin file to fix it. | | Top |
|
| Posted by
| David Haley
USA (3,881 posts) Bio
|
| Date
| Reply #25 on Fri 04 Jun 2004 08:58 AM (UTC) |
| Message
| I just can't help but think that you're limiting something just because you personally can't see a use for it and therefore you don't think it should be there at all. I think that the examples Nick gave are good; you might want a 'controller plugin' that receives an event and stops everybody else from receiving it in certain cases.
Yes, people could set things up to work in a weird order, but that would sort of be their problem now wouldn't it? You can also incorrectly install your OS applications just as when you write code you can make mistakes that break things.
How are things predictable in Windows? It would suffice to emulate the way many operating systems handle prioritization in event handling, and there you go.
Regardless, if you don't like it, why not just return false? And if somebody gives you a plugin that DOES stop the event, then there is likely to be a reason they did that.. and if it bothers you, you can simply go change it to false. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | | Top |
|
| Posted by
| Flannel
USA (1,230 posts) Bio
|
| Date
| Reply #26 on Fri 04 Jun 2004 04:12 PM (UTC) |
| Message
| I haven't really read about a quarter of the posts in the detail I should've, however I think the order thing is a valid concern.
As far as I'm aware, plugins are evaluated in a somewhat arbitrary order.
So one could never guarentee the same set of plugins would function the same on different computers, or possibly even on the same computer, at different times.
I'm not sure how, if this is the case, any sort of function like this would be viable. You could never really depend on it to stop all the other plugins.
Maybe I'm reading this all wrong, heck, I haven't payed enough attention to really know what this is all about.
If someone would like to explain to me both in a nutshell, but more importantly address the concern of order, It'd be much appreciated. |
~Flannel
Messiah of Rose
Eternity's Trials.
Clones are people two. | | Top |
|
| Posted by
| Shadowfyr
USA (1,792 posts) Bio
|
| Date
| Reply #27 on Fri 04 Jun 2004 09:27 PM (UTC) |
| Message
| Like I said. It isn't practical or viable for cases of 'all' plugins. Even with an OS, there is a distinct 'service' level that only specific applications run in, because they 'require' the ability to respond before normal applications get a chance to recieve an event. Such a service isn't generally made into one unless there is some critical thing that it needs to do, where is has to tell the OS to wait, since simply closing down would cause a problem. There isn't any such critical event that you necessarilly need to top in the case of all plugins in general. Providing sequencing or priorities for all plugins just creates problems.
However, like I also said, I see no reason why someone can't create a collection of plugins, give them a group name *and then* set a sequence for which ones execute in that group in a particular order.
Example:
Plugins Hash -
Fred's group -
Fred plugin 1 = priority 1
Fred plugin 2 = priority 5
Fred plugin 3 = priority 5
Zeb's plugin
Jim's group -
Jim plugin 1 = priority 55
Jim plugin 2 = priotiry 3454
A FireEvent would hit each plugin, ignoring the return, since it is irrelevant. However, if one of Fred's plugins sent out a FireGroupEvent("Halt",""), then plugin 1 would catch it, set the return value to True, so all the others ignore it and do whatever the halt message was for. Maybe disabling all the plugins in the group or something.
This allows you to do exactly what you are suggesting, but isolates the plugins that 'require' this feature from those that might recieve it and misinterpret the result. It also solves the priority issue, since a global event *cannot* halt additional event functions from recieving it, precisely because at 'that' level you cannot control which plugin has what priority and will respond first. Even if you allowed someone to set a priority at that level, you can't predict what value they will use.
Why exactly is it a bad thing to make it only work in a situation where you can isolate and control what the plugin priorities will be? It seems to me to be the best solution. You can tell someone that to make their plugin work with your group, give it a priority higher than X and place it in group Y. In the global scope though, you might conceivably have 10 groups of plugins made by 10 different people, all with completely different priority settings. Even if by pure chance you use the same event name as their plugin, your asking for trouble. However, if yours and theirs are all distinctly seperated, you don't need to worry what Joe Smoe used for his priorities, or even what events he uses that could mess you up.
Why is this a bad idea? Please, someone explain.. | | Top |
|
| Posted by
| Nick Gammon
Australia (23,173 posts) Bio
Forum Administrator |
| Date
| Reply #28 on Fri 04 Jun 2004 10:32 PM (UTC) |
| Message
|
Quote:
I think it would make sense to have the "fall through" behaviour as default, and "blocking" as optional for them.
I think in VB at least, we can make it so that not returning a value can default to be equivalent to a false, so the default behaviour would indeed to be fall through.
Quote:
As far as I'm aware, plugins are evaluated in a somewhat arbitrary order.
They will be evaluated in the order in which they are in your world file, as they are added to an internal list in that order. However, there is no really easy way of influencing that order, short of editing the world file.
It seems to me this is a separate issue. If the order of plugin evaluation is important, which it may be for other cases as well, then we need to discuss a "plugin sequence number" concept.
I tend to agree that if plugins are evaluated in an arbitrary, and not easily predicated order, then the idea of one plugin blocking an event may be a bit silly.
I think Shadowfyr's example of FireEvent "ChangeErrorColor", "Gold") would only apply to his plugins (who else would respond to "ChangeErrorColor"?) however I agree that if, say, the Chat plugin returned "true" even though it had not done anything with "ChangeErrorColor" that could be annoying.
However in this case you have to trust plugin authors to a certain extent, that they won't do something really silly. And, returning "handled" to an FireEvent when you didn't handle it, could be called silly.
For instance, a plugin might do 'DoCommand "quit" ', that would be annoying too.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | | Top |
|
| Posted by
| Nick Gammon
Australia (23,173 posts) Bio
Forum Administrator |
| Date
| Reply #29 on Fri 04 Jun 2004 10:53 PM (UTC) |
| Message
|
Quote:
However, like I also said, I see no reason why someone can't create a collection of plugins, give them a group name *and then* set a sequence for which ones execute in that group in a particular order.
This is an interesting idea. Initially plugins were supposed to be stand-alone things, however I can see that if they get more complex, especially with inter-plugin communication, then the issue arises that some plugins may happen to raise events that are misinterpreted, or mishandled, by other plugins by a different author.
One simple grouping approach would be "by author". So, if Shadowfyr's plugin raises an event, only Shadowfyr's plugins receive it.
Alternatively, you could specify a group name (or ID).
Another approach would be for plugins to "register" an event handler, eg. like this:
RegisterHandler "OnColourChanged", "MyColourChangedEvent"
(Ked suggested something similar on Page 1 of this thread).
However this does not totally address the priority issue - what if two plugins register to handle "OnColourChanged"? Who gets it first? Do they both get it?
Also, what if two authors register "OnColourChanged" to handle different things (in different ways)?
So, you need:
- Grouping - some events may only apply to a group
- Sequencing - to do things in the right order
- Stopping - maybe stop when an event is handled, maybe not
- Uniqueness - to stop plugin authors inadvertently clashing (eg. by choosing the same group names)
I acknowledge that a lot of this is what Shadowfyr said. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
138,382 views.
This is page 2, subject is 3 pages long:
1
2 3
It is now over 60 days since the last post. This thread is closed.
Refresh page
top