====== User-Defined Types ====== User-defined types (or UDT's) allow you to create your own data structures. In its simplest form, a type definition is a bunch of field definitions inside a ''TYPE ... END TYPE'' block. The following example illustrates a very simple type definition: TYPE EMPLOYEE firstname AS STRING * 16 lastname AS STRING * 16 salary AS LONG END TYPE A type can have any number of fields, but there is one restriction: the size of a single instance of the type may not exceed 64 bytes. In the above example, //firstname// and //lastname// take up 17 bytes each, and //salary//, being of LONG type takes 3 bytes. That's 37 bytes total, well below the limit. Having defined the new type as above, you can define variables of EMPLOYEE type and assign values to its fields using the dot (''.'') notation: DIM emp AS EMPLOYEE emp.firstname = "Mark" emp.lastname = "Cunnigham" emp.salary = 45500 To read a field value you can use the same dot-notation: PRINT emp.firstname : REM outputs: "Mark" Variables defined as UDT's are called //instances// of that type. In the above example, ''emp'' is an //instance// of the EMPLOYEE type. ===== Arrays of user defined types variables ===== Multiple instances of UDT's can be organized in arrays, for example: DIM employees(50) AS EMPLOYEE Now to access field values of a specific member in the array, you can combine the array notation and the dot notation: DIM sum AS LONG : sum = 0 FOR i AS BYTE = 0 TO 49 sum = sum + employees(i).salary NEXT i PRINT "the average salary at the company is "; sum / 50 Arrays can be dimensioned as user-defined type, however TYPE definitions cannot contain array fields. ===== Nested UDT's ===== A field in a TYPE definition can be of another TYPE, and so on, as long as a single insance does not exceed the 64 bytes limit explained above. TYPE VECTOR x AS INT y AS INT END TYPE TYPE SPRITE pos AS VECTOR color AS BYTE END TYPE To access fields within the nested type, you can extend the dot notation like in the following example: DIM monster AS SPRITE monster.pos.x = 160 monster.pos.y = 100 monster.color = 3 ===== Type methods ===== You can define [[Subroutines]] and [[Functions]] within a type declaration that allows you to define routines that work with data in a single instance of that type. These routines are called //type methods// and are very similar to object methods in object-oriented programming. Extending the example above, let's write a routine that moves the imaginary monster on the horizontal axis: TYPE VECTOR x AS INT y AS INT END TYPE TYPE SPRITE pos AS VECTOR color AS BYTE SUB move (amount AS INT) STATIC THIS.pos.x = THIS.pos.x + amount END SUB END TYPE DIM monster AS SPRITE monster.pos.x = 100 CALL monster.move(5) PRINT monster.pos.x : REM outputs 105 ===== The THIS keyword ===== Note the usage of the [[THIS]] keyword in the above example. ''THIS'' is a special variable that refers to the instance on which the method was called. In the above example, ''THIS'' refers to the variable that the ''move'' method was called on, in this case: //monster//. Adding methods to a TYPE definition does not increase an instance's size and therefore methods do not count in the 64 bytes size limit. Defining functions within type definitions allows you to write methods that return a value. The following example is a theoretical game where two players fight each other, hitting in rounds, with a random damage. The method ''hit(damage)'' subtracts the damage from a fighter's energy and the method ''isdead()'' tells if the fighter is out of energy. TYPE FIGHTER energy as INT SUB hit (damage AS BYTE) STATIC THIS.energy = THIS.energy - CINT(damage) END SUB FUNCTION isdead AS BYTE () STATIC RETURN THIS.energy <= 0 END FUNCTION END TYPE DIM player1 AS FIGHTER DIM player2 AS FIGHTER player1.energy = 1000 player2.energy = 1000 RANDOMIZE TI() DO CALL player1.hit(CBYTE(RNDL())) CALL player2.hit(CBYTE(RNDL())) PRINT "p1 energy: "; player1.energy; ", p2 energy: "; player2.energy LOOP UNTIL player1.isdead() OR player2.isdead() PRINT "game over" As seen above, you can organize code in a very well-structured way with the help of UDT's. <- functions|Previous page ^ udt|User-Defined Types ^ code_modules|Next page ->