diff --git a/BauSystem_API/src/de/steamwar/bausystem/shared/SizedStack.java b/BauSystem_API/src/de/steamwar/bausystem/shared/SizedStack.java new file mode 100644 index 00000000..7d503b2e --- /dev/null +++ b/BauSystem_API/src/de/steamwar/bausystem/shared/SizedStack.java @@ -0,0 +1,143 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.shared; + +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class SizedStack { + + private int maxSize; + private T[] data; + private int size; + private int head; + + public SizedStack(int size) { + this.maxSize = size; + //noinspection unchecked + this.data = (T[]) new Object[this.maxSize]; + this.head = 0; + this.size = 0; + } + + public T push(final T element) { + this.data[this.head] = element; + this.increaseHead(); + this.increaseSize(); + return element; + } + + public T pop() { + this.decreaseHead(); + this.decreaseSize(); + final T result = this.data[this.head]; + this.data[this.head] = null; + return result; + } + + public T peek() { + return this.data[this.head]; + } + + public boolean empty() { + return this.size == 0; + } + + protected boolean canEqual(final Object other) { + return other instanceof SizedStack; + } + + private void increaseHead() { + this.head++; + while (this.head > this.maxSize - 1) { + this.head -= this.maxSize; + } + } + + private void decreaseHead() { + this.head--; + while (this.head < 0) { + this.head += this.maxSize; + } + } + + private void increaseSize() { + if (this.size < this.maxSize) { + this.size++; + } + } + + private void decreaseSize() { + if (this.size > 0) { + this.size--; + } + } + + @Override + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + this.maxSize; + result = result * PRIME + this.toString().hashCode(); + result = result * PRIME + this.size; + return result; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof SizedStack)) { + return false; + } + final SizedStack other = (SizedStack) o; + if (!other.canEqual(this)) { + return false; + } + if (this.maxSize != other.maxSize) { + return false; + } + if (this.size != other.size) { + return false; + } + if (!this.data.getClass().equals(other.data.getClass())) { + return false; + } + return this.toString().equals(other.toString()); + } + + public int getMaxSize() { + return maxSize; + } + + public int getSize() { + return size; + } + + @Override + public String toString() { + final StringBuilder result = new StringBuilder("["); + for (int i = 0; i < this.size - 1; i++) { + result.append(this.data[(this.head - i - 1 < 0) ? (this.head - i - 1 + this.maxSize) : (this.head - i - 1)]).append(","); + } + result.append(this.data[(this.head - this.size < 0) ? (this.head - this.size + this.maxSize) : (this.head - this.size)]); + result.append("]"); + return result.toString(); + } +}