-
Notifications
You must be signed in to change notification settings - Fork 0
objects
Script-defined types provide a mechanism to make programming scripts easier instead of having to resort to tricks like manipulating lists.
Enabled by: yoption objects;
| Keywords: | Discription |
|---|---|
| abstract | declares a script-defined class's method as being abstract |
| base | used to access fields and methods of rootward class |
| class | declares a script-defined class's contents |
| constructor | declares a script-defined class's constructor method |
| delegate | defines a type that can hold a function/method entrypoint |
| final | declares that a script-defined class's method may not be overidden by leafward classes |
| interface | defines a script-defined interface's method prototypes |
| new | allocates a new instance of a script-defined class and calls a constructor. Also used on member declaration to ignore any rootward definition override |
| override | declares a script-defined class's method as overriding a rootward method |
| partial | declares that this is only part of a class's definition |
| private | declares a member can be accessed only from within class |
| protected | declares a member can be accessed only from within class or a leafward class |
| public | declares a member can be accessed anywhere |
| static | declares a script-defined class's method as being static |
| this | used to access the current script-defined class's object instance |
| typedef | used to define convenience names for types |
| virtual | declares a script-defined class's method may be overridden by leafward classes |
Note: Use 'undef' instead of 'null' to mean no object being referenced. Requires the 'yoption arrays;' statement to enable.
[ partial ] class <classname> [ : <extends>, <interface> ... ] {
<accessquals> [ partial ] class ... { ... }
<accessquals> constant <fieldname> = <constinitvalue> ;
<accessquals> constructor ( <arglist> ) [ : [ base ] ( <callargs> ) ] { <methodbody> }
<accessquals> delegate ... ( ... ) ;
<accessquals> interface ... { ... }
<fieldquals> <type> <fieldname> [ = <initvalue> ] ;
<methodquals> [ <rettype> ] <methodname> [ : <intftype> [ . <intfmeth> ] ]
( <arglist> ) [ ; | { <methodbody> } ]
<methodquals> <type> <propname> [ : <intfname> [ . <intfprop> ] ]
{ [ get [ ; | { <getbody> } ] ] [ set [ ; | { <setbody> } ] ] }
<methodquals> <type> '[' <arglist> ']' [ : <intftype> ]
{ [ get [ ; | { <getbody> } ] ] [ set [ ; | { <setbody> } ] ] }
typedef <typedefname> <definition> ;
}Instance methods and instance field initializers have 'base' and 'this' available. 'this.' is implied when accessing instance fields or methods from within an instance method or field initializer as is common with similar oo languages.
<type> '[' <arglist> ']' { [ get [ ; | { <getbody> } ] ] [ set [ ; | { <setbody } ] ] }
provides array-like syntax to access the property. For example:
class ArrayList<T> {
...
T [integer index] {
get
{
Ptr<T> ptr = first;
...
return ptr.val;
}
set
{
Ptr<T> ptr = first;
...
ptr.val = value;
}
}
}
...
ArrayList<string> strings = new ArrayList<string> ();
strings[3] = "abc";
llOwnerSay (strings[3]);
Multiple and non-integer indices are permitted, such as:
T [string name, integer version] {
...
} delegate [ <rettype> ] <delegatename> ( <arglist> ) ; <basetype>[] - one dimension
<basetype>[,] - two dimensions
<basetype>[,,] - three dimensions
... etc integer rows = number of rows wanted;
integer cols = number of columns wanted;
float[,] mat = new float[,] (rows,cols); // note: NOT new float[rows,cols] integer[,] mat = new int[,] { { 1,2,3 }, { 4,5 },, { 10,11,12, } };
creates a 4 row, 3 column matrix:
[ 1 2 3 ]
[ 4 5 0 ]
[ 0 0 0 ]
[ 10 11 12 ]
The ( 4,5 } got padded with zeroes to fill the row.
The ,, after the { 4,5 } said to skip a row.
The , after the 12 is ignored.
If a comma is not preceded by a value or a sublist,
it says to skip initializing that element of the array,
whatever dimension it is in. So the second comma of
,, after the { 4,5 } said to skip initializing the
whole third row of the matrix. The comma after the
12 did not skip anything because it was preceded by
a value (ie 12), as is the case with all the other
commas.
The initialization values can be arbitrary expressions of the
array element's type. mat[row,col] .Length = total number of elements in array (all dimensions multiplied)
.Length(n) = number of elements in dimension n, n=0 for leftmost dimension
float[,] mat = new float[,](2,3);
mat.Length -> 6
mat.Length(0) -> 2
mat.Length(1) -> 3in YEngine:
string[,][] jagged = new string[,][](3,4);equivalent C#:
string[,][] jagged = new string[3,4][];Both yield a 3x4 matrix 'jagged' where each of the 12 elements can hold an one-dimensional array of strings.
The elements are referenced with indices in the same order as the
declaration:
jagged[i,j] yields a value of type string[]
jagged[i,j][k] yields a value of type string interface <intfname> [ : <interface> ... ] {
[ partial ] class ... { ... }
delegate ... ( ... ) ;
interface ... { ... }
[ <rettype> ] <methodname> ( <arglist> ) ;
<type> <propname> { [ get ; ] [ set ; ] }
<type> '[' <arglist> ']' { [ get ; ] [ set ; ] }
typedef <typedefname> <definition> ;
} typedef <typedefname> <definition> ;Wherever is found in the source, substitute in . is a type.
Note that the order of the elements of the typedef statement are reversed compared to C or C++. The type name being declared comes first followed by the definition.
typedef can be used to avoid repeating long types:
Dictionary<string,integer> CreateNameDict ()
{
Dictionary<string,integer> names =
new Dictionary<string,integer> ();
return names;
}becomes:
typedef Str2IntDict Dictionary<string,integer>;
Str2IntDict CreateNameDict ()
{
Str2IntDict names = new Str2IntDict ();
return names;
}Note that Str2IntDict and Dictionary<string,integer> can be used interchangably throughout the source code in the example as they are considered to be exactly the same type. Str2IntDict is simply a shorthand for Dictionary<string,integer>.
Class, Delegate, Interfaces, Typedef definitions can have generic prototypes in their names and the prototypes can be referenced in the body of the definition as is common with similar oo languages.
Example:
public class ArrayMapper<K,V> {
private K[] keyArray;
private V[] valArray;
public constructor (integer len)
{
keyArray = new K[] (len);
valArray = new V[] (len);
}
public SetEntry (integer index, K kee, V val)
{
keyArray[index] = kee;
valArray[index] = val;
}
...
}and to access it...
ArrayMapper<string,integer> am = new ArrayMapper<string,integer> (10);
am.SetEntry (6, "tree-fife-niner", 359); <accessquals> := { public | protected | private }
<fieldquals> := <accessquals> [ static ]
<methodquals> := <accessquals> [ <methodalloc> ]
<methodalloc> := abstract | new | new abstract | override | override abstract |
override final | static | static new | virtual | virtual new
- qualifier keywords can appear in any order, eg, public new abstract and abstract public new are equally valid
except that partial, if specified, must be placed immediately before class
- exactly one of public, protected, private must be specified for each member of a class
- methodalloc can be any one of these combinations:
(omitted) : error if any overshadowed method, cannot be overridden
abstract : error if any overshadowed method, must be overridden
new : ignore any overshadowed method, cannot be overridden
new abstract : ignore any overshadowed method, must be overridden
override : must have overshadowed abstract/virtual, may be overidden
override abstract : must have overshadowed abstract, must be overridden
override final : must have overshadowed abstract/virtual, cannot be overridden
static : error if any overshadowed method, cannot be overridden
static new : ignore any overshadowed method, cannot be overridden
virtual : error if any overshadowed method, may be overidden
virtual new : ignore any overshadowed method, may be overidden
'new' says to ignore any rootward overshadowed method.
'final' says to prohibit any non-new overiding by leafward methods that would
otherwise allow it. 'override' is the only such case.
- fieldalloc can be any one of these combinations:
(omitted) : one per instance of allocated object
static : one shared by all instances of the object
<methodbody> : statements composing the method
can use 'this' to refer to the instance's members
can use 'base' to refer to extended class's members
<getbody> : like a <methodbody> that returns the value of the property
<setbody> : like a <methodbody> that has a single parameter named 'value'
that contains the value being written to the property
<methodname> includes script-defined names but can also be one of:
<<= >>= &= *= -= += /= %= |= ^=
<< >> & * - + / % | ^
== != <= >= < > && || ~ !
... that are used when the object is used in an expression with that operator. string xmrTypeName(object) returns typename of the given object
should be as specified in script source file
integer xmrHashCode(object) gets hash code of the given argument
xmrArrayCopy(object srcarray, integer srcstart, object dstarray, integer dststart, int count)
copies elements from one array to another
srcarray and dstarray must point to same-typed arrays, ie,
the element types must match. If the arrays are multi-dimensional,
use srcarray.Index(idx0,idx1,...) and dstarray.Index(idx0,idx1,...)
for the srcstart and dststart parameters.
list xmrArray2List(object srcarray, integer srcstart, int count)
creates a list from the given subrange of the source array
the array elements used can be any mixture of type float,integer,rotation,string,vector
xmrList2Array(list srclist, integer srcstart, object dstarray, int dststart, int count)
copies elements from the source list to the destination array
dstarray must be an array of a type that can hold the types of the list elements
object[] is always valid