Switched to using the Presence API for Range detection, removed unused util structs, fixed cable implementation to be somewhat sane
This commit is contained in:
parent
c28c6ccee0
commit
d45e501c42
13 changed files with 111 additions and 342 deletions
|
@ -44,10 +44,10 @@ energy.
|
|||
|
||||
To create a provider, implement the `EnergyProvider` interface. This interface has two methods:
|
||||
|
||||
- `void exists(EnergyReceiver receiver, ArrayList<Vec3i> pointsOfPresence);`
|
||||
- `void exists(EnergyReceiver receiver);`
|
||||
|
||||
This method is called when the matchmaking service finds a receiver that can receive energy from this provider. The
|
||||
provider should check if this receiver meets all of it's requirements, then call the Ready() method on the receiver to
|
||||
provider should check if this receiver meets all of its requirements, then call the Ready() method on the receiver to
|
||||
make a connection.
|
||||
|
||||
- `long extract(long amount, EnergyReceiver receiver);`
|
||||
|
|
30
build.gradle
30
build.gradle
|
@ -11,11 +11,10 @@ base {
|
|||
}
|
||||
|
||||
repositories {
|
||||
// Add repositories to retrieve artifacts from in here.
|
||||
// You should only use this when depending on other mods because
|
||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||
// for more information about repositories.
|
||||
maven {
|
||||
name = "Arzumify's Maven"
|
||||
url = "https://maven.ailur.dev"
|
||||
}
|
||||
}
|
||||
|
||||
loom {
|
||||
|
@ -38,6 +37,9 @@ dependencies {
|
|||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
// Presence API
|
||||
implementation "arzumify:presence:${project.presence_version}"
|
||||
|
||||
// Testing
|
||||
testImplementation(platform('org.junit:junit-bom:5.12.0'))
|
||||
testImplementation('org.junit.jupiter:junit-jupiter')
|
||||
|
@ -79,21 +81,3 @@ jar {
|
|||
rename { "${it}_${inputs.properties.archivesName}" }
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
create("mavenJava", MavenPublication) {
|
||||
artifactId = project.archives_base_name
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
// Notice: This block does NOT have the same function as the block in the top level.
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
}
|
||||
}
|
|
@ -7,8 +7,9 @@ minecraft_version=1.21.4
|
|||
yarn_mappings=1.21.4+build.8
|
||||
loader_version=0.16.10
|
||||
# Mod Properties
|
||||
mod_version=1.2.1
|
||||
mod_version=2.0.0
|
||||
maven_group=arzumify.polyenergy
|
||||
archives_base_name=polyenergy
|
||||
# Dependencies
|
||||
fabric_version=0.118.0+1.21.4
|
||||
fabric_version=0.118.0+1.21.4
|
||||
presence_version=1.1.1
|
|
@ -0,0 +1,7 @@
|
|||
package arzumify.polyenergy.api;
|
||||
|
||||
import arzumify.presence.presences.IntegerPresence;
|
||||
import arzumify.presence.presences.PresenceProvider;
|
||||
|
||||
public interface EnergyPresence extends PresenceProvider<IntegerPresence> {
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
package arzumify.polyenergy.api;
|
||||
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// Provides energy to EnergyReceivers. Can be implemented by anything able to tick and provide energy!
|
||||
public interface EnergyProvider {
|
||||
public interface EnergyProvider extends EnergyPresence {
|
||||
/**
|
||||
* When called by a receiver, attempts to remove energy from the provider.
|
||||
* Do not attempt to extract energy until {@link EnergyReceiver#ready(EnergyProvider)} is called by the receiver.
|
||||
|
@ -22,7 +18,6 @@ public interface EnergyProvider {
|
|||
* This particular overload is for coordinate-based matchmaking.
|
||||
*
|
||||
* @param receiver The receiver that exists.
|
||||
* @param pointsOfPresence The points of presence of the receiver (can be multiple, e.g. for a network of wires or a large entity).
|
||||
*/
|
||||
void exists(EnergyReceiver receiver, ArrayList<Vec3i> pointsOfPresence);
|
||||
void exists(EnergyReceiver receiver);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package arzumify.polyenergy.api;
|
||||
|
||||
// Receives energy from EnergyProviders. Can be implemented by anything able to tick and receive energy!
|
||||
public interface EnergyReceiver {
|
||||
public interface EnergyReceiver extends EnergyPresence {
|
||||
/**
|
||||
* When called by a provider, indicates that the provider exists and is ready to have energy extracted from.
|
||||
* Do not attempt to call {@link EnergyProvider#extract(long, EnergyReceiver)} on any provider until this method is called.
|
||||
|
|
|
@ -1,64 +1,67 @@
|
|||
package arzumify.polyenergy.impl;
|
||||
|
||||
import arzumify.polyenergy.api.EnergyPresence;
|
||||
import arzumify.polyenergy.api.EnergyProvider;
|
||||
import arzumify.polyenergy.api.EnergyReceiver;
|
||||
import arzumify.presence.matchmaker.Channel;
|
||||
import arzumify.presence.matchmaker.MatchMaker;
|
||||
import arzumify.presence.presences.IntegerPresence;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
// It's slightly more optimized now, as in it could realistically run in Minecraft.
|
||||
// Reset: O(1) constant time, we're just deleting everything
|
||||
// Add Provider: O(m * k^2) where m is the number of receivers and k is the number of points of presence
|
||||
// Add Receiver: O(n * k^2) where n is the number of providers and k is the number of points of presence
|
||||
// Remove Provider: O(n + m) where n is the number of providers and m is the number of matches for the provider
|
||||
// Remove Receiver: O(m) where m is the number of receivers
|
||||
// I think we stop the optimisations here, the bottleneck is no longer the matchmaker but Minecraft itself.
|
||||
// If more optimisation is needed we can try to perform Vector math in a more efficient way, but I think this is good enough.
|
||||
// CoordinateMatchMaker is now implemented using the Presence API
|
||||
|
||||
public class CoordinateMatchMaker {
|
||||
private static final CopyOnWriteArrayList<ProviderDetails> providers = new CopyOnWriteArrayList<>();
|
||||
private static final CopyOnWriteArrayList<ReceiverDetails> receivers = new CopyOnWriteArrayList<>();
|
||||
private static final ConcurrentHashMap<ProviderDetails, Set<ReceiverDetails>> matches = new ConcurrentHashMap<>();
|
||||
private static final Channel receivers = new Channel();
|
||||
private static final Channel providers = new Channel();
|
||||
private static final ConcurrentHashMap<EnergyProvider, Set<EnergyReceiver>> matches = new ConcurrentHashMap<>();
|
||||
private static MatchMaker<IntegerPresence, EnergyPresence> matchMaker = new MatchMaker<>();
|
||||
|
||||
public static void reset() {
|
||||
providers.clear();
|
||||
receivers.clear();
|
||||
matches.clear();
|
||||
matchMaker = new MatchMaker<>();
|
||||
}
|
||||
|
||||
public static void addProvider(ProviderDetails provider) {
|
||||
providers.add(provider);
|
||||
matches.put(provider, ConcurrentHashMap.newKeySet());
|
||||
public static void addProvider(EnergyProvider provider) {
|
||||
matchMaker.Add(provider, providers);
|
||||
// Search for receivers within range of this provider
|
||||
for (ReceiverDetails receiver : receivers) {
|
||||
if (provider.isInRange(receiver.pointsOfPresence())) {
|
||||
provider.provider().exists(receiver.receiver(), provider.pointsOfPresence());
|
||||
matches.get(provider).add(receiver);
|
||||
var receivers = matchMaker.Search(provider, CoordinateMatchMaker.receivers);
|
||||
if (receivers != null) {
|
||||
for (EnergyPresence receiver : receivers) {
|
||||
if (receiver instanceof EnergyReceiver) {
|
||||
provider.exists((EnergyReceiver) receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addReceiver(ReceiverDetails receiver) {
|
||||
receivers.add(receiver);
|
||||
public static void addReceiver(EnergyReceiver receiver) {
|
||||
matchMaker.Add(receiver, receivers);
|
||||
// Search for providers within range of this receiver
|
||||
for (ProviderDetails provider : providers) {
|
||||
if (provider.isInRange(receiver.pointsOfPresence())) {
|
||||
provider.provider().exists(receiver.receiver(), provider.pointsOfPresence());
|
||||
matches.get(provider).add(receiver);
|
||||
var providers = matchMaker.Search(receiver, CoordinateMatchMaker.providers);
|
||||
if (providers != null) {
|
||||
for (EnergyPresence provider : providers) {
|
||||
if (provider instanceof EnergyProvider) {
|
||||
((EnergyProvider) provider).exists(receiver);
|
||||
matches.putIfAbsent((EnergyProvider) provider, ConcurrentHashMap.newKeySet());
|
||||
matches.get(provider).add(receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeProvider(ProviderDetails provider) {
|
||||
providers.remove(provider);
|
||||
public static void removeProvider(EnergyProvider provider) {
|
||||
matchMaker.Remove(provider, providers);
|
||||
if (matches.get(provider) != null) {
|
||||
for (ReceiverDetails receiver : matches.get(provider)) {
|
||||
receiver.receiver().unready(provider.provider());
|
||||
for (EnergyReceiver receiver : matches.get(provider)) {
|
||||
receiver.unready(provider);
|
||||
}
|
||||
}
|
||||
matches.remove(provider);
|
||||
}
|
||||
|
||||
public static void removeReceiver(ReceiverDetails receiver) {
|
||||
receivers.remove(receiver);
|
||||
public static void removeReceiver(EnergyReceiver receiver) {
|
||||
matchMaker.Remove(receiver, receivers);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package arzumify.polyenergy.impl;
|
||||
|
||||
import arzumify.polyenergy.api.EnergyProvider;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public record ProviderDetails(ArrayList<Vec3i> pointsOfPresence, EnergyProvider provider, int range) {
|
||||
public static ProviderDetails NewSimple(Vec3i position, EnergyProvider provider) {
|
||||
var pointsOfPresence = new ArrayList<Vec3i>();
|
||||
pointsOfPresence.add(position);
|
||||
return new ProviderDetails(pointsOfPresence, provider, 1);
|
||||
}
|
||||
|
||||
public boolean isInRange(ArrayList<Vec3i> pointsOfPresence) {
|
||||
for (Vec3i point : pointsOfPresence) {
|
||||
for (Vec3i myPoint : this.pointsOfPresence) {
|
||||
var manhattanDistance = point.getManhattanDistance(myPoint);
|
||||
if (manhattanDistance == 0) {
|
||||
return false;
|
||||
} else if (manhattanDistance <= range) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package arzumify.polyenergy.impl;
|
||||
|
||||
import arzumify.polyenergy.api.EnergyReceiver;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public record ReceiverDetails(ArrayList<Vec3i> pointsOfPresence, EnergyReceiver receiver) {
|
||||
public static ReceiverDetails NewSimple(Vec3i position, EnergyReceiver receiver) {
|
||||
var pointsOfPresence = new ArrayList<Vec3i>();
|
||||
pointsOfPresence.add(position);
|
||||
return new ReceiverDetails(pointsOfPresence, receiver);
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
package arzumify.polyenergy.util;
|
||||
|
||||
import arzumify.polyenergy.api.EnergyProvider;
|
||||
import arzumify.polyenergy.api.EnergyReceiver;
|
||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
||||
import arzumify.polyenergy.impl.ProviderDetails;
|
||||
import arzumify.polyenergy.impl.ReceiverDetails;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A simple battery that can provide and receive energy. Has a range of 1 block in all directions (directly adjacent blocks).
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SimpleBattery extends BlockEntity implements EnergyProvider, EnergyReceiver, ServerBlockEntityEvents.Unload, ServerBlockEntityEvents.Load {
|
||||
private final long capacity;
|
||||
private final long inputRate;
|
||||
private final long outputRate;
|
||||
private final ProviderDetails providerDetails = ProviderDetails.NewSimple(pos, this);
|
||||
private final ReceiverDetails receiverDetails = ReceiverDetails.NewSimple(pos, this);
|
||||
private final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
||||
private long energy = 0;
|
||||
private boolean providing = false;
|
||||
|
||||
public SimpleBattery(BlockEntityType<?> type, BlockPos pos, BlockState state, long capacity, long inputRate, long outputRate) {
|
||||
super(type, pos, state);
|
||||
this.capacity = capacity;
|
||||
this.inputRate = inputRate;
|
||||
this.outputRate = outputRate;
|
||||
CoordinateMatchMaker.addProvider(providerDetails);
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
}
|
||||
|
||||
public static void tick(World ignoredWorld, BlockPos ignoredPos, BlockState ignoredState, SimpleBattery battery) {
|
||||
var leftToFill = Math.min(battery.inputRate, battery.capacity - battery.energy);
|
||||
for (EnergyProvider provider : battery.providers) {
|
||||
// Less than zero shouldn't be possible, but just in case...
|
||||
if (leftToFill <= 0) {
|
||||
break;
|
||||
}
|
||||
long extracted = provider.extract(leftToFill, battery);
|
||||
battery.energy += extracted;
|
||||
leftToFill -= extracted;
|
||||
}
|
||||
if (!battery.providing && battery.energy > 0) {
|
||||
CoordinateMatchMaker.addProvider(battery.providerDetails);
|
||||
battery.providing = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(long amount, EnergyReceiver receiver) {
|
||||
if (providing) {
|
||||
long extracted = Math.min(Math.min(outputRate, amount), energy);
|
||||
energy -= extracted;
|
||||
if (energy == 0) {
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
}
|
||||
return extracted;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exists(EnergyReceiver receiver, ArrayList<Vec3i> pointsOfPresence) {
|
||||
receiver.ready(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ready(EnergyProvider provider) {
|
||||
providers.add(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unready(EnergyProvider provider) {
|
||||
providers.remove(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
if (energy > 0) {
|
||||
CoordinateMatchMaker.addProvider(providerDetails);
|
||||
providing = true;
|
||||
}
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
CoordinateMatchMaker.removeReceiver(receiverDetails);
|
||||
providers.clear();
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
package arzumify.polyenergy.util;
|
||||
|
||||
import arzumify.polyenergy.api.EnergyProvider;
|
||||
import arzumify.polyenergy.api.EnergyReceiver;
|
||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
||||
import arzumify.polyenergy.impl.ProviderDetails;
|
||||
import arzumify.polyenergy.impl.ReceiverDetails;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// Cables can have ONE provider and MANY receivers.
|
||||
@SuppressWarnings("unused")
|
||||
public class SimpleCable extends BlockEntity implements EnergyProvider, EnergyReceiver, ServerBlockEntityEvents.Unload, ServerBlockEntityEvents.Load {
|
||||
private final long capacity;
|
||||
private final long inputRate;
|
||||
private final long outputRate;
|
||||
private final ProviderDetails providerDetails = ProviderDetails.NewSimple(pos, this);
|
||||
private final ReceiverDetails receiverDetails = ReceiverDetails.NewSimple(pos, this);
|
||||
private EnergyProvider currentProvider;
|
||||
private long energy = 0;
|
||||
|
||||
public SimpleCable(BlockEntityType<?> type, BlockPos pos, BlockState state, long capacity, long inputRate, long outputRate) {
|
||||
super(type, pos, state);
|
||||
this.capacity = capacity;
|
||||
this.inputRate = inputRate;
|
||||
this.outputRate = outputRate;
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
}
|
||||
|
||||
public static void tick(World ignoredWorld, BlockPos ignoredPos, BlockState ignoredState, SimpleCable cable) {
|
||||
if (cable.currentProvider != null && cable.energy < cable.capacity) {
|
||||
cable.energy += cable.currentProvider.extract(Math.min(cable.capacity - cable.energy, cable.inputRate), cable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(long amount, EnergyReceiver receiver) {
|
||||
System.out.println("Extracting " + amount + " energy");
|
||||
long extracted = Math.min(Math.min(outputRate, amount), energy);
|
||||
energy -= extracted;
|
||||
return extracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exists(EnergyReceiver receiver, ArrayList<Vec3i> pointsOfPresence) {
|
||||
if (currentProvider != null) {
|
||||
receiver.ready(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ready(EnergyProvider provider) {
|
||||
if (currentProvider == null) {
|
||||
currentProvider = provider;
|
||||
CoordinateMatchMaker.addProvider(providerDetails);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unready(EnergyProvider provider) {
|
||||
if (currentProvider == provider) {
|
||||
currentProvider = null;
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
CoordinateMatchMaker.removeReceiver(receiverDetails);
|
||||
currentProvider = null;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
import arzumify.polyenergy.api.EnergyProvider;
|
||||
import arzumify.polyenergy.api.EnergyReceiver;
|
||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
||||
import arzumify.polyenergy.impl.ProviderDetails;
|
||||
import arzumify.polyenergy.impl.ReceiverDetails;
|
||||
import arzumify.presence.presences.IntegerPresence;
|
||||
import arzumify.presence.presences.Presence;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -20,9 +19,8 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
|||
public final long capacity;
|
||||
public final long inputRate;
|
||||
public final long outputRate;
|
||||
public final IntegerPresence presence;
|
||||
public final String name;
|
||||
public final ProviderDetails providerDetails;
|
||||
public final ReceiverDetails receiverDetails;
|
||||
public final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
||||
public long energy = 0;
|
||||
public boolean providing = false;
|
||||
|
@ -31,11 +29,10 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
|||
this.capacity = capacity;
|
||||
this.inputRate = inputRate;
|
||||
this.outputRate = outputRate;
|
||||
this.providerDetails = ProviderDetails.NewSimple(pos, this);
|
||||
this.receiverDetails = ReceiverDetails.NewSimple(pos, this);
|
||||
this.name = name;
|
||||
CoordinateMatchMaker.addProvider(providerDetails);
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
this.presence = new IntegerPresence((short) 1, new arzumify.presence.maths.Vec3i(pos.getX(), pos.getY(), pos.getZ()));
|
||||
CoordinateMatchMaker.addProvider(this);
|
||||
CoordinateMatchMaker.addReceiver(this);
|
||||
}
|
||||
|
||||
public static void tick(SimpleCodeOnlyBattery battery) {
|
||||
|
@ -51,7 +48,7 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
|||
leftToFill -= extracted;
|
||||
}
|
||||
if (!battery.providing && battery.energy > 0) {
|
||||
CoordinateMatchMaker.addProvider(battery.providerDetails);
|
||||
CoordinateMatchMaker.addProvider(battery);
|
||||
battery.providing = true;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +61,7 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
|||
energy -= extracted;
|
||||
System.out.println(name + " extracted " + extracted + " energy");
|
||||
if (energy == 0) {
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
CoordinateMatchMaker.removeProvider(this);
|
||||
}
|
||||
return extracted;
|
||||
} else {
|
||||
|
@ -73,7 +70,7 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void exists(EnergyReceiver receiver, ArrayList<Vec3i> pointsOfPresence) {
|
||||
public void exists(EnergyReceiver receiver) {
|
||||
System.out.println(name + " found other receiver");
|
||||
receiver.ready(this);
|
||||
}
|
||||
|
@ -93,16 +90,21 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
|||
@Override
|
||||
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
if (energy > 0) {
|
||||
CoordinateMatchMaker.addProvider(providerDetails);
|
||||
CoordinateMatchMaker.addProvider(this);
|
||||
providing = true;
|
||||
}
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
CoordinateMatchMaker.addReceiver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
CoordinateMatchMaker.removeReceiver(receiverDetails);
|
||||
CoordinateMatchMaker.removeProvider(this);
|
||||
CoordinateMatchMaker.removeReceiver(this);
|
||||
providers.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presence<IntegerPresence> presence() {
|
||||
return presence;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,46 @@
|
|||
import arzumify.polyenergy.api.EnergyProvider;
|
||||
import arzumify.polyenergy.api.EnergyReceiver;
|
||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
||||
import arzumify.polyenergy.impl.ProviderDetails;
|
||||
import arzumify.polyenergy.impl.ReceiverDetails;
|
||||
import arzumify.presence.presences.IntegerPresence;
|
||||
import arzumify.presence.presences.Presence;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
// Cables can have ONE provider and MANY receivers.
|
||||
public class SimpleCodeOnlyCable implements EnergyProvider, EnergyReceiver, ServerBlockEntityEvents.Unload, ServerBlockEntityEvents.Load {
|
||||
public final long capacity;
|
||||
public final long inputRate;
|
||||
public final long outputRate;
|
||||
public final IntegerPresence presence;
|
||||
public final String name;
|
||||
public final ProviderDetails providerDetails;
|
||||
public final ReceiverDetails receiverDetails;
|
||||
public long energy = 0;
|
||||
public EnergyProvider currentProvider;
|
||||
public final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
||||
|
||||
public SimpleCodeOnlyCable(Vec3i pos, long capacity, long inputRate, long outputRate, String name) {
|
||||
this.capacity = capacity;
|
||||
this.inputRate = inputRate;
|
||||
this.outputRate = outputRate;
|
||||
this.providerDetails = ProviderDetails.NewSimple(pos, this);
|
||||
this.receiverDetails = ReceiverDetails.NewSimple(pos, this);
|
||||
this.name = name;
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
this.presence = new IntegerPresence((short) 1, new arzumify.presence.maths.Vec3i(pos.getX(), pos.getY(), pos.getZ()));
|
||||
CoordinateMatchMaker.addReceiver(this);
|
||||
}
|
||||
|
||||
public static void tick(SimpleCodeOnlyCable cable) {
|
||||
System.out.println(cable.name + " ticking");
|
||||
if (cable.currentProvider != null && cable.energy < cable.capacity) {
|
||||
cable.energy += cable.currentProvider.extract(Math.min(cable.capacity - cable.energy, cable.inputRate), cable);
|
||||
var leftToFill = Math.min(cable.inputRate, cable.capacity - cable.energy);
|
||||
for (EnergyProvider provider : cable.providers) {
|
||||
// Less than zero shouldn't be possible, but just in case...
|
||||
if (leftToFill <= 0) {
|
||||
break;
|
||||
}
|
||||
long extracted = provider.extract(leftToFill, cable);
|
||||
cable.energy += extracted;
|
||||
leftToFill -= extracted;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,9 +54,9 @@ public class SimpleCodeOnlyCable implements EnergyProvider, EnergyReceiver, Serv
|
|||
}
|
||||
|
||||
@Override
|
||||
public void exists(EnergyReceiver receiver, ArrayList<Vec3i> pointsOfPresence) {
|
||||
public void exists(EnergyReceiver receiver) {
|
||||
System.out.println(name + " found other receiver");
|
||||
if (currentProvider != null) {
|
||||
if (!providers.isEmpty()) {
|
||||
receiver.ready(this);
|
||||
}
|
||||
}
|
||||
|
@ -58,30 +64,34 @@ public class SimpleCodeOnlyCable implements EnergyProvider, EnergyReceiver, Serv
|
|||
@Override
|
||||
public void ready(EnergyProvider provider) {
|
||||
System.out.println(name + " found other provider");
|
||||
if (currentProvider == null) {
|
||||
currentProvider = provider;
|
||||
CoordinateMatchMaker.addProvider(providerDetails);
|
||||
providers.add(provider);
|
||||
if (providers.size() == 1) {
|
||||
CoordinateMatchMaker.addProvider(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unready(EnergyProvider provider) {
|
||||
if (currentProvider == provider) {
|
||||
System.out.println(name + " lost other provider");
|
||||
currentProvider = null;
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
providers.remove(provider);
|
||||
if (providers.isEmpty()) {
|
||||
CoordinateMatchMaker.removeProvider(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
CoordinateMatchMaker.addReceiver(receiverDetails);
|
||||
CoordinateMatchMaker.addReceiver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||
CoordinateMatchMaker.removeProvider(providerDetails);
|
||||
CoordinateMatchMaker.removeReceiver(receiverDetails);
|
||||
currentProvider = null;
|
||||
CoordinateMatchMaker.removeProvider(this);
|
||||
CoordinateMatchMaker.removeReceiver(this);
|
||||
providers.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presence<IntegerPresence> presence() {
|
||||
return presence;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue