Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: yarooze on Tue 10/12/2024 14:21:23

Title: Struct attributes - syntactic sugar?
Post by: yarooze on Tue 10/12/2024 14:21:23
Hi!

I'm a little bit confused with the struct attributes.


1. What is the point to use them instead of simple fields and methods? Only to mask getter/setter?


Here are the examples from the doc.

With attribute:
struct Weapon
{
    protected int damage; // this is our actual property to store the damage
    import attribute int Damage; // this is our attribute
    import int get_Damage();
    import void set_Damage(int damage);
};

int Weapon::get_Damage()
{
    return this.damage;
}

void Weapon::set_Damage(int damage)
{
    this.damage = damage;
}


Weapon *weapon = new Weapon;
weapon.Damage = 10;

Without:
struct Weapon
{
    protected int damage;
    import int GetDamage();
    import void SetDamage(int);
};

int Weapon::GetDamage()
{
    return this.damage;
}

void Weapon::SetDamage(int damage)
{
    this.damage = damage;
}

Weapon *weapon = new Weapon;
weapon.SetDamage(10);
Display("%d", weapon.GetDamage());


The example without attribute is shorter but makes the same, or am I missing something?


2. what is this "this" injection for? To access fields without "this."? But there is no injection in the constructor, but "_data" is called without "this.". Can I inject "this" into simple getter and access protected fields? How can I access a global variable with the same name?  :confused:

managed struct MyStruct
{
     import void MyStruct(int data); // this is constructor
     import readonly attribute int Data;

     writeprotected int _data;
};

// script
void MyStruct::MyStruct(int data)
{
     _data = data;
}

int get_Data(this MyStruct*)
{
     return _data;
}






Title: Re: Struct attributes - syntactic sugar?
Post by: Crimson Wizard on Tue 10/12/2024 15:59:54
Yes, attributes (aka properties) are syntactic sugar over get/set functions.

Compared to a get/set pair they provide a single "attribute" name used for both get and set:
Code (ags) Select
// functions
object.SetValue(new_value);
int value = object.GetValue();
// attribute
object.Value = new_value;
int value = object.Value;

Attributes combine variable syntax and abilities of a function.

Like variables, attributes may use assignment operators, including combined operators like += or ++:
Code (ags) Select
object.Value++;
object.Value -= 10;

Like functions, attributes may have side effects (additional processing hidden behind them), they don't have to have a strict field associated with them. You may have a single attribute that changes multiple data on assignment, or multiple attributes that write or read same data in different ways.



You do not have to declare get_ and set_ functions in the struct. You may omit these, and then define them inside a script body as extender functions. That will save amount of code for the struct declaration.
This is also explained in the manual: https://adventuregamestudio.github.io/ags-manual/OOProgramming.html#access-with-extender-functions



Quote from: yarooze on Tue 10/12/2024 14:21:232. what is this "this" injection for?

The "this" in parameter list is used in extender function declaration only in order to tell which struct this function belongs to.
https://adventuregamestudio.github.io/ags-manual/ExtenderFunctions.html

If you write a function which was declared in a struct, then you use "Struct::Function" syntax, and you don't have to use "this" in parameter list, since compiler will already know that it belongs to "Struct".

In the example that you post, "void MyStruct" is already declared in the struct, so you use "MyStruct::MyStruct" syntax when writing its body.
But function "get_Data" is not declared in the struct, so you use extender syntax "get_Data(this MyStruct*)" in order to tell that this belongs to MyStruct.


In AGS 3 you must use "this." always in member functions. In AGS 4 the new compiler allows to omit "this."
However there's currently a problem in case member name matches global variable. IIRC in such case a global variable will take priority. So you better use "this.". We have a issue ticket opened for this reason:
https://github.com/adventuregamestudio/ags/issues/2067#issuecomment-1660533516
Title: Re: Struct attributes - syntactic sugar?
Post by: yarooze on Wed 11/12/2024 20:46:25
Thank you, Crimson Wizard. No questions left for this topic. (https://i.postimg.cc/DwVbxVf6/good.gif)