Scripts “forget” their own types after calling RunTemplate()

In continuation of this previous bug where scripts lost track of template types, it turns out that (also?) in the latest 010 Editor, they lose track of their own types.

test.bt →

struct TemplateStruct
{
    int value;
};

TemplateStruct templateStruct;

test.1sc →

struct ScriptStruct
{
    int value;
};

void PrintScriptStruct(ScriptStruct& s)
{
    Printf("%d\n", s.value);
}

local ScriptStruct gScriptStruct;
gScriptStruct.value = 5;
PrintScriptStruct(gScriptStruct);

RunTemplate("test.bt");

PrintScriptStruct(gScriptStruct);

The first call to PrintScriptStruct() succeeds, but the second fails with “The given type does not exist.”

What’s more, if you do the following, 010 will crash:

  • Open an arbitrary binary file.
  • Open test.1sc.
  • Run the script on the binary file using the dropdown next to the play button. Click Ignore to dismiss the above error.
  • Select the tab of the binary file.
  • Select the tab of the script again.
  • Run the script through the dropdown again.

And another one: nested structs in scripts apparently don’t work.

struct StringWrapper
{
    string value;
};

struct StringList
{
    int count;
    StringWrapper items[1000];
};

local StringList gMyList;

This results in the following error at the declaration of items: “Structs must be declared with ‘local’ keyword in a script or see ‘RunTemplate’ function to execute a template from a script.”

You are right that it is possible for a Script to lose defined types after calling RunTemplate. Can you check if this update fixes the issue: http://download.sweetscape.com/010EditorWin64Installer16.0.2c.exe

Nested structs are supported in scripts but you have to use the ‘local’ keyword inside the struct like this:

struct StringWrapper
{
    string value;
};

struct StringList
{
    int count;
    local StringWrapper items[1000];  // <- need local here
};

local StringList gMyList;

Graeme
SweetScape Software

Yes, that build fixes the error, and I also can’t reproduce the crash anymore. Thank you for the fast turnaround.

For nested structs: I see, but it still seems a bit strange that local would be required for the field. Why is it not enough to place it at the top-level structure instantiation (gMyList)? Why is it needed for structure-typed fields but not for primitive ones? More generally, it’s my understanding that scripts can only have local variables, so doesn’t that make the keyword redundant? (The official example doesn’t use it either.)

Actually, this made me curious to try out nested local structures in templates, and sure enough, those have unexpected behavior too: we can create local variables that advance the file pointer.

Is this by design?