Today I learned - Share your newly found knowledge!

Quote:
Originally Posted by Freezo
Посмотреть сообщение
Today i learned that when you declare a stock or a function like :

Код:
stock printf.one() { }
The compiler doesn't manage that, well because of the point '.', and it gives an error of "Undefined symbol", but how can we fix that?

Well its really simple.
  1. First, we will need to declare a define
  2. the define will basically replace the real one.
Take a look:

Код:
#define printf. _replace_
Код:
stock printf.one() { }
stock printf.two() { }
stock printf.three() { }
What did i do? Well simply i create a define that replace the printf with _replace_ which the compiler will read it like this:

Код:
stock  _replace_one() {}
stock  _replace_two() {}
stock  _replace_three {}
Done.

Edit: i didn't tough that its something made before: Here
does giving a point (like "printf.one") benefit the code? Or isit a naming preference?
Reply

Quote:
Originally Posted by Darrenr
Посмотреть сообщение
does giving a point (like "printf.one") benefit the code? Or isit a naming preference?
the 'look' is like Object Oriented programming, and about performance I don't think that it will really benefit the code (I somehow thing that it will slow it down abit instead of using normal way) it might benefit you while reading the code.

I hope I helped any feedback is appreciated!
Reply

It does not affect speed in any way, because the replacements are doing during compile-time (not run-time).

I've done this previously:
pawn Код:
#define DB:: DB_

new DB::SomeVariable = 2;

stock DB::Initialize()
{
   
}
Reply

Today I learned that CallLocalFunction and CallRemoteFunction do in fact support arrays, and it copies the array to the heap of the receiving AMX, so it's safe to use between filterscripts and/or the gamemode.

There is one caveat: you must have an integer argument passed after it, containing the array size.

pawn Код:
new arr[] = {11, 22, 33, 44};
    CallRemoteFunction("test", "ai", arr, sizeof(arr));
}

forward test(arr[], arrlen);
public test(arr[], arrlen) {
    for (new i = 0; i < arrlen; i++) {
        printf("arr[%d] = %d", i, arr[i]);
    }
}
Output:
Код:
arr[0] = 11
arr[1] = 22
arr[2] = 33
arr[3] = 44
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
Today I learned that CallLocalFunction and CallRemoteFunction do in fact support arrays, and it copies the array to the heap of the receiving AMX, so it's safe to use between filterscripts and/or the gamemode.

There is one caveat: you must have an integer argument passed after it, containing the array size.

pawn Код:
new arr[] = {11, 22, 33, 44};
    CallRemoteFunction("test", "ai", arr, sizeof(arr));
}

forward test(arr[], arrlen);
public test(arr[], arrlen) {
    for (new i = 0; i < arrlen; i++) {
        printf("arr[%d] = %d", i, arr[i]);
    }
}
Output:
Код:
arr[0] = 11
arr[1] = 22
arr[2] = 33
arr[3] = 44
Think of it like you're passing a string. A string is an array of integer key codes (which are integers). An 'array' is an array of integers. After looking at it like that and knowing that you can pass strings then it's kind of obvious.
Reply

Integer key codes? What.
Either way, "cells" is the correct term when you talk about the abstract representation of a value in AMX memory. An integer is a cell with an empty tag. A float is a cell with the Float tag.

Passing an array is different from passing a string. If a string is sent from an array of size 128, but the string length is 10, then only 11 cells will be given to the callee.
Also, characters range from 0-255. Any bits above the 8th will be lost.
Reply

Today I learned that GetPlayerKeys doesn't work in OnPlayerDialogResponse callback.
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
Integer key codes? What.
Either way, "cells" is the correct term when you talk about the abstract representation of a value in AMX memory. An integer is a cell with an empty tag. A float is a cell with the Float tag.

Passing an array is different from passing a string. If a string is sent from an array of size 128, but the string length is 10, then only 11 cells will be given to the callee.
Also, characters range from 0-255. Any bits above the 8th will be lost.
This is pawn, a string is literally an array of characters. The characters are stored as integers. Unless you specifically tell the script to make a char array it will be treated as any other array.
Reply

I'm talking about CallRemoteFunction, and how strings/arrays are treated there. Not sure what you're on about..
There is no way for CallRemoteFunction to know the array size of a string, because it's not given to it; he only thing it knows is the string length. It allocates L+1 cells on the receiving AMX - not the size of the array holding the string.

A char array is no different from any other array. The "char" keyword is the exact same thing as doing a ceildiv by 4. The {n} subscript is to read/write each byte of an array, as opposed to each cell.

pawn Код:
new arr[1] = {0xAABBCCDD};
printf("%x, %x, %x, %x", arr{0}, arr{1}, arr{2}, arr{3});
new arr2[20 char] = {1, 2, ...};
for (new i = 0; i < sizeof(arr2); i++) printf("%d", arr2[i]);
Woo. Magic.
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
I'm talking about CallRemoteFunction, and how strings/arrays are treated there. Not sure what you're on about..
There is no way for CallRemoteFunction to know the array size of a string, because it's not given to it; he only thing it knows is the string length. It allocates L+1 cells on the receiving AMX - not the size of the array holding the string.

A char array is no different from any other array. The "char" keyword is the exact same thing as doing a ceildiv by 4. The {n} subscript is to read/write each byte of an array, as opposed to each cell.

pawn Код:
new arr[1] = {0xAABBCCDD};
printf("%x, %x, %x, %x", arr{0}, arr{1}, arr{2}, arr{3});
new arr2[20 char] = {1, 2, ...};
for (new i = 0; i < sizeof(arr2); i++) printf("%d", arr2[i]);
Woo. Magic.
My point is that if strings could be passed to CallRemote/LocalFunction, so can arrays.
Reply

Oh my bad, I thought you wanted to actually discuss the technical details. You just wanted to tell the world what you think.
Maybe we can start putting 2d arrays into them also? With your logic, it should work just fine!

Cool, another feature discovered by the power of ignorance!

Sarcasm aside, 2d arrays are doable but sizeof won't suffice for the size calculation.
Reply

printf iterates through it's parameters in reverse.
Reply

Today I learned that you can have concurrent operations using the comma operator.

Код:
new i, j;
	j = 0;
	i = (j++, j+=1, j+=1, j *= 2, j /= 10, j += 15, j * 2);
Which outputs 30 for as the value stored in "i".
Reply

Quote:
Originally Posted by Crayder
Посмотреть сообщение
printf iterates through it's parameters in reverse.
its*

A function doesn't iterate through its parameters; they are pushed onto the stack in reverse order.

PUSH c
PUSH b
PUSH a

The frame now looks like this:
12+8 - c
12+4 - b
12+0 - a
12 - arg count
8 - return addr
4 - ??
0 - return pos

If you look at the assembly output, you will see why it makes sense to do it that way.

Quote:
Originally Posted by ThePhenix
Посмотреть сообщение
Today I learned that you can have concurrent operations using the comma operator.

Код:
new i, j;
	j = 0;
	i = (j++, j+=1, j+=1, j *= 2, j /= 10, j += 15, j * 2);
Which outputs 30 for as the value stored in "i".
They're not concurrent (that would be crazy!). You can also do if/and/or/else without an if-statement.

pawn Код:
a && (a = 0) || (b = 1)
// translation:
if (a) {
    a = 0;
} else {
    b = 1;
}

a && (a = 0, b) && (b = 0, c) && (c = 0, d) && (d = 0)
// translation:
if (a) {
    a = 0;
   
    if (b) {
        b = 0;
       
        if (c) {
            c = 0;

            if (d) {
                d = 0;
            }
        }
    }
}
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
If you look at the assembly output, you will see why it makes sense to do it that way.
I did look at the assembly, that's how I figured it out in the first place.
Reply

Quote:
Originally Posted by Patrick
Посмотреть сообщение
I learned this quite a while ago but its worth something sharing. This will avoid you from repeating the code over and over again. Repeating dialogs could be annoying sometimes because you'll have to change everything that you've repeated.

pawn Код:
JustATestFunc(playerid, randomValue, higherValue)
{
    if(playerid == INVALID_PLAYER_ID)
    {
        goto RandomDialog;
        return 1;
    }
    if(randomValue < 10 || higherValue > 1000)
    {
        goto RandomDialog;
        return 1;
    }

    RandomDialog:
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_PASSWORD, "Example", "Example", "Yes", "No");
    return 1;
}
Instead of
pawn Код:
JustATestFunc(playerid, randomValue, higherValue)
{
    if(playerid == INVALID_PLAYER_ID)
    {
        ShowPlayerDialog(playerid, 0, DIALOG_STYLE_PASSWORD, "Example", "Example", "Yes", "No");
        return 1;
    }
    if(randomValue < 10 || higherValue > 1000)
    {
        ShowPlayerDialog(playerid, 0, DIALOG_STYLE_PASSWORD, "Example", "Example", "Yes", "No");
        return 1;
    }

    RandomDialog:
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_PASSWORD, "Example", "EXample", "Yes", "No");
    return 1;
}
Or, Here is how I'd do it:
PHP код:
JustATestFunc(playeridrandomValuehigherValue)
{
        
//Make sure everything is correct.
    
if(playerid != INVALID_PLAYER_ID) return 1;
    if(
randomValue 10 && higherValue 1000) return 1;
        
//Show the dialog.
    
ShowPlayerDialog(playerid0DIALOG_STYLE_PASSWORD"Example""Example""Yes""No");
    return 
1;

Also btw, the line about INVALID_PLAYER_ID should be the opposite but seeing as its only a test function, no problem :P
Reply

Quote:
Originally Posted by Patrick
Посмотреть сообщение
I learned this quite a while ago but its worth something sharing. This will avoid you from repeating the code over and over again. Repeating dialogs could be annoying sometimes because you'll have to change everything that you've repeated.

pawn Код:
goto RandomDialog;
Every self-respecting programmer will tell you that goto must never be used. It inevitably leads to spaghetti code and there are always better ways to solve it. To avoid "repeating the code over and over again", as you so nicely put it, functions were invented.
Reply

Quote:
Originally Posted by Vince
Посмотреть сообщение
Every self-respecting programmer will tell you that goto must never be used. It inevitably leads to spaghetti code and there are always better ways to solve it. To avoid "repeating the code over and over again", as you so nicely put it, functions were invented.
There are cases where it actually is a bit useful, but it's rare. In his example, he could just have refactored the if statements.

One place where goto is useful is obviously when dealing with #emit, but another place could be if you want to make a C-like switch statement with fall-through.

I've used it in strlib without feeling too bad about it, as well as here.

That said, always try to do what you do without using goto! It can cause undefined behavior and confusion..

For example, have a look at my goto usage in strlib here. I use "goto return_false" before the variable "ret" is instantiated - madness?!?!
goto modifies the FRM and stack. If you don't know what all these things mean, don't use it!
Reply

Quote:
Originally Posted by Vince
Посмотреть сообщение
Every self-respecting programmer will tell you that goto must never be used. It inevitably leads to spaghetti code and there are always better ways to solve it. To avoid "repeating the code over and over again", as you so nicely put it, functions were invented.
There's nothing wrong with using goto as long as its used correctly and you won't abuse the function because it just looks cooler and looks harder to read. You can always avoid spaghetti code, if you know what you're doing then you won't get a spaghetti code. You can always use functions + goto at the same time but I don't known if there's difference between functions + repetitive ShowPlayerDialog or functions + goto and 1 ShowPlayerDialog.

ps I am typing on my phone, sorry if there's a sentence that doesn't make sense.
Reply

Today I learned that no matter how many times I leave my command line to print an error for hours, it wont go away.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)