variable_struct_get/set doesn't work when sharing static variables/methods

Comments

5 comments

  • Devon Mullane

    This seems like a factory pattern.  It would require each constructor to contain a clone method, for example, but you could easily write something like:

    static clone = function() {
    var _new = new ThisStruct();
    _new.foo = foo.clone;
    _new.bar = bar;
    }

    If you wanted to make a more generic method, you could always check if the struct has a clone method first, use that if available, and otherwise perform a brute force clone instead.  However, even in the latter case the only difference between the static variable and the copied variable is that it's exposed if you were to look at the struct.  The static variables don't show up as part of the struct, for some reason, but the binding should be the same.  Unless there's a part of this bug I haven't seen yet, the only difference should be cosmetic and maybe a tiny extra bit of RAM.

    1
    Comment actions Permalink
  • Daniel Trksak

    Thanks for the reply. I understand that’s a solution that works, but creating a clone method in every single data structure with static variables/methods is a bit tedious. My issue isn’t that it’s an unsolvable problem, it’s that it would be real nice to be able to easily share all data between constructors in code with a single function or something.

    0
    Comment actions Permalink
  • Daniel Trksak

    I just thought of a fairly elegant solution based off of your comment. This way you could create a bunch of clone methods in a pretty simple manner, while also using my brute force universal clone function that doesn’t clone static variables, but does clone everything else.
    static clone = function()
    {
    var struct1 = new Struct();
    CloneNoStatic(struct1, self);
    return struct1;
    }
    If there was some way to get the name of a constructor from one of its created structs, this could be integrated into this universal function using asset_get_index().

    0
    Comment actions Permalink
  • Devon Mullane

    You can get the name of the constructor using instance_of() but it does not include inheritance unfortunately. Still, might be helpful.

    0
    Comment actions Permalink
  • Daniel Trksak

    Oh, that's perfect! I now have a piece of code that perfectly (to my knowledge) copies a struct (even static stuff) and returns it.

    Credit to https://github.com/JujuAdams

    Here's the code:

    /// @returm Copy of the given struct/array, including a copy of any nested structs and arrays
    ///
    /// @param struct/array The struct/array to be copied
    ///
    /// @jujuadams 2020-06-24

    function snap_deep_copy(_value)
    {
    return (new __snap_deep_copy(_value)).copy;
    }

    function __snap_deep_copy(_value) constructor
    {
    source = _value;
    copy = undefined;


    static copy_struct = function(_source)
    {
    var _structName = asset_get_index(instanceof(_source)); //Added
    var _copy = {};
    if(script_exists(_structName)) //Added
    _copy = new _structName(); //Added

    var _names = variable_struct_get_names(_source);
    var _i = 0;
    repeat(array_length(_names))
    {
    var _name = _names[_i];
    var _value = variable_struct_get(_source, _name);

    if (is_struct(_value))
    {
    _value = copy_struct(_value);
    }
    else if (is_array(_value))
    {
    _value = copy_array(_value);
    }

    variable_struct_set(_copy, _name, _value);

    ++_i;
    }

    return _copy;
    };

    static copy_array = function(_source)
    {
    var _length = array_length(_source);
    var _copy = array_create(_length,);

    var _i = 0;
    repeat(_length)
    {
    var _value = _source[_i];

    if (is_struct(_value))
    {
    _value = copy_struct(_value);
    }
    else if (is_array(_value))
    {
    _value = copy_array(_value);
    }

    _copy[@ _i] = _value;

    ++_i;
    }

    return _copy;
    };



    if (is_struct(source))
    {
    copy = copy_struct(source);
    }
    else if (is_array(source))
    {
    copy = copy_array(source);
    }
    else
    {
    copy = source;
    }
    }

    0
    Comment actions Permalink

Please sign in to leave a comment.