[sfall] Arrays questions

cfmod

First time out of the vault
This code...
Code:
variable 
  begin 
   
    FrameNumber; 
    FramesQuantity; 
     
  end 
 
#define display_frame(param1, param2, param3, param4, param5, param6) DisplayGFX(param5, param1, param2, param3, param4); \ 
                                                                      ShowWin; \ 
                                                                      wait(param6) 
 
#define sequence(param1) FramesQuantity := len_array(string_split(param1, " % ")); \ 
                         FrameNumber := 0; \ 
                         while FramesQuantity > FrameNumber do \ 
                           begin \ 
                             display_frame(166, 35, 308, 308, get_array(string_split(param1, " % "), FrameNumber), Delay); \ 
                             FrameNumber := FrameNumber + 1; \ 
                           end
Code:
sequence("pcx\\valve_30.pcx % pcx\\valve_60.pcx % pcx\\valve_90.pcx")
...sometimes produces error:

error.png


I wasn't able to find any dependencies in error appearing, it shows at random time, i can run sequence() at least 4 times before error appears, but sometimes it appears immediately after running sequence().
I've tried to rewrite code many times and i've noticed that problem is in arrays. Something works wrong in that code, but i can't understand what exactly. Can you help me?

Question number two: can i store array in some sort of variable, to address it in the future, like this:
Code:
TempArray := string_split("element_1 % element_2", " % "); 
get_array(TempArray, 0);
?
 
cfmod said:
This code...
<snip>
...sometimes produces error:
Is it possible that param1 sometimes isn't a string?

cfmod said:
Question number two: can i store array in some sort of variable, to address it in the future, like this:
Code:
TempArray := string_split("element_1 % element_2", " % "); 
get_array(TempArray, 0);
Yes, that will work, and will be faster than calling string_split twice too.

The array returned by string_split is valid until the function which called it returns, unless you call fix_array on it, in which case it's permanent until you use free_array.
 
Timeslip said:
Is it possible that param1 sometimes isn't a string?
No, it's always a string :) I have checked that carefully.
Timeslip said:
Yes, that will work, and will be faster than calling string_split twice too.
I have changed code slightly...
Code:
variable
  begin
    
    TempArray;
    FrameNumber;
    FramesQuantity;
    
  end

#define sequence(param1) TempArray := string_split(param1, " % "); \
                         debug_message("Array length = " + len_array(TempArray)); \
                         FramesQuantity := len_array(TempArray); \
                         FrameNumber := 0; \
                         while FramesQuantity > FrameNumber do \
                           begin \
                             display_frame(166, 35, 308, 308, get_array(TempArray, FrameNumber), Delay); \
                             FrameNumber := FrameNumber + 1; \
                           end
...but len_array(TempArray) returns -1:

screenie_002.png


. When i'm trying to store array in variable, nothing works. What i am doing wrong?
 
len_array returns -1 if the variable you give it isn't an array, and the only time string_split doesn't return an array is when one of the parameters isn't a string, but you've already checked that. :|

I don't know what's going on there. I just tried it myself in case I've broken something at some point, or if it depends on one parameter being a variable and the other not or something, but this snippit of code works fine here.
Code:
variable tmp, tmp2;
tmp2:="bin%gle";
tmp:=string_split(tmp2, "%");
display_msg(""+len_array(tmp)); //Prints 2, as expected
 
Finally, i've localised the problem. This code
[spoiler:db950bdfdd]variable tmp, tmp2;
tmp2:="bin%gle";
tmp:=string_split(tmp2, "%");
display_msg(""+len_array(tmp)); //Prints 2, as expected[/spoiler:db950bdfdd]
works fine, unless procedure, containing it, called from AddButtonProc().

Another words, this will work and return 2:
Code:
procedure use_p_proc
  begin

    call timeslip;
    
  end

procedure timeslip
  begin

    variable tmp, tmp2;
    tmp2:="bin%gle";
    tmp:=string_split(tmp2, "%");
    display_msg(""+len_array(tmp)); // Prints 2, as expected
    
  end
. But this won't work and will return - 1:
Code:
procedure use_p_proc
  begin
    CreateWin("timeslip", 0, 0, 640, 379);
    AddButton("Button_Array", 40, 354, 50, 25);
    AddButtonProc("Button_Array", do_nothing, do_nothing, do_nothing, timeslip);
    AddButtonText("Button_Array", "Array");
    ShowWin;
  end

procedure timeslip
  begin

    variable tmp, tmp2;
    tmp2:="bin%gle";
    tmp:=string_split(tmp2, "%");
    display_msg(""+len_array(tmp)); // Prints 2, as expected
    
  end
 
Don't forget about concurrency. Yes this sounds strange for Fallout, but it exist. If you write several statements one-by-one its not always means uninterruptible execution. And as I know interface functions never blocks execution because they update screen. So here you catch "new frame" event, and all of your temporary arrays are invalidated. Critical section is a only solution I think. But if you put whole sequence in critical section this will produce new problem - you will get only last frame from sequence. You need to fix array before drawing and release it after.

PS. pleased that my plugin are used by someone :)
 
Senpay said:
Critical section is a only solution I think. But if you put whole sequence in critical section this will produce new problem - you will get only last frame from sequence. You need to fix array before drawing and release it after.
How to make critical section in Fallout2? What do you mean - fix array?
 
Now it works as it should. I've used fix_array...free_array. Thanks Timeslip and Senpay :)

Little note: when i'm using startcritical...endcritical, cursor stucks during animation sequence.
 
Little note: when i'm using startcritical...endcritical, cursor stucks during animation sequence.
This is because in critical section screen doesn't update. But if you will fix array right after its creation, and before any drawing, you don't need to use critical sections.
 
Back
Top