@@ -16,80 +16,208 @@
*/
package net.tridentsdk.server.ui.bossbar;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import net.tridentsdk.chat.ChatComponent;
import net.tridentsdk.server.util.BitUtils;
import net.tridentsdk.ui.bossbar.BossBarColor;
import net.tridentsdk.ui.bossbar.BossBarDivision;

import javax.annotation.concurrent.ThreadSafe;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
* A customizable boss bar that can be used by a client.
*
* @author TridentSDK
* @since 0.5-alpha
*/
@Getter
@ThreadSafe
@NoArgsConstructor
@AllArgsConstructor
public class CustomBossBar extends AbstractBossBar {
private final AtomicReference<ChatComponent> title =
new AtomicReference<>(ChatComponent.text("Boss Bar"));
private final AtomicInteger health = new AtomicInteger();
private final AtomicReference<BossBarColor> color = new AtomicReference<>();
private final AtomicReference<BossBarDivision> division = new AtomicReference<>();
private final AtomicBoolean darkenSky = new AtomicBoolean();
private final AtomicBoolean dragonBar = new AtomicBoolean();

private volatile ChatComponent title = ChatComponent.text("Boss Bar");
private volatile float health;
private volatile BossBarColor color;
private volatile BossBarDivision division;
private volatile boolean darkenSky;
private volatile boolean dragonBar;
public CustomBossBar(ChatComponent chatComponent, int health, BossBarColor color, BossBarDivision division, boolean darkenSky, boolean dragonBar) {
this.title.set(chatComponent);
this.health.set(health);
this.color.set(color);
this.division.set(division);
this.darkenSky.set(darkenSky);
this.dragonBar.set(dragonBar);
}

@Override
public boolean isDefault() {
return false;
}

@Override
public ChatComponent getTitle() {
return this.title.get();
}

@Override
public void setTitle(ChatComponent title) {
if (title != null && !this.title.equals(title)) {
this.changedTitle = true;
this.title = title;
ChatComponent old;
while (true) {
old = this.title.get();
if (title != null && !title.equals(old)) {
if (this.title.compareAndSet(old, title)) {
this.casState(3);
break;
}
} else {
break;
}
}
}

@Override
public float getHealth() {
return Float.intBitsToFloat(this.health.get());
}

@Override
public void setHealth(float health) {
if (this.health != health) {
this.changedHealth = true;
this.health = health;
int old;
int n = Float.floatToRawIntBits(health);

while (true) {
old = this.health.get();
if (old != n) {
if (this.health.compareAndSet(old, n)) {
this.casState(2);
break;
}
} else {
break;
}
}
}

@Override
public BossBarColor getColor() {
return this.color.get();
}

@Override
public void setColor(BossBarColor color) {
if (color != null && this.color != color) {
this.changedStyle = true;
this.color = color;
BossBarColor old;
while (true) {
old = this.color.get();
if (color != null && !color.equals(old)) {
if (this.color.compareAndSet(old, color)) {
this.casState(1);
break;
}
} else {
break;
}
}
}

@Override
public BossBarDivision getDivision() {
return this.division.get();
}

@Override
public void setDivision(BossBarDivision division) {
if (division != null && this.division != division) {
this.changedStyle = true;
this.division = division;
BossBarDivision old;
while (true) {
old = this.division.get();
if (division != null && !division.equals(old)) {
if (this.division.compareAndSet(old, division)) {
this.casState(1);
break;
}
} else {
break;
}
}
}

@Override
public boolean isDarkenSky() {
return this.darkenSky.get();
}

@Override
public void setDarkenSky(boolean darkenSky) {
if (this.darkenSky != darkenSky) {
this.darkenSky = true;
this.darkenSky = darkenSky;
boolean old;

while (true) {
old = this.darkenSky.get();
if (old != darkenSky) {
if (this.darkenSky.compareAndSet(old, darkenSky)) {
break;
}
} else {
break;
}
}
}

@Override
public boolean isDragonBar() {
return this.dragonBar.get();
}

@Override
public void setDragonBar(boolean dragonBar) {
if (this.dragonBar != dragonBar) {
this.changedFlags = true;
this.dragonBar = dragonBar;
boolean old;

while (true) {
old = this.dragonBar.get();
if (old != dragonBar) {
if (this.dragonBar.compareAndSet(old, dragonBar)) {
this.casState(0);
break;
}
} else {
break;
}
}
}

/**
* Performs a compare and swap on the state field which
* indicates whether or not a particular field has
* been changed yet.
*
* @param idx the index to cas (described in
* {@link AbstractBossBar#b})
*/
private void casState(int idx) {
int b;
while (true) {
b = super.b;

// Check if bit already set
if ((b >>> idx & 1) == 1) {
break;
}

if (AbstractBossBar.STATE.compareAndSet(this, b, BitUtils.setBit(b, 0, true))) {
break;
}
}
}

@Override
public CustomBossBar clone() {
return new CustomBossBar(ChatComponent.fromJson(title.asJson().getAsJsonObject()), health, color, division, darkenSky, dragonBar);
return new CustomBossBar(ChatComponent.fromJson(this.title.get().asJson().getAsJsonObject()),
this.health.get(),
this.color.get(),
this.division.get(),
this.darkenSky.get(),
this.dragonBar.get());
}

}
}
@@ -34,6 +34,11 @@ public DefaultBossBar(/* EnderDragon dragon */) {
this.division = BossBarDivision.NO_DIVISION;
}

@Override
public boolean isDefault() {
return true;
}

@Override
public ChatComponent getTitle() {
return ChatComponent.create().setText("Just a default boss bar because #yolo");
@@ -57,7 +62,7 @@ public void setHealth(float health) {

@Override
public BossBarColor getColor() {
return color; // TODO - perhaps this needs to be changed
return this.color; // TODO - perhaps this needs to be changed
}

@Override
@@ -67,7 +72,7 @@ public void setColor(BossBarColor color) {

@Override
public BossBarDivision getDivision() {
return division;
return this.division;
}

@Override

This file was deleted.

@@ -70,7 +70,7 @@ public static int countSetBits(short s) {
* @param i the value to count bits
* @return the amount of set bits
*/
public int countSetBits(int i){
public static int countSetBits(int i) {
return countSetBits(i, 32);
}

@@ -80,7 +80,7 @@ public int countSetBits(int i){
* @param l the value to count bits
* @return the amount of set bits
*/
public int countSetBits(long l){
public static int countSetBits(long l) {
return countSetBits(l, 64);
}

@@ -91,7 +91,7 @@ public int countSetBits(long l){
* @param b the value to count unset bits
* @return the amount of unset bits
*/
public int countUnsetBits(byte b){
public static int countUnsetBits(byte b) {
return 8 - countSetBits(b, 8);
}

@@ -102,7 +102,7 @@ public int countUnsetBits(byte b){
* @param s the value to count unset bits
* @return the amount of unset bits
*/
public int countUnsetBits(short s){
public static int countUnsetBits(short s) {
return 16 - countSetBits(s, 16);
}

@@ -113,7 +113,7 @@ public int countUnsetBits(short s){
* @param i the value to count unset bits
* @return the amount of unset bits
*/
public int countUnsetBits(int i){
public static int countUnsetBits(int i) {
return 32 - countSetBits(i, 32);
}

@@ -124,7 +124,7 @@ public int countUnsetBits(int i){
* @param l the value to count unset bits
* @return the amount of set bits
*/
public int countUnsetBits(long l){
public static int countUnsetBits(long l) {
return 64 - countSetBits(l, 64);
}

@@ -137,7 +137,7 @@ public int countUnsetBits(long l){
* value
* @return the value after setting the bit
*/
public byte setBit(byte b, int bit, boolean state){
public static byte setBit(byte b, int bit, boolean state) {
return (byte) (state ? (b | 1 << bit) : (b & ~(1 << bit)));
}

@@ -149,7 +149,7 @@ public byte setBit(byte b, int bit, boolean state){
* @param state the state to set at the bit in the value
* @return the value after setting the bit
*/
public short setBit(short s, int bit, boolean state){
public static short setBit(short s, int bit, boolean state) {
return (short) (state ? (s | 1 << bit) : (s & ~(1 << bit)));
}

@@ -161,7 +161,7 @@ public short setBit(short s, int bit, boolean state){
* @param state the state to set at the bit in the value
* @return the value after setting the bit
*/
public int setBit(int i, int bit, boolean state) {
public static int setBit(int i, int bit, boolean state) {
return state ? (i | 1 << bit) : (i & ~(1 << bit));
}

@@ -173,7 +173,7 @@ public int setBit(int i, int bit, boolean state) {
* @param state the state to set at the bit in the value
* @return the value after setting the bit
*/
public long setBit(long l, int bit, boolean state) {
public static long setBit(long l, int bit, boolean state) {
return state ? (l | 1 << bit) : (l & ~(1 << bit));
}
}