diff --git a/Manual/contents/Additional_Information/Additional_Information.htm b/Manual/contents/Additional_Information/Additional_Information.htm index 5f5951c99..bf2fd1370 100644 --- a/Manual/contents/Additional_Information/Additional_Information.htm +++ b/Manual/contents/Additional_Information/Additional_Information.htm @@ -27,7 +27,6 @@

Additional Information
  • Guide To Using Shaders
  • Guide To Primitives And Vertex Building
  • Guide To Using Blendmodes
  • -
  • Guide To Using JSON
  • Project Format
  • Compatibility Functions
  • Compatibility Scripts
  • diff --git a/Manual/contents/Additional_Information/Guide_To_Using_Blendmodes.htm b/Manual/contents/Additional_Information/Guide_To_Using_Blendmodes.htm index c2d8eaadf..b18c3e2d7 100644 --- a/Manual/contents/Additional_Information/Guide_To_Using_Blendmodes.htm +++ b/Manual/contents/Additional_Information/Guide_To_Using_Blendmodes.htm @@ -153,10 +153,10 @@

    SURFACES AND ALPHA

    Back: Additional Information
    -
    Next: Guide To Using JSON
    +
    Next: Project Format
    -
    © Copyright YoYo Games Ltd. 2023 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2024 All Rights Reserved
    -

    Static Struct

    -

    Every function has a "static struct", where its static variables are stored. You can get that struct using static_get:

    -

    function counter() {
    -     static count = 0;
    -     return count ++;
    - }
    -
    - repeat (10) counter();
    -
    - // Get static struct of counter()
    - var _static_counter = static_get(counter);
    -
    - // Both of these read the same variable
    - show_debug_message(counter.count); // 10
    - show_debug_message(_static_counter.count); // 10 -

    -

    This is also true for constructor functions. Each constructor has a static struct, where its static variables and static methods are stored.

    -

    Every struct created from the constructor accesses its static variables from that static struct.

    -
    -

    Static Chain

    -

    When you use constructor inheritance, those constructors form a "static chain" - a chain of static structs where each child links to its parent.

    -

    For example, let's say you have a constructor item, and a constructor potion which is a child of item:

    -

    function item() constructor {}
    -
    - function potion() : item() constructor {}
    -
    - var _potion = new potion(); -

    -

    You can get the static struct of potion using static_get(potion) - this is where the static variables for potion are stored. Let's call this static_potion.

    -

    Now, if you call static_get(static_potion), you will get the static struct for item! This is the same struct you would get from static_get(item).

    -

    function item () constructor {}
    - function potion () : item () constructor {}
    -
    - var _potion = new potion();
    - var _static_potion = static_get(potion);
    -
    - show_debug_message(static_get(item) == static_get(_static_potion)); // true (1) -

    -

    This is because item is the parent of the potion constructor, so the static struct for item is linked to the static struct for potion.

    -

    The static structs of the top-level constructor functions, i.e. those that don't have a parent constructor, share the same parent struct. This struct is the "root" static struct, which has undefined as its parent struct: 

    -

    var _static_item = static_get(item);         // the static struct of item
    - var _root = static_get(_static_item);        // the static struct of all top-level static structs
    - var _must_be_undefined = static_get(_root);  // undefined

    -

    This shared struct is the root parent struct of all structs and defines the default toString function that's called when the struct is converted to string.

    -

    This means that you can get the full static chain of a struct as follows:

    -

    static_chain = [];
    - var _node = static_get(potion);                        // the static struct to start at
    - while (!is_undefined(_node))
    - {
    -     array_push(static_chain, _node);
    -     _node = static_get(_node);
    - };
    -
    - array_foreach(static_chain, show_debug_message);       // output the path to the root struct -

    -

    Same Variable Name in Parent & Child Constructor

    -

    As static variables belong to the constructor in which they're defined, it is possible to define a static variable in a child constructor with the same name as a static variable of the parent constructor. For example: 

    -

    function shape () constructor
    - {
    -     static count = 0;
    -     count++;
    -     
    -     static shapes = [];
    -     array_push(shapes, self);
    - }
    - function rectangle () : shape () constructor
    - {
    -     static count = 0;
    -     count++;
    - }
    - function square () : rectangle () constructor
    - {
    -     static count = 0;
    -     count++;
    - }
    - function ellipse () : shape () constructor
    - {
    -     static count = 0;
    -     count++;
    - }

    -

    Each shape now has its own count static variable that keeps track of the number of items of that shape. Child shapes will increment the count of their parent shapes as well, as they run their parents' constructors in addition to their own.

    -

    s1 = new shape();        // Added 1 shape
    - s2 = new rectangle();    // Added 1 rectangle (and therefore also 1 shape)
    - s3 = new square();       // Added 1 square (and therefore also 1 rectangle and 1 shape)
    - s4 = new ellipse();      // Added 1 ellipse (and therefore also 1 shape)
    -
    - show_debug_message($"Number of shapes: {shape.count}");          // 4
    - show_debug_message($"Number of rectangles: {rectangle.count}");  // 2
    - show_debug_message($"Number of squares: {square.count}");        // 1
    - show_debug_message($"Number of ellipses: {ellipse.count}");      // 1 -

    -

    How the Dot Operator Looks Up a Variable Name

    -

    Let's say you're looking for a specific variable in a struct, using the dot operator (i.e. struct.variable_name).

    -

    If the struct contains a non-static variable with that name, the dot operator returns that variable. If it doesn't, the dot operator returns the first variable in the static chain with that name, checking the current static struct, and then traversing back the entire static chain, if needed, until a variable with that name is encountered. If the variable name cannot be found anywhere in the static chain, GameMaker will throw an error.

    -

    For example:

    -

    function root() constructor {
    -     static show = function() {
    -         show_debug_message("root");
    -     }
    - }
    -
    - function child() : root() constructor { }
    -
    - function child_with_static_func() : root() constructor {
    -     static show = function() {
    -         show_debug_message("child_with_static_func");
    -     }
    - }
    -
    - function child_with_func() : root() constructor {
    -     show = function() {
    -         show_debug_message("child_with_func");
    -     }
    - }
    -
    - child1 = new child();
    - child1.show();
    -
    - child2 = new child_with_static_func();
    - child2.show();
    -
    - child3 = new child_with_func();
    - child3.show(); -

    -

    The following happens in the above code: 

    - -

    Parent's Static Variable or Method

    -

    In certain situations you may want to access a static variable or method of the parent constructor from within the child constructor. To achieve this, you can go up the static chain and access the parent's static variable: 

    -

    function parent() constructor
    - {
    -     static init = function() { show_debug_message("Parent Innit?"); }
    - }
    -
    - function child() : parent() constructor
    - {
    -     static init = function()
    -     {
    -         var _static = static_get(self);
    -         var _static_parent = static_get(_static);
    -         _static_parent.init(); // Calls the parent's init()
    -         
    -         show_debug_message("Child Innit!");
    -     }
    - } -

    -

    Checking Inheritance

    -

    You can use is_instanceof to check if a struct belongs to the given constructor, or has the constructor as a parent.

    -

    This is done by checking if your struct has the given constructor's static struct anywhere in its static chain.

    -
    -

    Changing The Static Struct

    -

    The function static_set is provided to let you change the static struct of a function (constructor or not). This way you can change what static variables are available to a constructor and its structs, and also change the "static chain" that a constructor belongs to.

    -

    The recommended use-case for this function is deserialisation. If you're loading structs from JSON, those structs won't belong to any constructors, however you can change that by using static_set to "apply" a constructor to a struct, so that that struct receives its shared static variables and you can run is_instanceof to check its kind.

    -
    -

     

    -

     

    - - - - - \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Encoding_And_Hashing/Encoding_And_Hashing.htm b/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Encoding_And_Hashing/Encoding_And_Hashing.htm index 6b885fdb6..21f283d3f 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Encoding_And_Hashing/Encoding_And_Hashing.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Encoding_And_Hashing/Encoding_And_Hashing.htm @@ -19,7 +19,6 @@

    Encoding And Hashing  Encoding is NOT encryption! A base64 encoding renders the file unreadable to the naked eye and will require an effort on behalf of the user to decode, but it is not secure from hacking. It is recommended that you mix those functions with your own encryption (there are many forms of encryption and script functions for GameMaker available on the internet).

    Function Reference

    JSON

    -

     See Guide To Using JSON for detailed information on how to use JSON in GameMaker.