AGS language cheat sheet

Started by Monsieur OUXX, Tue 12/04/2016 17:04:23

Previous topic - Next topic

Monsieur OUXX

Help me redact this cheat sheet.


AGS 3.4 PATCH2 (current released version)

Use caseC#AGS languageComments
Classclassstruct
(don't forget the semicolon at the end!)
Non-instantiable class
(for example, if you want to make a factory
or a set of static utility methods)
abstractbuiltin (that's a trick, that keyword was not originally intented for that)
static member in a classstaticuse a static attribute + a local variable in the script bodySee http://www.adventuregamestudio.co.uk/wiki/Keyword:_attribute
properties (getters and setters)use propertiesattribute+extenderSee http://www.adventuregamestudio.co.uk/wiki/Keyword:_attribute
yeah, yeah, I know that my description in the first column is a poor summary of what properties are.
Array propertiespropertySame as above, but use geti_ and seti_See http://www.adventuregamestudio.co.uk/wiki/Keyword:_attribute
ConstructorsnewYou can use this keyword only for arrays of primitive types (e.g. int[]), unmanaged structs (see below in the table), arrays of unmanaged structs (see below in the table), arrays of built-in types' pointers.
int i[] = new int[20];
DummyStruct1 d = new DummyStruct1; //provided DummyStruct1 was declared "unmanaged"
DummyStruct1 a[] = new DummyStruct1[1];
DynamicSprite* s[] = new dynamicSprite[1];


arrays as parameters : void MyFunc(int a[]) {...}by reference (changes propagate back)by referenceI didn't test what "returning" an array does, but it probably creates a copy
string as parameter : void MyFunc(String s) {...}by copyby copyyeah, yeah, I know that it isn't as simple as "by copy" for strings in C#.
dynamic arrays of custom class
(see also: "dynamic arrays of (built-in) pointers")
MyClass obj[] = new MyClass[20];not possible if 'unmanaged' struct
//this does not work:
struct DummyStruct1{
    int i;
};
...
DummyStruct1 a[];
a = new DummyStruct1[1];
DummyStruct1 d;
a[0] = d;

Possible if 'managed' struct
autoptr managed struct DummyStruct1{
    int i;
    import void Func();
};

void DummyStruct1::Func()
{
    Console.W("i=%d", this.i);
}
void Test3()
{
    DummyStruct1 a[];
    a = new DummyStruct1[1];
    DummyStruct1 d = new DummyStruct1;
    a[0] = d;
    a[0].Func();
}

...unless it contains a dynamic array
autoptr managed struct DummyStruct1{
    int i[]; //won't compile
    import void Func();
};
fixed-sized arrays of custom class
(see also: "dynamic arrays of built-in class")
MyClass obj[20];MyClass obj[20];
UNLESS : ... unless what, by the way? what forbids it?
a class member inside a classclass ClassA{
    int i;
}
class ClassB {
    ClassA a; //this (needs to call "new" later on)
}
not possible
(except as pointers to built-in types:
struct ClassB {
     DynamicSprite* sp;
     GUI* g;
     String s;
};
void game_start() {
  ClassB b;
  b.sp = DynamicSprite.Create(...)
  b.g = ...; //any existing GUI
  b.s = "mlkmlkmk";
}
fixed-sized arrays of built-in classMyClass obj[20]; //actually references
possible...
  s2 = new String[10];  s2[0] = "test";

  DynamicSprite* sp3[10];  sp3[0] = DynamicSprite.Create(10, 10);
...including in structs...
  struct MyClass {
    DynamicSprite* sp[3];
    String s[3];
  };
  MyClass t;
  t.s[0] = "test";
  t.sp[0] = DynamicSprite.Create(10, 10);
...and arrays of structs structs...
  MyClass t[10];
  t[0].s[0] = "test";
  t[0].sp[0] = DynamicSprite.Create(10, 10);
dynamic arrays of built-in classMyClass obj[] = new MyClass[20];
//This C# example actulaly
//shows references,
//but who cares

Instantiable built-in types:
  Possible...
  String s2[];  s2 = new String[10];
  ...including in structs
   struct MyClass {
    String s[];
   };
   MyClass o; o.s = newString[10];

Non-Instantiable built-in types:
   Possible...
   DynamicSprite* sp[];
   sp = new DynamicSprite[10];
   sp[0] = DynamicSprite.Create(10, 10);

   ...except in structs
   struct MyClass {
      DynamicSprite* sp[];
       //this will compile but
       //you can't instantiate
       //at runtime :'(
   };
   
 

Monsieur OUXX

No one has anything to add on this topic?
 

Crimson Wizard

Sorry, haven't had time to read this yet.

Gurok

#3
EDIT: I just realised this cheat sheet was probably written about 3.3.x. The notes I made apply to AGS 3.4.0 and above. Think of them as future redactions to your cheat sheet.

Spoiler
managed isn't the equivalent of abstract. The closest analogue in AGS to abstract would be builtin, but even that's not right because you can't extend builtin structs.

managed means that any variables you use of that type must be pointers. Conversely, structs without managed are always allocated either statically or on the stack. Yes, this is a quirk. I think we'd be better served by managed simply allowing pointers (as well as regular stack variables), or even deprecating managed.

Dynamic arrays of a custom class are possible, but you must use a pointer to the struct variable:

Code: ags
managed struct MyClass
{
};

function game_start()
{ 
	MyClass *a[†‹] = new MyClass[20];
        .
        .
        .


Also, new will work not just for arrays of primitive types, but arrays of managed structs (as seen above) and instantiating single managed structs.
[close]
[img]http://7d4iqnx.gif;rWRLUuw.gi

Monsieur OUXX

Quote
abstract
I'm not trying to explain what's an abstract class to do abstract classes in AGS. What I'm doing is what's presented in the first column of the table: prevent a class from being instantiated.
As you said I probably made a mistake: The cheat is to add "builtin" in front of it, not "managed".

Quote from: Gurok on Mon 18/04/2016 02:16:55
EDIT: I just realised this cheat sheet was probably written about 3.3.x. The notes I made apply to AGS 3.4.0 and above.
Nope. I definitely tested 3.4.x.
But your post clearly shows how I got lost in the information about new features. I knew instantiating structs was now possible, but just couldn't find it, or how. so I thought I had imagined it.

Quote
MyClass *a[†‹] = new MyClass[20];
So admitedly this is now possible. But what I'm interested in, is what is not possible.
For example, can I have an array of DynamicSprite, String, ViewFrame, File in such a class?
Can I have an array of MyClass* in another custom struct?
How do I put an instance of Myclass in the array? Like this? (below)
Quote
MyClass c;
a[0] = c;

 

Monsieur OUXX

#5
Gurok : After verifying, it's not possible to do this :


Code: ags

//None of this is valid even in 3.4.0.6+
managed struct MyStruct
{
  DynamicSprite* sp;
};

managed struct MyStruct
{
  int a[];
};



Therefore, it kind of defeats the purpose...
 

Crimson Wizard

#6
Quote from: Monsieur OUXX on Mon 18/04/2016 11:54:31
Therefore, it kind of defeats the purpose...
The user's managed structs are still limited. This is not because we want them to be limited, but because allowing pointers inside them would require a big amount of extra work, which none of us could find time for yet.

We found that it is easy to just let user have managed structs with no pointers for now, so we added that.

Monsieur OUXX

Quote from: Crimson Wizard on Mon 18/04/2016 15:48:42
The user's managed structs are still limited. This is not because we want them to be limited, but because allowing pointers inside them would require a big amount of extra work, which none of us could find time for yet.
We found that it is easy to just let user have managed structs with no pointers for now, so we added that.

Hey just to be clear: I'm not criticizing all the work -- and I know that it's only missing for lack of time! The fact that I'm trying to sort out what's possible does not mean that I'm not grateful for this amazing engine and the great recent enhancements.
 

Crimson Wizard

#8
Quote from: Monsieur OUXX on Mon 18/04/2016 21:16:09
Hey just to be clear: I'm not criticizing all the work -- and I know that it's only missing for lack of time! The fact that I'm trying to sort out what's possible does not mean that I'm not grateful for this amazing engine and the great recent enhancements.

Well, I am making that clarification too, because I do not want people think that it was our plan to leave it like that forever.

As for the usage, you can still create managed structs containing simple types, including fixed-sized arrays of simple types.
The most common example is:
Code: ags

managed struct Point
{
    int x;
    int y;
};


In 3.4.0 you can create these dynamically using "new" and pass it to another function with pointer to struct.
Code: ags

Point* CreatePoint(int x, int y)
{
    Point* p = new Point;
    p.x = x;
    p.y = y;
    return p;
}

void DoSomethingWithPoint(Point* p)
{
    // ...
}

Crimson Wizard

#9
I completely forgot about this sheet, but since we found there is a misunderstanding about some parts, I decided to check it through again.

1. "Non-instantiable class (for example, if you want to make a factory or a set of static utility methods)"
If you mean non-instantiable as in purpose, then the C# equivalent will be "static class". Abstract class cannot be instantiated too, but it is meant for overriding, while static classes are meant for a "set of static utility methods".

That said, if you have a struct in AGS that has only static members (that is - static functions, because AGS does not support static variables), instantiating it is allowed, but it won't do anything good or bad, because you simply won't be able to do anything with that except calling same static members.

2. "static member in a class -- use a static attribute + a local variable in the script body"
Probably meaning static variable? Because there are also static functions. Unless by "member" you mean specifically "something that stores data" (I think usually member means "anything inside class").

3. Properties, and Array properties.
I guess this is more suitable for the Wiki article you linked, but I think I will mentions this here first.

That may not be immediately obvious, but for array properties you do not have to accept strictly real indices, or indices that refer to actual arrays.
It is possible to make an array property and translate given index into something else.
For a practical example, think of accepting arbitrary unique ID of some object as an "index", and then converting it to real index by finding such ID in the fixed-sized array.



Crimson Wizard

#10
Going on...

4. Arrays as parameters
QuoteI didn't test what "returning" an array does, but it probably creates a copy
Returning arrays also pass by reference. In fact AGS does not pass by copy anything but basic types: int, float, pointers. By pointers I mean that pointers themselves are indeed copied, but the actual objects they point to are not (in other words, you end up having 2 or more pointers to the same object).

5. String as parameter
"String" is a pointer to string in AGS, although * sign is hidden for convenience (String struct is declared with autoptr modifier which does the trick). This is why Strings are also passed by reference, not by copy.

It's just that Strings are inmutable, meaning that you apply any operation on them (like Append), a new string is created. But as long as you do not modify string, it is all the same object.

6. Dynamic arrays of custom class
You can create dynamic arrays of both managed and unmanaged structs. What you cannot currently do, is create dynamic array of a struct that has managed member pointer (not property, but regular variable).

7. A class member inside a class
There is a difference between non-managed class variable inside a class, and managed pointer inside a class.
You can have managed pointers to both built-in and user structs in a non-managed struct.
For some reasons, that I do not really understand, you cannot have non-managed structs inside any other structs. (I mean, I do not see any immediate technical difficulties that would prevent that, but... maybe there are some).

8. Fixed-sized arrays of built-in class and Dynamic arrays of built-in class.
I see that there is a misunderstanding regarding what "built-in" class is and what makes it special.
You may have both fixed-sized and dynamic arrays of ANY managed struct, including both built-in and declared by user.
What you cannot have, is managed struct that contains managed member pointers.

You could merge "dynamic arrays of custom class" and "Dynamic arrays of built-in class" into "Dynamic arrays of managed class", because they all follow same rules.

What makes builtin classes special is that neither actually have managed member pointers. All of them have only properties that work (get/set) with managed pointers. However, when such object is created by an engine, it may have references to other objects, including managed ones, it's just that these are dealt by engine, not AGS script, so that is not affected by any restrictions.

"Builtin" simply means that you cannot create an object of that class yourself. Only engine can do that, and also engine implements all the functionality (methods and properties) of such class.

Monsieur OUXX

Really cool additions CW. Thanks a lot.
 

SMF spam blocked by CleanTalk