Raised This Month: $51 Target: $400
 12% 

Passing relatively long string(s) to native


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
damage220
Member
Join Date: Jul 2022
Location: Ukraine
Old 05-18-2023 , 15:14   Passing relatively long string(s) to native
Reply With Quote #1

I have a lot of multidimensional arrays like this one:
PHP Code:
stock const NO_FLASHBANG[][] = {
    
"Throw a flashbang first",
    
"Сначала киньте флешку",
    
"Спочатку киньте флешку",
}; 
I use these arrays for multilingual support. Comparing to builtin mechanism I prefer this much more due to static linking, neat syntax and some post processing I do to the strings. I use several functions defined in .inc file which is included in each plugin that requires it. This file is getting bigger and contains code that it should not contain by the definition of include file (or I think so), and I want a separate plugin to do the job.

So my question is how to reduce buffer copy when using natives? Style 1 native is deprecated, but the other one requires buffer to copy to. These strings may be 128 + 256 + 256 bytes long and copying them on each call is something I would like to avoid.

I know there is vdformat but it requires arg number, so I have to separate multidimensional array to separate arrays (strings). It completely ruins call syntax
PHP Code:
ml_print(csenderNO_FLASHBANG[0], NO_FLASHBANG[1], NO_FLASHBANG[2], ...params
I thought I can deal it with macros but it seems that macros in Pawn do not support variadic arguments. There is however one possible option but I have to mess order of parameters.
PHP Code:
#define ml_print(%1,%2,%3) ml_print2(%1[0], %1[1], %1[2], %2, %3)
ml_print2(const en_fmt[], const ru_fmt[], const ua_fmt[], csenderany:...)
// call syntax
ml_print(NO_FLASHBANGcsender, ...params
I could define multidimensional arrays as one-dimensional using enum.
PHP Code:
enum _:ML {
    
ML_EN,
    
ML_RU,
    
ML_UA,
};
stock const NO_FLASHBANG[ML] = {
    
"Throw a flashbang first",
    
"Сначала киньте флешку",
    
"Спочатку киньте флешку",
}; 
I know it is not possible to set offset for vdformat, it only allows to specify buffer directly which again lead me to buffer copy first. Is there anything else I can use instead of vdformat? Perhaps I could send pointer to array and read directly from memory (though I got memory access error when I tried), could I? I am totally fine with implementing my own printf analog because I mostly use %s and %d specifiers without width/precise modifiers. Perhaps there is some tweak for macros I am not aware of?

Last edited by damage220; 05-18-2023 at 15:14.
damage220 is offline
SVC
Junior Member
Join Date: Mar 2021
Old 05-18-2023 , 15:37   Re: Passing relatively long string(s) to native
Reply With Quote #2

I've never play with LANG on a plugin, but if i can help...
¿First, what is exactly you want to do?. Sorry if can't understand yet.
PHP Code:
//What I've see is, you want do something like this:
ml_print(NO_FLASHBANG/*dont know what this specifies*/sender, ....params);

// an later, natives will automatically determine what 'NO_FLASHBANG' ML used, based on player's lang, is it? 
SVC is offline
damage220
Member
Join Date: Jul 2022
Location: Ukraine
Old 05-18-2023 , 16:23   Re: Passing relatively long string(s) to native
Reply With Quote #3

SVC,
I do not use builtin mechanism for localization.
damage220 is offline
SVC
Junior Member
Join Date: Mar 2021
Old 05-18-2023 , 21:57   Re: Passing relatively long string(s) to native
Reply With Quote #4

Quote:
Originally Posted by damage220 View Post
SVC,
I do not use builtin mechanism for localization.
Hi again.
Sorry, but i dont know what this means
SVC is offline
damage220
Member
Join Date: Jul 2022
Location: Ukraine
Old 05-18-2023 , 23:00   Re: Passing relatively long string(s) to native
Reply With Quote #5

Quote:
Originally Posted by SVC View Post
Hi again.
Sorry, but i dont know what this means
%L specifier for format functions like client_print, console_print, etc...
https://forums.alliedmods.net/showthread.php?t=4358
damage220 is offline
fysiks
Veteran Member
Join Date: Sep 2007
Location: Flatland, USA
Old 05-19-2023 , 02:05   Re: Passing relatively long string(s) to native
Reply With Quote #6

Quote:
Originally Posted by damage220 View Post
I have a lot of multidimensional arrays like this one:
PHP Code:
stock const NO_FLASHBANG[][] = {
    
"Throw a flashbang first",
    
"Сначала киньте флешку",
    
"Спочатку киньте флешку",
}; 
I use these arrays for multilingual support. Comparing to builtin mechanism I prefer this much more due to static linking, neat syntax and some post processing I do to the strings. I use several functions defined in .inc file which is included in each plugin that requires it. This file is getting bigger and contains code that it should not contain by the definition of include file (or I think so), and I want a separate plugin to do the job.

So my question is how to reduce buffer copy when using natives? Style 1 native is deprecated, but the other one requires buffer to copy to. These strings may be 128 + 256 + 256 bytes long and copying them on each call is something I would like to avoid.

I know there is vdformat but it requires arg number, so I have to separate multidimensional array to separate arrays (strings). It completely ruins call syntax
PHP Code:
ml_print(csenderNO_FLASHBANG[0], NO_FLASHBANG[1], NO_FLASHBANG[2], ...params
I thought I can deal it with macros but it seems that macros in Pawn do not support variadic arguments. There is however one possible option but I have to mess order of parameters.
PHP Code:
#define ml_print(%1,%2,%3) ml_print2(%1[0], %1[1], %1[2], %2, %3)
ml_print2(const en_fmt[], const ru_fmt[], const ua_fmt[], csenderany:...)
// call syntax
ml_print(NO_FLASHBANGcsender, ...params
Why would you be passing the ML strings every single time you want to print something? Just pass them once, cache them and use some sort of reference to pass via the print native to get the correct ML string.



Quote:
Originally Posted by damage220 View Post
I could define multidimensional arrays as one-dimensional using enum.
PHP Code:
enum _:ML {
    
ML_EN,
    
ML_RU,
    
ML_UA,
};
stock const NO_FLASHBANG[ML] = {
    
"Throw a flashbang first",
    
"Сначала киньте флешку",
    
"Спочатку киньте флешку",
}; 
This is not valid code. Strings are arrays of characters therefore an array of strings is necessarily a 2D array.
__________________
fysiks is offline
lexzor
Veteran Member
Join Date: Nov 2020
Old 05-19-2023 , 07:25   Re: Passing relatively long string(s) to native
Reply With Quote #7

PHP Code:
enum (+=1) {
    
ML_EN 0,
    
ML_RU,
    
ML_UA,
};
stock const NO_FLASHBANG[] = {
    
"Throw a flashbang first",
    
"Сначала киньте флешку",
    
"Спочатку киньте флешку",
}; 
then you can use them

PHP Code:
client_print(idprint_console"%s"NO_FLASHBANG[ML_RU]) 

Last edited by lexzor; 05-19-2023 at 07:25.
lexzor is offline
damage220
Member
Join Date: Jul 2022
Location: Ukraine
Old 05-19-2023 , 13:54   Re: Passing relatively long string(s) to native
Reply With Quote #8

Quote:
Originally Posted by fysiks View Post
Why would you be passing the ML strings every single time you want to print something? Just pass them once, cache them and use some sort of reference to pass via the print native to get the correct ML string.
I thought of it. I could use array to cache these ML strings and Trie to find needed index, but it has drawbacks:
1. I should first register these strings. And unlike to built in mechanism I cannot just register dictionary using file, I will have to specify each string separately.
2. String I would use to lookup values may contain misspelling which can be found only in RUNTIME. When I mentioned about static linking I meant exactly this case.

Quote:
Originally Posted by fysiks View Post
This is not valid code. Strings are arrays of characters therefore an array of strings is necessarily a 2D array.
My bad, it should be ML_EN[128], ML_RU[256], ...
damage220 is offline
damage220
Member
Join Date: Jul 2022
Location: Ukraine
Old 05-19-2023 , 14:05   Re: Passing relatively long string(s) to native
Reply With Quote #9

Quote:
Originally Posted by lexzor View Post
PHP Code:
enum (+=1) {
    
ML_EN 0,
    
ML_RU,
    
ML_UA,
};
stock const NO_FLASHBANG[] = {
    
"Throw a flashbang first",
    
"Сначала киньте флешку",
    
"Спочатку киньте флешку",
}; 
then you can use them

PHP Code:
client_print(idprint_console"%s"NO_FLASHBANG[ML_RU]) 
1. Plugin has to know the language that player selected (it is not a big deal, I can handle it with forward or retrieve the value using native)
2. This is not optimized when sending messages to 32 players, as this string should be formatted 32 times. I cache strings for different languages and reuse them later.
3. I cannot define my own specifiers, e.g. %(в|ла). The first string (before |) specifies ending for male and the second is for female.

Last edited by damage220; 05-19-2023 at 14:06.
damage220 is offline
Reply



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

Forum Jump


All times are GMT -4. The time now is 20:30.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode