Generated code
The Java schema-generated code consists of two main parts: data classes and component classes. Data
classes are used to represent data at rest and correspond to the schemalang type
definitions;
component classes correspond to schemalang component
definitions and contain metadata and classes
for sending and receiving component data (updates, command requests and command responses).
A data class will be generated for each type defined in the schema, with fields corresponding to each field in the schema definition.
For each component, we generate:
- a metaclass implementing
improbable.worker.ComponentMetaclass
. These metaclasses are used when referring to specific components when using the API - every generic type parameterC
expects a metaclass argument. - an
Update
class nested inside the metaclass. This has an optional field for each field in the component (since it represents a diff). - command
Request
andResponse
classes nested inside the metaclass. These have an optional field for each command defined by the component (using the request type and response type of the command respectively); however, only one field can be set at a time. Note that the behaviour of responding to a command request using the response field for a different command is undefined.
Data representation
- Strings are represented as UTF-8 encoded
String
members. Make sure to use this same encoding when updating a component. list<T>
fields are represented as ajava.util.List<T>
of the repeated type.map<Key, Value>
fields are represented asjava.util.Map<Key, Value>
.option<T>
fields are represented asimprobable.collections.Option<T>
.
Example
Consider the following simple schema (in package example;
):
type StatusEffect {
string name = 1;
int32 multiplier = 2;
}
component Creature {
id = 12345;
int32 health = 1;
list<StatusEffect> effects = 2;
}
The generated code will contain the Creature
ComponentMetaclass
and the Creature.Update
class. Moreover, there will be a StatusEffect
class
representing the StatusEffect
type,
and CreatureData
type for the (auto-generated) underlying type of the component.
Here are some ways that these classes can be used with the API:
public static void generatedCodeExamples(Connection connection) {
Dispatcher dispatcher = new Dispatcher();
dispatcher.onAuthorityChange(Creature.COMPONENT, op -> {
switch (op.authority) {
case AUTHORITATIVE:
// We were granted authority over the status component. Send an update.
Creature.Update update = new Creature.Update();
update.setHealth(10);
connection.sendComponentUpdate(Creature.COMPONENT, op.entityId, update);
break;
case AUTHORITY_LOSS_IMMINENT:
// Authority loss imminent.
break;
case NOT_AUTHORITATIVE:
// Authority was revoked.
break;
}
});
dispatcher.onComponentUpdate(Creature.COMPONENT, op -> {
// Again, use the extension method Get() to get the concrete type of update.
Creature.Update update = op.update;
if (update.getEffects().isPresent()) {
// The `effects` field was updated.
}
});
}