SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help

Reply
 
Thread Tools Display Modes
Old 22/11/2017, 09:42 PM   #11
Dayrion
High-roller
 
Dayrion's Avatar
 
Join Date: Jan 2016
Location: France
Posts: 1,471
Reputation: 120
Default Re: [Macro] Mutliple macros in one

The thing I don't understand is that %8$ before each "cmd_".
PHP Code:
#define CMD: __:CMD_1:CMD_2:CMD_3:$

#define CMD_1:CMD_2:CMD_3:%8$%1[%2](%3) %8$cmd_%1(%3) <cmd_state: %2>
#define CMD_2:CMD_3:%8$%1{%2}(%3)         %8$cmd_%1(%3) if (Is%2(playerid))
#define CMD_3:%8$%1(%3)                 %8$cmd_%1(%3) 
I'm wondering how the compiler consider "u@(u[_:%0 u@$" ? as a variable?
PHP Code:
u@(u[_:CMD_10]);cmd_ban(playeridparams[]) if (IsAdmin(playerid))
{
    return 
1;

__________________
« What matters isn't to going further, it's the way to get there »
Dayrion is offline   Reply With Quote
Old 22/11/2017, 09:58 PM   #12
Y_Less
Spam Machine
 
Y_Less's Avatar
 
Join Date: Jun 2008
Location: 629 - git.io/Y
Posts: 14,536
Reputation: 2938
Default Re: [Macro] Mutliple macros in one

I explained both those things in the posts I linked.
Y_Less is offline   Reply With Quote
Old 22/11/2017, 11:38 PM   #13
Dayrion
High-roller
 
Dayrion's Avatar
 
Join Date: Jan 2016
Location: France
Posts: 1,471
Reputation: 120
Default Re: [Macro] Mutliple macros in one

Quote:
Originally Posted by Y_Less View Post
I explained both those things in the posts I linked.
Okei. I understand after like 10 re-reading but I still don't understand (and that making errors), how this things can works:
PHP Code:
u@(u[_0]);
u@(u[_:c_l@1:c_l@20]); etc 
It's ouside the function so why it should work?

PHP Code:
main()
{
    (
CUSTOM_S_ACTUAL_STATE CUSTOM_S_ALL);

    
u@(u[_:c_l@1:c_l@20]);PrintZ(C_E_A#TEST, "path",  "message");
    
u@(u[_:c_l@1:c_l@20]);PrintZ(C_E_A#TEST, "path",  "message & args: %i", 99);
    
u@(u[_:c_l@1:c_l@20]);PrintZ(C_E_A#TEST, "General",  "message");
    
u@(u[_:c_l@1:c_l@20]);PrintZ(C_E_A#TEST, "General",  "message & args: %i", 99);

Code:
(78) : error 004: function "u@" is not implemented
(78) : warning 221: label name "_" shadows tag name
(78) : warning 215: expression has no effect
(78) : error 001: expected token: ";", but found "]"
(78) : error 029: invalid expression, assumed zero
(78) : fatal error 107: too many error messages on one line
Your code (which is outside any functions or whatever) actually works (of course lol) and doesn't trigger the compiler about u@u(...)
PHP Code:
u@(u[_:CMD_1:CMD_20]);cmd_my_command(playeridparams[])
{
    return 
1;
}

u@(u[_0]);cmd_my_command(playeridparams[]) <cmd_statehelp>
{
    return 
1;
}

u@(u[_:CMD_10]);cmd_ban(playeridparams[]) if (IsAdmin(playerid))
{
    return 
1;

EDIT: It was a brilliant idea you got. So impressive
__________________
« What matters isn't to going further, it's the way to get there »
Dayrion is offline   Reply With Quote
Old 23/11/2017, 07:44 PM   #14
Y_Less
Spam Machine
 
Y_Less's Avatar
 
Join Date: Jun 2008
Location: 629 - git.io/Y
Posts: 14,536
Reputation: 2938
Default Re: [Macro] Mutliple macros in one

OK, a better explanation.

Imagine this code:

PHP Code:
forward MyFunc(arr[10]); 
You can put a tag on the array size:

PHP Code:
forward MyFunc(arr[_:10]); 
But it turns out you can put MANY tags on the array size, as long as the first one is right:

PHP Code:
forward MyFunc(arr[_:Float:TAG_MACRO:10]); 
You can also forward the same function multiple times:

PHP Code:
forward MyFunc(arr[10]);
forward MyFunc(arr[10]);
forward MyFunc(arr[10]); 
And if you do so, the tags on the array size don't have to match, as long as the first one is the same, and the sizes are the same:

PHP Code:
forward MyFunc(arr[_:MACRO_1:10]);
forward MyFunc(arr[_:MACRO_2:10]);
forward MyFunc(arr[_:MACRO_3:10]); 
The "forward" keyword is optional:

PHP Code:
MyFunc(arr[10]);
MyFunc(arr[10]);
MyFunc(arr[10]); 
"@" is a valid symbol in a function name (if a function name starts with "@" it is public, even if you didn't use the "public" keyword). So let's choose a nice short name:

PHP Code:
u@(arr[10]);
u@(arr[10]);
u@(arr[10]); 
And do the same for the array's name:

PHP Code:
u@(u[10]);
u@(u[10]);
u@(u[10]); 
And make the code invalid, so you can't actually call it (because you can't really have a size 0 array):

PHP Code:
u@(u[0]);
u@(u[0]);
u@(u[0]); 
Put the different macros back in:

PHP Code:
u@(u[_:MACRO_1:0]);
u@(u[_:MACRO_2:0]);
u@(u[_:MACRO_3:0]); 
Now we have the start point for the macro. This explains why it only works outside functions - there's no need for this inside functions as you can just use normal tag overrides on the function return:

PHP Code:
(_:MACRO_1:MACRO_2:CallInAFunction()); 
So, now we come to this:

PHP Code:
#define __:%0$ u@(u[_:%0 u@$ 
You have three macros, all matching different functions (I just made these up):

PHP Code:
// Detect a function with only "playerid", and make it "stock".
#define MACRO_1:%0(playerid) stock %0(playerid)

// Detect functions with two arrays, and append both sizes.
#define MACRO_2:%0(%1[%2],%3[%4]) %0(%1[%2], %3[%4], size_%1 = sizeof (%1), size_%3 = sizeof (%3)) 

// Detect functions with 4 parameters, and make a note of it.
#define MACRO_3:%0(%1,%2,%3,%4) public bool:has_4_%0 = true;%0(%1,%2,%3,%4) 
How do you combine them? Like this:

PHP Code:
__:MACRO_1:MACRO_2:MACRO_3:$ 
Note the "$". This means "end of the code for the macro tricks, start of user code". This demands a tiny modification to the original macros. Adding in "%8$" will detect this "$" as the end of the macro's internal implementation and the start of user code. Note that you need to put it back again so that the code keeps running. I also changed "MACRO_2:" to "MACRO_2:MACRO_3:", to demonstrate that they are still in order (and hidden within "%8" normally). Doing it this way will only match "MACRO_3:" if "MACRO_2:" didn't match - otherwise they will both be run (and thus "MACRO_3:" will match because "MACRO_2:" just converted the code to having four parameters):

PHP Code:
// Detect a function with only "playerid", and make it "stock".
#define MACRO_1:%8$%0(playerid) %8$stock %0(playerid)

// Detect functions with two arrays, and append both sizes.
#define MACRO_2:MACRO_3:%8$%0(%1[%2],%3[%4]) %8$%0(%1[%2], %3[%4], size_%1 = sizeof (%1), size_%3 = sizeof (%3)) 

// Detect functions with 4 parameters, and make a note of it.
#define MACRO_3:%8$%0(%1,%2,%3,%4) %8$public bool:has_4_%0 = true;%0(%1,%2,%3,%4) 
"__" is just:

PHP Code:
#define __:%0$ u@(u[_:%0 u@$ 
So this:

PHP Code:
__:MACRO_1:MACRO_2:MACRO_3:$ 
Becomes:

PHP Code:
u@(u[_:MACRO_1:MACRO_2:MACRO_3:u@$ 
If you were to do:

PHP Code:
#define FUNC_DETECTOR: __:MACRO_1:MACRO_2:MACRO_3:$

FUNC_DETECTOR:MyFunc(ab)
{

You would get:

PHP Code:
u@(u[_:MACRO_1:MACRO_2:MACRO_3:u@$MyFunc(ab)
{

Now you should be able to see how the macros are tags within the array size, how the shortened forward is used to drive everything, and how "$" marks where the user's code starts. Thus, while you don't need to know it, the contents of "%8" in "MACRO_1" is "MACRO_2:MACRO_3:u@". But there's one final part. This isn't valid code. The array is never closed and "$" can't actually be used there. That's why the last thing after the tag macros is "u@$" and there's this macro:

PHP Code:
#define u@$ 0]); 
After the compiler has gone through "MACRO_1", "MACRO_2", and "MACRO_3", it gets to "u@$", matches it, and outputs:

PHP Code:
u@(u[_:MACRO_1:MACRO_2:MACRO_3:0]);MyFunc(ab)
{

Why doesn't the function name "u@" match that macro? Because it isn't immediately followed by "$", which is required for the macro to match. Why did I use the same name twice? To keep the code short and using as few short names as possible. A single character name would have undoubtedly caused havok with all sorts of code using single character variable names. Two characters are often a problem for the same reason, but very few people use "@" in symbol names, so I've practically stolen it. All valid two letter symbol names involving "@" ("@a", "@9", "A@" etc) are used in either YSI, codeparse.inc, or here (with no duplicates). There may be a few free leading upper-case ("T@" etc) ones after my current rewrite, but I've never once had someone complain about a conflict.
Y_Less is offline   Reply With Quote
Old 24/11/2017, 11:01 PM   #15
Dayrion
High-roller
 
Dayrion's Avatar
 
Join Date: Jan 2016
Location: France
Posts: 1,471
Reputation: 120
Default Re: [Macro] Mutliple macros in one

Thanks a lot. That helped a lot. I didn't understand for the first part.
That's a very nice trick. Also, that can't work in a function since you can't forward a function inside another one?
If it can, well I missed an another part of your explain.

Edit:
Okei. I took the exact same trick to do that but the only bad thing is a global variable is needed to make that work.
PHP Code:
new this_custom_hgfdsq[1];
#define c_ji_t@$                 0] = 0;
#define __@:%0$                 this_custom_hgfdsq[_:%0 c_ji_t@$

#define         L:                __@:c_l@1:c_l@2:c_l@3:c_l@4:$L:
... other macro
main
()
{
    
L:TEST(@, "message");

Compile fine and works.
Have any advice or whatever that can help me to improve myself ? :P
__________________
« What matters isn't to going further, it's the way to get there »

Last edited by Dayrion; 25/11/2017 at 04:40 AM.
Dayrion is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[Ajuda] Macros AndrePls Português/Portuguese 11 25/12/2012 08:05 PM
Mutliple Strings in Commands aintaro Scripting Help 2 17/08/2012 10:19 PM
Help Macros TheArcher Help Archive 5 24/07/2011 12:25 PM
Variables accessible in mutliple scripts littlegrimlin1 Help Archive 6 28/02/2010 04:57 AM


All times are GMT. The time now is 11:28 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.