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 Goto page Previous  1, 2
shalimar Posted: Sat Sep 29, 2007 6:04 am
[2.04] Simple Color trigger failure
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Wed Oct 03, 2007 10:21 am   
 
No, I like the long answers! Smile

But, actually, what I have seen if probably just on prompt triggers then. But, if the screen was frozen in v2.04, would prompt lines get combined in the screen buffer such that the IAC EOR or IAC GA would get lost? As I don't think this was caused by the network (in this version - it may well have been in zMUD).
Reply with quote
Zugg
MASTER


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

PostPosted: Wed Oct 03, 2007 4:44 pm   
 
Possibly. The prompt triggers are fired when the IAC EOR or IAC GA are processed when sending the data to the screen, but then the trigger might be trying to grab the text on the screen that isn't there. So yes, that is a possibility.
Reply with quote
Zugg
MASTER


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

PostPosted: Thu Oct 04, 2007 9:27 pm   
 
Well, I thought I was done with this problem, but I guess not Sad

After more testing, I have decided that I don't like the multi-threaded command line. The problem is that it is possible to have commands sent to the MUD in the wrong order if you type really fast and have triggers that can slow down one command, but not another. For example:

command1 (has some trigger processing associated with it)
command2

might cause "command2" to be sent to the MUD before "command1", if they are typed separately into the command line (and thus go into two separate threads). This problem shows up now and then when spamming speedwalk macros to the MUD (each macro gets it's own thread, and the order in which commands are sent to the MUD is therefore not deterministic).

So I decided to go back to using a WaitForMultipleObjects API call that would not allow Windows message processing (like the keyboard) while a thread is executing. This means that if you enter a long loop on the command line, like:
Code:
a=0;#loop 10000 {a=@a+1}

then CMUD won't respond to mouse or keyboard input until the loop is done. To prevent this, you can force the thread to move to the background using #WAIT, as with:
Code:
#WAIT;a=0;#loop 10000 {a=@a+1}

The initial #WAIT causes the thread to return immediate and continue processing in the background. So, since it was easy to force a long calculation to run in the background, I decided it would be better to force people to explicitly add #WAIT when they needed it, rather than always making multiple threads on the command line.

OK, so this is all fine and good. Works fine. The problem is that now we have lost the ability to abort scripts. Since CMUD is waiting for the command line thread to finish, and it's not processing any Windows messages, then there is no way to recognize that the ESC key has been pressed.

As soon as you start allowing processing of keyboard events, then there is no way to stop the user from entering a new command and pressing Enter, causing another thread to be created while the previous thread isn't done yet.

I have spent most of the day trying to come up with a wait-loop that would check for the ESC key, but I haven't found anything yet. We need to use some variation of MsgWaitForMultipleObjects, since we need to wait until the background thread fires a Windows Event telling us that it is complete. Using the message mask, I can look for keyboard events. But there is no way to look through the Windows message queue for the ESC key without removing the messages from the queue. If you use PeekMessage with NO_REMOVE, then it just keeps returning the same keyboard event over and over. If you use PeekMessage with REMOVE, then either you need to discard them, or add them back to the queue.

If you discard non-ESC keys, then you cannot type-ahead while a command line is running (random keys just get discarded, which makes speedwalking a real pain). If you add them back to the queue, then the WaitForMultipleObjects API just immediately returns again because there are new events in the queue. Also, taking the keyboard events out of the key and then stuffing them back messes up any synchronization between the keyboard messages and any other messages in the Windows queue.

I'm still doing some Google searching on this to see if I can come up with a way to handle it. I really don't want to give up the ESC functionality. But this is taking a lot longer to deal with than I expected.
Reply with quote
Zugg
MASTER


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

PostPosted: Thu Oct 04, 2007 9:40 pm   
 
Well, I just love the fact that everytime I post a problem, the act of posting it makes me think of an idea and fix the problem :)

So, here is the really weird fix to this. Turns out that PeekMessage has an interesting side-effect...it "marks" every message in the queue as "not new" so that MsgWaitForMultipleObjects does not return until another *new* message has been added. So I call PeekMessage with NO_REMOVE to cause it to mark all of the messages as "not new", but then I use the GetAsyncKeyState to test to see if the ESC key is down. So, here is the sample code of the wait loop:
Code:
repeat
  Result := MsgWaitForMultipleObjects( NumEvents, EventHandles, false, INFINITE, QS_KEY);
  if Result = WAIT_OBJECT_0 + NumEvents then begin
    PeekMessage(Msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE); {this sets the flags for existing events that they were "seen"}
    if GetAsyncKeyState( VK_ESCAPE) AND $01 <> 0 then end;
    end
  else Done := true {one of the events fired}
until Done;

When I tested this with a long loop entered on the command line, I then typed ahead "testing" and then pressed ESC. Sure enough, as soon as I pressed ESC, the loop terminated, and then I saw "testing" entered into the command line (typeahead still working) and then saw the command line cleared as the ESC was processed normally.

The nice side effect of this implementation is that you can press Ctrl-ESC to cause the current command line thread to return *without* aborting the thread. Essentially, this puts the command line thread into the background. So you can execute a long loop, the press Ctrl-ESC to put the thread in the background, and then immediately start typing another command. Sort of works like Ctrl-Z on Unix to put something into the background. Pretty cool.

Anyway, I'm going to continue my testing with this implementation and see if it works better now.
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4805
Location: Pensacola, FL, USA

PostPosted: Thu Oct 04, 2007 11:32 pm   
 
Ooooo that sounds really cool, does that mean highlights are working properly again?
_________________
Discord server
Reply with quote
Zugg
MASTER


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

PostPosted: Fri Oct 05, 2007 1:21 am   
 
Yep, highlights are working now too.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
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