Refactor energy handling: replace Presence API with Located API, update interfaces, and improve energy transfer logic
This commit is contained in:
parent
b3e9ec627e
commit
e4bf695173
|
@ -37,8 +37,8 @@ dependencies {
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
// Presence API
|
// Located API
|
||||||
implementation "arzumify:presence:${project.presence_version}"
|
implementation "arzumify:located:${project.located_version}"
|
||||||
|
|
||||||
// Testing
|
// Testing
|
||||||
testImplementation(platform('org.junit:junit-bom:5.12.0'))
|
testImplementation(platform('org.junit:junit-bom:5.12.0'))
|
||||||
|
|
|
@ -7,9 +7,9 @@ minecraft_version=1.20
|
||||||
yarn_mappings=1.20+build.1
|
yarn_mappings=1.20+build.1
|
||||||
loader_version=0.16.10
|
loader_version=0.16.10
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=2.0.1
|
mod_version=3.0.0
|
||||||
maven_group=arzumify.polyenergy
|
maven_group=arzumify.polyenergy
|
||||||
archives_base_name=polyenergy
|
archives_base_name=polyenergy
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_version=0.118.0+1.21.4
|
fabric_version=0.118.0+1.21.4
|
||||||
presence_version=1.1.1
|
located_version=1.0.0
|
|
@ -0,0 +1,6 @@
|
||||||
|
package arzumify.polyenergy.api;
|
||||||
|
|
||||||
|
import arzumify.located.api.Provider;
|
||||||
|
|
||||||
|
public interface EnergyBlock extends Provider {
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
package arzumify.polyenergy.api;
|
|
||||||
|
|
||||||
import arzumify.presence.presences.IntegerPresence;
|
|
||||||
import arzumify.presence.presences.PresenceProvider;
|
|
||||||
|
|
||||||
public interface EnergyPresence extends PresenceProvider<IntegerPresence> {
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
package arzumify.polyenergy.api;
|
package arzumify.polyenergy.api;
|
||||||
|
|
||||||
// Provides energy to EnergyReceivers. Can be implemented by anything able to tick and provide energy!
|
// Provides energy to EnergyReceivers. Can be implemented by anything able to tick and provide energy!
|
||||||
public interface EnergyProvider extends EnergyPresence {
|
public interface EnergyProvider extends EnergyBlock {
|
||||||
/**
|
/**
|
||||||
* When called by a receiver, attempts to remove energy from the provider.
|
* 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.
|
* Do not attempt to extract energy until {@link EnergyReceiver#ready(EnergyProvider)} is called by the receiver.
|
||||||
|
@ -14,10 +14,21 @@ public interface EnergyProvider extends EnergyPresence {
|
||||||
long extract(long amount, EnergyReceiver receiver);
|
long extract(long amount, EnergyReceiver receiver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When called by the server matchmaker, indicates that this is a possible receiver to call {@link EnergyReceiver#ready(EnergyProvider)} on.
|
* When called by a receiver, indicates that the receiver exists and is capable of starting a connection with the provider.
|
||||||
* This particular overload is for coordinate-based matchmaking.
|
* This is a good time to verify that the receiver falls under the criteria for your energy provider.
|
||||||
|
* We recommend using a Set to store the receivers that are ready to receive energy, such that when your block is no longer
|
||||||
|
* able to provide energy, you can call {@link EnergyReceiver#unready(EnergyProvider)} on all of them.
|
||||||
|
* Call {@link EnergyReceiver#ready(EnergyProvider)} on the receiver to establish the connection.
|
||||||
*
|
*
|
||||||
* @param receiver The receiver that exists.
|
* @param receiver The receiver that exists.
|
||||||
*/
|
*/
|
||||||
void exists(EnergyReceiver receiver);
|
void ready(EnergyReceiver receiver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When called by a receiver, indicates that the receiver that no longer exists or is no longer able to receive energy.
|
||||||
|
* You do not need to call {@link EnergyReceiver#unready(EnergyProvider)} on the receiver.
|
||||||
|
*
|
||||||
|
* @param receiver The receiver that no longer exists.
|
||||||
|
*/
|
||||||
|
void unready(EnergyReceiver receiver);
|
||||||
}
|
}
|
|
@ -1,11 +1,10 @@
|
||||||
package arzumify.polyenergy.api;
|
package arzumify.polyenergy.api;
|
||||||
|
|
||||||
// Receives energy from EnergyProviders. Can be implemented by anything able to tick and receive energy!
|
// Receives energy from EnergyProviders. Can be implemented by anything able to tick and receive energy!
|
||||||
public interface EnergyReceiver extends EnergyPresence {
|
public interface EnergyReceiver extends EnergyBlock {
|
||||||
/**
|
/**
|
||||||
* When called by a provider, indicates that the provider exists and is ready to have energy extracted from.
|
* 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.
|
* Do not attempt to call {@link EnergyProvider#extract(long, EnergyReceiver)} on any provider until this method is called.
|
||||||
* This method may be called multiple times by the same provider. Please ignore any duplicate calls, as they may occur in the MatchMaking implementation.
|
|
||||||
* We recommend using a Set to store the providers that are ready to provide energy.
|
* We recommend using a Set to store the providers that are ready to provide energy.
|
||||||
*
|
*
|
||||||
* @param provider The provider that exists and is ready to provide energy to this receiver.
|
* @param provider The provider that exists and is ready to provide energy to this receiver.
|
||||||
|
@ -13,10 +12,10 @@ public interface EnergyReceiver extends EnergyPresence {
|
||||||
void ready(EnergyProvider provider);
|
void ready(EnergyProvider provider);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When called by the server matchmaker, indicates that this provider is no longer able to provide energy to this receiver.
|
* When called by the provider, indicates that the provider no longer exists or is no longer able to provide energy.
|
||||||
* Wait for another call to {@link EnergyReceiver#ready(EnergyProvider)} before attempting to extract energy from this provider.
|
* You do not need to call {@link EnergyProvider#unready(EnergyReceiver)} on the provider.
|
||||||
*
|
*
|
||||||
* @param provider The provider that is no longer able to provide energy to this receiver.
|
* @param provider The provider that no longer exists.
|
||||||
*/
|
*/
|
||||||
void unready(EnergyProvider provider);
|
void unready(EnergyProvider provider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
||||||
// CoordinateMatchMaker is now implemented using the Presence API
|
|
||||||
|
|
||||||
public class CoordinateMatchMaker {
|
|
||||||
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() {
|
|
||||||
matchMaker = new MatchMaker<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addProvider(EnergyProvider provider) {
|
|
||||||
matchMaker.Add(provider, providers);
|
|
||||||
// Search for receivers within range of this provider
|
|
||||||
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(EnergyReceiver receiver) {
|
|
||||||
matchMaker.Add(receiver, receivers);
|
|
||||||
// Search for providers within range of this 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(EnergyProvider provider) {
|
|
||||||
matchMaker.Remove(provider, providers);
|
|
||||||
if (matches.get(provider) != null) {
|
|
||||||
for (EnergyReceiver receiver : matches.get(provider)) {
|
|
||||||
receiver.unready(provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matches.remove(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeReceiver(EnergyReceiver receiver) {
|
|
||||||
matchMaker.Remove(receiver, receivers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package arzumify.polyenergy.impl;
|
||||||
|
|
||||||
|
import arzumify.polyenergy.api.EnergyBlock;
|
||||||
|
|
||||||
|
public class MatchMaker {
|
||||||
|
public static arzumify.located.impl.MatchMaker<EnergyBlock> matchMaker = new arzumify.located.impl.MatchMaker<>();
|
||||||
|
}
|
|
@ -1,25 +1,17 @@
|
||||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
import arzumify.located.math.Vec3i;
|
||||||
import net.minecraft.util.math.Vec3i;
|
import arzumify.polyenergy.impl.MatchMaker;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.Timeout;
|
import org.junit.jupiter.api.Timeout;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
@Timeout(1)
|
@Timeout(1)
|
||||||
public class EnergyTests {
|
public class EnergyTests {
|
||||||
public static void assertWithError(double expected, double actual, double error) {
|
|
||||||
assertTrue(expected - error <= actual && actual <= expected + error);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void assertWithError(double expected, double actual) {
|
|
||||||
assertWithError(expected, actual, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
// Delete all batteries
|
// Delete all batteries
|
||||||
CoordinateMatchMaker.reset();
|
MatchMaker.matchMaker = new arzumify.located.impl.MatchMaker<>();
|
||||||
System.out.println("Reset CoordinateMatchMaker");
|
System.out.println("Reset CoordinateMatchMaker");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +22,8 @@ public class EnergyTests {
|
||||||
// Battery1 should be able to provide energy to battery2
|
// Battery1 should be able to provide energy to battery2
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
battery1.energy = 16;
|
battery1.energy = 16;
|
||||||
|
@ -45,8 +39,8 @@ public class EnergyTests {
|
||||||
System.out.println("Battery2 energy: " + battery2.energy);
|
System.out.println("Battery2 energy: " + battery2.energy);
|
||||||
|
|
||||||
// Battery1 should have lost 10 energy and battery2 should have gained 10 energy
|
// Battery1 should have lost 10 energy and battery2 should have gained 10 energy
|
||||||
assertWithError(6, battery1.energy);
|
assertEquals(6, battery1.energy);
|
||||||
assertWithError(10, battery2.energy);
|
assertEquals(10, battery2.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -56,6 +50,8 @@ public class EnergyTests {
|
||||||
// Battery1 should be able to provide energy to battery2
|
// Battery1 should be able to provide energy to battery2
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
battery1.energy = 16;
|
battery1.energy = 16;
|
||||||
|
@ -79,9 +75,9 @@ public class EnergyTests {
|
||||||
System.out.println("Battery1 energy: " + battery1.energy);
|
System.out.println("Battery1 energy: " + battery1.energy);
|
||||||
System.out.println("Battery2 energy: " + battery2.energy);
|
System.out.println("Battery2 energy: " + battery2.energy);
|
||||||
|
|
||||||
// Battery1 should have lost 6 energy and battery2 should have gained 6 energy (±1)
|
// Battery1 should have lost 5 energy and battery2 should have gained 5 energy
|
||||||
assertWithError(10, battery1.energy);
|
assertEquals(11, battery1.energy);
|
||||||
assertWithError(6, battery2.energy);
|
assertEquals(5, battery2.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -91,6 +87,8 @@ public class EnergyTests {
|
||||||
// Battery1 should be able to provide energy to battery2
|
// Battery1 should be able to provide energy to battery2
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
battery1.energy = 16;
|
battery1.energy = 16;
|
||||||
|
@ -116,8 +114,8 @@ public class EnergyTests {
|
||||||
System.out.println("Battery2 energy: " + battery2.energy);
|
System.out.println("Battery2 energy: " + battery2.energy);
|
||||||
|
|
||||||
// Battery1 should have lost 5 energy and battery2 should have gained 5 energy
|
// Battery1 should have lost 5 energy and battery2 should have gained 5 energy
|
||||||
assertWithError(11, battery1.energy);
|
assertEquals(11, battery1.energy);
|
||||||
assertWithError(5, battery2.energy);
|
assertEquals(5, battery2.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -127,6 +125,8 @@ public class EnergyTests {
|
||||||
// Battery1 should be able to provide energy to battery2
|
// Battery1 should be able to provide energy to battery2
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
battery1.energy = 16;
|
battery1.energy = 16;
|
||||||
|
@ -161,8 +161,8 @@ public class EnergyTests {
|
||||||
System.out.println("Battery2 energy: " + battery2.energy);
|
System.out.println("Battery2 energy: " + battery2.energy);
|
||||||
|
|
||||||
// Battery1 should have lost 10 energy and battery2 should have gained 10 energy
|
// Battery1 should have lost 10 energy and battery2 should have gained 10 energy
|
||||||
assertWithError(6, battery1.energy);
|
assertEquals(6, battery1.energy);
|
||||||
assertWithError(10, battery2.energy);
|
assertEquals(10, battery2.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -172,6 +172,8 @@ public class EnergyTests {
|
||||||
// Battery1 should be able to provide energy to battery2
|
// Battery1 should be able to provide energy to battery2
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
battery1.energy = 16;
|
battery1.energy = 16;
|
||||||
|
@ -207,8 +209,8 @@ public class EnergyTests {
|
||||||
System.out.println("Battery2 energy: " + battery2.energy);
|
System.out.println("Battery2 energy: " + battery2.energy);
|
||||||
|
|
||||||
// Battery1 should have lost 10 energy and battery2 should have gained 10 energy
|
// Battery1 should have lost 10 energy and battery2 should have gained 10 energy
|
||||||
assertWithError(6, battery1.energy);
|
assertEquals(6, battery1.energy);
|
||||||
assertWithError(10, battery2.energy);
|
assertEquals(10, battery2.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -218,6 +220,8 @@ public class EnergyTests {
|
||||||
// They should both provide energy to each other and stay at equilibrium
|
// They should both provide energy to each other and stay at equilibrium
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 1, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 1, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 1, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 1, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 and battery2 some energy
|
// Give battery1 and battery2 some energy
|
||||||
battery1.energy = 8;
|
battery1.energy = 8;
|
||||||
|
@ -246,6 +250,9 @@ public class EnergyTests {
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 1, 0, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 1, 0, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 0, 1, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 0, 1, "Battery2");
|
||||||
var battery3 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 1, 0, "Battery3");
|
var battery3 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 1, 0, "Battery3");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
battery3.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery2 some energy
|
// Give battery2 some energy
|
||||||
battery2.energy = 16;
|
battery2.energy = 16;
|
||||||
|
@ -263,9 +270,9 @@ public class EnergyTests {
|
||||||
System.out.println("Battery3 energy: " + battery3.energy);
|
System.out.println("Battery3 energy: " + battery3.energy);
|
||||||
|
|
||||||
// Battery1 and battery3 should have gained 8 energy and battery2 should have lost 16 energy
|
// Battery1 and battery3 should have gained 8 energy and battery2 should have lost 16 energy
|
||||||
assertWithError(8, battery1.energy);
|
assertEquals(8, battery1.energy);
|
||||||
assertWithError(0, battery2.energy);
|
assertEquals(0, battery2.energy);
|
||||||
assertWithError(8, battery3.energy);
|
assertEquals(8, battery3.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -276,6 +283,9 @@ public class EnergyTests {
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(1, 0, 0), 16, 1, 0, "Battery2");
|
||||||
var battery3 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 0, 1, "Battery3");
|
var battery3 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 0, 1, "Battery3");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
battery3.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 and battery3 some energy
|
// Give battery1 and battery3 some energy
|
||||||
battery1.energy = 8;
|
battery1.energy = 8;
|
||||||
|
@ -294,35 +304,9 @@ public class EnergyTests {
|
||||||
System.out.println("Battery3 energy: " + battery3.energy);
|
System.out.println("Battery3 energy: " + battery3.energy);
|
||||||
|
|
||||||
// Battery2 should have 16 energy and battery1 and battery3 should have 0 energy
|
// Battery2 should have 16 energy and battery1 and battery3 should have 0 energy
|
||||||
assertWithError(0, battery1.energy);
|
assertEquals(0, battery1.energy);
|
||||||
assertWithError(16, battery2.energy);
|
assertEquals(16, battery2.energy);
|
||||||
assertWithError(0, battery3.energy);
|
assertEquals(0, battery3.energy);
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnergyTransferWithRange() {
|
|
||||||
System.out.println("Energy transfer with range test");
|
|
||||||
// Create two batteries with coordinates (0, 0, 0) and (2, 0, 0)
|
|
||||||
// Battery1 should be able to provide energy to battery2
|
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 1, 0, "Battery2");
|
|
||||||
|
|
||||||
// Give battery1 some energy
|
|
||||||
battery1.energy = 16;
|
|
||||||
|
|
||||||
// Tick the batteries 10 times
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
SimpleCodeOnlyBattery.tick(battery1);
|
|
||||||
SimpleCodeOnlyBattery.tick(battery2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output the energy of the batteries
|
|
||||||
System.out.println("Battery1 energy: " + battery1.energy);
|
|
||||||
System.out.println("Battery2 energy: " + battery2.energy);
|
|
||||||
|
|
||||||
// Battery1 should have lost no energy and battery2 should have gained no energy
|
|
||||||
assertWithError(16, battery1.energy);
|
|
||||||
assertWithError(0, battery2.energy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -333,6 +317,9 @@ public class EnergyTests {
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 16, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(2, 0, 0), 16, 1, 0, "Battery2");
|
||||||
var cable = new SimpleCodeOnlyCable(new Vec3i(1, 0, 0), 1, 1, 1, "Cable");
|
var cable = new SimpleCodeOnlyCable(new Vec3i(1, 0, 0), 1, 1, 1, "Cable");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
cable.onLoad(null, null);
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
battery1.energy = 16;
|
battery1.energy = 16;
|
||||||
|
@ -352,9 +339,9 @@ public class EnergyTests {
|
||||||
System.out.println("Cable energy: " + cable.energy);
|
System.out.println("Cable energy: " + cable.energy);
|
||||||
|
|
||||||
// Battery1 should have lost 16 energy, battery2 should have gained 15 energy, and the cable should have 1 energy
|
// Battery1 should have lost 16 energy, battery2 should have gained 15 energy, and the cable should have 1 energy
|
||||||
assertWithError(1, cable.energy);
|
assertEquals(0, cable.energy);
|
||||||
assertWithError(0, battery1.energy);
|
assertEquals(0, battery1.energy);
|
||||||
assertWithError(15, battery2.energy);
|
assertEquals(16, battery2.energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -364,9 +351,13 @@ public class EnergyTests {
|
||||||
// Battery1 should be able to provide energy to battery2
|
// Battery1 should be able to provide energy to battery2
|
||||||
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 32, 0, 1, "Battery1");
|
var battery1 = new SimpleCodeOnlyBattery(new Vec3i(0, 0, 0), 32, 0, 1, "Battery1");
|
||||||
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(11, 0, 0), 16, 1, 0, "Battery2");
|
var battery2 = new SimpleCodeOnlyBattery(new Vec3i(11, 0, 0), 16, 1, 0, "Battery2");
|
||||||
|
battery1.onLoad(null, null);
|
||||||
|
battery2.onLoad(null, null);
|
||||||
|
|
||||||
var cables = new SimpleCodeOnlyCable[10];
|
var cables = new SimpleCodeOnlyCable[10];
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
cables[i] = new SimpleCodeOnlyCable(new Vec3i(i + 1, 0, 0), 16, 1, 1, "Cable" + (i + 1));
|
cables[i] = new SimpleCodeOnlyCable(new Vec3i(i + 1, 0, 0), 16, 1, 1, "Cable" + (i + 1));
|
||||||
|
cables[i].onLoad(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give battery1 some energy
|
// Give battery1 some energy
|
||||||
|
@ -399,6 +390,7 @@ public class EnergyTests {
|
||||||
var batteries = new SimpleCodeOnlyBattery[1000];
|
var batteries = new SimpleCodeOnlyBattery[1000];
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
batteries[i] = new SimpleCodeOnlyBattery(new Vec3i(i, 0, 0), 16, 1, 2, "Battery" + i);
|
batteries[i] = new SimpleCodeOnlyBattery(new Vec3i(i, 0, 0), 16, 1, 2, "Battery" + i);
|
||||||
|
batteries[i].onLoad(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give the first battery some energy
|
// Give the first battery some energy
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
import arzumify.located.math.Vec3i;
|
||||||
import arzumify.polyenergy.api.EnergyProvider;
|
import arzumify.polyenergy.api.EnergyProvider;
|
||||||
import arzumify.polyenergy.api.EnergyReceiver;
|
import arzumify.polyenergy.api.EnergyReceiver;
|
||||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
import arzumify.polyenergy.impl.MatchMaker;
|
||||||
import arzumify.presence.presences.IntegerPresence;
|
|
||||||
import arzumify.presence.presences.Presence;
|
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.Vec3i;
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@ -19,20 +19,18 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
||||||
public final long capacity;
|
public final long capacity;
|
||||||
public final long inputRate;
|
public final long inputRate;
|
||||||
public final long outputRate;
|
public final long outputRate;
|
||||||
public final IntegerPresence presence;
|
public final Vec3i pos;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
public final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
||||||
|
public final Set<EnergyReceiver> receivers = ConcurrentHashMap.newKeySet();
|
||||||
public long energy = 0;
|
public long energy = 0;
|
||||||
public boolean providing = false;
|
|
||||||
|
|
||||||
public SimpleCodeOnlyBattery(Vec3i pos, long capacity, long inputRate, long outputRate, String name) {
|
public SimpleCodeOnlyBattery(Vec3i pos, long capacity, long inputRate, long outputRate, String name) {
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
this.inputRate = inputRate;
|
this.inputRate = inputRate;
|
||||||
this.outputRate = outputRate;
|
this.outputRate = outputRate;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.presence = new IntegerPresence((short) 1, new arzumify.presence.maths.Vec3i(pos.getX(), pos.getY(), pos.getZ()));
|
this.pos = pos;
|
||||||
CoordinateMatchMaker.addProvider(this);
|
|
||||||
CoordinateMatchMaker.addReceiver(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick(SimpleCodeOnlyBattery battery) {
|
public static void tick(SimpleCodeOnlyBattery battery) {
|
||||||
|
@ -47,34 +45,30 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
||||||
battery.energy += extracted;
|
battery.energy += extracted;
|
||||||
leftToFill -= extracted;
|
leftToFill -= extracted;
|
||||||
}
|
}
|
||||||
if (!battery.providing && battery.energy > 0) {
|
|
||||||
CoordinateMatchMaker.addProvider(battery);
|
|
||||||
battery.providing = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long extract(long amount, EnergyReceiver receiver) {
|
public long extract(long amount, EnergyReceiver receiver) {
|
||||||
if (providing) {
|
System.out.println(name + " extracting " + amount + " energy");
|
||||||
System.out.println(name + " extracting " + amount + " energy");
|
long extracted = Math.min(Math.min(outputRate, amount), energy);
|
||||||
long extracted = Math.min(Math.min(outputRate, amount), energy);
|
energy -= extracted;
|
||||||
energy -= extracted;
|
System.out.println(name + " extracted " + extracted + " energy");
|
||||||
System.out.println(name + " extracted " + extracted + " energy");
|
return extracted;
|
||||||
if (energy == 0) {
|
|
||||||
CoordinateMatchMaker.removeProvider(this);
|
|
||||||
}
|
|
||||||
return extracted;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exists(EnergyReceiver receiver) {
|
public void ready(EnergyReceiver receiver) {
|
||||||
System.out.println(name + " found other receiver");
|
System.out.println(name + " found other receiver");
|
||||||
|
receivers.add(receiver);
|
||||||
receiver.ready(this);
|
receiver.ready(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unready(EnergyReceiver receiver) {
|
||||||
|
System.out.println(name + " lost other receiver");
|
||||||
|
receivers.remove(receiver);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ready(EnergyProvider provider) {
|
public void ready(EnergyProvider provider) {
|
||||||
System.out.println(name + " found other provider");
|
System.out.println(name + " found other provider");
|
||||||
|
@ -89,22 +83,44 @@ public class SimpleCodeOnlyBattery implements EnergyProvider, EnergyReceiver, Se
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||||
if (energy > 0) {
|
MatchMaker.matchMaker.Add(this);
|
||||||
CoordinateMatchMaker.addProvider(this);
|
reload();
|
||||||
providing = true;
|
|
||||||
}
|
|
||||||
CoordinateMatchMaker.addReceiver(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||||
CoordinateMatchMaker.removeProvider(this);
|
MatchMaker.matchMaker.Remove(this);
|
||||||
CoordinateMatchMaker.removeReceiver(this);
|
for (EnergyProvider provider : providers) {
|
||||||
|
provider.unready(this);
|
||||||
|
}
|
||||||
|
for (EnergyReceiver receiver : receivers) {
|
||||||
|
receiver.unready(this);
|
||||||
|
}
|
||||||
providers.clear();
|
providers.clear();
|
||||||
|
receivers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Presence<IntegerPresence> presence() {
|
public Collection<arzumify.located.math.Vec3i> points() {
|
||||||
return presence;
|
return List.of(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String dimension() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
var found = MatchMaker.matchMaker.Search(this);
|
||||||
|
if (found != null) {
|
||||||
|
for (var foundEnergyBlocks : found) {
|
||||||
|
if (foundEnergyBlocks instanceof EnergyProvider && !providers.contains(foundEnergyBlocks)) {
|
||||||
|
((EnergyProvider) foundEnergyBlocks).ready(this);
|
||||||
|
}
|
||||||
|
if (foundEnergyBlocks instanceof EnergyReceiver && !receivers.contains(foundEnergyBlocks)) {
|
||||||
|
((EnergyReceiver) foundEnergyBlocks).ready(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
import arzumify.located.math.Vec3i;
|
||||||
import arzumify.polyenergy.api.EnergyProvider;
|
import arzumify.polyenergy.api.EnergyProvider;
|
||||||
import arzumify.polyenergy.api.EnergyReceiver;
|
import arzumify.polyenergy.api.EnergyReceiver;
|
||||||
import arzumify.polyenergy.impl.CoordinateMatchMaker;
|
import arzumify.polyenergy.impl.MatchMaker;
|
||||||
import arzumify.presence.presences.IntegerPresence;
|
|
||||||
import arzumify.presence.presences.Presence;
|
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.Vec3i;
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@ -16,18 +16,18 @@ public class SimpleCodeOnlyCable implements EnergyProvider, EnergyReceiver, Serv
|
||||||
public final long capacity;
|
public final long capacity;
|
||||||
public final long inputRate;
|
public final long inputRate;
|
||||||
public final long outputRate;
|
public final long outputRate;
|
||||||
public final IntegerPresence presence;
|
public final Vec3i pos;
|
||||||
public final String name;
|
public final String name;
|
||||||
public long energy = 0;
|
public long energy = 0;
|
||||||
public final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
public final Set<EnergyProvider> providers = ConcurrentHashMap.newKeySet();
|
||||||
|
public final Set<EnergyReceiver> receivers = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
public SimpleCodeOnlyCable(Vec3i pos, long capacity, long inputRate, long outputRate, String name) {
|
public SimpleCodeOnlyCable(Vec3i pos, long capacity, long inputRate, long outputRate, String name) {
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
this.inputRate = inputRate;
|
this.inputRate = inputRate;
|
||||||
this.outputRate = outputRate;
|
this.outputRate = outputRate;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.presence = new IntegerPresence((short) 1, new arzumify.presence.maths.Vec3i(pos.getX(), pos.getY(), pos.getZ()));
|
this.pos = pos;
|
||||||
CoordinateMatchMaker.addReceiver(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick(SimpleCodeOnlyCable cable) {
|
public static void tick(SimpleCodeOnlyCable cable) {
|
||||||
|
@ -54,44 +54,69 @@ public class SimpleCodeOnlyCable implements EnergyProvider, EnergyReceiver, Serv
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exists(EnergyReceiver receiver) {
|
public void ready(EnergyReceiver receiver) {
|
||||||
System.out.println(name + " found other receiver");
|
System.out.println(name + " found other receiver");
|
||||||
if (!providers.isEmpty()) {
|
receivers.add(receiver);
|
||||||
receiver.ready(this);
|
receiver.ready(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unready(EnergyReceiver receiver) {
|
||||||
|
System.out.println(name + " lost other receiver");
|
||||||
|
receivers.remove(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ready(EnergyProvider provider) {
|
public void ready(EnergyProvider provider) {
|
||||||
System.out.println(name + " found other provider");
|
System.out.println(name + " found other provider");
|
||||||
providers.add(provider);
|
providers.add(provider);
|
||||||
if (providers.size() == 1) {
|
|
||||||
CoordinateMatchMaker.addProvider(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unready(EnergyProvider provider) {
|
public void unready(EnergyProvider provider) {
|
||||||
providers.remove(provider);
|
providers.remove(provider);
|
||||||
if (providers.isEmpty()) {
|
|
||||||
CoordinateMatchMaker.removeProvider(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
public void onLoad(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||||
CoordinateMatchMaker.addReceiver(this);
|
MatchMaker.matchMaker.Add(this);
|
||||||
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
public void onUnload(BlockEntity blockEntity, ServerWorld serverWorld) {
|
||||||
CoordinateMatchMaker.removeProvider(this);
|
MatchMaker.matchMaker.Remove(this);
|
||||||
CoordinateMatchMaker.removeReceiver(this);
|
for (EnergyReceiver receiver : receivers) {
|
||||||
|
receiver.unready(this);
|
||||||
|
}
|
||||||
|
for (EnergyProvider provider : providers) {
|
||||||
|
provider.unready(this);
|
||||||
|
}
|
||||||
providers.clear();
|
providers.clear();
|
||||||
|
receivers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Presence<IntegerPresence> presence() {
|
public Collection<Vec3i> points() {
|
||||||
return presence;
|
return List.of(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String dimension() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
var found = MatchMaker.matchMaker.Search(this);
|
||||||
|
if (found != null) {
|
||||||
|
for (var foundEnergyBlocks : found) {
|
||||||
|
if (foundEnergyBlocks instanceof EnergyProvider && !providers.contains(foundEnergyBlocks)) {
|
||||||
|
((EnergyProvider) foundEnergyBlocks).ready(this);
|
||||||
|
}
|
||||||
|
if (foundEnergyBlocks instanceof EnergyReceiver && !receivers.contains(foundEnergyBlocks)) {
|
||||||
|
((EnergyReceiver) foundEnergyBlocks).ready(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue