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

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion Goto page 1, 2  Next
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Mon Aug 04, 2008 5:12 pm   

Howto: MXP substitution
 
I have a question on making an MXP substitution, please point me in the right direction and I'll write code implementation myself. I would like to hear you opinions and may be an examples from your real scripts. Rolling Eyes

Let's consider this MUD output:
Code:
^text1 AnyText2 text3$

and this capturing trigger pattern:
Code:
text1 (*) text3


AnyText2 is really ANY text - words, punctuation, spaces. text1 and text3 are quite static words which could be easily triggered off.

My task is capture AnyText2 and substitute it with mxp <send> link, leaving text1 and text3 intact. I already made a link creating function (lets call it @ReplaceFunc(...) ), now I need perform substitution. What will be the best solution?

1) Using of #SUB command. Doing this way I will be forced to capture all 3 parts of the line, otherwise #SUB will lose text1 and text3. The trigger pattern in this case will looks like
Code:
^(text1) (*) (text3)$

and the script will be
Code:
#SUB %1 @ReplaceFunc(...) %3


2) Gag triggered line and perform manual substitution without using of #SUB, then echo result to the screen. Doing this way I can replace %t1 from %trigger with result from @ReplaceFunc(...) function and send back the entire string as #MXP command. The trigger pattern in this case will looks like
Code:
^text1 (*) text3$

and the script will be
Code:
#MXP 1 %1 @ReplaceFunc(...) %3


What is the best practice? Where the time overheads will be minimal? Are there any other ways that perform the same task better\smarter\faster that I did not thought about?
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Mon Aug 04, 2008 7:47 pm   Re: Howto: MXP substitution
 
Well there is another way similar to 1 (and probably worse!)
3)
Code:
^text1 (*) text3$

and the script will be
Code:
#SUB %replace(%line,%1,@ReplaceFunc(...))

I'd have gone with option 1 though.
Reply with quote
Toxic
Adept


Joined: 27 May 2008
Posts: 299

PostPosted: Mon Aug 04, 2008 7:49 pm   Re: Howto: MXP substitution
 
Seb wrote:
Well there is another way similar to 1 (and probably worse!)
3)
Code:
^text1 (*) text3$

and the script will be
Code:
#SUB %replace(%line,%1,@ReplaceFunc(...))

I'd have gone with option 1 though.


I would use %trigger in place of %line here. Just to be safe. But yeah, thats one way.
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Mon Aug 04, 2008 8:40 pm   
 
Try using #PSUB? It's what the command was first created for, after all.
_________________
EDIT: I didn't like my old signature
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Tue Aug 05, 2008 5:10 am   
 
Seb&Toxic
Ok, I'll think about %replace(%line... solution, thanks.

MattLofton:
PSUB can't handle mxp commands, you'll get all tags visible. And since PSUB is not a function, I can't use it with #MXP
_________________
My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Tue Aug 05, 2008 3:47 pm   
 
Well, I only suggested solution 3 because you asked for other solutions: I'd still go with your solution 1 though. I reckon it's the most efficient.
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Tue Aug 05, 2008 10:16 pm   
 
I've made some tests with 1000 steps loop:

#SUB: 10 sec 234 msec
#MXP: 11 sec 859 msec
#MXP without #GAG: 3 sec 875 msec (!!!)
_________________
My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Wed Aug 06, 2008 2:50 am   
 
But you need the #GAG with the #MXP, right? So #SUB is slightly faster and the last line is just for interest's sake...
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Wed Aug 06, 2008 4:51 am   
 
Yep, I just wonder how slow #GAG is. Shocked
_________________
My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Wed Aug 06, 2008 4:04 pm   
 
Well, it didn't surprise me that much (since you sometimes used to see lines appear before being gagged) that #GAG is relatively slow, which is why I guessed (1) would be fastest.
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Wed Aug 06, 2008 9:09 pm   
 
Wink Can you tell me what will be the right way for send VT102 escape codes? Wanna try to do cursor movement 1 row up before sending #MXP.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Fri Aug 08, 2008 2:09 am   
 
Well the codes are here, but I don't know how you can send them.
Reply with quote
Tech
GURU


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

PostPosted: Fri Aug 08, 2008 5:20 pm   
 
I'd have to double check but I'm pretty sure you can do something like
Code:
#send %e%char(code)


There was a discussion recently in the forums about preventing the send of codes outside of the character range to prevent text spoofing on MUDs.
_________________
Asati di tempari!
Reply with quote
oldguy2
Wizard


Joined: 17 Jun 2006
Posts: 1201

PostPosted: Sat Aug 09, 2008 7:36 am   
 
You guys are trying to get too complicated. Here is your answer.

Code:
<trigger priority="10" regex="true" id="1">
  <pattern>^firstword (.*) lastword$</pattern>
  <value>$words=%numwords(%line)
$firstword=%word(%line,1)
$lastword=%word(%line,$words)
#substitute {$firstword Go $lastword}</value>
</trigger>



The Go part should show "<send>go</send>" but it keeps stripping out the XML for the MXP for some reason. I used a hyperlink to test and it worked perfectly.

I tested on this line "#show {firstword * .. __ +++ doesn't exi_ lastword}" and it display firstword [url]GO[/url] lastword.

Edit: Gah what the heck is up with this? Why doesn't [url] work and why is it stripping code out of the code box?

Well here is what it looks like in the value since it won't let me post the XML.

Code:
$words=%numwords(%line)
$firstword=%word(%line,1)
$lastword=%word(%line,$words)
#substitute {$firstword <send>Go</send> $lastword}
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Sun Aug 10, 2008 10:19 pm   
 
Seb
Yes, I've red that document already, thanks for link anyway.

Tech
After that discussion there was another one. As I've understood from it, control of cursor movement is possible. May be I got it wrong... But if it is possible, how can I do the following (for example):
Code:
Cursor movement (<n>=how many chars or lines), cursor stop at margin.
  Up
    Esc  [ <n> A
    033 133   101


oldguy2
No one tries to get too complicated. Smile Currently, I stick with #SUB and wonder if there any other possibilities to speed things up. As I said, #MXP is very fast, but #GAG slows down overall performance.
Before CMUD gets constantly crashing for me on both package and xml, my actual trigger' #SUB command was the same as I wrote in my first post and the same as you wrote.
Here is it: #SUB {%concat(%1, @createEditLink(...params...), %3)} , where the function returns "<send>go</send>"-like text. Now, I have this code in the function body
Code:
#SWITCH ($iMode)
  (0)
    {
      $strTmp = %concat("<send '", $strTmp, "'>", $linkText, "</send>");
    }
  (1)
    {
      $strTmp = %concat("#MXP 1 ""<send '", $strTmp, "'>", $linkText, "</send>");
    }
#RETURN $strTmp;

and want to understand can I control cursor position for use fast #MXP in second case or no.

And I do not need use %word() or other like functions because I'll create triggers manually on already known patterns. But thanks for you input! Smile
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Mon Aug 11, 2008 2:44 pm   
 
Arde wrote:
But if it is possible, how can I do the following (for example):
Code:
Cursor movement (<n>=how many chars or lines), cursor stop at margin.
  Up
    Esc  [ <n> A
    033 133   101



That was a stupid question. Confused The answer is %e[nA.

Update: quick test for using cursor control+#MXP show me almost the same timings as #SUB did. To be honest, I expected results better than that. Sad
Reply with quote
oldguy2
Wizard


Joined: 17 Jun 2006
Posts: 1201

PostPosted: Tue Aug 12, 2008 6:10 am   
 
Well alrighty then. You asked for faster I thought.

Quote:
I've made some tests with 1000 steps loop:

#SUB: 10 sec 234 msec
#MXP: 11 sec 859 msec
#MXP without #GAG: 3 sec 875 msec (!!!)


My version took all of 1.970 seconds...

By the way, the use of %word had nothing to do with if you knew the pattern or not. You said the first and last words were always static and I didn't capture anything. I'm not sure what you are talking about there.

Sticking your function in the #sub line and running the 1000 line loop again came back with only 1.921 seconds.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Tue Aug 12, 2008 6:44 pm   
 
So oldguy2's computer is over 5 times faster than Arde's?
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Tue Aug 12, 2008 7:39 pm   
 
Seb: Laughing

No, Seb, overall speed depends on many factors: pattern length, matched text, what script was used in trigger body, how many other scripts in your current package, how many lines in the scrollback buffer... I'll post my test triggers when I'll finish with last variant (with esc codes), then you (and oldguy2) may run it on yours machines. Wink

Update: Ahh, one more thing. In my tests I've use real function call (@createEditLink), while oldguy2 used something more simple, I guess.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Tue Aug 12, 2008 7:57 pm   
 
Ahha, well you never said your testing set-up was more complicated than your original post! Laughing I must say I was surprised at how slow the times were for what you posted, but now I know it's not a blank session...
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Tue Aug 12, 2008 8:17 pm   
 
Seb:

actually, it was a blank session. A test session with 5-6 settings in it at all plus 1 real function that performs script generation and packing it as MXP link. Hmm... Think I should test speed with dummy function call instead... In other hand, testing with real function can tell me what timings I will have in my real package...


Last edited by Arde on Tue Aug 12, 2008 8:21 pm; edited 1 time in total
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Tue Aug 12, 2008 8:20 pm   
 
Well, obviously you tested what is more interesting for you, but a dummy function call would have been enlightening for us. However, I suppose oldguy2 provided that test.
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Tue Aug 12, 2008 8:27 pm   
 
Grhm... Yes, you are right. All what I can say that he posted it 4 days ago and it was too high above for me to look at it when I wrote a reply Embarassed
_________________
My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Tue Aug 12, 2008 8:53 pm   
 
Final results:
#SUB - 10 sec 140 msec
#GAG+#MXP - 10 sec 391 msec
Esc+#MXP - 10 sec 344 msec

Here is my test settings, based on real MUD output, where I'm trying to replace character title with clickable link. Clicking on the link results in editing of a variable that holds title value. My main idea was make a generic link creating function, but now I stopped by CMUD bugs, playing with timings only. Please note, that function is completed yet.

I used "X", "Y" and "Z" in %concat just to prevent triggers to fire on their own resulting string causing an indefinite loop. Btw, how I can fight this problem?


Code:

  <trigger name="trg1" priority="60" stop="true" enabled="false" id="6">
    <pattern>^Arde(*)~(level: 20~)$</pattern>
    <value>#GAG
#MXP 1 %concat("X", %replace(%trigger, %t1, @createEditLink(%t1, "PROMPT TEXT", "CharTitle", 0)))</value>
  </trigger>
  <trigger name="trg2" priority="60" stop="true" enabled="false" id="7">
    <pattern>^(Arde )(*)(  ~(level: 20~))$</pattern>
    <value>#SUB {%concat("Y", %1, @createEditLink(%2, "PROMPT TEXT", "CharTitle", 0), %3)}</value>
  </trigger>
  <trigger name="trg3" priority="60" stop="true" id="8">
    <pattern>^(Arde )(*)(  ~(level: 20~))$</pattern>
    <value>%e[2A
#MXP 1 %concat("Z", %1, @createEditLink(%2, "PROMPT TEXT", "CharTitle", 0), %3)</value>
  </trigger>
<func name="createEditLink" type="Literal" id="4">
  <value><![CDATA[$strTmp = "";

// Checking $iMode value
#IF (($iMode = "") OR ($iMode <> 1))
{
  // Setting default mode to 0
  $iMode = 0;
}

$varName = %subregex($varName, "@", "");

// Make a string like $tmp_cEL=%prompt(@Var1, "Prompt for %prompt");#IF ($tmp_cEL<>"") {#IF ($tmp_cEL==" ") {$varName = ""} {Var1 = $tmp_cEL}}
// i.e. if user press Cancel and %prompt returns "", do not clear specified variable but preserve its value
// Clear variable only if user entered 1 single space character.
$strTmp = %concat("$tmp_cEL = %prompt(@",$varName,", """, $promptText, ". If you want delete current value, enter 1 single space character."");#IF ($tmp_cEL<>"""") {#IF ($tmp_cEL=="" "") {$varName = """"} {", $varName, " = $tmp_cEL}}");

// Format output according to $iMode value
#SWITCH ($iMode)
  (0)
    {
      $strTmp = %concat("<send '", $strTmp, "'>", $linkText, "</send>");
    }
  (1)
    {
      $strTmp = %concat("#MXP 1 ""<send '", $strTmp, "'>", $linkText, "</send>");
    }

#RETURN $strTmp;]]></value>
  <arglist>$linkText,$promptText,$varName,$iMode</arglist>
  <notes>Create a clickable link with $linkText message. If you click on it, a pop-up window with $promptText will appear on the screen, filled with current value of @{$varName} variable. Optional $iMode value controls what form of MXP command will be produced. If $iMode==0 (default), then a string with " tags, suitable for using in #SUB triggers, will be returned. If $iMode==1, then a string "#MXP 1..." will be returned. In this case you should use #EXEC in order produced MXP command to work.</notes>
</func>
<var name="CharTitle" id="5">Blah-blah-blah</var>


Test script: #LOOP 1000 {#SHOW "Arde - test string. Just a test string. (level: 20)"}
Reply with quote
Zugg
MASTER


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

PostPosted: Tue Aug 12, 2008 10:24 pm   
 
Btw, if you are just trying to remove the @ character in your $varName variable, why use %subregex? Seems like just using %replace would be much faster than calling the entire regular expression engine. Probably won't make a huge difference though.

Actually, I just got distracted and decided to test some of this. I imported your script, but your Test doesn't fire the triggers for trg2 or trg3. Looks like there are some extra spaces needed somewhere. I added an extra space in the test line before the (level: 20) and that seemed to fire the triggers.

Btw, here is the test script that I finally used along with extra code to display the test speed result:
Code:
$last=%secs;#LOOP 1000 {#SHOW "Arde - test string. Just a test string.  (level: 20)"};#show time: (%secs-$last)


I got results of:
trg1: 6.921 secs
trg2: 7.933 secs
trg3: 8.038 secs

so that pretty much matches what you saw (my computer is just a bit faster) although the difference between the methods seems a bit larger than what you found.

I *did* find a bug when dealing with user-defined functions within enabled/disabled classes. I was trying to create a dummy function in a different class to see if the speed of the function was causing the difference. And I found that when disabling/enabling different classes containing the same function name, the triggers would still call the disabled function unless I manually recompiled it using the Compiled Code tab. So I've added this to the bug list too.

But when I replaced your function with just "#RETURN test" and then ran trg3, I got a time of 5.383 seconds which shows that less than half the time is because of the function.

My guess is that you are just seeing the speed limits of using anything that causes the screen output to update. When you are normally scrolling text in CMUD, the screen is only updated when your Refresh Amount number of lines is received. By default this is 6, so it updates the screen every 6 lines received from the MUD. (Obviously it also updates the screen when a prompt is received).

When using #SUB, #MXP, #CW, #GAG, etc, the screen is updated immediately so that you see your changed text. And especially in Vista, causing a screen update is relatively slow.

I'll be looking at the screen update code later in the future to see if it can be improved, especially given how slow it is in Vista compared to XP. But that's after the new mapper.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Goto page 1, 2  Next
Page 1 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