HyCodeYourTale
classpublicPriority 3

InternalReferenceResolver

com.hypixel.hytale.server.npc.asset.builder.InternalReferenceResolver

8

Methods

8

Public Methods

2

Fields

1

Constructors

Constructors

public
InternalReferenceResolver()

Methods

Public Methods (8)

public
void addBuilder(int index, BuilderInstructionReference builder)
public
<T> Builder<T> getBuilder(int index, Class<?> classType)
public
int getOrCreateIndex(String name)
public
IntSet getRecordedDependenices()
@Nullable
public
void optimise()
public
void setRecordDependencies()
public
void stopRecordingDependencies()
public
void validateInternalReferences(String configName, List<String> errors)

Fields

Private/Package Fields (2)

privateObject2IntMap<String> indexMap
privateIntSet recordedDependencies

Related Classes

Source Code

package com.hypixel.hytale.server.npc.asset.builder;

import com.hypixel.hytale.server.npc.instructions.Instruction;
import com.hypixel.hytale.server.npc.instructions.builders.BuilderInstructionReference;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class InternalReferenceResolver {
   private final List<BuilderInstructionReference> builders = new ObjectArrayList();
   @Nullable
   private Object2IntMap<String> indexMap;
   @Nullable
   private Int2ObjectMap<String> nameMap = new Int2ObjectOpenHashMap();
   @Nullable
   private IntSet recordedDependencies;

   public InternalReferenceResolver() {
      this.indexMap = new Object2IntOpenHashMap();
      this.indexMap.defaultReturnValue(-2147483648);
   }

   public int getOrCreateIndex(String name) {
      int index = this.indexMap.getInt(name);
      if (index == -2147483648) {
         index = this.builders.size();
         this.indexMap.put(name, index);
         this.nameMap.put(index, name);
         this.builders.add(null);
      }

      if (this.recordedDependencies != null) {
         this.recordedDependencies.add(index);
      }

      return index;
   }

   public void setRecordDependencies() {
      this.recordedDependencies = new IntOpenHashSet();
   }

   @Nullable
   public IntSet getRecordedDependenices() {
      return this.recordedDependencies;
   }

   public void stopRecordingDependencies() {
      this.recordedDependencies = null;
   }

   public void addBuilder(int index, BuilderInstructionReference builder) {
      Objects.requireNonNull(builder, "Builder cannot be null when adding as a reference");
      if (index < 0 || index >= this.builders.size()) {
         throw new IllegalArgumentException("Slot for putting builder must be >= 0 and < the size of the list");
      } else if (this.builders.get(index) != null) {
         throw new IllegalStateException(String.format("Duplicate internal reference builder with name: %s", this.nameMap.get(index)));
      } else {
         this.builders.set(index, builder);
      }
   }

   public void validateInternalReferences(String configName, @Nonnull List<String> errors) {
      for (int i = 0; i < this.builders.size(); i++) {
         BuilderInstructionReference builder = this.builders.get(i);
         if (builder == null) {
            errors.add(configName + ": Internal reference builder: " + (String)this.nameMap.get(i) + " doesn't exist");
         } else {
            try {
               this.validateNoCycles(builder, i, new IntArrayList());
            } catch (IllegalArgumentException var6) {
               errors.add(configName + ": " + var6.getMessage());
            }
         }
      }
   }

   private void validateNoCycles(@Nonnull BuilderInstructionReference builder, int index, @Nonnull IntArrayList path) {
      if (path.contains(index)) {
         throw new IllegalArgumentException("Cyclic reference detected for internal component reference: " + (String)this.nameMap.get(index));
      } else {
         path.add(index);
         IntIterator i = builder.getInternalDependencies().iterator();

         while (i.hasNext()) {
            int dependency = i.nextInt();
            BuilderInstructionReference nextBuilder = this.builders.get(dependency);
            if (nextBuilder == null) {
               throw new IllegalStateException("Reference to internal reference builder: " + (String)this.nameMap.get(dependency) + " which doesn't exist");
            }

            this.validateNoCycles(nextBuilder, dependency, path);
         }

         path.removeInt(path.size() - 1);
      }
   }

   public <T> Builder<T> getBuilder(int index, Class<?> classType) {
      if (classType != Instruction.class) {
         throw new IllegalArgumentException("Internal references are currently only supported for instruction list");
      } else {
         return this.builders.get(index);
      }
   }

   public void optimise() {
      this.indexMap = null;
      this.nameMap = null;
   }
}