SA-MP Forums Archive
Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+---- Forum: Help Archive (https://sampforum.blast.hk/forumdisplay.php?fid=89)
+---- Thread: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever (/showthread.php?tid=146093)



Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - Coicatak - 05.05.2010

I see lots of people making complex defines like
pawn Код:
#define SendFormat(%0,%1,%2,%3) do{new str[128];format(_str,128,%2,%3);SendClientMessage(%0,%1,_str);}while(FALSE)
not to write
pawn Код:
new string[128];
format(string, sizeof(string), "grdgr %d rgsrg", integer);
SendClientMessage(playerid, COLOR, string);
But why don't just do:
pawn Код:
#define FormatMsg(%0,%1,%2,%3) format(%2, sizeof(%2), %3); \
SendClientMessage(%0, %1, %2)

//%0 = playerid, %1 = color, %2 = string to format then send, %3 = string content
//Example of use:
new string[128];
new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name));
FormatMsg(playerid, COLOR, string, "Message sent to pl %d named %s", playerid, name);
Or
pawn Код:
#define FormatMsgEx(%0,%1,%2) new STRING[128]; \
format(STRING, 128, %2); \
SendClientMessage(%0, %1, %2)

//%0 = playerid, %1 = color, %2 = string content
//Example of use:
new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name));
FormatMsgEx(playerid, COLOR, "Message sent to pl %d named %s", playerid, name);
?

This works perfectly and it's very simple. It can take a infinite number of argument, and it's much faster than all the other SendFormattedMessage functions I've seen. At least I'm sure of it, am I wrong?


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - Coicatak - 06.05.2010

Up


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - RyDeR` - 06.05.2010

pawn Код:
// HUGE credit to ZeeX for finally cracking this problem:
// http://forum.sa-mp.com/index.php?topic=79810.msg901721#msg901721
stock CPF(playerid, color, fstring[], {Float, _}:...)
{
    // This is the number of parameters which are not variable that are passed
    // to this function (i.e. the number of named parameters).
    static const
        STATIC_ARGS = 3;
    // Get the number of variable arguments.
    new
        n = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
    if (n)
    {
        new
            message[128],
            arg_start,
            arg_end;
       
        // Load the real address of the last static parameter. Do this by
        // loading the address of the last known static parameter and then
        // adding the value of [FRM].
        #emit CONST.alt        fstring
        #emit LCTRL          5
        #emit ADD
        #emit STOR.S.pri       arg_start
       
        // Load the address of the last variable parameter. Do this by adding
        // the number of variable parameters on the value just loaded.
        #emit LOAD.S.alt       n
        #emit ADD
        #emit STOR.S.pri       arg_end
       
        // Push the variable arguments. This is done by loading the value of
        // each one in reverse order and pushing them. I'd love to be able to
        // rewrite this to use the values of pri and alt for comparison,
        // instead of having to constantly load and reload two variables.
        do
        {
            #emit LOAD.I
            #emit PUSH.pri
            arg_end -= BYTES_PER_CELL;
            #emit LOAD.S.pri     arg_end
        }
        while (arg_end > arg_start);
       
        // Push the static format parameters.
        #emit PUSH.S         fstring
        #emit PUSH.C         128
        #emit PUSH.ADR        message
       
        // Now push the number of arguments passed to format, including both
        // static and variable ones and call the function.
        n += BYTES_PER_CELL * 3;
        #emit PUSH.S         n
        #emit SYSREQ.C        format
       
        // Remove all data, including the return value, from the stack.
        n += BYTES_PER_CELL;
        #emit LCTRL          4
        #emit LOAD.S.alt       n
        #emit ADD
        #emit SCTRL          4
       
        return SendClientMessage(playerid, color, message);
        //return print(message);
    }
    else
    {
        return SendClientMessage(playerid, color, fstring);
        //return print(fstring);
    }
}
Author ******.
Oh and BYTES_PER_CELL = 4.


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - CaHbKo - 06.05.2010

I join the question.

I was using CPF for a long time now, and always wondered if all those #emits are taking too long or not.
Well, it doesn't make my server lag or something, but macro looks smaller and more efficient in my eyes.

I'm not sure how to test the function 'speed', maybe someone already did this?


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - RyDeR` - 06.05.2010

Quote:
Originally Posted by CaHbKo
I join the question.

I was using CPF for a long time now, and always wondered if all those #emits are taking too long or not.
Well, it doesn't make my server lag or something, but macro looks smaller and more efficient in my eyes.

I'm not sure how to test the function 'speed', maybe someone already did this?
I'll. I'll post the results here.


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - RyDeR` - 06.05.2010

I used as string "\"%s\" is my name!!" (%s = pName = "RyDeR")
and both runned them 1.000.000 times and format with 128 bytes used 656 ms.
CPF had 986 ms.

It's clearly that using it in your command is much faster.


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - dice7 - 06.05.2010

Quote:
Originally Posted by » RyDeR «
I used as string "\"%s\" is my name!!" (%s = pName = "RyDeR")
and both runned them 1.000.000 times and format with 128 bytes used 656 ms.
CPF had 986 ms.

It's clearly that using it in your command is much faster.
Well of course format() is much faster, since It's a native function. And since the define consist of native functions only, it will always be faster then ****** CPF. And also, none of the defines in the first post work

pawn Код:
#define FormatMsgEx(%0,%1,%2,%3) new string[128]; \
format(string,128,%2,%3); \
SendClientMessage(%0,%1,%2)



Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - Sergei - 06.05.2010

Quote:
Originally Posted by » RyDeR «
I used as string "\"%s\" is my name!!" (%s = pName = "RyDeR")
and both runned them 1.000.000 times and format with 128 bytes used 656 ms.
CPF had 986 ms.

It's clearly that using it in your command is much faster.
You will really notice that yeah .. 0,000986ms or 0,000656ms.


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - RyDeR` - 07.05.2010

True, but CPF IMO is much easier.


Re: Macro SendFormatMessage, SendFormattedMessage, FormatMessage, or whatever - Coicatak - 08.05.2010

Quote:
Originally Posted by dice7
none of the defines in the first post work
The first one works perfectly, I've tested it, but yes the second one is wrong as there is one parameter not needed. Fixed.

So back to my question, why use something as complex as CPF whereas using this simple define?