|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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.
Let's consider this MUD output:
Code: |
^text1 AnyText2 text3$
|
and this capturing trigger pattern:
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
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? |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Mon Aug 04, 2008 7:47 pm Re: Howto: MXP substitution |
Well there is another way similar to 1 (and probably worse!)
3)
and the script will be
Code: |
#SUB %replace(%line,%1,@ReplaceFunc(...))
|
I'd have gone with option 1 though. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: 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)
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. |
|
|
|
MattLofton GURU
Joined: 23 Dec 2000 Posts: 4834 Location: USA
|
Posted: 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 |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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 |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: 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.
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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 |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: 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...
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Wed Aug 06, 2008 4:51 am |
Yep, I just wonder how slow #GAG is.
|
|
_________________ 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 |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: 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.
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Wed Aug 06, 2008 9:09 pm |
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.
|
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Fri Aug 08, 2008 2:09 am |
Well the codes are here, but I don't know how you can send them.
|
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: 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! |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: 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} |
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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. 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! |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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. 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. |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: 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. |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Tue Aug 12, 2008 6:44 pm |
So oldguy2's computer is over 5 times faster than Arde's?
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Tue Aug 12, 2008 7:39 pm |
Seb:
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.
Update: Ahh, one more thing. In my tests I've use real function call (@createEditLink), while oldguy2 used something more simple, I guess. |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Tue Aug 12, 2008 7:57 pm |
Ahha, well you never said your testing set-up was more complicated than your original post! 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...
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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 |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: 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.
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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
|
|
_________________ 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 |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: 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)"} |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: 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. |
|
|
|
|
|