Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement locks #13

Open
wants to merge 14 commits into
base: develop/1.14.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ sourceSets {
}

configurations {
//Inform the alternate sourcesets about forge
apiCompile.extendsFrom(compile)
testCompile.extendsFrom(compile)
}

test {
Expand All @@ -60,14 +62,32 @@ minecraft {
runs {
client {
workingDirectory project.file("run")
source sourceSets.main
source sourceSets.api
mods {
epos {
source sourceSets.main
source sourceSets.api
}
}
}

server {
workingDirectory project.file("run")
source sourceSets.main
source sourceSets.api
mods {
epos {
source sourceSets.main
source sourceSets.api
}
}
}

data {
workingDirectory project.file("run")
mods {
epos {
source sourceSets.main
source sourceSets.api
}
}
}
}
}
Expand All @@ -83,7 +103,7 @@ dependencies {
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_version}"

minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
compile fg.deobf('com.hrznstudio:titanium:2.1.+')
compile fg.deobf("com.hrznstudio:titanium:${minecraft_version}-${titanium_version}")
}

task srcJar(type: Jar) {
Expand Down Expand Up @@ -166,8 +186,4 @@ static String getBuildNumber() {
buildNumber = System.getenv("bamboo_buildNumber") != null ? System.getenv("bamboo_buildNumber") : ""
}
return buildNumber
}

configurations {
apiCompile.extendsFrom(compile)
}
}
7 changes: 4 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
minecraft_version=1.14.4
forge_version=28.0.45
mappings_version=20190810-1.14.3
forge_version=28.1.90
mappings_version=20191119-1.14.3

base_version=4.0.0
junit_version=5.5.0
junit_version=5.5.2
titanium_version=2.2.+

team=Team Acronym Coders
group=com.teamacronymcoders
Expand Down
3 changes: 3 additions & 0 deletions src/api/java/com/teamacronymcoders/epos/api/EposAPI.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.teamacronymcoders.epos.api;

import com.teamacronymcoders.epos.api.feat.Feat;
import com.teamacronymcoders.epos.api.locks.LockRegistry;
import com.teamacronymcoders.epos.api.path.IPath;
import com.teamacronymcoders.epos.api.path.MissingPath;
import com.teamacronymcoders.epos.api.pathfeature.PathFeatureProvider;
Expand All @@ -20,4 +21,6 @@ public class EposAPI {
RegistryManager.ACTIVE.getRegistry(Feat.class);
public static final IForgeRegistry<PathFeatureProvider> PATH_FEATURE_PROVIDER_REGISTRY =
RegistryManager.ACTIVE.getRegistry(PathFeatureProvider.class);

public static final LockRegistry LOCK_REGISTRY = new LockRegistry();
SkySom marked this conversation as resolved.
Show resolved Hide resolved
}
6 changes: 1 addition & 5 deletions src/api/java/com/teamacronymcoders/epos/api/feat/Feat.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package com.teamacronymcoders.epos.api.feat;

import net.minecraft.util.ResourceLocation;
import java.util.List;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.registries.ForgeRegistryEntry;
import net.minecraftforge.registries.IForgeRegistry;

import javax.annotation.Nonnull;
import java.util.List;

public class Feat extends ForgeRegistryEntry<Feat> {
private final List<FeatEventHandler<?>> eventHandlers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

import com.google.common.collect.Lists;
import com.teamacronymcoders.epos.api.characterstats.ICharacterStats;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.eventbus.api.Event;
import org.apache.logging.log4j.util.TriConsumer;

import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;

@ParametersAreNonnullByDefault
public class FeatBuilder {
private final ResourceLocation registryName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.teamacronymcoders.epos.api.feat;

import com.teamacronymcoders.epos.api.characterstats.ICharacterStats;
import java.util.Objects;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.eventbus.api.Event;
import org.apache.logging.log4j.util.TriConsumer;

import java.util.Objects;

public class FeatEventHandler<T extends Event> {
public final ResourceLocation featId;
public final TriConsumer<T, LivingEntity, ICharacterStats> eventHandler;
Expand Down
11 changes: 5 additions & 6 deletions src/api/java/com/teamacronymcoders/epos/api/feat/Feats.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Maps;
import com.teamacronymcoders.epos.api.characterstats.ICharacterStats;
import net.minecraft.entity.LivingEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.eventbus.api.Event;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import net.minecraft.entity.LivingEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.eventbus.api.Event;

public class Feats implements INBTSerializable<CompoundNBT> {
private final Map<Feat, FeatSource> feats;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponent;
import net.minecraft.util.text.TranslationTextComponent;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class JsonUtils {
@Nonnull
public static String getString(JsonObject jsonObject, String fieldName) throws JsonParseException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.teamacronymcoders.epos.api.locks;

public interface IGenericFuzzyLockType {
}
161 changes: 161 additions & 0 deletions src/api/java/com/teamacronymcoders/epos/api/locks/LockRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package com.teamacronymcoders.epos.api.locks;

import com.teamacronymcoders.epos.api.locks.keys.GenericLockKey;
import com.teamacronymcoders.epos.api.locks.keys.IFuzzyLockKey;
import com.teamacronymcoders.epos.api.locks.keys.ILockKey;
import com.teamacronymcoders.epos.api.locks.keys.creator.ILockKeyCreator;
import com.teamacronymcoders.epos.api.locks.keys.creator.IMultiLockKeyCreator;
import com.teamacronymcoders.epos.api.requirements.IRequirement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;

//TODO: JavaDoc remaining methods once the RequirementCombiner system is developed,
// as the description for them may change some
public class LockRegistry {

private static final List<IRequirement> EMPTY_REQUIREMENTS = Collections.emptyList();

private final List<ILockKeyCreator<? extends ILockKey>> keyCreators = new ArrayList<>();
private final List<IMultiLockKeyCreator<? extends ILockKey>> multiKeyCreators = new ArrayList<>();
private final Map<ILockKey, List<IRequirement>> locks = new HashMap<>();
private final Map<ILockKey, Set<IFuzzyLockKey>> fuzzyLockInfo = new HashMap<>();

/**
* Unlike the 1.12 system this has it so that each lock key has one registration for each type
* it can be created from Each one has to be checked when getting by type rather than knowing
* it "should" be good for that type already
*
* @param creator A Lock Key Creator that creates keys of type KEY given an object.
* @param <KEY> The type of key the given lock creator is for.
*/
//TODO: Evaluate if there is any performance impact of checking against all compared to directly getting the subset that works
public <KEY extends ILockKey> void registerLockType(@Nonnull ILockKeyCreator<KEY> creator) {
keyCreators.add(creator);
}

/**
* @param creator A Lock Key Creator that creates multiple keys at once of type KEY given an object.
* @param <KEY> The type of key the given lock creator is for.
*/
public <KEY extends ILockKey> void registerMultiLockType(@Nonnull IMultiLockKeyCreator<KEY> creator) {
multiKeyCreators.add(creator);
}

/**
* For use in reloading, and unit tests
*/
public void clearLocks() {
locks.clear();
fuzzyLockInfo.clear();
}

public void addLockByKey(@Nonnull ILockKey key, @Nonnull List<IRequirement> requirements) {
//Don't allow having locks on the generic key that is just for when there isn't enough information about a fuzzy lock key
if (!(key instanceof GenericLockKey) && !requirements.isEmpty()) {
locks.put(key, requirements);
if (key instanceof IFuzzyLockKey) {
IFuzzyLockKey fuzzy = (IFuzzyLockKey) key;
if (!fuzzy.isNotFuzzy()) {
//Store the fuzzy instance in a list for the specific item
fuzzyLockInfo.computeIfAbsent(fuzzy.getNotFuzzy(), k -> new HashSet<>()).add(fuzzy);
}
}
}
}

/**
* Gets the requirements by the the given {@link ILockKey}. If the give key is an {@link IFuzzyLockKey},
* retrieves all requirements that match; similar to {@link #getFuzzyRequirements(IFuzzyLockKey)}.
* @param key The {@link ILockKey} to retrieve the requirements of.
* @return A {@link List} of requirements for the given {@link ILockKey}
*/
@Nonnull
public List<IRequirement> getRequirementsByKey(@Nonnull ILockKey key) {
if (key instanceof IFuzzyLockKey) {
return getFuzzyRequirements((IFuzzyLockKey) key);
}
return locks.getOrDefault(key, EMPTY_REQUIREMENTS);
}

/**
* Gets the requirements by the given {@link IFuzzyLockKey}. This includes the base "non fuzzy"
* lock key variant and any requirements that are {@link IFuzzyLockKey#fuzzyEquals(IFuzzyLockKey)}
* to the given key.
* @param key The {@link IFuzzyLockKey} to retrieve the requirements of.
* @return A {@link List} of requirements for the given {@link IFuzzyLockKey}
*/
@Nonnull
public List<IRequirement> getFuzzyRequirements(@Nonnull IFuzzyLockKey key) {
List<IRequirement> requirements = new ArrayList<>();
if (key.isNotFuzzy()) {
addRequirementsFromLock(requirements, key);
} else {
ILockKey baseLock = key.getNotFuzzy();
//Add the base lock's requirements
addRequirementsFromLock(requirements, baseLock);
Set<IFuzzyLockKey> fuzzyLookup = fuzzyLockInfo.get(baseLock);
if (fuzzyLookup != null) {
for (IFuzzyLockKey fuzzyLock : fuzzyLookup) {
if (key.fuzzyEquals(fuzzyLock)) { //Build up the best match
//fuzzy is the given object and has all info and fuzzyLock is the partial information
addRequirementsFromLock(requirements, fuzzyLock);
}
}
}
}
return requirements;
}

@Nonnull
public List<IRequirement> getLocks(@Nonnull Collection<Object> objects) {
//TODO: Helper method for combining the locks of multiple same type objects (Maybe even allow of different type objects)
// If it doesn't support different type objects should there be some optimization so it doesn't recheck all the types
List<IRequirement> requirements = new ArrayList<>();
for (Object object : objects) {
requirements.addAll(getLocks(object));
}
return requirements;
}

@Nonnull
public List<IRequirement> getLocks(@Nonnull Object object) {
List<IRequirement> requirements = new ArrayList<>();
for (ILockKeyCreator<? extends ILockKey> keyCreator : keyCreators) {
ILockKey lockKey = keyCreator.createFrom(object);
if (lockKey != null) {
//We didn't fail to create a lock key with our object,
// so we can add any requirements we find to our list of requirements.
requirements.addAll(getRequirementsByKey(lockKey));
}
}
//Handle any multi keys
for (IMultiLockKeyCreator<? extends ILockKey> keyCreator : multiKeyCreators) {
Collection<? extends ILockKey> lockKeys = keyCreator.createFrom(object);
for (ILockKey lockKey : lockKeys) {
requirements.addAll(getRequirementsByKey(lockKey));
}
}
return requirements;
}

/**
* Helper method to add a lock's requirements to the requirement list.
* If there are no requirements for the given key, do nothing.
* @param requirements List of requirements to add to
* @param key The lock key to get the requirements of.
*/
private void addRequirementsFromLock(@Nonnull List<IRequirement> requirements, @Nonnull ILockKey key) {
List<IRequirement> reqs = locks.get(key);
if (reqs != null) {
//If there are locks for the key add them
requirements.addAll(reqs);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.teamacronymcoders.epos.api.locks.keys;

import com.teamacronymcoders.epos.api.locks.IGenericFuzzyLockType;
import javax.annotation.Nonnull;

public final class GenericLockKey implements ILockKey {

@Nonnull
private IGenericFuzzyLockType type;

public GenericLockKey(@Nonnull IGenericFuzzyLockType type) {
this.type = type;
}

@Override
public boolean equals(Object o) {
return o == this || o instanceof GenericLockKey && type.equals(((GenericLockKey) o).type);
}

@Override
public int hashCode() {
return type.hashCode();
}
}
Loading