Properties
Properties exist as a way to sync data from server to client without having to send the entire TARDIS/its component to the client.
PropertiesHolder (V1, DEPRECATED)
(Or as i call them, properties v1) were the original properties, only support primitive types, String
and Identifier
.
PropertiesHolder
is a wrapper for a Map<String, Object>
. Doesn’t support nested data (technically it does, but it will sync the object containing the nested data as one whole, not partially).
They were deprecated as of 1.0.5
Properties & Values (V2)
(Or as i call them, properties v2). Supports nested data. Instead of being bound to a single PropertiesHolder
, any component that extends KeyedTardisComponent
will be able to use them.
The API consists of 2 main classes, Property
and Value
.
Property
is a blueprint for all values. A schema if you will. Values refer to its defining property to serialize and deserialize data.Value
is the container for any object. It tracks data, has a getter and a setter.
Example:
class ExampleHandler extends KeyedTardisComponent {
private static final Property<String> EX_STR = Property.of(Type.STRING, "ex_str", "default value");
// Use implementations to get accurate properties for primitive types.
private static final IntProperty EX_INT = new IntProperty("ex_int", component -> PropertiesHandler.get(component.tardis(), "ex_int")); // read the default value from v1
private final Value<String> exStr = EX_STR.create(this);
private final IntValue exInt = EX_INT.create(this);
@Override
public void onLoaded() {
// it is important to load the values in this method. It's ensured to be called on both sides when the component is loaded
this.exStr.of(this, EX_STR);
this.exInt.of(this, EX_INT);
}
// ...
}
Primitive Values
While you can use the Value
class with the boxed variants of primitives (Integer
, Boolean
, etc), it’s not always the desired solution.
Boxed primitives are objects, meaning they can have a null
value, while the primitives take 0
or false
as default.
If you want your properties have the same behaviour as primitives, then use primitive values.
Instead of doing Property<Integer>
and Value<Integer>
use IntProperty
and IntValue
. Same applies to float
& boolean
(as of 1.0.5).
Ranged Properties
RangedIntProperty
allows you to automatically clamp the value between a start and end integers.
Only do this if the desired behaviour breaks with values out of the range. Otherwise, make a public setter for the value, that clamps it.
The clamp range will affect values set by packets and commands too.