Line 14: |
Line 14: |
| } | | } |
| </syntaxhighlight> | | </syntaxhighlight> |
− |
| |
− |
| |
| For each basic object instance, a codec can be constructed using <code>RecordCodecBuilder::create</code>. This takes in a function that converts an <code>Instance</code> of an object, which is a group of codecs for each serializable field, to an <code>App</code>, which is an unary type constructor for allowing algorithms to be generalized using generics. | | For each basic object instance, a codec can be constructed using <code>RecordCodecBuilder::create</code>. This takes in a function that converts an <code>Instance</code> of an object, which is a group of codecs for each serializable field, to an <code>App</code>, which is an unary type constructor for allowing algorithms to be generalized using generics. |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
Line 22: |
Line 20: |
| }); | | }); |
| </syntaxhighlight> | | </syntaxhighlight> |
− |
| |
− |
| |
| To add a list of valid codecs, which is denoted by <code>P</code>where n is the number of fields in the instance,<code>Instance#group</code>is used which takes in codecs converted into an <code>App</code> of some kind. This example will examine three such scenarios. | | To add a list of valid codecs, which is denoted by <code>P</code>where n is the number of fields in the instance,<code>Instance#group</code>is used which takes in codecs converted into an <code>App</code> of some kind. This example will examine three such scenarios. |
− |
| |
| | | |
| First, there is a primitive integer field. All primitive codecs are declared within the <code>Codec</code> class along with a few extra primitive streams (in this case we will use <code>Codec#INT</code>). To convert this codec into a valid key-pair form, the parameter name needs to be specified. This can be done using <code>Codec#fieldOf</code> which will take in a string which represents the key of this field. This will convert the codec into a MapCodec which as the name states creates a key-value pair to deserialize the instance from. From there, how to serialize the instance from the class object must also be specified. This can be done using <code>MapCodec#forGetter</code> which takes in a function that converts the class object to the type instance, hence the getter method name. This creates a <code>RecordCodecBuilder</code> which will be the final state of the codec as it is an instance of <code>App</code>. | | First, there is a primitive integer field. All primitive codecs are declared within the <code>Codec</code> class along with a few extra primitive streams (in this case we will use <code>Codec#INT</code>). To convert this codec into a valid key-pair form, the parameter name needs to be specified. This can be done using <code>Codec#fieldOf</code> which will take in a string which represents the key of this field. This will convert the codec into a MapCodec which as the name states creates a key-value pair to deserialize the instance from. From there, how to serialize the instance from the class object must also be specified. This can be done using <code>MapCodec#forGetter</code> which takes in a function that converts the class object to the type instance, hence the getter method name. This creates a <code>RecordCodecBuilder</code> which will be the final state of the codec as it is an instance of <code>App</code>. |
− |
| |
− |
| |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
| public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { | | public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { |
Line 36: |
Line 29: |
| }); | | }); |
| </syntaxhighlight> | | </syntaxhighlight> |
− |
| |
− |
| |
| Next, there is a list of <code>BlockPos</code> which has a premade codec within itself. However, a <code>Codec</code> needs to be converted into a <code>Codec</code>. Luckily, there are a few helpers within the codec class that allows some of these conversions to be trivial. In this case, <code>Codec#listOf</code> will convert a codec of some generic into a list of that generic. The process for attaching the codec is exactly the same. | | Next, there is a list of <code>BlockPos</code> which has a premade codec within itself. However, a <code>Codec</code> needs to be converted into a <code>Codec</code>. Luckily, there are a few helpers within the codec class that allows some of these conversions to be trivial. In this case, <code>Codec#listOf</code> will convert a codec of some generic into a list of that generic. The process for attaching the codec is exactly the same. |
− |
| |
− |
| |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
| public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { | | public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { |
Line 48: |
Line 37: |
| }); | | }); |
| </syntaxhighlight> | | </syntaxhighlight> |
− |
| |
− |
| |
| A few other notable mentions that might be used within a codec: | | A few other notable mentions that might be used within a codec: |
| {| class="wikitable" style="margin-left: auto; margin-right: auto; width: 1415px;" data-mce-style="margin-left: auto; margin-right: auto; width: 1415px;" | | {| class="wikitable" style="margin-left: auto; margin-right: auto; width: 1415px;" data-mce-style="margin-left: auto; margin-right: auto; width: 1415px;" |
Line 75: |
Line 62: |
| |} | | |} |
| Last, there is a Item. This is optional and should default to <code>Items#AIR</code> when not defined. Here, there will be two techniques used to grab the associated codec. By default, a <code>Registry</code> is an instance of a codec. Therefore, the codec can be grabbed by specifying the registry instance (e.g. <code>Registry#ITEM</code>). What if there is no vanilla registry instance however? Then, another codec method can be used: <code>Codec#xmap</code>. This allows the associated object to be mapped to another object. A function specifies mapping the associated object to the new object for decoding and vice versa for encoding. For example, the <code>ResourceLocation</code> codec can be mapped to an <code>Item</code> through the forge registry instance. | | Last, there is a Item. This is optional and should default to <code>Items#AIR</code> when not defined. Here, there will be two techniques used to grab the associated codec. By default, a <code>Registry</code> is an instance of a codec. Therefore, the codec can be grabbed by specifying the registry instance (e.g. <code>Registry#ITEM</code>). What if there is no vanilla registry instance however? Then, another codec method can be used: <code>Codec#xmap</code>. This allows the associated object to be mapped to another object. A function specifies mapping the associated object to the new object for decoding and vice versa for encoding. For example, the <code>ResourceLocation</code> codec can be mapped to an <code>Item</code> through the forge registry instance. |
− |
| |
| | | |
| To define a field as optional, <code>Codec#optionalFieldOf</code> should be used. One instance holds the value as an <code>Optional</code> while the other allows a defined default value. | | To define a field as optional, <code>Codec#optionalFieldOf</code> should be used. One instance holds the value as an <code>Optional</code> while the other allows a defined default value. |
− |
| |
− |
| |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
| public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { | | public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { |
Line 87: |
Line 71: |
| }); | | }); |
| </syntaxhighlight> | | </syntaxhighlight> |
− |
| |
− |
| |
| Now, there is a product <code>P3</code> as there is three parameters. To convert this into an <code>App</code>, the method <code>P#apply</code> should be called. This takes in an <code>Applicative</code> which our builder is an instance of and a function that returns the class object given the specified wrapped arguments. Creating a new constructor is one way of creating the outputted codec for the class object. | | Now, there is a product <code>P3</code> as there is three parameters. To convert this into an <code>App</code>, the method <code>P#apply</code> should be called. This takes in an <code>Applicative</code> which our builder is an instance of and a function that returns the class object given the specified wrapped arguments. Creating a new constructor is one way of creating the outputted codec for the class object. |
− |
| |
− |
| |
| <syntaxhighlight lang="java"> | | <syntaxhighlight lang="java"> |
| public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { | | public static final Codec<ExampleCodecClass> CODEC = RecordCodecBuilder.create(builder -> { |
Line 102: |
Line 82: |
| ==Limitations== | | ==Limitations== |
| Codecs are required to abide by a String-Object key-pair. Any codec that does not have a String key will throw an error during encoding and decoding. | | Codecs are required to abide by a String-Object key-pair. Any codec that does not have a String key will throw an error during encoding and decoding. |
− |
| |
| | | |
| A group can have at most 16 inner codecs normally. This limitation is specified by the number of product generic classes available. | | A group can have at most 16 inner codecs normally. This limitation is specified by the number of product generic classes available. |