Data Members
Quick reference
data-member1 | = | [expression ws ‘. ’ ws] data-name |
data-name2 | = | ’@ ’ | ‘@@ ’ variable-name |
variable-name | = | name-predicate |
name-predicate3 | = | instance-name [’? ’] |
instance-name | = | lowercase {alphanumeric} |
Both class instances (particular instantiations of classes or simply “objects”) and classes (object types) can have members that store data.
Instance data members start with @
and class data members start with @@
.
Here is a mental aid to differentiate them:
- temporary variables are all at the current scope and do not need any
@
:param1
,obj
,list
- instance data is one level deep, so use one
@
:vector.@x
,guy.@hit_points
,@member_data
- class data is two levels deep, so use two
@@
:BadGuy.@@hit_points_max
,@@random
,@@class_data
For some background history on the naming convention for data members see Why @
and @@
for data?.
Instance Data
All data members for a class instance (“class instance data members” or just “data members” or “instance data”) must start with a single “at” symbol @
. For example, particular Enemy
objects (such as bad_bart
and mean_mimi
) could store the current hit points in a data member called @hit_points
or more fully bad_bart.@hit_points
, mean_mimi.@hit_points
Any instance data members are declared in a !Data.sk
file and need to be bound to an object in any object instance constructor. Constructors start with an !
and their files are named !().sk
or !
ctor_name
().sk
. After the instance data is initialized in a constructor you can access them in other SkookumScript code as needed. The files and their names are managed automatically for you by the SkookumIDE.
- Declared in
!Data.sk
:
Real !@hit_points
- Initialized in a constructor such as
!()
:
@hit_points: 100
- Used in code:
@hit_points-- if @hit_points <= 0 [die_horrible_death]
Class data
All data members for a class (“class data members” or just “class data”) must start with two “at” symbols @@
. For example, a maximum amount of hit points for any Enemy
class could be called @@hit_point_max
or more fully Enemy.@@hit_point_max
.
NOTE Class instance objects may also access class data members so mean_mimi.@@hit_point_max
is also valid.
Any class data members are declared in a !DataC.sk
file and need to be bound to an object in the class constructor. Class constructors are named !
and their files are named !()C.sk
. The C
in the file indicates that it is for a whole class and not an instance of a class. After the class data is initialized in a class constructor you can access them in other SkookumScript code as needed. Again, the files and their names are managed automatically for you by the SkookumIDE.
- Declared in
!DataC.sk
:
Real !@@hit_point_max
- initialized in class a constructor such as
!()
:
@@hit_point_max: 100.0
- Used in code:
@hit_points : @@random.uniform_range( @@hit_point_min @@hit_point_max)
Adding new data members
To create new data members they must be declared and initialized in a constructor.
The best way to add a new data member is to use the New Class or Member pane of the Members widget in the SkookumIDE.
Comparision: C++ Data members
Instance data members starting with @
in SkookumScript are similar to C++ non-static members. C++ non-static data members often have a naming convention such as start with m_
for m
ember. Though again these are just conventions and not enforced by the compiler.
Class data members starting with @@
in SkookumScript are similar to C++ static
data members. C++ static data members often have a naming convention such as start with ms_
for m
ember s
tatic. Though these are also just conventions and not enforced by the compiler.
Data member declaration
data-filename4 | = | ’!Data ’ [‘C ’] ‘.sk ’ |
data-file | = | ws [data-definition {wsr data-definition} ws] |
data-definition5 | = | {annotation ws} [class-desc wsr] ‘! ’ data-name |
annotation6 | = | ’& ’ instance-name |
Data members must be declared for a whole class which includes specifying their class type. Multiple data members are declared in the same !Data.sk
(for instance data) or !DataC.sk
(for class data).
You can see the data member file definition for both class and instance data members in the SkookumScript syntax.
Initialization in constructors
After data members have been declared they need to bind :
to an initial object in the appropriate constructor – an instance constructor for instance data members and the class constructor for class data members. This is called data member initialization. All data members must be bound by the end of a constructor or it is considered to be an error. As a safety measure, if an object is not bound to a data member in its appropriate constructor then it is automatically bound to the nil
object so at least it is bound to something – though the nil
object may not match the expected class type of the data member.
Using data members in code
Binding objects and type inference
Since data members can be used in different routines, it is not possible for the SkookumScript parser to infer their class type if it changes just by looking at a particular routine. Data members could be bound :
to one object type in one routine and a different routine could concurrently change the object type without the parser knowing.
This means that as far as the Parser is concerned the only class type that a data member can be is the type that is specified when it is declared (in its !Data.sk
or !DataC.sk
file). The parser restricts rebinding of a data member to object types that are of the same type or a subclass of the type in its declaration.
NOTE Temporary variables and parameter variables within a routine or an arbitrary code snippet can have their types inferred by the SkookumScript parser – all the context is within the one file for the parser to see where and when variables are bound to particular types of objects.
Special considerations for raw
data members
Data members that have the raw
annotation in their declaration allow non-SkookumScript values created by the runtime (such as Unreal Engine 4 Blueprint variables) to be treated as if they were SkookumScript data members. This is for convenience and aesthetics – they are more like accessor method calls behind the scenes.
See more detail on raw data members
-
Optional expression can be used to access data member from an object – if omitted,
this
is inferred. ↩ -
’
@
’ indicates instance data member and ‘@@
’ indicates class instance data member. ↩ -
Optional ‘
?
’ used as convention to indicate predicate variable or method of return typeBoolean
(true
orfalse
). ↩ -
A file name appended with ‘
C
’ indicates that the file describes class members rather than instance members. ↩ -
Optional class-desc is compiler hint for expected type of member variable. If class omitted,
Object
inferred orBoolean
if data-name ends with ‘?
’. If data-name ends with ‘?
’ and class-desc is specified it must beBoolean
. ↩ -
The context / file where an annotation is placed limits which values are valid. ↩