Skip to content

Commit

Permalink
make fragments have states instead of using 3 booleans
Browse files Browse the repository at this point in the history
  • Loading branch information
burgerindividual committed Sep 22, 2020
1 parent da5744f commit 1297afa
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 51 deletions.
61 changes: 28 additions & 33 deletions src/main/java/amidst/fragment/Fragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.function.UnaryOperator;

import amidst.documentation.AmidstThread;
import amidst.documentation.CalledByAny;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.ThreadSafe;
import amidst.gui.main.viewer.Drawer;
Expand Down Expand Up @@ -91,9 +91,7 @@
public class Fragment {
public static final int SIZE = Resolution.FRAGMENT.getStep();

private final AtomicBoolean isInitialized = new AtomicBoolean(false);
private final AtomicBoolean isLoading = new AtomicBoolean(false);
private final AtomicBoolean isLoaded = new AtomicBoolean(false);
private final AtomicReference<State> state;
private volatile CoordinatesInWorld corner;

private volatile float alpha;
Expand All @@ -103,6 +101,7 @@ public class Fragment {
private final AtomicReferenceArray<List<WorldIcon>> worldIcons;

public Fragment(int numberOfLayers) {
this.state = new AtomicReference<State>(State.UNINITIALIZED);
this.images = new AtomicReferenceArray<>(numberOfLayers);
this.worldIcons = new AtomicReferenceArray<>(numberOfLayers);
}
Expand Down Expand Up @@ -161,7 +160,7 @@ public void putWorldIcons(int layerId, List<WorldIcon> icons) {
}

public List<WorldIcon> getWorldIcons(int layerId) {
if (isLoaded.get()) {
if (state.get().equals(State.LOADED)) {
List<WorldIcon> result = worldIcons.get(layerId);
if (result != null) {
return result;
Expand All @@ -170,43 +169,32 @@ public List<WorldIcon> getWorldIcons(int layerId) {
return Collections.emptyList();
}

@CalledByAny
public void setInitialized() {
this.isInitialized.set(true);
public void setState(State state) {
this.state.set(state);
}

@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
public boolean getAndSetLoading() {
return this.isLoading.getAndSet(true);
public State getState() {
return this.state.get();
}

@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
public void setLoaded() {
this.isLoading.set(false);
this.isLoaded.set(true);
public State getAndSetState(State state) {
return this.state.getAndSet(state);
}

@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
public boolean recycle() {
if (!this.isLoading.get()) {
this.isLoaded.set(false);
this.isInitialized.set(false);
return true;
} else {
return false;
}
public State updateAndGetState(UnaryOperator<State> updateFunction) {
return this.state.updateAndGet(updateFunction);
}

public boolean isInitialized() {
return isInitialized.get();
}

public boolean isLoading() {
return isLoading.get();
@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
// can only be recycled if it's not loading
public boolean tryRecycle() {
return this.state.updateAndGet(s -> s.equals(State.LOADING) ? State.LOADING : State.UNINITIALIZED).equals(State.UNINITIALIZED);
}

public boolean isLoaded() {
return isLoaded.get();
@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
// can only be recycled if it's not loading
public boolean tryRecycleNotLoaded() {
return this.state.updateAndGet(s -> s.equals(State.LOADING) || s.equals(State.LOADED) ? s : State.UNINITIALIZED).equals(State.UNINITIALIZED);
}

public void setCorner(CoordinatesInWorld corner) {
Expand All @@ -216,4 +204,11 @@ public void setCorner(CoordinatesInWorld corner) {
public CoordinatesInWorld getCorner() {
return corner;
}

public static enum State {
UNINITIALIZED,
INITIALIZED,
LOADING,
LOADED;
}
}
2 changes: 1 addition & 1 deletion src/main/java/amidst/fragment/FragmentManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public Fragment requestFragment(CoordinatesInWorld coordinates) {
cache.increaseSize();
}
fragment.setCorner(coordinates);
fragment.setInitialized();
fragment.setState(Fragment.State.INITIALIZED);
loadingQueue.offer(fragment);
return fragment;
}
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/amidst/fragment/FragmentQueueProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import amidst.documentation.CalledByAny;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.fragment.Fragment.State;
import amidst.fragment.layer.LayerManager;
import amidst.mojangapi.world.Dimension;
import amidst.settings.Setting;
Expand Down Expand Up @@ -97,19 +98,19 @@ private void processRecycleQueue() {

@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
private void loadFragment(Dimension dimension, Fragment fragment) {
if (fragment.isInitialized()) {
if (fragment.isLoaded()) {
layerManager.reloadInvalidated(dimension, fragment);
} else if (!fragment.getAndSetLoading()) {
layerManager.loadAll(dimension, fragment);
fragment.setLoaded();
}
if (fragment.getState().equals(Fragment.State.LOADED)) {
layerManager.reloadInvalidated(dimension, fragment);
} else if (!fragment.getState().equals(Fragment.State.UNINITIALIZED)
&& !fragment.getAndSetState(Fragment.State.LOADING).equals(Fragment.State.LOADING)) {
//If it's not loading, set loading and continue. If it is already loading, don't continue.
layerManager.loadAll(dimension, fragment);
fragment.setState(State.LOADED);
}
}

@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
private void recycleFragment(Fragment fragment) {
if (fragment.recycle()) {
if (fragment.tryRecycle()) {
removeFromLoadingQueue(fragment);
availableQueue.offer(fragment);
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/amidst/gui/main/viewer/Drawer.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ private void drawLayers() {
setAlphaComposite(1.0f);
g2d.setTransform(layerMatrix);
drawer.draw(fragment, g2d, time);
} else if (fragment.isLoaded()) {
} else if (fragment.getState().equals(Fragment.State.LOADED)) {
setAlphaComposite(fragment.getAlpha());
g2d.setTransform(layerMatrix);
drawer.draw(fragment, g2d, time);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private String getBiomeNameAt(CoordinatesInWorld coordinates) {
@CalledOnlyBy(AmidstThread.EDT)
private String getOverworldBiomeNameAt(CoordinatesInWorld coordinates) {
Fragment fragment = graph.getFragmentAt(coordinates);
if (fragment != null && fragment.isLoaded()) {
if (fragment != null && fragment.getState().equals(Fragment.State.LOADED)) {
long x = coordinates.getXRelativeToFragmentAs(Resolution.QUARTER);
long y = coordinates.getYRelativeToFragmentAs(Resolution.QUARTER);
short biome = fragment.getBiomeDataAt((int) x, (int) y);
Expand Down
16 changes: 9 additions & 7 deletions src/main/java/amidst/util/SwingUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.logging.AmidstLogger;

public enum SwingUtils {
;

/**
* This helps with allowing swing components to get garbage collected.
*/
Expand Down Expand Up @@ -40,9 +41,10 @@ public static void destroyComponentTree(Component c) {
}
}
}

/**
* <a href="https://bugs.openjdk.java.net/browse/JDK-4380536?focusedCommentId=12103089&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12103089">source</a>
* <a href=
* "https://bugs.openjdk.java.net/browse/JDK-4380536?focusedCommentId=12103089&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12103089">source</a>
*/
@SuppressWarnings("unchecked")
@CalledOnlyBy(AmidstThread.EDT)
Expand All @@ -61,15 +63,15 @@ public static void removeListeners(Component comp) {
} catch (Exception e) {
// It is possible that someone could create a listener
// that doesn't extend from EventListener. If so, ignore it
System.out.println("Listener " + params[0] + " does not extend EventListener");
AmidstLogger.info("Listener " + params[0] + " does not extend EventListener");
continue;
}
for (int j = 0; j < listeners.length; j++) {
try {
method.invoke(comp, new Object[] { listeners[j] });
//System.out.println("removed Listener " + name + " for comp " + comp + "\n");
//AmidstLogger.info("removed Listener " + name + " for comp " + comp + "\n");
} catch (Exception e) {
System.out.println("Cannot invoke removeListener method " + e);
AmidstLogger.info("Cannot invoke removeListener method " + e);
// Continue on. The reason for removing all listeners is to
// make sure that we don't have a listener holding on to something
// which will keep it from being garbage collected. We want to
Expand All @@ -82,7 +84,7 @@ public static void removeListeners(Component comp) {
// one argument is removePropertyChangeListener. If it is
// something other than that, flag it and move on.
if (!name.equals("removePropertyChangeListener"))
System.out.println(" Wrong number of Args " + name);
AmidstLogger.info(" Wrong number of Args " + name);
}
}
}
Expand Down

0 comments on commit 1297afa

Please sign in to comment.