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
Fang Xianfu
GURU


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

PostPosted: Sun Apr 20, 2008 9:53 pm   

[2.22] Should the wait commands resume after timeout?
 
So I was reading the manual to check my facts for this post, and I noticed that when the timeout is reached, the script is aborted. This seemed wrong to me - I seemed to remember that the wait commands resumed their thread on timeout. Whether that was the case or not, I think it should be changed (back) so that the timeout commands are run and then the thread is resumed.

The reason I suggest this is because it's very difficult to produce this behaviour with the current setup. You'd have to store all the code that's after the wait in a function or alias and then call that both after the wait and in the timeout commands, or just paste the whole script into the timeout command verbatim. Very very messy.

If it was changed so that the thread was resumed rather than aborted, it'd be simple to produce the current behaviour - you just stick #abort 1 in the timeout command and go and have a cup of tea. Having it this way allows you to do lots of other things though - store a value in a variable that triggers a slightly different script to be run or a slightly different string to be displayed, continue running the script normally after the timeout, whatever. Much better.
_________________
Rorso's syntax colouriser.

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


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sun Apr 20, 2008 10:08 pm   
 
#WAITFOR was expanded to have additional options. I think we all forgot to document it.
#WAITFOR pattern [timeout] [commands on pattern match] [commands on timeout]
#WAITFOR with only pattern waits indefinitely for the pattern to match then moves on.
#WAITFOR with pattern and timeout moves on when the pattern matches, and aborts the script when a timeout occurs
The full syntax is self expalnatory, but I never tested if captures become available to the "pattern matched" command set.

Looking through the cmd.db #WAITSIGNAL received the same additions as #WAITFOR. Also if you are going to update the help you should use #EXIT in the example rather then #ABORT 1, since I think that is the abortion level they use on a timeout.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Fang Xianfu
GURU


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

PostPosted: Sun Apr 20, 2008 11:27 pm   
 
No, it's documented - that's how I found out about it. My point is that the thread shouldn't be aborted when the timeout occurs, it should continue. My argument was that it's easy to write a script to make it abort and hard to write a script to make it continue, so make it continue.
_________________
Rorso's syntax colouriser.

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


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Mon Apr 21, 2008 12:56 am   
 
I was sorely mistaken it did get documented, and now that I am actually following your thinking instead of trying to do other programming. I also see the point that when a timeout set of commands is provided the remaineder of the thread should be continued. I would even go so far as saying that if any of the optional command portions are present then the thread shouldn't be aborted. Which I am guessing is what you were thinking.

Looking back on it I am rather sure it always did an abort. I remember being a little irritated about how it worked. Zugg added the true and false command portions and I never got around to playing with it to whine some more.

I think this makes the final request for both #WAITFOR and #WAITSIGNAL
Code:
#WAITxxx {whatever}
 waits until the appropiate whatever occurs or has the thread cancelled by another command
#WAITxxx {whatever} timeout
 waits until the appropiate whatever occurs or timeout ms has passed
 cancels the thread on the timeout
#WAITxxx {whatever} timeout {commands}
 waits until the appropiate whatever occurs or timeout ms has passed
 preforming the commands portion if whatever occurred
#WAITxxx {whatever} timeout {com1} {com2}
 waits until the appropiate whatever occurs or timeout ms has passed
 preforming the com1 portion if whatever occurred
 preforming the com2 portion if timeout occurred
Sound about right?

Now how about #WAITTHREAD? That has an optional state condition already to contend with. I think I toyed with something like spawning 2 threads one with a timeout on the wait for an original thread and a stop for the second, then the second waits on the first to either stop it or get timed out. A very big mess, that I am pretty sure I scrapped, and declared #WAITTHREAD mostly useless too.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Fang Xianfu
GURU


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

PostPosted: Mon Apr 21, 2008 1:11 am   
 
That's not quite what I meant - the thread should never be cancelled just by timing out, even (perhaps especially) if you don't specify a timeout command. If you want it to cancel, you can say so very easily with #abort. If you don't want it to, you just want it to wait for a pattern or x seconds until the thread resumes, you can just leave it off.

So:

Code:
#waitxxx whatever
 wait until whatever happens
#waitxxx whatever timeout
 wait until whatever happens or timeout ms, then resume
#waitxxx whatever timeout command
 wait until whatever happens or timeout ms, perform command if whatever happened, then resume
#waitxxx whatever timeout com1 com2
 wait until whatever happens or timeout ms, perform com1 if whatever happened, com2 if timed out, and then resume.
_________________
Rorso's syntax colouriser.

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


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Mon Apr 21, 2008 2:15 am   
 
Hrm, how would you know it timed out when using the second syntax (#waitxxx whatever timeout)? #WAITFOR could be tested by examining %line, but there is no similar way to test #WAITSIGNAL. I would suggest that syntax really does need some form of cancelling. Perhaps the current #ABORT like behavior is too strong and doing #EXIT would be better. This would change the abort point to cover the current code block while still allowing higher level code to interpret the results correctly. An example of this idea would be
Code:
#ALIAS test {#WAITFOR a 1000;Success=1};Success=0;#EXEC "test";#SHOW @Success
The change to an #EXIT like behavior would cause the alias test to end when the wait times out. This stops the "Success=1" within the alias from being done, leaving Success with the original value of 0. Because it no longer cancels the entire thread the "#SHOW @Success" still occurs displaying 0.

For a new/novice user a trigger or alias would directly use the #WAITxxx and therefore they would be unaffected, as it would appear to be the same level of cancellation.

A more experienced user that is using functions and aliases as subroutines should have little to no trouble adapting. I am not really sure how much in between ground there is.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Fang Xianfu
GURU


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

PostPosted: Mon Apr 21, 2008 3:02 am   
 
Vijilante wrote:
Hrm, how would you know it timed out when using the second syntax (#waitxxx whatever timeout)?

You wouldn't, but it wouldn't matter. If you wanted to know, it'd be because you were going to do something in response, and you can just use a timeout command for that. If you wanted to use it in an #if, you could use a timeout command to change the value of a local variable. You'd use that syntax when you wanted to wait either for a pattern or for x ms, but didn't care which one caused the thread to continue.

For example, say you've eaten a herb and have 2 seconds before you get a message "You can eat another herb". You decide to use #waitfor "You can eat another herb" 3000 to wait for the message so that your script will continue when you can eat another herb, but if you don't receive the message for whatever reason, it'll still try to continue after enough time has elapsed that you know you should be able to eat another herb.

Vijilante wrote:
For a new/novice user a trigger or alias would directly use the #WAITxxx and therefore they would be unaffected, as it would appear to be the same level of cancellation.

A more experienced user that is using functions and aliases as subroutines should have little to no trouble adapting. I am not really sure how much in between ground there is.

I'm not sure if you're agreeing with me or disagreeing with me here. It seems like you're saying "novices won't notice a difference and advanced users can change", but I'm not sure.

You're right about #abort 1 being too much. Just assume that every time I've said "#abort 1" in this discussion I mean "#exit".
_________________
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: Mon Apr 21, 2008 4:17 pm   
 
I'll throw my $0.02 in as well....the #WAITxxx commands should NOT abort, exit, or anything else by default.

My reasoning is simple, and has already been explained by Fang.
  • If a coder wants to exit or abort in the event of a timeout, it is very easy to make that happen using the timeout commands (e.g. #WAITSIGNAL someSig 5000 {} {#EXIT}).
  • However, if you do NOT want to exit or abort, but the command does it automatically, then you're forced into some really weird coding contortions to get your desired behavior (e.g. use WAITSIGNAL with no timeout, but have an alarm to set a 'timeout' variable and throw the signal anyway).

The only good reason that I can see for having #WAITxxx commands do #EXIT for you is backward compatibility....if they've done one up until now, then we'd break existing code by changing it. Even in that case, however, I'd still advocate for the change, because I think it's a good one.

At the very least, I'd like to see the #EXIT suppressed if the timeout commands are supplied by the coder (even empty, so that '#WAITSIGNAL mySignal 5000 {} {}' would NOT automatically exit) - at least that would allow the other behavior with only minimal contortions.
_________________
Come visit Mozart Mud...and tell an imm that Aerith sent you!
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Tue Apr 22, 2008 1:29 pm   
 
Fang's argument makes sense to me. I wonder how much code this would break? I fortunately haven't used these commands much, though I can see some situations where Fang's version could be useful to me. What I don't know is how much code other people have that would need to be revised.
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Tue Apr 22, 2008 2:02 pm   
 
I've been having some problems with threads in general of late, but haven't had time to narrow anything down.

The only one that I could get to work partly the way I needed it to was #WAITSIGNAL.

I would be ECSTATIC if the timeout commands actually did what I put in the second set of curly braces when the timeout occurred
as apposed to silently eating them and never telling me what the ---- happened to the code I told it to execute. Confused
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Apr 23, 2008 8:25 pm   
 
If I am understanding this discussion, then I think I disagree. The #WAITFOR is a good example. Here is how it was intended to be used in simple scripts. For example, an auto-login script:
Code:
#TRIGGER {^Username:} {
  #SEND Username
  #WAITFOR {Password:} 3000
  #SEND Password
  }

I don't want normal users to need to worry about using #ABORT. In this example, if you don't receive the "Password" prompt within 3 seconds, the script *SHOULD* abort. You only want to send the Password data if the MUD has responded with the proper prompt.

For advanced scripters that don't want the script aborted, then that's when you use the extended syntax that was documented. For example:
Code:
#TRIGGER {^Username:} {
  #SEND Username
  #WAITFOR {Password:} 3000 {
    #SEND Password
    } {
    #SAY "I didn't get any password prompt!"
    }
  #SAY "I'm done"
  }

Unless there is a bug, then the "I'm done" line should always be printed regardless of whether #WAITFOR times out or not. So when using this extended syntax, #WAITFOR will *not* abort your script. It only aborts when using the simple syntax listed in the first example.

I cannot change the fundamental operation of the #WAIT commands at this late stage. But I think you just need to use the extended syntax and then you should be fine.

If there is a bug with this that isn't working correctly, then definitely post an example.

Btw, I actually already use #WAITFOR extensively in my own scripts. For example, I have an alias that tries to do a recall command. The problem is that Recall doesn't work when in combat. So I don't want to use the mapper #RECALL command to move me on the map unless I know that my recall was successful. So, I have this simple alias:
Code:
#ALIAS recall {
  #SEND recall
  #WAITFOR {The Temple Square} 3000
  #RECALL
  }

Again, I *want* this script to abort if "The Temple Square" text is not received. And I specifically designed it this way so that novice programmers don't need to worry about starting a new block with #WAITFOR and potentially causing scripts with multiple #waits to get nested within more and more {} blocks.
Reply with quote
Fang Xianfu
GURU


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

PostPosted: Wed Apr 23, 2008 8:51 pm   
 
I see where you're going with this, in that case - it was just a problem with the documentation, specifically where it says "If the timeout expires, the rest of the thread's script is aborted" because that obviously isn't true in your second example (which works). I had a look at the file in an attempt to fix it, but it's really hard to get the wording right. Perhaps someone else has an idea.
_________________
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: Wed Apr 23, 2008 9:19 pm   
 
Yeah, it's tricky wording. The script isn't aborted when you use the *full* syntax. Otherwise it is. Basically, unless you tell CMUD what to do when the WAIT times out (using the extended syntax), then the default "action" is to abort the script.

In other words, the simple syntax:
Code:
#WAITFOR {Pattern} timeout

is essentially expanded into the full form of this:
Code:
#WAITFOR {Pattern} timeout {} {#ABORT 1}
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