|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Mon Nov 12, 2007 1:07 pm
OnLoad event |
Zugg, in a topic somewhere you mentioned using that event. I don't see it in the drop down list for event names, and I also can't seem to get such an event to occur. I am wondering if it was put in or is still on the wishlist.
|
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Nov 12, 2007 6:15 pm |
Hmm...I'll have to look into that. I had *thought* that I implemented it, but maybe I forgot about it. But I know the idea was to provide an easy way for packages to initialize themselves after being loaded. If it's not there, then I'll make sure it gets added to 2.12.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Nov 12, 2007 9:00 pm |
Yep, you were right...it wasn't implemented ;)
Implementing this important event also helped me find and fix the bugs regarding default values not being set correctly.
The OnLoad event works *slightly* differently than normal events. Instead of raising OnLoad globally, CMUD only raises the OnLoad event for a specific module/window after it is loaded. The context for the OnLoad event is the module/window being loaded. So this works just like you'd expect it to: you can use this event to initialize any variables within the module being loaded. If you create a variable within the OnLoad event, the variable gets created within the current class of the module being loaded.
Once a module is loaded, calling OnLoad again won't have any effect. If you want to reset a module, use the #RESET command as normal. This means that calling '#RAISE OnLoad' isn't going to do anything since the event has already been called when the module was first loaded. |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Mon Nov 12, 2007 10:59 pm |
Zugg wrote: |
The OnLoad event works *slightly* differently than normal events. Instead of raising OnLoad globally, CMUD only raises the OnLoad event for a specific module/window after it is loaded. The context for the OnLoad event is the module/window being loaded. |
What about OnConnect, OnDisconnect, OnRoom*, OnWalk* - surely these have, or should have, a context. It is only a window that connects or disconnects, not all of CMUD. If the OnWalk* and OnRoom* events are global, that would be a problem for people who have more than one connection. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Nov 12, 2007 11:32 pm |
Anything associated with the mapper runs within the context of the window that is associated with the mapper. And right now that only really works with a single window (multiple mapper windows is something for the mapper rewrite).
For OnConnect and OnDisconnect, they still have the context of the window with the network connection that is connecting or disconnecting, but I can see situations where you might want to run a script in some other package to toggle some feature when you are connected/not connected. So it makes more sense to fire those events normally and let anyone trap them. You can always look at the %curwin to determine what window is connecting/disconnecting.
The reason I made OnLoad an exception to the global event rule is that I can imagine some packages that might be very sensitive to having their OnLoad event called more than once, or called when some other package is loaded. |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Mon Nov 12, 2007 11:44 pm |
OK. I assume they don't cross over from one session to another though? (If you have two sessions open.)
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Nov 12, 2007 11:49 pm |
If you have multiple sessions and one window connects, the OnConnect event is sent to all modules, just like with any other event. Yes, it's possible that this needs to be tweaked too. But I'll have to think about this...making more exceptions like this tells me that something else is wrong or that there's a better way to do it.
|
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Tue Nov 13, 2007 12:25 am |
All modules OK, maybe, but all packages? Packages that are in other sessions? If one really needed to send the OnConnect and OnDisconnect to another window or package, there must be other ways of propagating it, like with a custom event or a signal handled in the OnConnect event of the package in which it occurred. Maybe this is impractical, but these events should only be visible for Packages where the Package containing the Window where the event occurred is enabled, at least.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Nov 13, 2007 1:22 am |
I think you are right, but since user-defined events are global and are seen by all packages, then it sounds like what we really have is a case where some events need to be global, some just within the package, and some just within the module/window (like OnLoad). And rather than kludging this on an event by event basis and causing a lot of confusion, it sounds more like I need to add an option to events where you can change this. That's why I am still thinking about it.
|
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Tue Nov 13, 2007 2:10 am |
Yeah, you are probably right. I'll let you think about it, and maybe someone like Vijilante who is more on top of scope than me can chime in on this too.
|
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Nov 13, 2007 11:09 am |
Why not have events like OnConnect raised with some parameters? Like the site or IP it's connecting to, or the window that's causing the connection? That way you have the option of either responding to only certain types of OnConnect, or all of them.
That way you wouldn't need to make OnLoad an exception to the rule - its parameter would be whatever was loaded. |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Nov 13, 2007 1:48 pm |
A source parameter for all of the system events actually sounds pretty good.
We don't to have complex package dependencies, but I suspect it is going to happen. For example I might have a package that is fully functional by itself, but when another my packages is loaded more features are added. A nice example of this is CMud and zMapper.
Using a parameter would allow all the system events to work consistently, and places the repsonsibility of determining when to handle them on the user. I think it is a clean simple solution. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Nov 13, 2007 5:22 pm |
I'll probably add parameters also. But I'm afraid OnLoad would still be an exception because I really don't want every package to have to test the argument in OnLoad to decide whether it needs to run. It would be really easy for someone to forget that. Also, what argument would you pass? The name of the module being loaded? Then you'd have to deal with modules/windows that had the same name. The only "unique" identifier for Modules/Windows is the GUID that you can see in the XML tab, and I really don't want people to have to test against that value just to initialize their package. Also, in the case of OnLoad, there is no reason for any other module to get that event. If you had a package dependency and wanted to initialize package B when package A is loaded, then you can easily just raise an event from package A's onLoad event that package B responds to.
So in this case, it's a bit too much to put on the user I think. At least for OnLoad. So I still need to think about this. |
|
|
|
JQuilici Adept
Joined: 21 Sep 2005 Posts: 250 Location: Austin, TX
|
Posted: Tue Nov 13, 2007 6:28 pm |
A clever package author might be able to dodge the complex package dependencies, at least in the case that Vijilante mentions above. If a writer wants to have a package A add functionality when package B is loaded...just have B raise a BIsAvailable event in its own OnLoad handler, and have A catch it (so it can enable its extra goodness). As long as A and B are coming from the same author(s), it should work fine.
However, the system completely depends on the end user enabling the right set of packages for each window/module, to get the right functionality. I don't see a good way to get around it under the current system - you can't enable packages for a window in code, so you just have to write instructions for the package user.
As a specific example, consider a multiplaying session with two character windows, where one has A and B enabled, but the other has only A enabled. To handle it properly, A would have to store a B-is-available variable in the window itself, and manually check it each time (rather than enabling or disabling internal classes). |
|
_________________ Come visit Mozart Mud...and tell an imm that Aerith sent you! |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Nov 13, 2007 6:34 pm |
Could you raise an event from Package A's OnLoad that Package B would respond to if Package B weren't loaded yet? Just wondering because that'll make OnLoad hard to respond to no matter what's used to let other packages respond to it.
There are already problems with modules and windows with the same name when you do //Module/class/var, which'll also be a problem if you're doing this sort of OptionalDeps thing. That gave me the impression that modules and windows should ideally have unique names, like aliases should, and so neatly avoiding that problem with OnLoad.
As an aside, I was inspired to suggest event parameters based on the WoW UI, which I've been buffing up on this week. Addons are very similar to packages in many ways. |
|
|
|
JQuilici Adept
Joined: 21 Sep 2005 Posts: 250 Location: Austin, TX
|
Posted: Tue Nov 13, 2007 7:01 pm |
Fang Xianfu wrote: |
Could you raise an event from Package A's OnLoad that Package B would respond to if Package B weren't loaded yet? Just wondering because that'll make OnLoad hard to respond to no matter what's used to let other packages respond to it. |
Excellent point. I hadn't considered that. I guess Package B has to set the BIsAvailable var in the window itself, then. Might even evolve into a convention where well-behaved packages set a window variable containing their version number, or something like that, in the OnLoad handler. Anyone who wants to use it can then check to see if it's there and the right version is loaded.
Fang Xianfu wrote: |
There are already problems with modules and windows with the same name when you do //Module/class/var, which'll also be a problem if you're doing this sort of OptionalDeps thing. That gave me the impression that modules and windows should ideally have unique names, like aliases should, and so neatly avoiding that problem with OnLoad. |
It's worse, actually. Two modules with unique names, but identically named classes inside, can also cause problems, even if none of the settings inside those classes are named the same. E.g. if you have //module1/interface/foo and //module2/interface/bar, the reference @interface/foo may or may not actually find the variable. (It appears that, internally, it looks for the first 'interface' class it can find, then checks to see if 'foo' is inside. If not, it gives up, rather than continuing to look for other 'interface' classes.)
So, yeah, if everything has unique names, life is good. But a package-writer can't rely on an end-user (or another package-writer) not using the same name by accident. A long and obscure name makes collisions less likely, but not impossible. And long, obscure names for visible windows are not aesthetically pleasing anyway... |
|
_________________ Come visit Mozart Mud...and tell an imm that Aerith sent you! |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Nov 13, 2007 7:17 pm |
jquilici wrote: |
It appears that, internally, it looks for the first 'interface' class it can find, then checks to see if 'foo' is inside. If not, it gives up, rather than continuing to look for other 'interface' classes |
Have you reported this apparent bug? Sounds like it needs fixing. |
|
|
|
JQuilici Adept
Joined: 21 Sep 2005 Posts: 250 Location: Austin, TX
|
Posted: Tue Nov 13, 2007 7:56 pm |
Fang Xianfu wrote: |
Have you reported this apparent bug? Sounds like it needs fixing. |
No, but I have now.
This was one of the things I encountered when I was originally trying to get my head around scoping. I hadn't convinced myself that it WAS a bug, as opposed to funky semantics. |
|
_________________ Come visit Mozart Mud...and tell an imm that Aerith sent you! |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Nov 13, 2007 9:21 pm |
Quote: |
Could you raise an event from Package A's OnLoad that Package B would respond to if Package B weren't loaded yet? |
Nope. If B isn't loaded yet, then how could it possibly respond? It can't. |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Nov 13, 2007 9:27 pm |
jquilici wrote: |
I guess Package B has to set the BIsAvailable var in the window itself, then. |
Unfortunately, this still wouldn't solve the problem. If A optionally depends on B, but A is loaded before B, then when be checks BIsAvailable, it won't be. The simplest way would be with some kind of %isPackageInstalled function that checks the whole list of packages.
Alternatively, you could have OnLoad loaded for each individual package, and then PackagesLoaded when package loading is complete. The OnLoad event would set the variable, and the PacakgesLoaded event would check them.
This is definitely getting more complex than it's worth.
EDIT: @Zugg: It was more of a rhetorical question, but also just making absolutely sure it was true. Also, while I'm here, another possible solution - OnLoad is called when loading of packages is complete, not when an individual package loads. Perhaps its parameter could be a string list of the packages that're loaded, if you need it? |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Nov 13, 2007 11:58 pm |
Keep in mind that there isn't a lot of support for package dependency yet. And this isn't going to be handled before the next public version. So, package designers should generally try to avoid making dependent packages, or at least make sure they provide detailed instructions to their users so that they get loaded in the right order.
And no, OnLoad is called when an individual package has been loaded. It doesn't wait until all packages are loaded. Otherwise the File/Open option in the package editor wouldn't trigger the OnLoad event. It's triggered by the load routine of a specific package. |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Wed Nov 14, 2007 12:27 am |
jquilici wrote: |
A clever package author might be able to dodge the complex package dependencies, at least in the case that Vijilante mentions above. If a writer wants to have a package A add functionality when package B is loaded...just have B raise a BIsAvailable event in its own OnLoad handler, and have A catch it (so it can enable its extra goodness). As long as A and B are coming from the same author(s), it should work fine. |
I do something similar to this but I take a much simpler approach...
I use the %class to check if a given module is enabled and then I take the appropriate action. To me this even better because even if a package is loaded, a particular module may not be enabled.
For instance I have a menu driven status window that offers more options depending on what module is enable.
Code: |
%if(%class(CoreStatus) == 1,%concat(" <send '","#EXEC ",%char(34),"#RaiseEvent displayCharacterStatus CoreStatus",%char(34),"'>Character Statistics</send>", %crlf %crlf ," ")) |
|
|
_________________ Asati di tempari! |
|
|
|
|
|