Package commoble.databuddy.data

# Class CodecJsonDataManager<T>

java.lang.Object
net.minecraft.server.packs.resources.SimplePreparableReloadListener<Map<net.minecraft.resources.ResourceLocation,​com.google.gson.JsonElement>>
net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener
commoble.databuddy.data.CodecJsonDataManager<T>

All Implemented Interfaces:
  `net.minecraft.server.packs.resources.PreparableReloadListener`

public class CodecJsonDataManager<T> extends net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener

See drullkus's primer on what codecs are and how to assemble them:
https://gist.github.com/Drullkus/1bca3f2d7f048b1fe03be97c28f87910

Usage for this is as follows:

A) Make a codec for your json
e.g. if you have a json like

     {
            "value": "some:block"
     }

And we have a data class that looks like

     public class BlockHolder
     {
            public final Block block;
            public BlockHolder(Block block) {this.block = block;}
     }

Then we can make a codec via

     // use the ResourceLocation codec to create a Block codec
     Codec<Block> BLOCK_CODEC = ResourceLocation.CODEC.xmap(ForgeRegistries.BLOCKS::getValue, Block::getRegistryName);
     // use that to build a codec for BlockHolder. RecordCodecBuilder builds codecs that deserialize {}objects or CompoundNBTs.
     Codec<BlockHolder> BLOCK_HOLDER_CODEC = RecordCodecBuilder.create(instance -> instance.group(
                    // we can stuff up to 16 fields into the group method, using a codec for each field...
                    BLOCK_CODEC.fieldOf("block").forGetter(blockHolder -> blockHolder.block)
            ).apply(instance, BlockHolder::new); // use the constructor to finish assembling the codec

B) Now that we have a codec, we can register our data manager to the server as a reload listener

     public static final CodecJsonDataManager<BlockHolder> BLOCK_HOLDERS = new CodecJsonDataManager("block_holders", BLOCK_HOLDER_CODEC, LOGGER);
     public static void onAddReloadListeners(AddReloadListenerEvent event)
     {
            event.addListener(BLOCK_HOLDERS);
     }

The above event runs during server init. The data manager's map will be recreated during server init and when somebody uses the /reload command. Storing this in a static field should be safe in most cases, but if somebody were to somehow be running multiple servers at once then problems may occur.

Finally, we can use BLOCK_HOLDERS.getData("some_modid:some_json") to get the data represented by the json at data/modid/block_holders/some_json.json

The folder name that we specified as "block_holders" can potentially include subfolders in the name as well, so we (the people who made the data loader) could use our own modid as part of the folder name to avoid name collisions, e.g. using "blockholdermod/block_holders" as the folder name would result in a json with the id "bananas:banana_block" to be located at data/bananas/blockholdermod/block_holders/some_json.json

## Nested Class Summary

## Nested classes/interfaces inherited from interface net.minecraft.server.packs.resources.PreparableReloadListener

`net.minecraft.server.packs.resources.PreparableReloadListener.PreparationBarrier`

## Field Summary

Fields
Modifier and Type
Field
Description
`protected Map<net.minecraft.resources.ResourceLocation,​T>`
`data`
The raw data that we parsed from json last time resources were reloaded

## Constructor Summary

Constructors
Constructor
Description
`CodecJsonDataManager​(String folderName, com.mojang.serialization.Codec<T> codec, org.apache.logging.log4j.Logger logger)`
Creates a data manager with a standard gson parser
`CodecJsonDataManager​(String folderName, com.mojang.serialization.Codec<T> codec, org.apache.logging.log4j.Logger logger, com.google.gson.Gson gson)`
As above but with a custom GSON

## Method Summary

Modifier and Type
Method
Description
`protected void`
`apply​(Map<net.minecraft.resources.ResourceLocation,​com.google.gson.JsonElement> jsons, net.minecraft.server.packs.resources.ResourceManager resourceManager, net.minecraft.util.profiling.ProfilerFiller profiler)`
`T`
`getData​(net.minecraft.resources.ResourceLocation id)`
Get the data object for the given key
`<PACKET> CodecJsonDataManager<T>`
`subscribeAsSyncable​(net.minecraftforge.fmllegacy.network.simple.SimpleChannel channel, Function<Map<net.minecraft.resources.ResourceLocation,​T>,​PACKET> packetFactory)`
This should be called at most once, in a mod constructor (FMLCommonSetupEvent *may* work as well) Calling this method in static init may cause it to be called later than it should be.

### Methods inherited from class net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener

`getPreparedPath, prepare`

### Methods inherited from class net.minecraft.server.packs.resources.SimplePreparableReloadListener

`reload`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface net.minecraft.server.packs.resources.PreparableReloadListener

`getName`

## Field Details

### data

protected Map<net.minecraft.resources.ResourceLocation,​T> data
The raw data that we parsed from json last time resources were reloaded

## Constructor Details

### CodecJsonDataManager

public CodecJsonDataManager​(String folderName, com.mojang.serialization.Codec<T> codec, org.apache.logging.log4j.Logger logger)
Creates a data manager with a standard gson parser

Parameters:
  `folderName` - The name of the data folder that we will load from, vanilla folderNames are "recipes", "loot_tables", etc
  Jsons will be read from data/all_modids/folderName/all_jsons
  folderName can include subfolders, e.g. "some_mod_that_adds_lots_of_data_loaders/cheeses"
  `codec` - A codec to deserialize the json into your T, see javadocs above class
  `logger` - A logger that will log json parsing problems when they are caught.

### CodecJsonDataManager

public CodecJsonDataManager​(String folderName, com.mojang.serialization.Codec<T> codec, org.apache.logging.log4j.Logger logger, com.google.gson.Gson gson)
As above but with a custom GSON

Parameters:
  `folderName` - The name of the data folder that we will load from, vanilla folderNames are "recipes", "loot_tables", etc
  Jsons will be read from data/all_modids/folderName/all_jsons
  folderName can include subfolders, e.g. "some_mod_that_adds_lots_of_data_loaders/cheeses"
  `codec` - A codec to deserialize the json into your T, see javadocs above class
  `logger` - A logger that will log json parsing problems when they are caught.
  `gson` - A gson for parsing the raw json data into JsonElements. JsonElement-to-T conversion will be done by the codec, so gson type adapters shouldn't be necessary here

## Method Details

### getData

@Nullable public T getData​(net.minecraft.resources.ResourceLocation id)
Get the data object for the given key

Parameters:
  `id` - A resourcelocation identifying a json; e.g. a json at data/some_modid/folderName/some_json.json has id "some_modid:some_json"
Returns:
  The java object that was deserializd from the json with the given ID, or null if no such object is associated with that ID

### apply

protected void apply​(Map<net.minecraft.resources.ResourceLocation,​com.google.gson.JsonElement> jsons, net.minecraft.server.packs.resources.ResourceManager resourceManager, net.minecraft.util.profiling.ProfilerFiller profiler)

Specified by:
  `apply` in class `net.minecraft.server.packs.resources.SimplePreparableReloadListener<Map<net.minecraft.resources.ResourceLocation,​com.google.gson.JsonElement>>`

### subscribeAsSyncable

public <PACKET> CodecJsonDataManager<T> subscribeAsSyncable​(net.minecraftforge.fmllegacy.network.simple.SimpleChannel channel, Function<Map<net.minecraft.resources.ResourceLocation,​T>,​PACKET> packetFactory)
This should be called at most once, in a mod constructor (FMLCommonSetupEvent *may* work as well) Calling this method in static init may cause it to be called later than it should be. Calling this method A) causes the data manager to send a data-syncing packet to all players when a server /reloads data, and B) subscribes the data manager to the PlayerLoggedIn event to allow it to sync itself to players when they log in. Be aware that the invoker must still manually subscribe the relevant packet type to the channel themselves.

Type Parameters:
  `PACKET` - the packet type that will be sent on the given channel
Parameters:
  `channel` - The networking channel of your mod
  `packetFactory` - A packet constructor or factory method that converts the given map to a packet object to send on the given channel
Returns:
  this manager object