convert string to function?

I

itameio

Guest
lets say i have 'game_end()' stored as a string in a variable, is there anyway for me to call the string from the variable and execute it as the function it is?
 
The next question is, why do you want to store a function or piece of code as a string to execute later? There's likely a better work around then a code parser.
 

Weird Dragon

Wizard
GMC Elder
Wouldn't it be simpler to do something along the lines of this:

Code:
if my_variable == 'game_end()'
    {
        game_end();
    }
or a switch statement if "my_variable" can have different values.

***
PS. I am excited as to what your answer is to @stainedofmind's question.
 
I

itameio

Guest
The next question is, why do you want to store a function or piece of code as a string to execute later? There's likely a better work around then a code parser.
Wouldn't it be simpler to do something along the lines of this:

PS. I am excited as to what your answer is to @stainedofmind's question.
I'm curious if there was something else still around like execute_string(), yeah there is probably better ways of doing but I'm not even sure of what I want to do with it anymore.

Wouldn't it be simpler to do something along the lines of this:

Code:
if my_variable == 'game_end()'
    {
        game_end();
    }
or a switch statement if "my_variable" can have different values.

I can't use that since what i'm trying to do is insert some code around a string in a variable, so that it would basically execute the code with the previously given string, which i learnt can't work, damn it it's a little complicated. . . i'm not sure how to go about it. . .


TL;DR:I want to use string_copy in adjust_arabic_text but i can't use it in the draw event because it makes the game slower and can't call it from a variable because string_copy wouldn't work.

I have downloaded this extension which makes game maker supports Arabic language, and it only has 1 function which is adjust_arabic_text("Arabic text here") which basically makes Arabic display correctly. so since i'm creating a visual novel, I need to have some text effects such as the dialogue being drawn letter by letter, for which I use String_copy function in the draw event.

so the problem with using these two functions together is that one of them needs to be in the other, if i put adjust_arabic_text() in the string_copy() function, the text is drawn from last letter to first (because in order for Arabic to be displayed correctly on game maker, it needs to be reversed, and thus this happens), an effect which I don't desire to use.
but that is fixed by putting the string_copy() function in the adjust_arabic_text() function, which displays the text correctly and draws it letter by letter from first to last.

after that another problem surfaced, since I use that code in the draw event, the adjust_arabic_text() was being executed every step of the game, which greatly slowed the game down on android, so I decided to have the text adjusted at the beginning of the game by assigning it to variables and using them in the draw_event later (the extension creator suggested this later too) but that didn't work the problem was that the "Count" element of the string_copy() function was not being increased as i intended it to (i use a variable in a step event to increase it and it worked when the code was in the draw event) so the text was not appearing at all since the count starts at 0.

so i had to remove the string_copy from the variable code, left only adjust_arabic_text() with the string to adjust, and put string_copy(myvariable . . in the draw event, which replicated the first problem of the text being drawn from last to first.

so my idea of fixing it was to include the string_copy() again in the variable by using functions such as string_replace and string_insert and that did not work too . . .

and now i'm stuck, i need a way about this, i want to use string_copy in adjust_arabic_text but i can't use it in the draw event because it makes the game slower and can't call it from a variable because string_copy wouldn't work.
 
Last edited by a moderator:

ZeDuval

Member
@Alemar5 It's been a while and my extension ( which I should update ), which never covered all functions to begin with, will be barely usable in times of GM>2.3.

I wrote this as an alternative for you:

GML:
/// @function function_execute( name, args )
/// @description executes builtin function or user script by name
/// @param {string} name the function name
/// @param {any} args the arguments that will be forwarded to the function
/// @returns {any} the return value of the executed function
function function_execute( name, args ){
    
    static ____builtin_functions = undefined
    
    // this code block will only run once on first usage of function_execute
    if( is_undefined( ____builtin_functions ) ){
        
        ____builtin_functions = {}
        
        // id range for builtin scripts(functions) is 0 - 100000
        for( var _i=0; _i <= 100000; _i++ ){
            
            var _name = script_get_name( _i )
            
            // break loop once we reach the first unused id
            if( _name == "<unknown>" ) break

            // skip this iteration, prevent error from trying to access an internal function
            if( string_char_at( _name, 1 ) == "@" ) continue

            ____builtin_functions[$_name] = _i

        }

    }
    
    // determine if name is a user script or a builtin function
    var _ind = asset_get_type( name ) == asset_script ? asset_get_index( name ) : ____builtin_functions[$name]
    
    if( is_undefined( _ind ) ) throw ("unknown function or script: " + name)
    
    var _args = array_create( argument_count - 1 )
    // get all provided arguments minus the first as a real array
    for( var _i=1; _i < argument_count; _i++ ) _args[_i-1] = argument[_i]

    return script_execute_ext( _ind, _args )
    
}
✌
 

Alice

Darts addict
Forum Staff
Moderator
TL;DR:I want to use string_copy in adjust_arabic_text but i can't use it in the draw event because it makes the game slower and can't call it from a variable because string_copy wouldn't work.
If I understood your problem correctly:

1. You need to use adjust_arabic_text(...) to properly support the Arabic language version

2. You need to use string_copy(...) for the letter-by-letter typing effect

3. If you use adjust_arabic_text(...) inside string_copy(...), the typing-out text first displays last letters.
That's because adjust_arabic_text(...) internally reverses the text to be typed out - so what appears like "Hello, world!" actually stores characters for "!dlrow ,olleH", but GM renders it in a way that it looks like proper Arabic "Hello, world!"
And if you perform string_copy(...) on it, the text to be displayed goes through "!dl", "!dlrow", "!dlrow ,oll" and finally "!dlrow ,olleH", which in Arabic appears as something like "ld!", "world!", "llo, world!" and "Hello, world!" respectively.
From your descriptions, it seemed like the text types out the last letter first, but the letters being typed out display in the correct order (and if all letters are typed out, the whole text is correct). Please correct me if I'm wrong.

4. If you use string_copy(...) inside adjust_arabic_text(...), it works correctly but you have to perform adjust_arabic_text() every step and it's horribly slow

Based on this description, I think no special converting string to function needs to be used? Instead, I'd choose different variants of string_copy depending on the language: regular string_copy for English, and Arabic-adjusted string_copy for Arabic. It could be defined as such:
GML:
function string_copy_adjusted(_str, _index, _count, _reverse) {
    if (!_reverse) {
        return string_copy(_str, _index, _count);
    } else {
        var _length = string_length(_str);
        return string_copy(_str, 1 + _length - _count - (_index - 1), _count);
    }
}
This function, given something like string_copy_adjusted("Hello, world!", 1, 5, false) will return "Hello" (like regular string_copy), while given string_copy_adjusted("Hello, world!", 1, 5, true) it will return "world!" instead. So if you do the following in Draw event where the text is typed out:
GML:
var _text = string_copy_adjusted(_str, 1, _shown_characters, global.language == "Arabic");
Then the typed out text will be "leH", "olleH", "row ,olleH" and finally "!dlrow ,olleH", which should display as "Hel", "Hello", "Hello, wor" and "Hello, world!" respectively.

So yeah, I don't see how converting string to function was supposed to help you here, but it sounds like way more hassle than necessary for this specific problem. In fact, I imagine parsing such string-represented function would result in massive slowdowns, maybe even worse than calling adjust_arabit_text every frame. ^^'

Note: I have made some dialogue systems which allowed performing certain commands after certain dialogue, but in such cases rather than executing GML verbatim I opted for mapping dialogue script commands to functions defined in GM. But it's been a while since I actually made scripting language evaluation in GM (I haven't made any visual novels for Jams recently...).
 
Top