Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: 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
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: 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.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: 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.)
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: 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.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: 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.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: 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.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: 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
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: 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!
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: 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.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: 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!
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: 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.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: 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!
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: 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?
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: 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.
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: 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!
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net