Skip to content

Instantly share code, notes, and snippets.

@3TUSK
Last active January 2, 2019 07:15
Show Gist options
  • Save 3TUSK/475575dbfd255b4a7a1a73193534bded to your computer and use it in GitHub Desktop.
Save 3TUSK/475575dbfd255b4a7a1a73193534bded to your computer and use it in GitHub Desktop.
Kill roughly 80% of your boilerplate code
/*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to <http://unlicense.org/>
*/
package frogcraftrebirth.common.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import net.minecraft.advancements.ICriterionTrigger;
import net.minecraft.advancements.PlayerAdvancements;
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public abstract class AbstractCriterionTrigger<C, I extends AbstractCriterionTrigger.Instance<C>> implements ICriterionTrigger<I> {
private final ResourceLocation identifier;
// TODO (3TUSK): HashMap or IdentityHashMap?
private final Map<PlayerAdvancements, Set<Listener<I>>> trackers = new IdentityHashMap<>();
protected AbstractCriterionTrigger(ResourceLocation identifier) {
this.identifier = identifier;
}
@Override
public final ResourceLocation getId() {
return this.identifier;
}
@Override
public final void addListener(PlayerAdvancements playerAdvancements, Listener<I> listener) {
this.trackers.computeIfAbsent(playerAdvancements, unused -> new HashSet<>()).add(listener);
}
@Override
public final void removeListener(PlayerAdvancements playerAdvancements, Listener<I> listener) {
Set<Listener<I>> tracker = this.trackers.get(playerAdvancements);
if (tracker != null) {
tracker.remove(listener);
if (tracker.isEmpty()) {
this.trackers.remove(playerAdvancements);
}
}
}
@Override
public final void removeAllListeners(PlayerAdvancements playerAdvancements) {
this.trackers.remove(playerAdvancements);
}
@Override
public abstract I deserializeInstance(JsonObject json, JsonDeserializationContext context);
public final void trigger(EntityPlayerMP player, C context) {
PlayerAdvancements advancements = player.getAdvancements();
Set<Listener<I>> listeners = this.trackers.get(advancements);
if (listeners != null) {
List<Listener<I>> triggered = new ArrayList<>();
for (Listener<I> listener : listeners) {
if (listener.getCriterionInstance().test(context)) {
triggered.add(listener);
}
}
for (Listener<I> listener : triggered) {
listener.grantCriterion(advancements);
}
}
}
protected static abstract class Instance<C> extends AbstractCriterionInstance {
protected Instance(ResourceLocation identifier) {
super(identifier);
}
public abstract boolean test(C context);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment