User Tools

Site Tools


tutorial:transfer-api_fluid_implementation

This is an old revision of the document!


Fabric Transfer API: How to implement Storage<FluidVariant>

This article is part of a series on the Fabric Transfer API. Link to the home page of the series.

Now that you understand how to find instances of Storage<FluidVariant> and how to use them, you are now ready to learn how it can be implemented. It's possible to implement directly by implementing the interface and filling the methods, but Fabric API already provides many implementations that you can use and combine for almost any task.

Overview of the base implementations

SingleVariantStorage

SingleVariantStorage<FluidVariant> is a storage implementation that can only store a single fluid at a given time. It's suitable for a single tank or “fluid slot”.

Usage example:

public final SingleVariantStorage<FluidVariant> fluidStorage = new SingleVariantStorage<>() {
	@Override
	protected FluidVariant getBlankVariant() {
		return FluidVariant.blank(); // This should always be FluidVariant.blank() for fluid storages.
	}
 
	@Override
	protected long getCapacity(FluidVariant variant) {
		// Here, you can pick your capacity depending on the fluid variant.
		// For example, if we want to store 8 buckets of any fluid:
		return 8 * FluidConstants.BUCKET;
	}
 
	@Override
	protected void onFinalCommit() {
		// Optional: anything that needs to be done after a successful insertion or extraction. Calling markDirty at the very least is recommended.
	}
 
	@Override
	protected boolean canInsert(FluidVariant variant) {
		// Optional: can be used to prevent insertion of some fluid variants.
	}
 
	@Override
	protected boolean canExtract(FluidVariant variant) {
		// Optional: can be used to prevent extraction of some fluid variants.
	}
};

FilteringStorage

FilteringStorage can filter access to another existing storage.

insertOnlyOf and extractOnlyOf can be useful to create a new object that can only insert or extract into an existing storage. Usage example:

// Storage that we already have, allows any insertion or extraction.
Storage<FluidVariant> existingStorage = ...;
 
// Wrapper that will forward any insertion to existingStorage, but will return 0 for any extraction attempt.
Storage<FluidVariant> insertionWrapper = FilteringStorage.insertOnlyOf(existingStorage);
// Wrapper that will forward any extraction to existingStorage, but will return 0 for any insertion attempt.
Storage<FluidVariant> extractionWrapper = FilteringStorage.extractOnlyOf(existingStorage);

Subclassing FilteringStorage and overriding canInsert and/or canExtract is also possible if more advanced filtering is necessary.

CombinedStorage

CombinedStorage can create a Storage that wraps multiple storages.

Usage example:

Storage<FluidVariant> storage1, storage2, storage3 = ...;
 
// This combined storage will insert and extract from 1, 2, and 3 (in that order).
Storage<FluidVariant> combinedStorage = new CombinedStorage<>(List.of(storage1, storage2, storage3));
tutorial/transfer-api_fluid_implementation.1643831996.txt.gz · Last modified: 2022/02/02 19:59 by technici4n