- Definition
You can define a struct type using the new directive #Struct :
Code: Select all
#Struct StructName {
Type1 MemberName1;
Type2 MemberName2;
Type3 MemberName3;
}
- Basic usage
Once defined, your new struct can be used in the same way as most other types.
When you define a new struct variable, all its members are initialized to default values ("", False, 0, Null, []...).
Use the symbol '.' to access its members.
Code: Select all
#Struct MyStruct {
Integer MyMember;
}
main() {
declare MyStruct MyVar;
log(MyVar.MyMember); //Output : 0
MyVar.MyMember = 1;
log(MyVar.MyMember); //Output : 1
declare MyStruct MyCopy = MyVar;
log(MyCopy.MyMember); //Output : 1
MyVar.MyMember = MyVar.MyMember + 1;
log(MyVar.MyMember); //Output : 2
log(MyCopy.MyMember); //Output : 1
}
Code: Select all
#Struct MyStruct {
Integer MyMember;
}
MyStruct ToMyStruct(Integer _Value) {
declare MyStruct Result;
Result.MyMember = _Value;
return Result;
}
Integer FromMyStruct(MyStruct _Value) {
return _Value.MyMember;
}
main() {
declare MyStruct MyVar;
MyVar.MyMember = 1;
declare MyStruct MyCopy = MyVar;
log(MyCopy == MyVar); //Output : True
MyVar = ToMyStruct(2);
log(MyCopy); //Output : {Integer MyMember 1}
log(MyCopy == MyVar); //Output : False
}
- Traits
Struct types are compatible with declare for, metadata, persistent, netread and netwrite, but only if all their members are compatible too.
- Libraries
There are two ways to use a struct from a library. The first one is to use the "::" symbol to access a struct the same way you can access a constant.
Code: Select all
#Include "MyLibFile.Script.txt" as MyLib
main() {
declare MyLib::MyStruct MyVar;
}
Code: Select all
//Order matters : be careful not to declare library aliases before the corresponding #Include
#Include "MyLibFile.Script.txt" as MyLib
#Struct MyLib::MyStruct as AliasStruct
#Const MyLib::MyConst as AliasConst
main() {
//The next line means exactly the same as declare MyLib::MyStruct MyVar;
declare AliasStruct MyVar;
}
Note that if you want to use the same struct in two different script files (or a script file and a manialink script), you will need to define the exact same struct in the different contexts, ie same struct name and same members (name and type) in the same order.
Be aware that if two libs define the very same struct, you'll see a warning telling you that there are two definitions of the same struct type that are interchangeables, since this may not be the intended behaviour.
If you need to use the same struct in two different files, you can define it in an other library file and include it in both scripts.
- Initialization
You can create a struct variable using the syntax StructName{StructMember1 = Value1, StructMember2 = Value2, StructMember3 = Value3}.
Code: Select all
#Struct MyStruct {
Real MyRealMember;
Text MyTextMember;
}
main() {
declare MyStruct MyVar = MyStruct{MyRealMember = 1.0, MyTextMember = "Example"};
}
On the topic of default values, please note that structs do NOT support implicit type to value conversion and that feature is now deprecated. Please use explicit values instead in your future scripts (yes, [] is now a valid way to create an empty list).
For example:
Code: Select all
Text[] AddEmpty(Text[] _List)
{
declare Text[] Result = _List;
Result.add("");
return Result;
}
main()
{
// Deprecated
declare Text[] MyList = AddEmpty(Text[]);
// Use this instead
declare Text[] MyList = AddEmpty([]);
}
- JSON conversion
ManiaScript includes two functions to handle conversion between structs variables and JSON objects, .tojson() and .fromjson(Text).
The first one produces the JSON Text representing the struct variable. The second one fills the members of a struct variable according to the JSON Text and returns a boolean value.
This value is True only if all struct member that were matched with a JSON element were filled correctly. Do note that missing or unneeded JSON elements will be skipped and won't impact the return value.
Code: Select all
#Struct MyStruct {
Real MyRealMember;
Text MyTextMember;
}
main() {
declare MyStruct MyVar = MyStruct{MyRealMember = 1.0, MyTextMember = "Example"};
declare JSONText = MyVar.tojson();
log (JSONText); //output : {"MyRealMember":1,"MyTextMember":"Example"}
declare MyStruct MyCopy;
declare Boolean CopyOk = MyCopy.fromjson(JSONText); //MyCopy is now a copy of MyVar
}
Note that these two functions work with array types too, but in this case the root of the JSON Text will be an array instead of an object, and some JSON readers may flag this JSON as incorrect.
That's it! I hope that this new feature will make writing scripts easier and better! If you have any question or, really, anything to say about structs, please tell us here.