GMStruct Inheritance and Types

In a previous post, I went through the basic usage of GMStruct, but I deliberately left out some details about inheritance and types. This is what I will be covering in this post.

Basic Types

First of all, let's go over types in GMS. The first thing to note is that GMS comes with a set of basic types you can use: The String, Real, Pointer, Array and Boolean types.
You can use them to set the type of your struct attributes, in order to restrict the types of values you can pass to them at runtime. So far, nothing new.

Struct Types

However, there are more types available in GMS; every struct you define will have its own type. This allows you to define an attribute to have a struct type.
For instance, you could have a Cat and an Owner struct. The Cat struct may have an owner attribute. That owner struct would be defined to be of type Owner.
This would look like this:


So now we have basic struct types out of the way, let's have a look at inheritance.
Let's look at the example where we want to define a number of Pets.
For instance, we could have Cats, Dogs and Rabbits.

The above example will create three structs, of types Cat, Dog and Rabbit. However, we have the same attribute types three times for each struct. It would be nice to be able to type them only once.
Not only that, but we run into problems if now we want to define a Person struct, with a pet attribute. What type do we assign the pet attribute if we do not know what kind of per the person has?

This is when inheritance kicks in. By using inheritance, a struct can inherit every attribute from another struct. The struct will now also have multiple types: Its own type, but also the type of any attributes it inherits from.

Let's have a look at how we could rewrite the above example using inheritance:

Now the Cat, Dog and Rabbit classes will each have the name and size attribute, and their types will be of type Pet, on top of their own respective types.

Now writing a person class with an arbitrary pet attribute is easy:

At runtime

So this is the basic usage of GMS inheritance. But what does this offer at runtime?
GMStruct generates a number of useful functions to check the types of our structs.
First of all, Every type is stored in a global 'structs' enum.
If you generated a Cat and a Dog enum, the types would be named structs.Cat and structs.Dog.
You can get the type of any structs using the 
get_type function that will return the type of any supplied structs.Let's have a look at an example using our previous pets example:

This will first get the pet struct stored in the person class.
The type is then extracted from the pet struct, and a switch is performed on it, printing a different message based on the pet's type.

You can also check the type of a pet using the is_a function. Here is another example:

This allows you to more easily check the type of a struct, without having to extract its type first.

Finally, every struct comes with its own is_* function. For instance, a cat struct will come with the is_cat function, to check if the supplied struct is of the cat type.

Before I wrap up this post, Let's have a look at how manipulating inherited attributes work.
Let's have a look at a new example:

Here we have a simple shape struct, with name and color attributes. We also have a square and circle structs, that inherits from the shape struct.
Each of the structs will have their respective *_name and *_color attributes. 
So if we want to modify the color of a square, you could use the square_color function. However, you could also use the shape_color function and that would work just as well.
This is very useful when you know you are dealing with a shape, but don't know which one.
However, if you tried to call 
circle_radius on a square struct, GM would trhow an error.

In the future

At the moment basic types are 'hard wired' in GMStructs code. However this may not be the case for ever. Eventually they will be defined as structs themselves. This is not only neater internally, but will allow users to manipulate reals and strings much more naturally when struct functions become a thing.


Popular posts from this blog

GMStruct - extending GML with code generators

GMWolf - Defining States with Objects