Ondřej Hruška 11 years ago
commit d8530f2f1a
  1. 24
      .classpath
  2. 133
      src/mightypork/rogue/App.java
  3. 21
      src/mightypork/rogue/AppAccess.java
  4. 31
      src/mightypork/rogue/AppAdapter.java
  5. 43
      src/mightypork/rogue/Config.java
  6. 9
      src/mightypork/rogue/Const.java
  7. 5
      src/mightypork/rogue/CrashHandler.java
  8. 9
      src/mightypork/rogue/Paths.java
  9. 78
      src/mightypork/rogue/bus/DelegatingBusClient.java
  10. 8
      src/mightypork/rogue/bus/SimpleBusClient.java
  11. 13
      src/mightypork/rogue/bus/UpdateReceiver.java
  12. 41
      src/mightypork/rogue/bus/events/KeyboardEvent.java
  13. 61
      src/mightypork/rogue/bus/events/MouseButtonEvent.java
  14. 29
      src/mightypork/rogue/bus/events/MouseMotionEvent.java
  15. 28
      src/mightypork/rogue/bus/events/ScreenChangeEvent.java
  16. 20
      src/mightypork/rogue/bus/events/UpdateEvent.java
  17. 80
      src/mightypork/rogue/display/DisplaySystem.java
  18. 136
      src/mightypork/rogue/display/Screen.java
  19. 55
      src/mightypork/rogue/display/ScreenTestAnimations.java
  20. 3
      src/mightypork/rogue/display/constraints/Bounding.java
  21. 29
      src/mightypork/rogue/display/constraints/Constraint.java
  22. 5
      src/mightypork/rogue/display/rendering/Renderable.java
  23. 9
      src/mightypork/rogue/display/rendering/ScreenLayer.java
  24. 5
      src/mightypork/rogue/fonts/Align.java
  25. 283
      src/mightypork/rogue/fonts/FontManager.java
  26. 23
      src/mightypork/rogue/fonts/Fonts.java
  27. 316
      src/mightypork/rogue/fonts/LoadedFont.java
  28. 53
      src/mightypork/rogue/input/InputSystem.java
  29. 18
      src/mightypork/rogue/input/KeyBinder.java
  30. 27
      src/mightypork/rogue/input/KeyBinding.java
  31. 28
      src/mightypork/rogue/input/KeyBindingPool.java
  32. 57
      src/mightypork/rogue/input/KeyStroke.java
  33. 157
      src/mightypork/rogue/sounds/AudioX.java
  34. 47
      src/mightypork/rogue/sounds/BaseAudioPlayer.java
  35. 21
      src/mightypork/rogue/sounds/EffectPlayer.java
  36. 20
      src/mightypork/rogue/sounds/JointVolume.java
  37. 81
      src/mightypork/rogue/sounds/LoopPlayer.java
  38. 9
      src/mightypork/rogue/sounds/NullAudio.java
  39. 180
      src/mightypork/rogue/sounds/SoundSystem.java
  40. 25
      src/mightypork/rogue/tasks/TaskTakeScreenshot.java
  41. 47
      src/mightypork/rogue/testing/TestConstraints.java
  42. 123
      src/mightypork/rogue/testing/TestMsgbus.java
  43. 29
      src/mightypork/rogue/textures/TextureManager.java
  44. 15
      src/mightypork/rogue/textures/Textures.java
  45. 15
      src/mightypork/rogue/textures/Tx.java
  46. 55
      src/mightypork/rogue/textures/TxQuad.java
  47. 821
      src/mightypork/rogue/util/RenderUtils.java
  48. 3
      src/mightypork/rogue/util/Utils.java
  49. 92
      src/mightypork/utils/files/FileTreeDiff.java
  50. 313
      src/mightypork/utils/files/FileUtils.java
  51. 74
      src/mightypork/utils/files/OsUtils.java
  52. 491
      src/mightypork/utils/files/PropertyManager.java
  53. 110
      src/mightypork/utils/files/SimpleConfig.java
  54. 73
      src/mightypork/utils/files/ZipBuilder.java
  55. 136
      src/mightypork/utils/files/ZipUtils.java
  56. 36
      src/mightypork/utils/files/ion/AbstractIonList.java
  57. 53
      src/mightypork/utils/files/ion/AbstractIonMap.java
  58. 124
      src/mightypork/utils/files/ion/Ion.java
  59. 17
      src/mightypork/utils/files/ion/IonException.java
  60. 93
      src/mightypork/utils/files/ion/IonList.java
  61. 97
      src/mightypork/utils/files/ion/IonMap.java
  62. 31
      src/mightypork/utils/files/ion/IonMarks.java
  63. 17
      src/mightypork/utils/files/ion/Ionizable.java
  64. 3
      src/mightypork/utils/files/ion/IonizableOptional.java
  65. 139
      src/mightypork/utils/files/ion/StreamUtils.java
  66. 117
      src/mightypork/utils/logging/Log.java
  67. 201
      src/mightypork/utils/logging/LogInstance.java
  68. 7
      src/mightypork/utils/logging/LogMonitor.java
  69. 15
      src/mightypork/utils/logging/LogToSysoutMonitor.java
  70. 577
      src/mightypork/utils/math/Calc.java
  71. 94
      src/mightypork/utils/math/Polar.java
  72. 98
      src/mightypork/utils/math/Range.java
  73. 83
      src/mightypork/utils/math/color/HSV.java
  74. 201
      src/mightypork/utils/math/color/RGB.java
  75. 561
      src/mightypork/utils/math/coord/Coord.java
  76. 41
      src/mightypork/utils/math/coord/CoordAnimated.java
  77. 446
      src/mightypork/utils/math/coord/Rect.java
  78. 161
      src/mightypork/utils/math/easing/Easing.java
  79. 149
      src/mightypork/utils/objects/Convertor.java
  80. 38
      src/mightypork/utils/objects/Mutable.java
  81. 52
      src/mightypork/utils/objects/ObjectUtils.java
  82. 51
      src/mightypork/utils/objects/Pair.java
  83. 54
      src/mightypork/utils/objects/Triad.java
  84. 24
      src/mightypork/utils/objects/VarargsParser.java
  85. 3
      src/mightypork/utils/patterns/Destroyable.java
  86. 9
      src/mightypork/utils/patterns/subscription/Handleable.java
  87. 72
      src/mightypork/utils/patterns/subscription/MessageBus.java
  88. 86
      src/mightypork/utils/patterns/subscription/MessageChannel.java
  89. 9
      src/mightypork/utils/patterns/subscription/clients/DelegatingClient.java
  90. 5
      src/mightypork/utils/patterns/subscription/clients/ToggleableClient.java
  91. 92
      src/mightypork/utils/string/StringUtils.java
  92. 3
      src/mightypork/utils/string/validation/CharValidator.java
  93. 13
      src/mightypork/utils/string/validation/CharValidatorRegex.java
  94. 13
      src/mightypork/utils/string/validation/CharValidatorWhitelist.java
  95. 22
      src/mightypork/utils/string/validation/FileSuffixFilter.java
  96. 5
      src/mightypork/utils/string/validation/FilenameCharValidator.java
  97. 3
      src/mightypork/utils/string/validation/StringFilter.java
  98. 22
      src/mightypork/utils/time/FpsMeter.java
  99. 13
      src/mightypork/utils/time/Pauseable.java
  100. 17
      src/mightypork/utils/time/TimerDelta.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -2,34 +2,34 @@
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/jinput.jar" sourcepath="lib/lwjgl-source-2.8.4.zip"> <classpathentry kind="lib" path="lib/jinput.jar" sourcepath="lib">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="PR2-game/lib"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Rogue/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/jogg-0.0.7.jar"> <classpathentry kind="lib" path="lib/jogg-0.0.7.jar" sourcepath="lib">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="PR2-game/lib"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Rogue/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/jorbis-0.0.15.jar" sourcepath="lib/lwjgl-source-2.8.4.zip"> <classpathentry kind="lib" path="lib/jorbis-0.0.15.jar" sourcepath="lib">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="PR2-game/lib"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Rogue/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/lwjgl_util.jar" sourcepath="lib/lwjgl-source-2.8.4.zip"> <classpathentry kind="lib" path="lib/lwjgl_util.jar" sourcepath="lib">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="PR2-game/lib"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Rogue/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/lwjgl.jar" sourcepath="lib/lwjgl-source-2.8.4.zip"> <classpathentry kind="lib" path="lib/lwjgl.jar" sourcepath="lib">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="PR2-game/lib"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Rogue/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/slick-util.jar" sourcepath="lib/slick-util-src.zip"> <classpathentry kind="lib" path="lib/slick-util.jar" sourcepath="lib">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="PR2-game/lib"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Rogue/lib"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>

@ -1,6 +1,5 @@
package mightypork.rogue; package mightypork.rogue;
import java.io.File; import java.io.File;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
@ -31,40 +30,40 @@ import org.lwjgl.input.Keyboard;
* @author MightyPork * @author MightyPork
*/ */
public class App implements Destroyable, AppAccess { public class App implements Destroyable, AppAccess {
/** instance pointer */ /** instance pointer */
private static App inst; private static App inst;
private InputSystem input; private InputSystem input;
private SoundSystem sounds; private SoundSystem sounds;
private DisplaySystem display; private DisplaySystem display;
private MessageBus events; private MessageBus events;
/** current screen */ /** current screen */
private Screen screen; private Screen screen;
/** Flag that screenshot is scheduled to be taken next loop */ /** Flag that screenshot is scheduled to be taken next loop */
private boolean scheduledScreenshot = false; private boolean scheduledScreenshot = false;
/** /**
* @param args * @param args
*/ */
public static void main(String[] args) public static void main(String[] args)
{ {
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler()); Thread.setDefaultUncaughtExceptionHandler(new CrashHandler());
inst = new App(); inst = new App();
try { try {
inst.start(); inst.start();
} catch (Throwable t) { } catch (Throwable t) {
onCrash(t); onCrash(t);
} }
} }
/** /**
* Handle a crash * Handle a crash
* *
@ -73,19 +72,19 @@ public class App implements Destroyable, AppAccess {
public static void onCrash(Throwable error) public static void onCrash(Throwable error)
{ {
Log.e("The game has crashed.", error); Log.e("The game has crashed.", error);
if (inst != null) inst.shutdown(); if (inst != null) inst.shutdown();
} }
@Override @Override
public void shutdown() public void shutdown()
{ {
destroy(); destroy();
System.exit(0); System.exit(0);
} }
public void initialize() public void initialize()
{ {
Log.i("Initializing subsystems"); Log.i("Initializing subsystems");
@ -96,8 +95,8 @@ public class App implements Destroyable, AppAccess {
initSound(); initSound();
initInput(); initInput();
} }
@Override @Override
public void destroy() public void destroy()
{ {
@ -105,15 +104,15 @@ public class App implements Destroyable, AppAccess {
if (input != null) input.destroy(); if (input != null) input.destroy();
if (display != null) display.destroy(); if (display != null) display.destroy();
} }
private void initLock() private void initLock()
{ {
if (!Config.SINGLE_INSTANCE) return; if (!Config.SINGLE_INSTANCE) return;
if (!lockInstance()) { if (!lockInstance()) {
System.out.println("Working directory is locked.\nOnly one instance can run at a time."); System.out.println("Working directory is locked.\nOnly one instance can run at a time.");
//@formatter:off //@formatter:off
JOptionPane.showMessageDialog( JOptionPane.showMessageDialog(
null, null,
@ -122,13 +121,13 @@ public class App implements Destroyable, AppAccess {
JOptionPane.ERROR_MESSAGE JOptionPane.ERROR_MESSAGE
); );
//@formatter:on //@formatter:on
shutdown(); shutdown();
return; return;
} }
} }
private boolean lockInstance() private boolean lockInstance()
{ {
final File lockFile = new File(Paths.WORKDIR, ".lock"); final File lockFile = new File(Paths.WORKDIR, ".lock");
@ -137,7 +136,7 @@ public class App implements Destroyable, AppAccess {
final FileLock fileLock = randomAccessFile.getChannel().tryLock(); final FileLock fileLock = randomAccessFile.getChannel().tryLock();
if (fileLock != null) { if (fileLock != null) {
Runtime.getRuntime().addShutdownHook(new Thread() { Runtime.getRuntime().addShutdownHook(new Thread() {
@Override @Override
public void run() public void run()
{ {
@ -159,8 +158,8 @@ public class App implements Destroyable, AppAccess {
} }
return false; return false;
} }
/** /**
* initialize inputs * initialize inputs
*/ */
@ -168,11 +167,11 @@ public class App implements Destroyable, AppAccess {
{ {
events = new MessageBus(); events = new MessageBus();
events.subscribe(this); events.subscribe(this);
events.createChannel(UpdateEvent.class, UpdateEvent.Listener.class); events.createChannel(UpdateEvent.class, UpdateEvent.Listener.class);
} }
/** /**
* initialize sound system * initialize sound system
*/ */
@ -181,17 +180,17 @@ public class App implements Destroyable, AppAccess {
sounds = new SoundSystem(this); sounds = new SoundSystem(this);
sounds.setMasterVolume(1); sounds.setMasterVolume(1);
} }
/** /**
* initialize inputs * initialize inputs
*/ */
private void initInput() private void initInput()
{ {
input = new InputSystem(this); input = new InputSystem(this);
input.bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() { input.bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() {
@Override @Override
public void run() public void run()
{ {
@ -199,9 +198,9 @@ public class App implements Destroyable, AppAccess {
scheduledScreenshot = true; scheduledScreenshot = true;
} }
}); });
input.bindKeyStroke(new KeyStroke(false, Keyboard.KEY_F11), new Runnable() { input.bindKeyStroke(new KeyStroke(false, Keyboard.KEY_F11), new Runnable() {
@Override @Override
public void run() public void run()
{ {
@ -209,9 +208,9 @@ public class App implements Destroyable, AppAccess {
display.switchFullscreen(); display.switchFullscreen();
} }
}); });
input.bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() { input.bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() {
@Override @Override
public void run() public void run()
{ {
@ -220,8 +219,8 @@ public class App implements Destroyable, AppAccess {
} }
}); });
} }
/** /**
* initialize display * initialize display
*/ */
@ -231,8 +230,8 @@ public class App implements Destroyable, AppAccess {
display.createMainWindow(Const.WINDOW_W, Const.WINDOW_H, true, Config.START_IN_FS, Const.TITLEBAR); display.createMainWindow(Const.WINDOW_W, Const.WINDOW_H, true, Config.START_IN_FS, Const.TITLEBAR);
display.setTargetFps(Const.FPS_RENDER); display.setTargetFps(Const.FPS_RENDER);
} }
/** /**
* initialize main logger * initialize main logger
*/ */
@ -242,41 +241,41 @@ public class App implements Destroyable, AppAccess {
li.enable(Config.LOGGING_ENABLED); li.enable(Config.LOGGING_ENABLED);
li.enableSysout(Config.LOG_TO_STDOUT); li.enableSysout(Config.LOG_TO_STDOUT);
} }
private void start() private void start()
{ {
initialize(); initialize();
mainLoop(); mainLoop();
shutdown(); shutdown();
} }
/** timer */ /** timer */
private TimerDelta timerRender; private TimerDelta timerRender;
private void mainLoop() private void mainLoop()
{ {
screen = new ScreenTestAnimations(this); screen = new ScreenTestAnimations(this);
screen.setActive(true); screen.setActive(true);
timerRender = new TimerDelta(); timerRender = new TimerDelta();
while (!display.isCloseRequested()) { while (!display.isCloseRequested()) {
display.beginFrame(); display.beginFrame();
events.broadcast(new UpdateEvent(timerRender.getDelta())); events.broadcast(new UpdateEvent(timerRender.getDelta()));
if (scheduledScreenshot) { if (scheduledScreenshot) {
takeScreenshot(); takeScreenshot();
scheduledScreenshot = false; scheduledScreenshot = false;
} }
display.endFrame(); display.endFrame();
} }
} }
/** /**
* Do take a screenshot * Do take a screenshot
*/ */
@ -285,12 +284,12 @@ public class App implements Destroyable, AppAccess {
sounds.getEffect("gui.shutter").play(1); sounds.getEffect("gui.shutter").play(1);
Utils.runAsThread(new TaskTakeScreenshot(display)); Utils.runAsThread(new TaskTakeScreenshot(display));
} }
// //
// static accessors // static accessors
// //
/** /**
* @return sound system of the running instance * @return sound system of the running instance
*/ */
@ -299,8 +298,8 @@ public class App implements Destroyable, AppAccess {
{ {
return sounds; return sounds;
} }
/** /**
* @return input system of the running instance * @return input system of the running instance
*/ */
@ -309,8 +308,8 @@ public class App implements Destroyable, AppAccess {
{ {
return input; return input;
} }
/** /**
* @return display system of the running instance * @return display system of the running instance
*/ */
@ -319,8 +318,8 @@ public class App implements Destroyable, AppAccess {
{ {
return display; return display;
} }
/** /**
* @return event bus * @return event bus
*/ */
@ -329,5 +328,5 @@ public class App implements Destroyable, AppAccess {
{ {
return events; return events;
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue; package mightypork.rogue;
import mightypork.rogue.display.DisplaySystem; import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.input.InputSystem; import mightypork.rogue.input.InputSystem;
import mightypork.rogue.sounds.SoundSystem; import mightypork.rogue.sounds.SoundSystem;
@ -13,35 +12,35 @@ import mightypork.utils.patterns.subscription.MessageBus;
* @author MightyPork * @author MightyPork
*/ */
public interface AppAccess { public interface AppAccess {
/** /**
* @return sound system * @return sound system
*/ */
abstract SoundSystem snd(); abstract SoundSystem snd();
/** /**
* @return input system * @return input system
*/ */
abstract InputSystem input(); abstract InputSystem input();
/** /**
* @return display system * @return display system
*/ */
abstract DisplaySystem disp(); abstract DisplaySystem disp();
/** /**
* @return event bus * @return event bus
*/ */
abstract MessageBus bus(); abstract MessageBus bus();
/** /**
* Quit to OS<br> * Quit to OS<br>
* Destroy app & exit VM * Destroy app & exit VM
*/ */
abstract void shutdown(); abstract void shutdown();
} }

@ -1,6 +1,5 @@
package mightypork.rogue; package mightypork.rogue;
import mightypork.rogue.display.DisplaySystem; import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.input.InputSystem; import mightypork.rogue.input.InputSystem;
import mightypork.rogue.sounds.SoundSystem; import mightypork.rogue.sounds.SoundSystem;
@ -13,49 +12,49 @@ import mightypork.utils.patterns.subscription.MessageBus;
* @author MightyPork * @author MightyPork
*/ */
public class AppAdapter implements AppAccess { public class AppAdapter implements AppAccess {
private AppAccess app; private AppAccess app;
public AppAdapter(AppAccess app) { public AppAdapter(AppAccess app) {
if (app == null) throw new NullPointerException("AppAccess instance cannot be null."); if (app == null) throw new NullPointerException("AppAccess instance cannot be null.");
this.app = app; this.app = app;
} }
@Override @Override
public final SoundSystem snd() public final SoundSystem snd()
{ {
return app.snd(); return app.snd();
} }
@Override @Override
public final InputSystem input() public final InputSystem input()
{ {
return app.input(); return app.input();
} }
@Override @Override
public final DisplaySystem disp() public final DisplaySystem disp()
{ {
return app.disp(); return app.disp();
} }
@Override @Override
public final MessageBus bus() public final MessageBus bus()
{ {
return app.bus(); return app.bus();
} }
@Override @Override
public void shutdown() public void shutdown()
{ {
app.shutdown(); app.shutdown();
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue; package mightypork.rogue;
import mightypork.utils.files.PropertyManager; import mightypork.utils.files.PropertyManager;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
@ -11,42 +10,42 @@ import mightypork.utils.logging.Log;
* @author MightyPork * @author MightyPork
*/ */
public class Config { public class Config {
private static PropertyManager mgr; private static PropertyManager mgr;
// opts // opts
public static final int def_LAST_RUN_VERSION = 0; public static final int def_LAST_RUN_VERSION = 0;
public static int LAST_RUN_VERSION; public static int LAST_RUN_VERSION;
public static final boolean def_START_IN_FS = false; public static final boolean def_START_IN_FS = false;
public static boolean START_IN_FS; public static boolean START_IN_FS;
// property keys // property keys
private static final String PK_LAST_RUN_VERSION = "status.last_run_version"; private static final String PK_LAST_RUN_VERSION = "status.last_run_version";
private static final String PK_START_IN_FS = "cfg.start_in_fullscreen"; private static final String PK_START_IN_FS = "cfg.start_in_fullscreen";
/** /**
* Prepare config manager and load user settings * Prepare config manager and load user settings
*/ */
public static void init() public static void init()
{ {
Log.f2("Initializing configuration manager."); Log.f2("Initializing configuration manager.");
String comment = Const.APP_NAME + " config file"; String comment = Const.APP_NAME + " config file";
mgr = new PropertyManager(Paths.CONFIG, comment); mgr = new PropertyManager(Paths.CONFIG, comment);
mgr.cfgNewlineBeforeComments(true); mgr.cfgNewlineBeforeComments(true);
mgr.cfgSeparateSections(true); mgr.cfgSeparateSections(true);
mgr.putInteger(PK_LAST_RUN_VERSION, def_LAST_RUN_VERSION); mgr.putInteger(PK_LAST_RUN_VERSION, def_LAST_RUN_VERSION);
mgr.putBoolean(PK_START_IN_FS, def_START_IN_FS); mgr.putBoolean(PK_START_IN_FS, def_START_IN_FS);
load(); // load what has been "put" load(); // load what has been "put"
} }
/** /**
* Save changed fields to config file * Save changed fields to config file
*/ */
@ -54,28 +53,28 @@ public class Config {
{ {
mgr.setValue(PK_LAST_RUN_VERSION, Const.VERSION); mgr.setValue(PK_LAST_RUN_VERSION, Const.VERSION);
mgr.setValue(PK_START_IN_FS, START_IN_FS); mgr.setValue(PK_START_IN_FS, START_IN_FS);
mgr.apply(); mgr.apply();
} }
/** /**
* Load config file and assign values to fields * Load config file and assign values to fields
*/ */
public static void load() public static void load()
{ {
mgr.apply(); mgr.apply();
LAST_RUN_VERSION = mgr.getInteger(PK_LAST_RUN_VERSION); LAST_RUN_VERSION = mgr.getInteger(PK_LAST_RUN_VERSION);
START_IN_FS = mgr.getBoolean(PK_START_IN_FS); START_IN_FS = mgr.getBoolean(PK_START_IN_FS);
} }
// options that can't be configured via config file // options that can't be configured via config file
public static boolean LOGGING_ENABLED = true; public static boolean LOGGING_ENABLED = true;
public static boolean LOG_TO_STDOUT = true; public static boolean LOG_TO_STDOUT = true;
public static boolean SINGLE_INSTANCE = true; public static boolean SINGLE_INSTANCE = true;
public static boolean LOG_FONTS = false; public static boolean LOG_FONTS = false;
} }

@ -1,23 +1,22 @@
package mightypork.rogue; package mightypork.rogue;
/** /**
* Application constants * Application constants
* *
* @author MightyPork * @author MightyPork
*/ */
public class Const { public class Const {
// STRINGS // STRINGS
public static final int VERSION = 1; public static final int VERSION = 1;
public static final String APP_NAME = "Rogue"; public static final String APP_NAME = "Rogue";
public static final String TITLEBAR = APP_NAME + " v." + VERSION; public static final String TITLEBAR = APP_NAME + " v." + VERSION;
// AUDIO // AUDIO
public static final int FPS_RENDER = 200; // max public static final int FPS_RENDER = 200; // max
public static final long FPS_GUI_UPDATE = 60; public static final long FPS_GUI_UPDATE = 60;
// INITIAL WINDOW SIZE // INITIAL WINDOW SIZE
public static final int WINDOW_W = 1024; public static final int WINDOW_W = 1024;
public static final int WINDOW_H = 768; public static final int WINDOW_H = 768;

@ -1,16 +1,15 @@
package mightypork.rogue; package mightypork.rogue;
import java.lang.Thread.UncaughtExceptionHandler; import java.lang.Thread.UncaughtExceptionHandler;
public class CrashHandler implements UncaughtExceptionHandler { public class CrashHandler implements UncaughtExceptionHandler {
@Override @Override
public void uncaughtException(Thread t, Throwable e) public void uncaughtException(Thread t, Throwable e)
{ {
e.printStackTrace(); e.printStackTrace();
App.onCrash(e); App.onCrash(e);
} }
} }

@ -1,22 +1,21 @@
package mightypork.rogue; package mightypork.rogue;
import java.io.File; import java.io.File;
import mightypork.utils.files.OsUtils; import mightypork.utils.files.OsUtils;
public class Paths { public class Paths {
private static final String APPDIR_NAME = "rogue"; private static final String APPDIR_NAME = "rogue";
public static final File WORKDIR = OsUtils.getWorkDir(APPDIR_NAME); public static final File WORKDIR = OsUtils.getWorkDir(APPDIR_NAME);
public static final File LOGS = OsUtils.getWorkDir(APPDIR_NAME, "logs"); public static final File LOGS = OsUtils.getWorkDir(APPDIR_NAME, "logs");
public static final File SCREENSHOTS = OsUtils.getWorkDir(APPDIR_NAME, "screenshots"); public static final File SCREENSHOTS = OsUtils.getWorkDir(APPDIR_NAME, "screenshots");
public static final File CONFIG = new File(WORKDIR, "config.ini"); public static final File CONFIG = new File(WORKDIR, "config.ini");
public static final String DIR_EFFECTS = "res/sounds/effects/"; public static final String DIR_EFFECTS = "res/sounds/effects/";
public static final String DIR_MUSIC = "res/sounds/music/"; public static final String DIR_MUSIC = "res/sounds/music/";
public static final String DIR_LOOPS = "res/sounds/loops/"; public static final String DIR_LOOPS = "res/sounds/loops/";
} }

@ -1,6 +1,5 @@
package mightypork.rogue.bus; package mightypork.rogue.bus;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -23,25 +22,25 @@ import mightypork.utils.time.Updateable;
* @author MightyPork * @author MightyPork
*/ */
public abstract class DelegatingBusClient extends AppAdapter implements DelegatingClient, ToggleableClient, Destroyable, Updateable, UpdateEvent.Listener { public abstract class DelegatingBusClient extends AppAdapter implements DelegatingClient, ToggleableClient, Destroyable, Updateable, UpdateEvent.Listener {
/** Subsystem children subscribing to MessageBus */ /** Subsystem children subscribing to MessageBus */
private Set<Object> childSubscribers = new HashSet<Object>(); private Set<Object> childSubscribers = new HashSet<Object>();
private boolean wantUpdates = true; private boolean wantUpdates = true;
private boolean eventsEnabled = true; private boolean eventsEnabled = true;
public DelegatingBusClient(AppAccess app, boolean updates) { public DelegatingBusClient(AppAccess app, boolean updates) {
super(app); super(app);
bus().subscribe(this); bus().subscribe(this);
enableUpdates(updates); enableUpdates(updates);
init(); init();
} }
/** /**
* Add a child subscriber to the {@link MessageBus}.<br> * Add a child subscriber to the {@link MessageBus}.<br>
* *
@ -51,40 +50,41 @@ public abstract class DelegatingBusClient extends AppAdapter implements Delegati
public final boolean addChildSubscriber(Object client) public final boolean addChildSubscriber(Object client)
{ {
if (client == null) return false; if (client == null) return false;
childSubscribers.add(client); childSubscribers.add(client);
return true; return true;
} }
/** /**
* Remove a child subscriber * Remove a child subscriber
* *
* @param client subscriber to remove * @param client
* subscriber to remove
*/ */
public final void removeChildSubscriber(Object client) public final void removeChildSubscriber(Object client)
{ {
if (client == null) return; if (client == null) return;
childSubscribers.remove(client); childSubscribers.remove(client);
} }
@Override @Override
public final Collection<Object> getChildClients() public final Collection<Object> getChildClients()
{ {
return childSubscribers; return childSubscribers;
} }
@Override @Override
public final boolean doesDelegate() public final boolean doesDelegate()
{ {
return doesSubscribe(); return doesSubscribe();
} }
/** /**
* Set whether to receive {@link UpdateEvent}s (delta timing, one each * Set whether to receive {@link UpdateEvent}s (delta timing, one each
* frame).<br> * frame).<br>
@ -95,15 +95,15 @@ public abstract class DelegatingBusClient extends AppAdapter implements Delegati
{ {
wantUpdates = enable; wantUpdates = enable;
} }
@Override @Override
public final boolean doesSubscribe() public final boolean doesSubscribe()
{ {
return eventsEnabled; return eventsEnabled;
} }
/** /**
* Set whether events should be received. * Set whether events should be received.
* *
@ -113,33 +113,33 @@ public abstract class DelegatingBusClient extends AppAdapter implements Delegati
{ {
this.eventsEnabled = enable; this.eventsEnabled = enable;
} }
@Override @Override
public final void receive(UpdateEvent event) public final void receive(UpdateEvent event)
{ {
if (wantUpdates) update(event.getDeltaTime()); if (wantUpdates) update(event.getDeltaTime());
} }
@Override @Override
public final void destroy() public final void destroy()
{ {
deinit(); deinit();
enableUpdates(false); enableUpdates(false);
bus().unsubscribe(this); bus().unsubscribe(this);
} }
@Override @Override
public void update(double delta) public void update(double delta)
{ {
Log.w("Client " + getClass().getSimpleName() + " receives updates, but does not override the update() method."); Log.w("Client " + getClass().getSimpleName() + " receives updates, but does not override the update() method.");
} }
/** /**
* Initialize the subsystem<br> * Initialize the subsystem<br>
* (called during construction) * (called during construction)
@ -148,8 +148,8 @@ public abstract class DelegatingBusClient extends AppAdapter implements Delegati
{ {
// no impl // no impl
} }
/** /**
* Deinitialize the subsystem<br> * Deinitialize the subsystem<br>
* (called during destruction) * (called during destruction)
@ -158,5 +158,5 @@ public abstract class DelegatingBusClient extends AppAdapter implements Delegati
{ {
// no impl // no impl
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.bus; package mightypork.rogue.bus;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.AppAdapter; import mightypork.rogue.AppAdapter;
@ -11,13 +10,14 @@ import mightypork.rogue.AppAdapter;
* @author MightyPork * @author MightyPork
*/ */
public class SimpleBusClient extends AppAdapter { public class SimpleBusClient extends AppAdapter {
/** /**
* @param app app access * @param app
* app access
*/ */
public SimpleBusClient(AppAccess app) { public SimpleBusClient(AppAccess app) {
super(app); super(app);
bus().subscribe(this); bus().subscribe(this);
} }
} }

@ -1,26 +1,25 @@
package mightypork.rogue.bus; package mightypork.rogue.bus;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.events.UpdateEvent; import mightypork.rogue.bus.events.UpdateEvent;
import mightypork.utils.time.Updateable; import mightypork.utils.time.Updateable;
public abstract class UpdateReceiver extends SimpleBusClient implements UpdateEvent.Listener, Updateable { public abstract class UpdateReceiver extends SimpleBusClient implements UpdateEvent.Listener, Updateable {
public UpdateReceiver(AppAccess app) { public UpdateReceiver(AppAccess app) {
super(app); super(app);
} }
@Override @Override
public void receive(UpdateEvent event) public void receive(UpdateEvent event)
{ {
update(event.getDeltaTime()); update(event.getDeltaTime());
} }
@Override @Override
public abstract void update(double delta); public abstract void update(double delta);
} }

@ -1,6 +1,5 @@
package mightypork.rogue.bus.events; package mightypork.rogue.bus.events;
import mightypork.utils.patterns.subscription.Handleable; import mightypork.utils.patterns.subscription.Handleable;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
@ -12,19 +11,19 @@ import org.lwjgl.input.Keyboard;
* @author MightyPork * @author MightyPork
*/ */
public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> { public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
private int key; private int key;
private boolean down; private boolean down;
private char c; private char c;
public KeyboardEvent(int key, char c, boolean down) { public KeyboardEvent(int key, char c, boolean down) {
this.key = key; this.key = key;
this.c = c; this.c = c;
this.down = down; this.down = down;
} }
/** /**
* @return key code (see {@link org.lwjgl.input.Keyboard}) * @return key code (see {@link org.lwjgl.input.Keyboard})
*/ */
@ -32,8 +31,8 @@ public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
{ {
return key; return key;
} }
/** /**
* @return true if key was just pressed * @return true if key was just pressed
*/ */
@ -41,8 +40,8 @@ public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
{ {
return down; return down;
} }
/** /**
* @return true if key was just released * @return true if key was just released
*/ */
@ -50,8 +49,8 @@ public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
{ {
return !down; return !down;
} }
/** /**
* @return event character (if any) * @return event character (if any)
*/ */
@ -59,29 +58,31 @@ public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
{ {
return c; return c;
} }
@Override @Override
public void handleBy(Listener keh) public void handleBy(Listener keh)
{ {
keh.receive(this); keh.receive(this);
} }
public interface Listener { public interface Listener {
/** /**
* Handle an event * Handle an event
* *
* @param event event * @param event
* event
*/ */
public void receive(KeyboardEvent event); public void receive(KeyboardEvent event);
} }
@Override @Override
public String toString() public String toString()
{ {
return Keyboard.getKeyName(key) + ":" + (down ? "DOWN" : "UP"); return Keyboard.getKeyName(key) + ":" + (down ? "DOWN" : "UP");
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.bus.events; package mightypork.rogue.bus.events;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.patterns.subscription.Handleable; import mightypork.utils.patterns.subscription.Handleable;
@ -11,24 +10,28 @@ import mightypork.utils.patterns.subscription.Handleable;
* @author MightyPork * @author MightyPork
*/ */
public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> { public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
public static final int BUTTON_LEFT = 0; public static final int BUTTON_LEFT = 0;
public static final int BUTTON_MIDDLE = 1; public static final int BUTTON_MIDDLE = 1;
public static final int BUTTON_RIGHT = 2; public static final int BUTTON_RIGHT = 2;
private int button; private int button;
private int wheeld; private int wheeld;
private Coord pos; private Coord pos;
private boolean down; private boolean down;
/** /**
* Mouse button event * Mouse button event
* *
* @param pos event position * @param pos
* @param button button id * event position
* @param down button pressed * @param button
* @param wheeld wheel change * button id
* @param down
* button pressed
* @param wheeld
* wheel change
*/ */
public MouseButtonEvent(Coord pos, int button, boolean down, int wheeld) { public MouseButtonEvent(Coord pos, int button, boolean down, int wheeld) {
this.button = button; this.button = button;
@ -36,8 +39,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
this.pos = pos; this.pos = pos;
this.wheeld = wheeld; this.wheeld = wheeld;
} }
/** /**
* @return true if the event was caused by a button state change * @return true if the event was caused by a button state change
*/ */
@ -45,8 +48,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return button != -1; return button != -1;
} }
/** /**
* @return true if the event was caused by a wheel change * @return true if the event was caused by a wheel change
*/ */
@ -54,8 +57,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return wheeld != 0; return wheeld != 0;
} }
/** /**
* @return button id or -1 if none was pressed * @return button id or -1 if none was pressed
*/ */
@ -63,8 +66,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return button; return button;
} }
/** /**
* @return number of steps the wheel changed since last event * @return number of steps the wheel changed since last event
*/ */
@ -72,8 +75,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return wheeld; return wheeld;
} }
/** /**
* @return mouse position when the event occurred * @return mouse position when the event occurred
*/ */
@ -81,8 +84,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return pos; return pos;
} }
/** /**
* @return true if button was just pressed * @return true if button was just pressed
*/ */
@ -90,8 +93,8 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return button != -1 && down; return button != -1 && down;
} }
/** /**
* @return true if button was just released * @return true if button was just released
*/ */
@ -99,20 +102,22 @@ public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
{ {
return button != -1 && !down; return button != -1 && !down;
} }
@Override @Override
public void handleBy(Listener handler) public void handleBy(Listener handler)
{ {
handler.receive(this); handler.receive(this);
} }
public interface Listener { public interface Listener {
/** /**
* Handle an event * Handle an event
* *
* @param event event * @param event
* event
*/ */
public void receive(MouseButtonEvent event); public void receive(MouseButtonEvent event);
} }

@ -1,22 +1,21 @@
package mightypork.rogue.bus.events; package mightypork.rogue.bus.events;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.patterns.subscription.Handleable; import mightypork.utils.patterns.subscription.Handleable;
public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> { public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
private Coord move; private Coord move;
private Coord pos; private Coord pos;
public MouseMotionEvent(Coord pos, Coord move) { public MouseMotionEvent(Coord pos, Coord move) {
this.move = move; this.move = move;
this.pos = pos; this.pos = pos;
} }
/** /**
* @return movement since last {@link MouseMotionEvent} * @return movement since last {@link MouseMotionEvent}
*/ */
@ -24,8 +23,8 @@ public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
{ {
return move; return move;
} }
/** /**
* @return current mouse position * @return current mouse position
*/ */
@ -33,22 +32,24 @@ public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
{ {
return pos; return pos;
} }
@Override @Override
public void handleBy(Listener keh) public void handleBy(Listener keh)
{ {
keh.receive(this); keh.receive(this);
} }
public interface Listener { public interface Listener {
/** /**
* Handle an event * Handle an event
* *
* @param event event * @param event
* event
*/ */
public void receive(MouseMotionEvent event); public void receive(MouseMotionEvent event);
} }
} }

@ -1,50 +1,50 @@
package mightypork.rogue.bus.events; package mightypork.rogue.bus.events;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.patterns.subscription.Handleable; import mightypork.utils.patterns.subscription.Handleable;
public class ScreenChangeEvent implements Handleable<ScreenChangeEvent.Listener> { public class ScreenChangeEvent implements Handleable<ScreenChangeEvent.Listener> {
private boolean fullscreen; private boolean fullscreen;
private Coord screenSize; private Coord screenSize;
private boolean fsChanged; private boolean fsChanged;
public ScreenChangeEvent(boolean fsChanged, boolean fullscreen, Coord size) { public ScreenChangeEvent(boolean fsChanged, boolean fullscreen, Coord size) {
this.fullscreen = fullscreen; this.fullscreen = fullscreen;
this.screenSize = size; this.screenSize = size;
this.fsChanged = fsChanged; this.fsChanged = fsChanged;
} }
public boolean isFullscreen() public boolean isFullscreen()
{ {
return fullscreen; return fullscreen;
} }
public boolean fullscreenChanged() public boolean fullscreenChanged()
{ {
return fsChanged; return fsChanged;
} }
public Coord getScreenSize() public Coord getScreenSize()
{ {
return screenSize; return screenSize;
} }
@Override @Override
public void handleBy(Listener handler) public void handleBy(Listener handler)
{ {
handler.receive(this); handler.receive(this);
} }
public interface Listener { public interface Listener {
public void receive(ScreenChangeEvent event); public void receive(ScreenChangeEvent event);
} }
} }

@ -1,33 +1,33 @@
package mightypork.rogue.bus.events; package mightypork.rogue.bus.events;
import mightypork.utils.patterns.subscription.Handleable; import mightypork.utils.patterns.subscription.Handleable;
public class UpdateEvent implements Handleable<UpdateEvent.Listener> { public class UpdateEvent implements Handleable<UpdateEvent.Listener> {
private final double deltaTime; private final double deltaTime;
public UpdateEvent(double deltaTime) { public UpdateEvent(double deltaTime) {
this.deltaTime = deltaTime; this.deltaTime = deltaTime;
} }
public double getDeltaTime() public double getDeltaTime()
{ {
return deltaTime; return deltaTime;
} }
@Override @Override
public void handleBy(Listener handler) public void handleBy(Listener handler)
{ {
handler.receive(this); handler.receive(this);
} }
public interface Listener { public interface Listener {
public void receive(UpdateEvent event); public void receive(UpdateEvent event);
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.display; package mightypork.rogue.display;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -21,31 +20,31 @@ import org.lwjgl.opengl.DisplayMode;
public class DisplaySystem extends DelegatingBusClient implements Bounding { public class DisplaySystem extends DelegatingBusClient implements Bounding {
private DisplayMode windowDisplayMode; private DisplayMode windowDisplayMode;
private int targetFps; private int targetFps;
public DisplaySystem(AppAccess app) { public DisplaySystem(AppAccess app) {
super(app, true); super(app, true);
enableUpdates(false); enableUpdates(false);
} }
@Override @Override
protected void init() protected void init()
{ {
initChannels(); initChannels();
} }
@Override @Override
public void deinit() public void deinit()
{ {
Display.destroy(); Display.destroy();
} }
/** /**
* Initialize event channels * Initialize event channels
*/ */
@ -53,14 +52,14 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
{ {
bus().createChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class); bus().createChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
} }
public void setTargetFps(int fps) public void setTargetFps(int fps)
{ {
this.targetFps = fps; this.targetFps = fps;
} }
public void createMainWindow(int width, int height, boolean resizable, boolean fullscreen, String title) public void createMainWindow(int width, int height, boolean resizable, boolean fullscreen, String title)
{ {
try { try {
@ -69,7 +68,7 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
Display.setVSyncEnabled(true); Display.setVSyncEnabled(true);
Display.setTitle(title); Display.setTitle(title);
Display.create(); Display.create();
if (fullscreen) { if (fullscreen) {
switchFullscreen(); switchFullscreen();
Display.update(); Display.update();
@ -78,20 +77,20 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
throw new RuntimeException("Could not initialize screen", e); throw new RuntimeException("Could not initialize screen", e);
} }
} }
/** /**
* Toggle FS if possible * Toggle FS if possible
*/ */
public void switchFullscreen() public void switchFullscreen()
{ {
try { try {
if (!Display.isFullscreen()) { if (!Display.isFullscreen()) {
Log.f3("Entering fullscreen."); Log.f3("Entering fullscreen.");
// save window resize // save window resize
windowDisplayMode = new DisplayMode(Display.getWidth(), Display.getHeight()); windowDisplayMode = new DisplayMode(Display.getWidth(), Display.getHeight());
Display.setDisplayMode(Display.getDesktopDisplayMode()); Display.setDisplayMode(Display.getDesktopDisplayMode());
Display.setFullscreen(true); Display.setFullscreen(true);
Display.update(); Display.update();
@ -100,9 +99,9 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
Display.setDisplayMode(windowDisplayMode); Display.setDisplayMode(windowDisplayMode);
Display.update(); Display.update();
} }
bus().broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize())); bus().broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
} catch (Throwable t) { } catch (Throwable t) {
Log.e("Failed to toggle fullscreen mode.", t); Log.e("Failed to toggle fullscreen mode.", t);
try { try {
@ -113,19 +112,20 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
} }
} }
} }
public BufferedImage takeScreenshot() public BufferedImage takeScreenshot()
{ {
glReadBuffer(GL_FRONT); glReadBuffer(GL_FRONT);
int width = Display.getDisplayMode().getWidth(); int width = Display.getDisplayMode().getWidth();
int height = Display.getDisplayMode().getHeight(); int height = Display.getDisplayMode().getHeight();
int bpp = 4; // Assuming a 32-bit display with a byte each for red, green, blue, and alpha. int bpp = 4; // Assuming a 32-bit display with a byte each for red,
// green, blue, and alpha.
ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp); ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// convert to a buffered image // convert to a buffered image
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
@ -136,11 +136,11 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b); image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
} }
} }
return image; return image;
} }
/** /**
* @return true if close was requested (i.e. click on cross) * @return true if close was requested (i.e. click on cross)
*/ */
@ -148,8 +148,8 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
{ {
return Display.isCloseRequested(); return Display.isCloseRequested();
} }
/** /**
* Get fullscreen state * Get fullscreen state
* *
@ -159,8 +159,8 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
{ {
return Display.isFullscreen(); return Display.isFullscreen();
} }
/** /**
* Get screen size * Get screen size
* *
@ -170,8 +170,8 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
{ {
return new Coord(Display.getWidth(), Display.getHeight()); return new Coord(Display.getWidth(), Display.getHeight());
} }
/** /**
* Start a OpenGL frame * Start a OpenGL frame
*/ */
@ -180,12 +180,12 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
if (Display.wasResized()) { if (Display.wasResized()) {
bus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize())); bus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
} }
glLoadIdentity(); glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
/** /**
* End an OpenGL frame, flip buffers, sync to fps. * End an OpenGL frame, flip buffers, sync to fps.
*/ */
@ -194,8 +194,8 @@ public class DisplaySystem extends DelegatingBusClient implements Bounding {
Display.update(false); // don't poll input devices Display.update(false); // don't poll input devices
Display.sync(targetFps); Display.sync(targetFps);
} }
@Override @Override
public Rect getRect() public Rect getRect()
{ {

@ -1,6 +1,5 @@
package mightypork.rogue.display; package mightypork.rogue.display;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.DelegatingBusClient; import mightypork.rogue.bus.DelegatingBusClient;
@ -21,38 +20,39 @@ import mightypork.utils.math.coord.Rect;
* @author MightyPork * @author MightyPork
*/ */
public abstract class Screen extends DelegatingBusClient implements KeyBinder, Bounding, ScreenChangeEvent.Listener { public abstract class Screen extends DelegatingBusClient implements KeyBinder, Bounding, ScreenChangeEvent.Listener {
private KeyBindingPool keybindings; private KeyBindingPool keybindings;
private boolean active; private boolean active;
public Screen(AppAccess app) { public Screen(AppAccess app) {
super(app, true); super(app, true);
// disable events initially // disable events initially
enableEvents(false); enableEvents(false);
} }
@Override @Override
public final void bindKeyStroke(KeyStroke stroke, Runnable task) public final void bindKeyStroke(KeyStroke stroke, Runnable task)
{ {
keybindings.bindKeyStroke(stroke, task); keybindings.bindKeyStroke(stroke, task);
} }
@Override @Override
public final void unbindKeyStroke(KeyStroke stroke) public final void unbindKeyStroke(KeyStroke stroke)
{ {
keybindings.unbindKeyStroke(stroke); keybindings.unbindKeyStroke(stroke);
} }
/** /**
* Prepare for being shown * Prepare for being shown
* *
* @param shown true to show, false to hide * @param shown
* true to show, false to hide
*/ */
public final void setActive(boolean shown) public final void setActive(boolean shown)
{ {
@ -62,45 +62,45 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
setupViewport(); setupViewport();
onSizeChanged(getRect().getSize()); onSizeChanged(getRect().getSize());
onScreenEnter(); onScreenEnter();
// subscribe to event bus // subscribe to event bus
enableEvents(true); enableEvents(true);
} else { } else {
onScreenLeave(); onScreenLeave();
active = false; active = false;
// unsusbcribe from event bus // unsusbcribe from event bus
enableEvents(false); enableEvents(false);
} }
} }
private void setupGraphics() private void setupGraphics()
{ {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glClearDepth(1f); glClearDepth(1f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
setupViewport(); setupViewport();
} }
private void setupViewport() private void setupViewport()
{ {
// fix projection for changed size // fix projection for changed size
@ -109,80 +109,82 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
Coord s = disp().getSize(); Coord s = disp().getSize();
glViewport(0, 0, s.xi(), s.yi()); glViewport(0, 0, s.xi(), s.yi());
glOrtho(0, s.x, 0, s.y, -1000, 1000); glOrtho(0, s.x, 0, s.y, -1000, 1000);
// back to modelview // back to modelview
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
} }
@Override @Override
protected final void init() protected final void init()
{ {
keybindings = new KeyBindingPool(); keybindings = new KeyBindingPool();
addChildSubscriber(keybindings); addChildSubscriber(keybindings);
initScreen(); initScreen();
} }
@Override @Override
protected final void deinit() protected final void deinit()
{ {
deinitScreen(); deinitScreen();
} }
/** /**
* Initialize screen layout and key bindings.<br> * Initialize screen layout and key bindings.<br>
* Called during screen construction. * Called during screen construction.
*/ */
protected abstract void initScreen(); protected abstract void initScreen();
/** /**
* Clean up before screen is destroyed. * Clean up before screen is destroyed.
*/ */
protected abstract void deinitScreen(); protected abstract void deinitScreen();
/** /**
* Called when the screen becomes active * Called when the screen becomes active
*/ */
protected abstract void onScreenEnter(); protected abstract void onScreenEnter();
/** /**
* Called when the screen is no longer active * Called when the screen is no longer active
*/ */
protected abstract void onScreenLeave(); protected abstract void onScreenLeave();
/** /**
* Update GUI for new screen size * Update GUI for new screen size
* *
* @param size screen size * @param size
* screen size
*/ */
protected void onSizeChanged(Coord size) protected void onSizeChanged(Coord size)
{ {
// no impl // no impl
} }
/** /**
* Render screen contents (context is ready for 2D rendering) * Render screen contents (context is ready for 2D rendering)
*/ */
protected abstract void renderScreen(); protected abstract void renderScreen();
/** /**
* Update animations and timing * Update animations and timing
* *
* @param delta time elapsed * @param delta
* time elapsed
*/ */
protected abstract void updateScreen(double delta); protected abstract void updateScreen(double delta);
/** /**
* Render screen * Render screen
*/ */
@ -191,8 +193,8 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
glPushAttrib(GL_ENABLE_BIT); glPushAttrib(GL_ENABLE_BIT);
glPushMatrix(); glPushMatrix();
} }
/** /**
* Render screen * Render screen
*/ */
@ -201,8 +203,8 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
glPopAttrib(); glPopAttrib();
glPopMatrix(); glPopMatrix();
} }
/** /**
* @return true if screen is the curretn screen * @return true if screen is the curretn screen
*/ */
@ -210,19 +212,19 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
{ {
return active; return active;
} }
@Override @Override
public final void receive(ScreenChangeEvent event) public final void receive(ScreenChangeEvent event)
{ {
if (!isActive()) return; if (!isActive()) return;
setupViewport(); setupViewport();
onSizeChanged(event.getScreenSize()); onSizeChanged(event.getScreenSize());
} }
/** /**
* Update and render the screen * Update and render the screen
*/ */
@ -230,17 +232,17 @@ public abstract class Screen extends DelegatingBusClient implements KeyBinder, B
public final void update(double delta) public final void update(double delta)
{ {
updateScreen(delta); updateScreen(delta);
renderBegin(); renderBegin();
renderScreen(); renderScreen();
renderEnd(); renderEnd();
} }
@Override @Override
public final Rect getRect() public final Rect getRect()
{ {
return disp().getRect(); return disp().getRect();
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.display; package mightypork.rogue.display;
import java.util.Random; import java.util.Random;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
@ -19,15 +18,15 @@ import org.lwjgl.opengl.Display;
public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Listener { public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Listener {
public ScreenTestAnimations(AppAccess app) { public ScreenTestAnimations(AppAccess app) {
super(app); super(app);
} }
private Random rand = new Random(); private Random rand = new Random();
private AnimDoubleDeg degAnim = new AnimDoubleDeg(0, Easing.ELASTIC_OUT); private AnimDoubleDeg degAnim = new AnimDoubleDeg(0, Easing.ELASTIC_OUT);
//@formatter:off //@formatter:off
private AnimDouble[] anims = new AnimDouble[] { private AnimDouble[] anims = new AnimDouble[] {
new AnimDouble(0, Easing.BOUNCE_OUT), new AnimDouble(0, Easing.BOUNCE_OUT),
@ -95,12 +94,12 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
// new AnimDouble(0, Easing.ELASTIC_IN_OUT), // new AnimDouble(0, Easing.ELASTIC_IN_OUT),
}; };
//@formatter:on //@formatter:on
@Override @Override
public void initScreen() public void initScreen()
{ {
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() { bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
@Override @Override
public void run() public void run()
{ {
@ -109,9 +108,9 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
} }
} }
}); });
bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() { bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() {
@Override @Override
public void run() public void run()
{ {
@ -121,40 +120,40 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
} }
}); });
} }
@Override @Override
protected void deinitScreen() protected void deinitScreen()
{ {
// no impl // no impl
} }
@Override @Override
protected void onScreenEnter() protected void onScreenEnter()
{ {
// no impl // no impl
} }
@Override @Override
protected void onScreenLeave() protected void onScreenLeave()
{ {
// no impl // no impl
} }
@Override @Override
protected void updateScreen(double delta) protected void updateScreen(double delta)
{ {
degAnim.update(delta); degAnim.update(delta);
for (AnimDouble a : anims) { for (AnimDouble a : anims) {
a.update(delta); a.update(delta);
} }
} }
@Override @Override
protected void renderScreen() protected void renderScreen()
{ {
@ -163,31 +162,31 @@ public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Lis
double perBoxH = screenH / anims.length; double perBoxH = screenH / anims.length;
double padding = perBoxH * 0.1; double padding = perBoxH * 0.1;
double boxSide = perBoxH - padding * 2; double boxSide = perBoxH - padding * 2;
for (int i = 0; i < anims.length; i++) { for (int i = 0; i < anims.length; i++) {
AnimDouble a = anims[i]; AnimDouble a = anims[i];
RenderUtils.setColor(RGB.GREEN); RenderUtils.setColor(RGB.GREEN);
RenderUtils.quadSize(padding + a.getCurrentValue() * (screenW - perBoxH), screenH - perBoxH * i - perBoxH + padding, boxSide, boxSide); RenderUtils.quadSize(padding + a.getCurrentValue() * (screenW - perBoxH), screenH - perBoxH * i - perBoxH + padding, boxSide, boxSide);
} }
RenderUtils.setColor(RGB.YELLOW); RenderUtils.setColor(RGB.YELLOW);
RenderUtils.translate(new Coord(Display.getWidth() / 2, Display.getHeight() / 2)); RenderUtils.translate(new Coord(Display.getWidth() / 2, Display.getHeight() / 2));
RenderUtils.rotateZ(degAnim.getCurrentValue()); RenderUtils.rotateZ(degAnim.getCurrentValue());
RenderUtils.quadSize(-10, -10, 20, 200); RenderUtils.quadSize(-10, -10, 20, 200);
} }
@Override @Override
public void receive(MouseButtonEvent event) public void receive(MouseButtonEvent event)
{ {
if (event.isDown()) { if (event.isDown()) {
Coord vec = disp().getSize().half().vecTo(event.getPos()); Coord vec = disp().getSize().half().vecTo(event.getPos());
Polar p = Polar.fromCoord(vec); Polar p = Polar.fromCoord(vec);
degAnim.fadeTo(p.getAngleDeg() - 90, 1.5); degAnim.fadeTo(p.getAngleDeg() - 90, 1.5);
} }
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.display.constraints; package mightypork.rogue.display.constraints;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
@ -10,7 +9,7 @@ import mightypork.utils.math.coord.Rect;
* @author MightyPork * @author MightyPork
*/ */
public interface Bounding { public interface Bounding {
/** /**
* @return bounding rectangle * @return bounding rectangle
*/ */

@ -1,20 +1,19 @@
package mightypork.rogue.display.constraints; package mightypork.rogue.display.constraints;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
public abstract class Constraint implements Bounding { public abstract class Constraint implements Bounding {
protected Bounding context; protected Bounding context;
public Constraint(Bounding context) { public Constraint(Bounding context) {
this.context = context; this.context = context;
} }
/** /**
* Assign a context * Assign a context
* *
@ -24,8 +23,8 @@ public abstract class Constraint implements Bounding {
{ {
this.context = context; this.context = context;
} }
/** /**
* @return context * @return context
*/ */
@ -33,8 +32,8 @@ public abstract class Constraint implements Bounding {
{ {
return context; return context;
} }
/** /**
* @return context rect origin * @return context rect origin
*/ */
@ -42,8 +41,8 @@ public abstract class Constraint implements Bounding {
{ {
return context.getRect().getOrigin(); return context.getRect().getOrigin();
} }
/** /**
* @return context rect size * @return context rect size
*/ */
@ -51,9 +50,9 @@ public abstract class Constraint implements Bounding {
{ {
return context.getRect().getSize(); return context.getRect().getSize();
} }
@Override @Override
public abstract Rect getRect(); public abstract Rect getRect();
} }

@ -1,8 +1,7 @@
package mightypork.rogue.display.rendering; package mightypork.rogue.display.rendering;
public interface Renderable { public interface Renderable {
public void render(); public void render();
} }

@ -1,18 +1,17 @@
package mightypork.rogue.display.rendering; package mightypork.rogue.display.rendering;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.DelegatingBusClient; import mightypork.rogue.bus.DelegatingBusClient;
public abstract class ScreenLayer extends DelegatingBusClient implements Renderable { public abstract class ScreenLayer extends DelegatingBusClient implements Renderable {
public ScreenLayer(AppAccess app) { public ScreenLayer(AppAccess app) {
super(app, true); super(app, true);
} }
@Override @Override
public abstract void render(); public abstract void render();
} }

@ -1,13 +1,12 @@
package mightypork.rogue.fonts; package mightypork.rogue.fonts;
/** /**
* Alignment * Alignment
* *
* @author MightyPork * @author MightyPork
*/ */
public class Align { public class Align {
public static final int LEFT = -1; public static final int LEFT = -1;
public static final int RIGHT = 1; public static final int RIGHT = 1;
public static final int TOP = 1; public static final int TOP = 1;
@ -16,5 +15,5 @@ public class Align {
public static final int DOWN = -1; public static final int DOWN = -1;
public static final int CENTER = 0; public static final int CENTER = 0;
public static final int MIDDLE = 0; public static final int MIDDLE = 0;
} }

@ -1,6 +1,5 @@
package mightypork.rogue.fonts; package mightypork.rogue.fonts;
import java.awt.Font; import java.awt.Font;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
@ -18,16 +17,17 @@ import org.newdawn.slick.util.ResourceLoader;
* @author MightyPork * @author MightyPork
*/ */
public class FontManager { public class FontManager {
private static final boolean DEBUG = Config.LOG_FONTS; private static final boolean DEBUG = Config.LOG_FONTS;
/** /**
* Glyph tables. * Glyph tables.
* *
* @author MightyPork * @author MightyPork
*/ */
public static class Glyphs { public static class Glyphs {
//@formatter:off //@formatter:off
/** all glyphs */ /** all glyphs */
public static final String all = public static final String all =
@ -74,14 +74,14 @@ public class FontManager {
public static final String basic = alnum + signs; public static final String basic = alnum + signs;
//@formatter:on //@formatter:on
} }
/** /**
* Font style * Font style
* *
* @author MightyPork * @author MightyPork
*/ */
public static enum Style public static enum Style {
{
/** Normal */ /** Normal */
NORMAL, NORMAL,
/** Italic */ /** Italic */
@ -111,98 +111,102 @@ public class FontManager {
/** Outline variant of normal */ /** Outline variant of normal */
OUTLINE; OUTLINE;
} }
// /**
// * Preloaded font identifier [name, size, style] // /**
// * // * Preloaded font identifier [name, size, style]
// * @author MightyPork // *
// */ // * @author MightyPork
// public static class FontId { // */
// // public static class FontId {
// /** font size (pt) */ //
// public float size = 24; // /** font size (pt) */
// /** font name, registered with registerFile */ // public float size = 24;
// public String name = ""; // /** font name, registered with registerFile */
// /** font style. The given style must be in a file. */ // public String name = "";
// public Style style; // /** font style. The given style must be in a file. */
// // public Style style;
// /** Set of glyphs in this ID */ //
// public String glyphs = ""; // /** Set of glyphs in this ID */
// // public String glyphs = "";
// /** Index for faster comparision of glyph ids. */ //
// public int glyphset_id = 0; // /** Index for faster comparision of glyph ids. */
// // public int glyphset_id = 0;
// //
// /** //
// * Preloaded font identifier // /**
// * // * Preloaded font identifier
// * @param name font name (registerFile) // *
// * @param size font size (pt) // * @param name font name (registerFile)
// * @param style font style // * @param size font size (pt)
// * @param glyphs glyphs to load // * @param style font style
// */ // * @param glyphs glyphs to load
// public FontId(String name, double size, Style style, String glyphs) { // */
// this.name = name; // public FontId(String name, double size, Style style, String glyphs) {
// this.size = (float) size; // this.name = name;
// this.style = style; // this.size = (float) size;
// // this.style = style;
// if (glyphs.equals(Glyphs.basic)) { //
// glyphset_id = 1; // if (glyphs.equals(Glyphs.basic)) {
// } else if (glyphs.equals(Glyphs.alnum)) { // glyphset_id = 1;
// glyphset_id = 2; // } else if (glyphs.equals(Glyphs.alnum)) {
// } else if (glyphs.equals(Glyphs.basic_text)) { // glyphset_id = 2;
// glyphset_id = 3; // } else if (glyphs.equals(Glyphs.basic_text)) {
// } else if (glyphs.equals(Glyphs.numbers)) { // glyphset_id = 3;
// glyphset_id = 4; // } else if (glyphs.equals(Glyphs.numbers)) {
// } else if (glyphs.equals(Glyphs.alpha)) { // glyphset_id = 4;
// glyphset_id = 5; // } else if (glyphs.equals(Glyphs.alpha)) {
// } else if (glyphs.equals(Glyphs.all)) { // glyphset_id = 5;
// glyphset_id = 6; // } else if (glyphs.equals(Glyphs.all)) {
// } else if (glyphs.equals(Glyphs.alnum_extra)) { // glyphset_id = 6;
// glyphset_id = 7; // } else if (glyphs.equals(Glyphs.alnum_extra)) {
// } else if (glyphs.equals(Glyphs.signs)) { // glyphset_id = 7;
// glyphset_id = 8; // } else if (glyphs.equals(Glyphs.signs)) {
// } else if (glyphs.equals(Glyphs.signs_extra)) { // glyphset_id = 8;
// glyphset_id = 9; // } else if (glyphs.equals(Glyphs.signs_extra)) {
// } else { // glyphset_id = 9;
// this.glyphs = glyphs; // } else {
// } // this.glyphs = glyphs;
// } // }
// // }
// //
// @Override //
// public boolean equals(Object obj) // @Override
// { // public boolean equals(Object obj)
// if (obj == null) return false; // {
// if (!(obj.getClass().isAssignableFrom(getClass()))) return false; // if (obj == null) return false;
// if (obj instanceof FontId) { // if (!(obj.getClass().isAssignableFrom(getClass()))) return false;
// if (obj == this) return true; // if (obj instanceof FontId) {
// FontId id2 = ((FontId) obj); // if (obj == this) return true;
// boolean flag = true; // FontId id2 = ((FontId) obj);
// flag &= id2.size == size; // boolean flag = true;
// flag &= id2.name.equals(name); // flag &= id2.size == size;
// flag &= id2.style == style; // flag &= id2.name.equals(name);
// flag &= ((id2.glyphset_id != -1 && id2.glyphset_id == glyphset_id) || id2.glyphs.equals(glyphs)); // flag &= id2.style == style;
// return flag; // flag &= ((id2.glyphset_id != -1 && id2.glyphset_id == glyphset_id) ||
// } // id2.glyphs.equals(glyphs));
// return false; // return flag;
// } // }
// // return false;
// // }
// @Override //
// public int hashCode() //
// { // @Override
// return (new Float(size).hashCode()) ^ name.hashCode() ^ style.hashCode() ^ glyphset_id; // public int hashCode()
// } // {
// // return (new Float(size).hashCode()) ^ name.hashCode() ^ style.hashCode()
// // ^ glyphset_id;
// @Override // }
// public String toString() //
// { //
// return "[" + name + ", " + size + ", " + style + (glyphset_id > 0 ? ", g=" + glyphset_id : ", g=custom") + "]"; // @Override
// } // public String toString()
// } // {
// return "[" + name + ", " + size + ", " + style + (glyphset_id > 0 ?
// ", g=" + glyphset_id : ", g=custom") + "]";
// }
// }
/** /**
* Group of styles of one font. * Group of styles of one font.
* *
@ -210,19 +214,22 @@ public class FontManager {
*/ */
public static class FontFamily extends HashMap<Style, String> { public static class FontFamily extends HashMap<Style, String> {
} }
/** /**
* Table of font files. name {style:file,style:file,style:file...} * Table of font files. name {style:file,style:file,style:file...}
*/ */
private static HashMap<String, FontFamily> fontFiles = new HashMap<String, FontFamily>(); private static HashMap<String, FontFamily> fontFiles = new HashMap<String, FontFamily>();
/** /**
* Register font file. * Register font file.
* *
* @param path resource path (res/fonts/...) * @param path
* @param name font name (for binding) * resource path (res/fonts/...)
* @param style font style in this file * @param name
* font name (for binding)
* @param style
* font style in this file
*/ */
public static void registerFile(String path, String name, Style style) public static void registerFile(String path, String name, Style style)
{ {
@ -232,47 +239,59 @@ public class FontManager {
return; return;
} }
} }
// insert new table of styles to font name. // insert new table of styles to font name.
FontFamily family = new FontFamily(); FontFamily family = new FontFamily();
family.put(style, path); family.put(style, path);
fontFiles.put(name, family); fontFiles.put(name, family);
} }
/** Counter of loaded fonts */ /** Counter of loaded fonts */
public static int loadedFontCounter = 0; public static int loadedFontCounter = 0;
/** /**
* Preload font if needed, get preloaded font.<br> * Preload font if needed, get preloaded font.<br>
* If needed file is not available, throws runtime exception. * If needed file is not available, throws runtime exception.
* *
* @param name font name (registerFile) * @param name
* @param size font size (pt) * font name (registerFile)
* @param style font style * @param size
* @param glyphs glyphs needed * font size (pt)
* @param style
* font style
* @param glyphs
* glyphs needed
* @return the loaded font. * @return the loaded font.
*/ */
public static LoadedFont loadFont(String name, double size, Style style, String glyphs) public static LoadedFont loadFont(String name, double size, Style style, String glyphs)
{ {
return loadFont(name, size, style, glyphs, 9, 8, Coord.one(), 0, 0); return loadFont(name, size, style, glyphs, 9, 8, Coord.one(), 0, 0);
} }
/** /**
* Preload font if needed, get preloaded font.<br> * Preload font if needed, get preloaded font.<br>
* If needed file is not available, throws runtime exception. * If needed file is not available, throws runtime exception.
* *
* @param name font name (registerFile) * @param name
* @param size font size (pt) * font name (registerFile)
* @param style font style * @param size
* @param glyphs glyphs needed * font size (pt)
* @param correctLeft left horizontal correction * @param style
* @param correctRight right horizontal correction * font style
* @param scale font scale (changing aspect ratio) * @param glyphs
* @param clipTop top clip (0-1) - top part of the font to be cut off * glyphs needed
* @param clipBottom bottom clip (0-1) - bottom part of the font to be cut * @param correctLeft
* off * left horizontal correction
* @param correctRight
* right horizontal correction
* @param scale
* font scale (changing aspect ratio)
* @param clipTop
* top clip (0-1) - top part of the font to be cut off
* @param clipBottom
* bottom clip (0-1) - bottom part of the font to be cut off
* @return the loaded font. * @return the loaded font.
*/ */
public static LoadedFont loadFont(String name, double size, Style style, String glyphs, int correctLeft, int correctRight, Coord scale, double clipTop, double clipBottom) public static LoadedFont loadFont(String name, double size, Style style, String glyphs, int correctLeft, int correctRight, Coord scale, double clipTop, double clipBottom)
@ -290,9 +309,9 @@ public class FontManager {
} catch (NullPointerException npe) { } catch (NullPointerException npe) {
throw new RuntimeException("Font loading failed: no font file registered for name \"" + name + "\"."); throw new RuntimeException("Font loading failed: no font file registered for name \"" + name + "\".");
} }
InputStream in = ResourceLoader.getResourceAsStream(resourcePath); InputStream in = ResourceLoader.getResourceAsStream(resourcePath);
Font awtFont; Font awtFont;
try { try {
awtFont = Font.createFont(Font.TRUETYPE_FONT, in); awtFont = Font.createFont(Font.TRUETYPE_FONT, in);
@ -300,18 +319,18 @@ public class FontManager {
Log.e("Loading of font " + resourcePath + " failed.", e); Log.e("Loading of font " + resourcePath + " failed.", e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
awtFont = awtFont.deriveFont((float) size); // set font size awtFont = awtFont.deriveFont((float) size); // set font size
LoadedFont font = new LoadedFont(awtFont, true, glyphs); LoadedFont font = new LoadedFont(awtFont, true, glyphs);
font.setCorrection(correctLeft, correctRight); font.setCorrection(correctLeft, correctRight);
font.setClip(clipTop, clipBottom); font.setClip(clipTop, clipBottom);
font.setScale(scale.x, scale.y); font.setScale(scale.x, scale.y);
loadedFontCounter++; loadedFontCounter++;
if (DEBUG) Log.f3("Font from file \"" + resourcePath + "\" preloaded."); if (DEBUG) Log.f3("Font from file \"" + resourcePath + "\" preloaded.");
return font; return font;
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.fonts; package mightypork.rogue.fonts;
import static mightypork.rogue.fonts.FontManager.Style.*; import static mightypork.rogue.fonts.FontManager.Style.*;
import mightypork.rogue.fonts.FontManager.Glyphs; import mightypork.rogue.fonts.FontManager.Glyphs;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
@ -12,9 +11,9 @@ import mightypork.utils.logging.Log;
* @author Rapus * @author Rapus
*/ */
public class Fonts { public class Fonts {
public static LoadedFont splash_info; public static LoadedFont splash_info;
public static LoadedFont tooltip; public static LoadedFont tooltip;
public static LoadedFont gui; public static LoadedFont gui;
public static LoadedFont gui_title; public static LoadedFont gui_title;
@ -22,26 +21,26 @@ public class Fonts {
public static LoadedFont menu_button; public static LoadedFont menu_button;
public static LoadedFont menu_title; public static LoadedFont menu_title;
public static LoadedFont tiny; public static LoadedFont tiny;
private static void registerFileNames() private static void registerFileNames()
{ {
FontManager.registerFile("res/fonts/4feb.ttf", "4feb", NORMAL); FontManager.registerFile("res/fonts/4feb.ttf", "4feb", NORMAL);
} }
/** /**
* Load fonts needed for splash. * Load fonts needed for splash.
*/ */
public static void loadForSplash() public static void loadForSplash()
{ {
registerFileNames(); registerFileNames();
gui = FontManager.loadFont("4feb", 24, NORMAL, Glyphs.basic).setCorrection(8, 7); gui = FontManager.loadFont("4feb", 24, NORMAL, Glyphs.basic).setCorrection(8, 7);
splash_info = FontManager.loadFont("4feb", 42, NORMAL, "Loading."); splash_info = FontManager.loadFont("4feb", 42, NORMAL, "Loading.");
} }
/** /**
* Preload all fonts we will use in the game * Preload all fonts we will use in the game
*/ */
@ -53,8 +52,8 @@ public class Fonts {
menu_title = FontManager.loadFont("4feb", 34, NORMAL, Glyphs.basic_text); menu_title = FontManager.loadFont("4feb", 34, NORMAL, Glyphs.basic_text);
program_number = FontManager.loadFont("4feb", 28, NORMAL, Glyphs.numbers); program_number = FontManager.loadFont("4feb", 28, NORMAL, Glyphs.numbers);
tiny = FontManager.loadFont("4feb", 20, NORMAL, Glyphs.basic_text); tiny = FontManager.loadFont("4feb", 20, NORMAL, Glyphs.basic_text);
Log.i("Fonts loaded = " + FontManager.loadedFontCounter); Log.i("Fonts loaded = " + FontManager.loadedFontCounter);
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.fonts; package mightypork.rogue.fonts;
import static mightypork.rogue.fonts.Align.*; import static mightypork.rogue.fonts.Align.*;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
@ -39,82 +38,83 @@ import org.lwjgl.util.glu.GLU;
* @new version edited by MightyPork * @new version edited by MightyPork
*/ */
public class LoadedFont { public class LoadedFont {
private static final boolean DEBUG = Config.LOG_FONTS; private static final boolean DEBUG = Config.LOG_FONTS;
/** Map of user defined font characters (Character <-> IntObject) */ /** Map of user defined font characters (Character <-> IntObject) */
private Map<Character, CharStorageEntry> chars = new HashMap<Character, CharStorageEntry>(100); private Map<Character, CharStorageEntry> chars = new HashMap<Character, CharStorageEntry>(100);
/** Boolean flag on whether AntiAliasing is enabled or not */ /** Boolean flag on whether AntiAliasing is enabled or not */
private boolean antiAlias; private boolean antiAlias;
/** Font's size */ /** Font's size */
private int fontSize = 0; private int fontSize = 0;
/** Font's height */ /** Font's height */
private int fontHeight = 0; private int fontHeight = 0;
/** Texture used to cache the font 0-255 characters */ /** Texture used to cache the font 0-255 characters */
private int fontTextureID; private int fontTextureID;
/** Default font texture width */ /** Default font texture width */
private int textureWidth = 2048; private int textureWidth = 2048;
/** Default font texture height */ /** Default font texture height */
private int textureHeight = 2048; private int textureHeight = 2048;
/** A reference to Java's AWT Font that we create our font texture from */ /** A reference to Java's AWT Font that we create our font texture from */
private Font font; private Font font;
/** The font metrics for our Java AWT font */ /** The font metrics for our Java AWT font */
private FontMetrics fontMetrics; private FontMetrics fontMetrics;
private int correctL = 9, correctR = 8; private int correctL = 9, correctR = 8;
private double defScaleX = 1, defScaleY = 1; private double defScaleX = 1, defScaleY = 1;
private double clipVerticalT = 0; private double clipVerticalT = 0;
private double clipVerticalB = 0; private double clipVerticalB = 0;
private class CharStorageEntry { private class CharStorageEntry {
/** Character's width */ /** Character's width */
public int width; public int width;
/** Character's height */ /** Character's height */
public int height; public int height;
/** Character's stored x position */ /** Character's stored x position */
public int texPosX; public int texPosX;
/** Character's stored y position */ /** Character's stored y position */
public int texPosY; public int texPosY;
} }
public LoadedFont(Font font, boolean antiAlias, String charsNeeded) { public LoadedFont(Font font, boolean antiAlias, String charsNeeded) {
this.font = font; this.font = font;
this.fontSize = font.getSize() + 3; this.fontSize = font.getSize() + 3;
this.antiAlias = antiAlias; this.antiAlias = antiAlias;
createSet(charsNeeded.toCharArray()); createSet(charsNeeded.toCharArray());
fontHeight -= 1; fontHeight -= 1;
if (fontHeight <= 0) fontHeight = 1; if (fontHeight <= 0) fontHeight = 1;
} }
public void setCorrection(boolean on) public void setCorrection(boolean on)
{ {
if (on) { if (on) {
correctL = 9;//2 correctL = 9;// 2
correctR = 8;//1 correctR = 8;// 1
} else { } else {
correctL = 0; correctL = 0;
correctR = 0; correctR = 0;
} }
} }
private BufferedImage getFontImage(char ch) private BufferedImage getFontImage(char ch)
{ {
// Create a temporary image to extract the character's size // Create a temporary image to extract the character's size
@ -126,7 +126,7 @@ public class LoadedFont {
g.setFont(font); g.setFont(font);
fontMetrics = g.getFontMetrics(); fontMetrics = g.getFontMetrics();
int charwidth = fontMetrics.charWidth(ch) + 8; int charwidth = fontMetrics.charWidth(ch) + 8;
if (charwidth <= 0) { if (charwidth <= 0) {
charwidth = 7; charwidth = 7;
} }
@ -134,7 +134,7 @@ public class LoadedFont {
if (charheight <= 0) { if (charheight <= 0) {
charheight = fontSize; charheight = fontSize;
} }
// Create another image holding the character we are creating // Create another image holding the character we are creating
BufferedImage fontImage; BufferedImage fontImage;
fontImage = new BufferedImage(charwidth, charheight, BufferedImage.TYPE_INT_ARGB); fontImage = new BufferedImage(charwidth, charheight, BufferedImage.TYPE_INT_ARGB);
@ -143,28 +143,28 @@ public class LoadedFont {
gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
} }
gt.setFont(font); gt.setFont(font);
gt.setColor(Color.WHITE); gt.setColor(Color.WHITE);
int charx = 3; int charx = 3;
int chary = 1; int chary = 1;
gt.drawString(String.valueOf(ch), (charx), (chary) + fontMetrics.getAscent()); gt.drawString(String.valueOf(ch), (charx), (chary) + fontMetrics.getAscent());
return fontImage; return fontImage;
} }
private void createSet(char[] charsToLoad) private void createSet(char[] charsToLoad)
{ {
try { try {
class LoadedGlyph { class LoadedGlyph {
public char c; public char c;
public BufferedImage image; public BufferedImage image;
public int width; public int width;
public int height; public int height;
public LoadedGlyph(char c, BufferedImage image) { public LoadedGlyph(char c, BufferedImage image) {
this.image = image; this.image = image;
this.c = c; this.c = c;
@ -172,7 +172,7 @@ public class LoadedFont {
this.height = image.getHeight(); this.height = image.getHeight();
} }
} }
List<LoadedGlyph> glyphs = new ArrayList<LoadedGlyph>(); List<LoadedGlyph> glyphs = new ArrayList<LoadedGlyph>();
List<Character> loaded = new ArrayList<Character>(); List<Character> loaded = new ArrayList<Character>();
for (char ch : charsToLoad) { for (char ch : charsToLoad) {
@ -181,35 +181,35 @@ public class LoadedFont {
loaded.add(ch); loaded.add(ch);
} }
} }
Coord canvas = new Coord(128, 128); Coord canvas = new Coord(128, 128);
double lineHeight = 0; double lineHeight = 0;
Coord begin = new Coord(0, 0); Coord begin = new Coord(0, 0);
boolean needsLarger = false; boolean needsLarger = false;
while (true) { while (true) {
needsLarger = false; needsLarger = false;
for (LoadedGlyph glyph : glyphs) { for (LoadedGlyph glyph : glyphs) {
if (begin.x + glyph.width > canvas.x) { if (begin.x + glyph.width > canvas.x) {
begin.y += lineHeight; begin.y += lineHeight;
lineHeight = 0; lineHeight = 0;
begin.x = 0; begin.x = 0;
} }
if (lineHeight < glyph.height) { if (lineHeight < glyph.height) {
lineHeight = glyph.height; lineHeight = glyph.height;
} }
if (begin.y + lineHeight > canvas.y) { if (begin.y + lineHeight > canvas.y) {
needsLarger = true; needsLarger = true;
break; break;
} }
// draw. // draw.
begin.x += glyph.width; begin.x += glyph.width;
} }
if (needsLarger) { if (needsLarger) {
canvas.x *= 2; canvas.x *= 2;
canvas.y *= 2; canvas.y *= 2;
@ -220,62 +220,62 @@ public class LoadedFont {
break; break;
} }
} }
textureWidth = (int) canvas.x; textureWidth = (int) canvas.x;
textureHeight = (int) canvas.y; textureHeight = (int) canvas.y;
BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB); BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) imgTemp.getGraphics(); Graphics2D g = (Graphics2D) imgTemp.getGraphics();
g.setColor(new Color(0, 0, 0, 1)); g.setColor(new Color(0, 0, 0, 1));
g.fillRect(0, 0, textureWidth, textureHeight); g.fillRect(0, 0, textureWidth, textureHeight);
int rowHeight = 0; int rowHeight = 0;
int positionX = 0; int positionX = 0;
int positionY = 0; int positionY = 0;
for (LoadedGlyph glyph : glyphs) { for (LoadedGlyph glyph : glyphs) {
CharStorageEntry storedChar = new CharStorageEntry(); CharStorageEntry storedChar = new CharStorageEntry();
storedChar.width = glyph.width; storedChar.width = glyph.width;
storedChar.height = glyph.height; storedChar.height = glyph.height;
if (positionX + storedChar.width >= textureWidth) { if (positionX + storedChar.width >= textureWidth) {
positionX = 0; positionX = 0;
positionY += rowHeight; positionY += rowHeight;
rowHeight = 0; rowHeight = 0;
} }
storedChar.texPosX = positionX; storedChar.texPosX = positionX;
storedChar.texPosY = positionY; storedChar.texPosY = positionY;
if (storedChar.height > fontHeight) { if (storedChar.height > fontHeight) {
fontHeight = storedChar.height; fontHeight = storedChar.height;
} }
if (storedChar.height > rowHeight) { if (storedChar.height > rowHeight) {
rowHeight = storedChar.height; rowHeight = storedChar.height;
} }
// Draw it here // Draw it here
g.drawImage(glyph.image, positionX, positionY, null); g.drawImage(glyph.image, positionX, positionY, null);
positionX += storedChar.width; positionX += storedChar.width;
chars.put(glyph.c, storedChar); chars.put(glyph.c, storedChar);
} }
fontTextureID = loadImage(imgTemp); fontTextureID = loadImage(imgTemp);
imgTemp = null; imgTemp = null;
} catch (Exception e) { } catch (Exception e) {
System.err.println("Failed to create font."); System.err.println("Failed to create font.");
e.printStackTrace(); e.printStackTrace();
} }
} }
private void drawQuad(double drawX, double drawY, double drawX2, double drawY2, CharStorageEntry charObj) private void drawQuad(double drawX, double drawY, double drawX2, double drawY2, CharStorageEntry charObj)
{ {
double srcX = charObj.texPosX + charObj.width; double srcX = charObj.texPosX + charObj.width;
@ -290,9 +290,9 @@ public class LoadedFont {
double SrcHeight = srcY2 - srcY; double SrcHeight = srcY2 - srcY;
double RenderWidth = (SrcWidth / textureWidth); double RenderWidth = (SrcWidth / textureWidth);
double RenderHeight = (SrcHeight / textureHeight); double RenderHeight = (SrcHeight / textureHeight);
drawY -= DrawHeight * clipVerticalB; drawY -= DrawHeight * clipVerticalB;
GL11.glTexCoord2d(TextureSrcX, TextureSrcY); GL11.glTexCoord2d(TextureSrcX, TextureSrcY);
GL11.glVertex2d(drawX, drawY); GL11.glVertex2d(drawX, drawY);
GL11.glTexCoord2d(TextureSrcX, TextureSrcY + RenderHeight); GL11.glTexCoord2d(TextureSrcX, TextureSrcY + RenderHeight);
@ -302,8 +302,8 @@ public class LoadedFont {
GL11.glTexCoord2d(TextureSrcX + RenderWidth, TextureSrcY); GL11.glTexCoord2d(TextureSrcX + RenderWidth, TextureSrcY);
GL11.glVertex2d(drawX + DrawWidth, drawY); GL11.glVertex2d(drawX + DrawWidth, drawY);
} }
public int getWidth(String whatchars) public int getWidth(String whatchars)
{ {
if (whatchars == null) whatchars = ""; if (whatchars == null) whatchars = "";
@ -312,61 +312,61 @@ public class LoadedFont {
char currentChar = 0; char currentChar = 0;
for (int i = 0; i < whatchars.length(); i++) { for (int i = 0; i < whatchars.length(); i++) {
currentChar = whatchars.charAt(i); currentChar = whatchars.charAt(i);
charStorage = chars.get(currentChar); charStorage = chars.get(currentChar);
if (charStorage != null) { if (charStorage != null) {
totalwidth += charStorage.width - correctL; totalwidth += charStorage.width - correctL;
} }
} }
return (int) (totalwidth * defScaleX); return (int) (totalwidth * defScaleX);
} }
public int getHeight() public int getHeight()
{ {
return (int) (fontHeight * defScaleY * (1 - clipVerticalT - clipVerticalB)); return (int) (fontHeight * defScaleY * (1 - clipVerticalT - clipVerticalB));
} }
public int getLineHeight() public int getLineHeight()
{ {
return getHeight(); return getHeight();
} }
public void drawString(double x, double y, String text, double scaleX, double scaleY, RGB color) public void drawString(double x, double y, String text, double scaleX, double scaleY, RGB color)
{ {
drawString(x, y, text, 0, text.length() - 1, scaleX, scaleY, color, LEFT); drawString(x, y, text, 0, text.length() - 1, scaleX, scaleY, color, LEFT);
} }
public void drawString(double x, double y, String text, double scaleX, double scaleY, RGB color, int align) public void drawString(double x, double y, String text, double scaleX, double scaleY, RGB color, int align)
{ {
drawString(x, y, text, 0, text.length() - 1, scaleX, scaleY, color, align); drawString(x, y, text, 0, text.length() - 1, scaleX, scaleY, color, align);
} }
private void drawString(double x, double y, String text, int startIndex, int endIndex, double scaleX, double scaleY, RGB color, int align) private void drawString(double x, double y, String text, int startIndex, int endIndex, double scaleX, double scaleY, RGB color, int align)
{ {
x = Math.round(x); x = Math.round(x);
y = Math.round(y); y = Math.round(y);
scaleX *= defScaleX; scaleX *= defScaleX;
scaleY *= defScaleY; scaleY *= defScaleY;
CharStorageEntry charStorage = null; CharStorageEntry charStorage = null;
int charCurrent; int charCurrent;
int totalwidth = 0; int totalwidth = 0;
int i = startIndex, d = 1, c = correctL; int i = startIndex, d = 1, c = correctL;
float startY = 0; float startY = 0;
switch (align) { switch (align) {
case RIGHT: { case RIGHT: {
d = -1; d = -1;
c = correctR; c = correctR;
while (i < endIndex) { while (i < endIndex) {
if (text.charAt(i) == '\n') startY -= getHeight(); if (text.charAt(i) == '\n') startY -= getHeight();
i++; i++;
@ -377,7 +377,7 @@ public class LoadedFont {
for (int l = startIndex; l <= endIndex; l++) { for (int l = startIndex; l <= endIndex; l++) {
charCurrent = text.charAt(l); charCurrent = text.charAt(l);
if (charCurrent == '\n') break; if (charCurrent == '\n') break;
charStorage = chars.get((char) charCurrent); charStorage = chars.get((char) charCurrent);
if (charStorage != null) { if (charStorage != null) {
totalwidth += charStorage.width - correctL; totalwidth += charStorage.width - correctL;
@ -392,20 +392,20 @@ public class LoadedFont {
c = correctL; c = correctL;
break; break;
} }
} }
GL11.glPushAttrib(GL_ENABLE_BIT); GL11.glPushAttrib(GL_ENABLE_BIT);
GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID); GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID);
GL11.glColor4d(color.r, color.g, color.b, color.a); GL11.glColor4d(color.r, color.g, color.b, color.a);
GL11.glBegin(GL11.GL_QUADS); GL11.glBegin(GL11.GL_QUADS);
while (i >= startIndex && i <= endIndex) { while (i >= startIndex && i <= endIndex) {
charCurrent = text.charAt(i); charCurrent = text.charAt(i);
charStorage = chars.get(new Character((char) charCurrent)); charStorage = chars.get(new Character((char) charCurrent));
if (charStorage != null) { if (charStorage != null) {
if (d < 0) totalwidth += (charStorage.width - c) * d; if (d < 0) totalwidth += (charStorage.width - c) * d;
if (charCurrent == '\n') { if (charCurrent == '\n') {
@ -415,14 +415,14 @@ public class LoadedFont {
for (int l = i + 1; l <= endIndex; l++) { for (int l = i + 1; l <= endIndex; l++) {
charCurrent = text.charAt(l); charCurrent = text.charAt(l);
if (charCurrent == '\n') break; if (charCurrent == '\n') break;
charStorage = chars.get((char) charCurrent); charStorage = chars.get((char) charCurrent);
totalwidth += charStorage.width - correctL; totalwidth += charStorage.width - correctL;
} }
totalwidth /= -2; totalwidth /= -2;
} }
//if center get next lines total width/2; // if center get next lines total width/2;
} else { } else {
//@formatter:off //@formatter:off
drawQuad( drawQuad(
@ -432,25 +432,26 @@ public class LoadedFont {
charStorage charStorage
); );
//@formatter:on //@formatter:on
if (d > 0) totalwidth += (charStorage.width - c) * d; if (d > 0) totalwidth += (charStorage.width - c) * d;
} }
} }
i += d; i += d;
} }
GL11.glEnd(); GL11.glEnd();
GL11.glPopAttrib(); GL11.glPopAttrib();
} }
public static int loadImage(BufferedImage bufferedImage) public static int loadImage(BufferedImage bufferedImage)
{ {
try { try {
short width = (short) bufferedImage.getWidth(); short width = (short) bufferedImage.getWidth();
short height = (short) bufferedImage.getHeight(); short height = (short) bufferedImage.getHeight();
//textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ? (byte)32 : (byte)24; // textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ?
// (byte)32 : (byte)24;
int bpp = (byte) bufferedImage.getColorModel().getPixelSize(); int bpp = (byte) bufferedImage.getColorModel().getPixelSize();
ByteBuffer byteBuffer; ByteBuffer byteBuffer;
DataBuffer db = bufferedImage.getData().getDataBuffer(); DataBuffer db = bufferedImage.getData().getDataBuffer();
@ -460,45 +461,45 @@ public class LoadedFont {
for (int i = 0; i < intI.length; i++) { for (int i = 0; i < intI.length; i++) {
byte b[] = intToByteArray(intI[i]); byte b[] = intToByteArray(intI[i]);
int newIndex = i * 4; int newIndex = i * 4;
newI[newIndex] = b[1]; newI[newIndex] = b[1];
newI[newIndex + 1] = b[2]; newI[newIndex + 1] = b[2];
newI[newIndex + 2] = b[3]; newI[newIndex + 2] = b[3];
newI[newIndex + 3] = b[0]; newI[newIndex + 3] = b[0];
} }
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI); byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI);
} else { } else {
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData()); byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
} }
byteBuffer.flip(); byteBuffer.flip();
int internalFormat = GL11.GL_RGBA8, format = GL11.GL_RGBA; int internalFormat = GL11.GL_RGBA8, format = GL11.GL_RGBA;
IntBuffer textureId = BufferUtils.createIntBuffer(1); IntBuffer textureId = BufferUtils.createIntBuffer(1);
GL11.glGenTextures(textureId); GL11.glGenTextures(textureId);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0)); GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE); GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, internalFormat, width, height, format, GL11.GL_UNSIGNED_BYTE, byteBuffer); GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, internalFormat, width, height, format, GL11.GL_UNSIGNED_BYTE, byteBuffer);
return textureId.get(0); return textureId.get(0);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.exit(-1); System.exit(-1);
} }
return -1; return -1;
} }
public static boolean isSupported(String fontname) public static boolean isSupported(String fontname)
{ {
Font font[] = getFonts(); Font font[] = getFonts();
@ -507,14 +508,14 @@ public class LoadedFont {
} }
return false; return false;
} }
public static Font[] getFonts() public static Font[] getFonts()
{ {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
} }
public static Font getFont(String fontname, int style, float size) public static Font getFont(String fontname, int style, float size)
{ {
Font result = null; Font result = null;
@ -527,14 +528,14 @@ public class LoadedFont {
} }
return result; return result;
} }
public static byte[] intToByteArray(int value) public static byte[] intToByteArray(int value)
{ {
return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value }; return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value };
} }
public void destroy() public void destroy()
{ {
IntBuffer scratch = BufferUtils.createIntBuffer(1); IntBuffer scratch = BufferUtils.createIntBuffer(1);
@ -542,82 +543,91 @@ public class LoadedFont {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL11.glDeleteTextures(scratch); GL11.glDeleteTextures(scratch);
} }
public LoadedFont setScale(double x, double y) public LoadedFont setScale(double x, double y)
{ {
defScaleX = x; defScaleX = x;
defScaleY = y; defScaleY = y;
return this; return this;
} }
public LoadedFont setClip(double clipRatioTop, double clipRatioBottom) public LoadedFont setClip(double clipRatioTop, double clipRatioBottom)
{ {
clipVerticalT = clipRatioTop; clipVerticalT = clipRatioTop;
clipVerticalB = clipRatioBottom; clipVerticalB = clipRatioBottom;
return this; return this;
} }
public LoadedFont setCorrection(int correctionLeft, int correctionRight) public LoadedFont setCorrection(int correctionLeft, int correctionRight)
{ {
correctL = correctionLeft; correctL = correctionLeft;
correctR = correctionRight; correctR = correctionRight;
return this; return this;
} }
/** /**
* Draw string with font. * Draw string with font.
* *
* @param x x coord * @param x
* @param y y coord * x coord
* @param text text to draw * @param y
* @param color render color * y coord
* @param align (-1,0,1) * @param text
* text to draw
* @param color
* render color
* @param align
* (-1,0,1)
*/ */
public void draw(double x, double y, String text, RGB color, int align) public void draw(double x, double y, String text, RGB color, int align)
{ {
drawString(x, y, text, 1, 1, color, align); drawString(x, y, text, 1, 1, color, align);
} }
/** /**
* Draw string with font. * Draw string with font.
* *
* @param pos coord * @param pos
* @param text text to draw * coord
* @param color render color * @param text
* @param align (-1,0,1) * text to draw
* @param color
* render color
* @param align
* (-1,0,1)
*/ */
public void draw(Coord pos, String text, RGB color, int align) public void draw(Coord pos, String text, RGB color, int align)
{ {
drawString(pos.x, pos.y, text, 1, 1, color, align); drawString(pos.x, pos.y, text, 1, 1, color, align);
} }
public void drawFuzzy(Coord pos, String text, int align, RGB textColor, RGB blurColor, int blurSize) public void drawFuzzy(Coord pos, String text, int align, RGB textColor, RGB blurColor, int blurSize)
{ {
drawFuzzy(pos, text, align, textColor, blurColor, blurSize, true); drawFuzzy(pos, text, align, textColor, blurColor, blurSize, true);
} }
public void drawFuzzy(Coord pos, String text, int align, RGB textColor, RGB blurColor, int blurSize, boolean smooth) public void drawFuzzy(Coord pos, String text, int align, RGB textColor, RGB blurColor, int blurSize, boolean smooth)
{ {
glPushMatrix(); glPushMatrix();
glTranslated(pos.x, pos.y, pos.z); glTranslated(pos.x, pos.y, pos.z);
//shadow // shadow
int sh = blurSize; int sh = blurSize;
int l = glGenLists(1); int l = glGenLists(1);
glNewList(l, GL_COMPILE); glNewList(l, GL_COMPILE);
draw(0, 0, text, blurColor, align); draw(0, 0, text, blurColor, align);
glEndList(); glEndList();
for (int xx = -sh; xx <= sh; xx += (smooth ? 1 : sh)) { for (int xx = -sh; xx <= sh; xx += (smooth ? 1 : sh)) {
for (int yy = -sh; yy <= sh; yy += (smooth ? 1 : sh)) { for (int yy = -sh; yy <= sh; yy += (smooth ? 1 : sh)) {
if (xx == 0 && yy == 0) continue; if (xx == 0 && yy == 0) continue;
@ -627,12 +637,12 @@ public class LoadedFont {
glPopMatrix(); glPopMatrix();
} }
} }
glDeleteLists(l, 1); glDeleteLists(l, 1);
draw(0, 0, text, textColor, align); draw(0, 0, text, textColor, align);
glPopMatrix(); glPopMatrix();
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.input; package mightypork.rogue.input;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.DelegatingBusClient; import mightypork.rogue.bus.DelegatingBusClient;
import mightypork.rogue.bus.events.KeyboardEvent; import mightypork.rogue.bus.events.KeyboardEvent;
@ -15,37 +14,37 @@ import org.lwjgl.opengl.Display;
public class InputSystem extends DelegatingBusClient implements KeyBinder { public class InputSystem extends DelegatingBusClient implements KeyBinder {
// listeners // listeners
private KeyBindingPool keybindings; private KeyBindingPool keybindings;
public InputSystem(AppAccess app) { public InputSystem(AppAccess app) {
super(app, true); super(app, true);
} }
@Override @Override
protected void init() protected void init()
{ {
initDevices(); initDevices();
initChannels(); initChannels();
// global keybindings // global keybindings
keybindings = new KeyBindingPool(); keybindings = new KeyBindingPool();
addChildSubscriber(keybindings); addChildSubscriber(keybindings);
} }
@Override @Override
public void deinit() public void deinit()
{ {
Mouse.destroy(); Mouse.destroy();
Keyboard.destroy(); Keyboard.destroy();
} }
private void initDevices() private void initDevices()
{ {
try { try {
@ -56,45 +55,45 @@ public class InputSystem extends DelegatingBusClient implements KeyBinder {
throw new RuntimeException("Failed to initialize input devices.", e); throw new RuntimeException("Failed to initialize input devices.", e);
} }
} }
private void initChannels() private void initChannels()
{ {
bus().createChannel(KeyboardEvent.class, KeyboardEvent.Listener.class); bus().createChannel(KeyboardEvent.class, KeyboardEvent.Listener.class);
bus().createChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class); bus().createChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class);
bus().createChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class); bus().createChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class);
} }
@Override @Override
public void bindKeyStroke(KeyStroke stroke, Runnable task) public void bindKeyStroke(KeyStroke stroke, Runnable task)
{ {
keybindings.bindKeyStroke(stroke, task); keybindings.bindKeyStroke(stroke, task);
} }
@Override @Override
public void unbindKeyStroke(KeyStroke stroke) public void unbindKeyStroke(KeyStroke stroke)
{ {
keybindings.unbindKeyStroke(stroke); keybindings.unbindKeyStroke(stroke);
} }
@Override @Override
public void update(double delta) public void update(double delta)
{ {
Display.processMessages(); Display.processMessages();
while (Mouse.next()) { while (Mouse.next()) {
onMouseEvent(); onMouseEvent();
} }
while (Keyboard.next()) { while (Keyboard.next()) {
onKeyEvent(); onKeyEvent();
} }
} }
private void onMouseEvent() private void onMouseEvent()
{ {
int button = Mouse.getEventButton(); int button = Mouse.getEventButton();
@ -102,12 +101,12 @@ public class InputSystem extends DelegatingBusClient implements KeyBinder {
Coord pos = new Coord(Mouse.getEventX(), Mouse.getEventY()); Coord pos = new Coord(Mouse.getEventX(), Mouse.getEventY());
Coord move = new Coord(Mouse.getEventDX(), Mouse.getEventDY()); Coord move = new Coord(Mouse.getEventDX(), Mouse.getEventDY());
int wheeld = Mouse.getEventDWheel(); int wheeld = Mouse.getEventDWheel();
if (button != -1 || wheeld != 0) bus().broadcast(new MouseButtonEvent(pos, button, down, wheeld)); if (button != -1 || wheeld != 0) bus().broadcast(new MouseButtonEvent(pos, button, down, wheeld));
if (!move.isZero()) bus().broadcast(new MouseMotionEvent(pos, move)); if (!move.isZero()) bus().broadcast(new MouseMotionEvent(pos, move));
} }
private void onKeyEvent() private void onKeyEvent()
{ {
int key = Keyboard.getEventKey(); int key = Keyboard.getEventKey();

@ -1,22 +1,24 @@
package mightypork.rogue.input; package mightypork.rogue.input;
public interface KeyBinder { public interface KeyBinder {
/** /**
* Bind handler to a keystroke, replace current handler if any * Bind handler to a keystroke, replace current handler if any
* *
* @param stroke trigger keystroke * @param stroke
* @param task handler * trigger keystroke
* @param task
* handler
*/ */
abstract void bindKeyStroke(KeyStroke stroke, Runnable task); abstract void bindKeyStroke(KeyStroke stroke, Runnable task);
/** /**
* Remove handler from a keystroke (id any) * Remove handler from a keystroke (id any)
* *
* @param stroke stroke * @param stroke
* stroke
*/ */
abstract void unbindKeyStroke(KeyStroke stroke); abstract void unbindKeyStroke(KeyStroke stroke);
} }

@ -1,48 +1,47 @@
package mightypork.rogue.input; package mightypork.rogue.input;
import mightypork.rogue.bus.events.KeyboardEvent; import mightypork.rogue.bus.events.KeyboardEvent;
public class KeyBinding implements KeyboardEvent.Listener { public class KeyBinding implements KeyboardEvent.Listener {
private KeyStroke keystroke; private KeyStroke keystroke;
private Runnable handler; private Runnable handler;
private boolean wasActive = false; private boolean wasActive = false;
public KeyBinding(KeyStroke stroke, Runnable handler) { public KeyBinding(KeyStroke stroke, Runnable handler) {
this.keystroke = stroke; this.keystroke = stroke;
this.handler = handler; this.handler = handler;
wasActive = keystroke.isActive(); wasActive = keystroke.isActive();
} }
public boolean matches(KeyStroke stroke) public boolean matches(KeyStroke stroke)
{ {
return this.keystroke.equals(stroke); return this.keystroke.equals(stroke);
} }
public void setHandler(Runnable handler) public void setHandler(Runnable handler)
{ {
this.handler = handler; this.handler = handler;
} }
@Override @Override
public void receive(KeyboardEvent event) public void receive(KeyboardEvent event)
{ {
// ignore unrelated events // ignore unrelated events
if (!keystroke.getKeys().contains(event.getKey())) return; if (!keystroke.getKeys().contains(event.getKey())) return;
// run handler when event was met // run handler when event was met
if (keystroke.isActive() && !wasActive) { if (keystroke.isActive() && !wasActive) {
handler.run(); handler.run();
} }
wasActive = keystroke.isActive(); wasActive = keystroke.isActive();
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.input; package mightypork.rogue.input;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
@ -15,15 +14,17 @@ import mightypork.utils.logging.Log;
* @author MightyPork * @author MightyPork
*/ */
public class KeyBindingPool implements KeyBinder, KeyboardEvent.Listener { public class KeyBindingPool implements KeyBinder, KeyboardEvent.Listener {
private Set<KeyBinding> bindings = new HashSet<KeyBinding>(); private Set<KeyBinding> bindings = new HashSet<KeyBinding>();
/** /**
* Bind handler to a keystroke, replace current handler if any * Bind handler to a keystroke, replace current handler if any
* *
* @param stroke trigger keystroke * @param stroke
* @param task handler * trigger keystroke
* @param task
* handler
*/ */
@Override @Override
public void bindKeyStroke(KeyStroke stroke, Runnable task) public void bindKeyStroke(KeyStroke stroke, Runnable task)
@ -35,21 +36,22 @@ public class KeyBindingPool implements KeyBinder, KeyboardEvent.Listener {
return; return;
} }
} }
bindings.add(new KeyBinding(stroke, task)); bindings.add(new KeyBinding(stroke, task));
} }
/** /**
* Remove handler from keystroke (id any) * Remove handler from keystroke (id any)
* *
* @param stroke stroke * @param stroke
* stroke
*/ */
@Override @Override
public void unbindKeyStroke(KeyStroke stroke) public void unbindKeyStroke(KeyStroke stroke)
{ {
Iterator<KeyBinding> iter = bindings.iterator(); Iterator<KeyBinding> iter = bindings.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
KeyBinding kb = iter.next(); KeyBinding kb = iter.next();
if (kb.matches(stroke)) { if (kb.matches(stroke)) {
@ -58,8 +60,8 @@ public class KeyBindingPool implements KeyBinder, KeyboardEvent.Listener {
} }
} }
} }
@Override @Override
public void receive(KeyboardEvent event) public void receive(KeyboardEvent event)
{ {

@ -1,6 +1,5 @@
package mightypork.rogue.input; package mightypork.rogue.input;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
@ -9,16 +8,18 @@ import org.lwjgl.input.Keyboard;
public class KeyStroke { public class KeyStroke {
private Set<Integer> keys = new LinkedHashSet<Integer>(); private Set<Integer> keys = new LinkedHashSet<Integer>();
private boolean down = true; private boolean down = true;
/** /**
* KeyStroke * KeyStroke
* *
* @param down true for falling edge, up for rising edge * @param down
* @param keys keys that must be pressed * true for falling edge, up for rising edge
* @param keys
* keys that must be pressed
*/ */
public KeyStroke(boolean down, int... keys) { public KeyStroke(boolean down, int... keys) {
this.down = down; this.down = down;
@ -26,8 +27,8 @@ public class KeyStroke {
this.keys.add(k); this.keys.add(k);
} }
} }
/** /**
* Falling edge keystroke * Falling edge keystroke
* *
@ -38,25 +39,25 @@ public class KeyStroke {
this.keys.add(k); this.keys.add(k);
} }
} }
public boolean isActive() public boolean isActive()
{ {
boolean st = true; boolean st = true;
for (int k : keys) { for (int k : keys) {
st &= Keyboard.isKeyDown(k); st &= Keyboard.isKeyDown(k);
} }
return down ? st : !st; return down ? st : !st;
} }
public void setKeys(Set<Integer> keys) public void setKeys(Set<Integer> keys)
{ {
this.keys = keys; this.keys = keys;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
@ -65,8 +66,8 @@ public class KeyStroke {
result = prime * result + ((keys == null) ? 0 : keys.hashCode()); result = prime * result + ((keys == null) ? 0 : keys.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
@ -74,39 +75,39 @@ public class KeyStroke {
if (obj == null) return false; if (obj == null) return false;
if (!(obj instanceof KeyStroke)) return false; if (!(obj instanceof KeyStroke)) return false;
KeyStroke other = (KeyStroke) obj; KeyStroke other = (KeyStroke) obj;
if (keys == null) { if (keys == null) {
if (other.keys != null) return false; if (other.keys != null) return false;
} else if (!keys.equals(other.keys)) { } else if (!keys.equals(other.keys)) {
return false; return false;
} }
if (down != other.down) return false; if (down != other.down) return false;
return true; return true;
} }
@Override @Override
public String toString() public String toString()
{ {
String s = "("; String s = "(";
int cnt = 0; int cnt = 0;
Iterator<Integer> i = keys.iterator(); Iterator<Integer> i = keys.iterator();
for (; i.hasNext(); cnt++) { for (; i.hasNext(); cnt++) {
if (cnt > 0) s += "+"; if (cnt > 0) s += "+";
s += Keyboard.getKeyName(i.next()); s += Keyboard.getKeyName(i.next());
} }
s += down ? ",DOWN" : "UP"; s += down ? ",DOWN" : "UP";
s += ")"; s += ")";
return s; return s;
} }
public Set<Integer> getKeys() public Set<Integer> getKeys()
{ {
return keys; return keys;

@ -1,6 +1,5 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.files.FileUtils; import mightypork.utils.files.FileUtils;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
@ -16,12 +15,11 @@ import org.newdawn.slick.openal.SoundStore;
* @author MightyPork * @author MightyPork
*/ */
public class AudioX implements Destroyable { public class AudioX implements Destroyable {
private enum PlayMode private enum PlayMode {
{
EFFECT, MUSIC; EFFECT, MUSIC;
}; };
private Audio audio = null; private Audio audio = null;
private double pauseLoopPosition = 0; private double pauseLoopPosition = 0;
private boolean looping = false; private boolean looping = false;
@ -29,37 +27,38 @@ public class AudioX implements Destroyable {
private PlayMode mode = PlayMode.EFFECT; private PlayMode mode = PlayMode.EFFECT;
private double lastPlayPitch = 1; private double lastPlayPitch = 1;
private double lastPlayGain = 1; private double lastPlayGain = 1;
private final String resourcePath; private final String resourcePath;
private boolean loadFailed = false; private boolean loadFailed = false;
/** /**
* Create deferred primitive audio player * Create deferred primitive audio player
* *
* @param resourceName resource to load when needed * @param resourceName
* resource to load when needed
*/ */
public AudioX(String resourceName) { public AudioX(String resourceName) {
this.audio = null; this.audio = null;
this.resourcePath = resourceName; this.resourcePath = resourceName;
} }
/** /**
* Pause loop (remember position and stop playing) - if was looping * Pause loop (remember position and stop playing) - if was looping
*/ */
public void pauseLoop() public void pauseLoop()
{ {
if (!load()) return; if (!load()) return;
if (isPlaying() && looping) { if (isPlaying() && looping) {
pauseLoopPosition = audio.getPosition(); pauseLoopPosition = audio.getPosition();
stop(); stop();
paused = true; paused = true;
} }
} }
/** /**
* Resume loop (if was paused) * Resume loop (if was paused)
* *
@ -68,7 +67,7 @@ public class AudioX implements Destroyable {
public int resumeLoop() public int resumeLoop()
{ {
if (!load()) return -1; if (!load()) return -1;
int source = -1; int source = -1;
if (looping && paused) { if (looping && paused) {
if (mode == PlayMode.MUSIC) { if (mode == PlayMode.MUSIC) {
@ -81,8 +80,8 @@ public class AudioX implements Destroyable {
} }
return source; return source;
} }
/** /**
* Check if resource is loaded * Check if resource is loaded
* *
@ -92,8 +91,8 @@ public class AudioX implements Destroyable {
{ {
return audio != null; return audio != null;
} }
/** /**
* Try to load if not loaded already * Try to load if not loaded already
* *
@ -102,12 +101,14 @@ public class AudioX implements Destroyable {
public boolean load() public boolean load()
{ {
if (isLoaded()) return true; // already loaded if (isLoaded()) return true; // already loaded
if (loadFailed || resourcePath == null) return false; // not loaded, but can't load anyway if (loadFailed || resourcePath == null) return false; // not loaded, but
// can't load
// anyway
loadFailed = false; loadFailed = false;
try { try {
String ext = FileUtils.getExtension(resourcePath); String ext = FileUtils.getExtension(resourcePath);
// java 6 can't use String switch :( // java 6 can't use String switch :(
if (ext.equalsIgnoreCase("ogg")) { if (ext.equalsIgnoreCase("ogg")) {
audio = SoundStore.get().getOgg(resourcePath); audio = SoundStore.get().getOgg(resourcePath);
@ -121,61 +122,67 @@ public class AudioX implements Destroyable {
Log.e("Invalid audio file extension: " + resourcePath); Log.e("Invalid audio file extension: " + resourcePath);
loadFailed = true; // don't try next time loadFailed = true; // don't try next time
} }
} catch (Exception e) { } catch (Exception e) {
Log.e("Could not load " + resourcePath, e); Log.e("Could not load " + resourcePath, e);
loadFailed = true; // don't try next time loadFailed = true; // don't try next time
} }
return isLoaded(); return isLoaded();
} }
public void stop() public void stop()
{ {
if (!isLoaded()) return; if (!isLoaded()) return;
audio.stop(); audio.stop();
paused = false; paused = false;
} }
public boolean isPlaying() public boolean isPlaying()
{ {
if (!isLoaded()) return false; if (!isLoaded()) return false;
return audio.isPlaying(); return audio.isPlaying();
} }
public boolean isPaused() public boolean isPaused()
{ {
if (!isLoaded()) return false; if (!isLoaded()) return false;
return audio.isPaused(); return audio.isPaused();
} }
/** /**
* Play as sound effect at listener position * Play as sound effect at listener position
* *
* @param pitch pitch (1 = default) * @param pitch
* @param gain gain (0-1) * pitch (1 = default)
* @param loop looping * @param gain
* gain (0-1)
* @param loop
* looping
* @return source id * @return source id
*/ */
public int playAsEffect(double pitch, double gain, boolean loop) public int playAsEffect(double pitch, double gain, boolean loop)
{ {
return playAsEffect(pitch, gain, loop, SoundSystem.getListener()); return playAsEffect(pitch, gain, loop, SoundSystem.getListener());
} }
/** /**
* Play as sound effect at given X-Y position * Play as sound effect at given X-Y position
* *
* @param pitch pitch (1 = default) * @param pitch
* @param gain gain (0-1) * pitch (1 = default)
* @param loop looping * @param gain
* gain (0-1)
* @param loop
* looping
* @param x * @param x
* @param y * @param y
* @return source id * @return source id
@ -184,14 +191,17 @@ public class AudioX implements Destroyable {
{ {
return playAsEffect(pitch, gain, loop, x, y, SoundSystem.getListener().z); return playAsEffect(pitch, gain, loop, x, y, SoundSystem.getListener().z);
} }
/** /**
* Play as sound effect at given position * Play as sound effect at given position
* *
* @param pitch pitch (1 = default) * @param pitch
* @param gain gain (0-1) * pitch (1 = default)
* @param loop looping * @param gain
* gain (0-1)
* @param loop
* looping
* @param x * @param x
* @param y * @param y
* @param z * @param z
@ -200,63 +210,70 @@ public class AudioX implements Destroyable {
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y, double z) public int playAsEffect(double pitch, double gain, boolean loop, double x, double y, double z)
{ {
if (!load()) return -1; if (!load()) return -1;
this.lastPlayPitch = pitch; this.lastPlayPitch = pitch;
this.lastPlayGain = gain; this.lastPlayGain = gain;
looping = loop; looping = loop;
mode = PlayMode.EFFECT; mode = PlayMode.EFFECT;
return audio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z); return audio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z);
} }
/** /**
* Play as sound effect at given position * Play as sound effect at given position
* *
* @param pitch pitch (1 = default) * @param pitch
* @param gain gain (0-1) * pitch (1 = default)
* @param loop looping * @param gain
* @param pos coord * gain (0-1)
* @param loop
* looping
* @param pos
* coord
* @return source id * @return source id
*/ */
public int playAsEffect(double pitch, double gain, boolean loop, Coord pos) public int playAsEffect(double pitch, double gain, boolean loop, Coord pos)
{ {
if (!load()) return -1; if (!load()) return -1;
return playAsEffect(pitch, gain, loop, pos.x, pos.y, pos.z); return playAsEffect(pitch, gain, loop, pos.x, pos.y, pos.z);
} }
/** /**
* Play as music using source 0.<br> * Play as music using source 0.<br>
* Discouraged, since this does not allow cross-fading. * Discouraged, since this does not allow cross-fading.
* *
* @param pitch play pitch * @param pitch
* @param gain play gain * play pitch
* @param loop looping * @param gain
* play gain
* @param loop
* looping
* @return source * @return source
*/ */
public int playAsMusic(double pitch, double gain, boolean loop) public int playAsMusic(double pitch, double gain, boolean loop)
{ {
if (!load()) return -1; if (!load()) return -1;
this.lastPlayPitch = (float) pitch; this.lastPlayPitch = (float) pitch;
this.lastPlayGain = (float) gain; this.lastPlayGain = (float) gain;
looping = loop; looping = loop;
mode = PlayMode.MUSIC; mode = PlayMode.MUSIC;
return audio.playAsMusic((float) pitch, (float) gain, loop); return audio.playAsMusic((float) pitch, (float) gain, loop);
} }
@Override @Override
public void destroy() public void destroy()
{ {
if (!isLoaded()) return; if (!isLoaded()) return;
audio.release(); audio.release();
audio = null; audio = null;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
@ -265,8 +282,8 @@ public class AudioX implements Destroyable {
result = prime * result + ((resourcePath == null) ? 0 : resourcePath.hashCode()); result = prime * result + ((resourcePath == null) ? 0 : resourcePath.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
@ -281,5 +298,5 @@ public class AudioX implements Destroyable {
} }
return true; return true;
} }
} }

@ -1,66 +1,65 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.objects.Mutable; import mightypork.utils.objects.Mutable;
public abstract class BaseAudioPlayer { public abstract class BaseAudioPlayer {
/** the track */ /** the track */
private AudioX audio; private AudioX audio;
/** base gain for sfx */ /** base gain for sfx */
private double baseGain = 1; private double baseGain = 1;
/** base pitch for sfx */ /** base pitch for sfx */
private double basePitch = 1; private double basePitch = 1;
/** dedicated volume control */ /** dedicated volume control */
private Mutable<Double> gainMultiplier = null; private Mutable<Double> gainMultiplier = null;
public BaseAudioPlayer(AudioX track, double baseGain, Mutable<Double> gainMultiplier) { public BaseAudioPlayer(AudioX track, double baseGain, Mutable<Double> gainMultiplier) {
this(track, 1, baseGain, gainMultiplier); this(track, 1, baseGain, gainMultiplier);
} }
public BaseAudioPlayer(AudioX track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) { public BaseAudioPlayer(AudioX track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) {
this.audio = track; this.audio = track;
this.baseGain = baseGain; this.baseGain = baseGain;
this.basePitch = basePitch; this.basePitch = basePitch;
if (gainMultiplier == null) gainMultiplier = new Mutable<Double>(1D); if (gainMultiplier == null) gainMultiplier = new Mutable<Double>(1D);
this.gainMultiplier = gainMultiplier; this.gainMultiplier = gainMultiplier;
} }
public void destroy() public void destroy()
{ {
audio.destroy(); audio.destroy();
audio = null; audio = null;
} }
protected AudioX getAudio() protected AudioX getAudio()
{ {
return audio; return audio;
} }
protected double getGain(double multiplier) protected double getGain(double multiplier)
{ {
return baseGain * gainMultiplier.get() * multiplier; return baseGain * gainMultiplier.get() * multiplier;
} }
protected double getPitch(double multiplier) protected double getPitch(double multiplier)
{ {
return basePitch * multiplier; return basePitch * multiplier;
} }
/** /**
* Get if audio is valid * Get if audio is valid
* *
@ -70,8 +69,8 @@ public abstract class BaseAudioPlayer {
{ {
return (audio != null); return (audio != null);
} }
public void load() public void load()
{ {
if (canPlay()) audio.load(); if (canPlay()) audio.load();

@ -1,36 +1,35 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.objects.Mutable; import mightypork.utils.objects.Mutable;
public class EffectPlayer extends BaseAudioPlayer { public class EffectPlayer extends BaseAudioPlayer {
public EffectPlayer(AudioX track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) { public EffectPlayer(AudioX track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) {
super(track, (float) basePitch, (float) baseGain, gainMultiplier); super(track, (float) basePitch, (float) baseGain, gainMultiplier);
} }
public int play(double pitch, double gain) public int play(double pitch, double gain)
{ {
if (!canPlay()) return -1; if (!canPlay()) return -1;
return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false); return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false);
} }
public int play(double gain) public int play(double gain)
{ {
return play(1, gain); return play(1, gain);
} }
public int play(double pitch, double gain, Coord pos) public int play(double pitch, double gain, Coord pos)
{ {
if (!canPlay()) return -1; if (!canPlay()) return -1;
return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false, pos); return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false, pos);
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
import mightypork.utils.objects.Mutable; import mightypork.utils.objects.Mutable;
@ -11,21 +10,22 @@ import mightypork.utils.objects.Mutable;
* @author MightyPork * @author MightyPork
*/ */
public class JointVolume extends Mutable<Double> { public class JointVolume extends Mutable<Double> {
private Mutable<Double>[] volumes; private Mutable<Double>[] volumes;
/** /**
* Create joint volume with master gain of 1 * Create joint volume with master gain of 1
* *
* @param volumes individual volumes to join * @param volumes
* individual volumes to join
*/ */
public JointVolume(Mutable<Double>... volumes) { public JointVolume(Mutable<Double>... volumes) {
super(1D); super(1D);
this.volumes = volumes; this.volumes = volumes;
} }
/** /**
* Get combined gain (multiplied) * Get combined gain (multiplied)
*/ */
@ -35,11 +35,11 @@ public class JointVolume extends Mutable<Double> {
double d = super.get(); double d = super.get();
for (Mutable<Double> v : volumes) for (Mutable<Double> v : volumes)
d *= v.get(); d *= v.get();
return Calc.clampd(d, 0, 1); return Calc.clampd(d, 0, 1);
} }
/** /**
* Set master gain * Set master gain
*/ */

@ -1,6 +1,5 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.objects.Mutable; import mightypork.utils.objects.Mutable;
import mightypork.utils.time.Pauseable; import mightypork.utils.time.Pauseable;
import mightypork.utils.time.Updateable; import mightypork.utils.time.Updateable;
@ -10,38 +9,38 @@ import org.lwjgl.openal.AL10;
public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable { public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable {
private int sourceID = -1; private int sourceID = -1;
/** animator for fade in and fade out */ /** animator for fade in and fade out */
private AnimDouble fadeAnim = new AnimDouble(0); private AnimDouble fadeAnim = new AnimDouble(0);
private double lastUpdateGain = 0; private double lastUpdateGain = 0;
/** flag that track is paused */ /** flag that track is paused */
private boolean paused = true; private boolean paused = true;
/** Default fadeIn time */ /** Default fadeIn time */
private double inTime = 1; private double inTime = 1;
/** Default fadeOut time */ /** Default fadeOut time */
private double outTime = 1; private double outTime = 1;
public LoopPlayer(AudioX track, double pitch, double baseGain, Mutable<Double> gainMultiplier) { public LoopPlayer(AudioX track, double pitch, double baseGain, Mutable<Double> gainMultiplier) {
super(track, (float) pitch, (float) baseGain, gainMultiplier); super(track, (float) pitch, (float) baseGain, gainMultiplier);
paused = true; paused = true;
} }
public void setFadeTimes(double in, double out) public void setFadeTimes(double in, double out)
{ {
inTime = in; inTime = in;
outTime = out; outTime = out;
} }
private void initLoop() private void initLoop()
{ {
if (!canPlay() && sourceID == -1) { if (!canPlay() && sourceID == -1) {
@ -49,84 +48,84 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
getAudio().pauseLoop(); getAudio().pauseLoop();
} }
} }
@Override @Override
public void pause() public void pause()
{ {
if (!canPlay() || paused) return; if (!canPlay() || paused) return;
initLoop(); initLoop();
getAudio().pauseLoop(); getAudio().pauseLoop();
paused = true; paused = true;
} }
@Override @Override
public boolean isPaused() public boolean isPaused()
{ {
return paused; return paused;
} }
@Override @Override
public void resume() public void resume()
{ {
if (!canPlay() || paused) return; if (!canPlay() || paused) return;
initLoop(); initLoop();
sourceID = getAudio().resumeLoop(); sourceID = getAudio().resumeLoop();
paused = false; paused = false;
} }
@Override @Override
public void update(double delta) public void update(double delta)
{ {
if (!canPlay() || paused) return; if (!canPlay() || paused) return;
initLoop(); initLoop();
fadeAnim.update(delta); fadeAnim.update(delta);
double gain = getGain(fadeAnim.getCurrentValue()); double gain = getGain(fadeAnim.getCurrentValue());
if (!paused && gain != lastUpdateGain) { if (!paused && gain != lastUpdateGain) {
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain); AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
lastUpdateGain = gain; lastUpdateGain = gain;
} }
if (gain == 0 && !paused) pause(); // pause on zero volume if (gain == 0 && !paused) pause(); // pause on zero volume
} }
public void fadeIn(double secs) public void fadeIn(double secs)
{ {
if (!canPlay()) return; if (!canPlay()) return;
resume(); resume();
fadeAnim.fadeIn(secs); fadeAnim.fadeIn(secs);
} }
public void fadeOut(double secs) public void fadeOut(double secs)
{ {
if (!canPlay()) return; if (!canPlay()) return;
fadeAnim.fadeOut(secs); fadeAnim.fadeOut(secs);
} }
public void fadeIn() public void fadeIn()
{ {
fadeIn(inTime); fadeIn(inTime);
} }
public void fadeOut() public void fadeOut()
{ {
fadeOut(outTime); fadeOut(outTime);
} }
} }

@ -1,17 +1,16 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
public class NullAudio extends AudioX { public class NullAudio extends AudioX {
public NullAudio() { public NullAudio() {
super(""); super("");
} }
@Override @Override
public boolean load() public boolean load()
{ {
return false; return false;
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -26,24 +25,24 @@ import org.newdawn.slick.openal.SoundStore;
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class SoundSystem extends DelegatingBusClient { public class SoundSystem extends DelegatingBusClient {
private static final Coord INITIAL_LISTENER_POS = new Coord(0, 0, 0); private static final Coord INITIAL_LISTENER_POS = new Coord(0, 0, 0);
private static final int MAX_SOURCES = 256; private static final int MAX_SOURCES = 256;
private static final AudioX NO_SOUND = new NullAudio(); private static final AudioX NO_SOUND = new NullAudio();
private static final LoopPlayer NULL_LOOP = new LoopPlayer(NO_SOUND, 0, 0, null); private static final LoopPlayer NULL_LOOP = new LoopPlayer(NO_SOUND, 0, 0, null);
private static final EffectPlayer NULL_EFFECT = new EffectPlayer(NO_SOUND, 0, 0, null); private static final EffectPlayer NULL_EFFECT = new EffectPlayer(NO_SOUND, 0, 0, null);
private static Coord listener = new Coord(); private static Coord listener = new Coord();
static { static {
// initialize sound system // initialize sound system
SoundStore.get().setMaxSources(MAX_SOURCES); SoundStore.get().setMaxSources(MAX_SOURCES);
SoundStore.get().init(); SoundStore.get().init();
setListener(INITIAL_LISTENER_POS); setListener(INITIAL_LISTENER_POS);
} }
/** /**
* Set listener pos * Set listener pos
* *
@ -65,42 +64,42 @@ public class SoundSystem extends DelegatingBusClient {
AL10.alListener(AL10.AL_ORIENTATION, buf6); AL10.alListener(AL10.AL_ORIENTATION, buf6);
buf3 = buf6 = null; buf3 = buf6 = null;
} }
// -- instance -- // -- instance --
public Mutable<Double> masterVolume = new Mutable<Double>(1D); public Mutable<Double> masterVolume = new Mutable<Double>(1D);
public Mutable<Double> effectsVolume = new JointVolume(masterVolume); public Mutable<Double> effectsVolume = new JointVolume(masterVolume);
public Mutable<Double> loopsVolume = new JointVolume(masterVolume); public Mutable<Double> loopsVolume = new JointVolume(masterVolume);
private Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>(); private Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>();
private Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>(); private Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>();
private Set<AudioX> resources = new HashSet<AudioX>(); private Set<AudioX> resources = new HashSet<AudioX>();
public SoundSystem(AppAccess app) { public SoundSystem(AppAccess app) {
super(app, true); super(app, true);
} }
@Override @Override
protected void init() protected void init()
{ {
// empty // empty
} }
@Override @Override
public void deinit() public void deinit()
{ {
for (AudioX r : resources) { for (AudioX r : resources) {
r.destroy(); r.destroy();
} }
SoundStore.get().clear(); SoundStore.get().clear();
AL.destroy(); AL.destroy();
} }
@Override @Override
public void update(double delta) public void update(double delta)
{ {
@ -108,38 +107,48 @@ public class SoundSystem extends DelegatingBusClient {
lp.update(delta); lp.update(delta);
} }
} }
public static Coord getListener() public static Coord getListener()
{ {
return listener; return listener;
} }
/** /**
* Register effect resource * Register effect resource
* *
* @param key sound key * @param key
* @param resource resource path * sound key
* @param pitch default pitch (1 = unchanged) * @param resource
* @param gain default gain (0-1) * resource path
* @param pitch
* default pitch (1 = unchanged)
* @param gain
* default gain (0-1)
*/ */
public void addEffect(String key, String resource, double pitch, double gain) public void addEffect(String key, String resource, double pitch, double gain)
{ {
EffectPlayer p = new EffectPlayer(getResource(resource), pitch, gain, effectsVolume); EffectPlayer p = new EffectPlayer(getResource(resource), pitch, gain, effectsVolume);
effects.put(key, p); effects.put(key, p);
} }
/** /**
* Register loop resource (music / effect loop) * Register loop resource (music / effect loop)
* *
* @param key sound key * @param key
* @param resource resource path * sound key
* @param pitch default pitch (1 = unchanged) * @param resource
* @param gain default gain (0-1) * resource path
* @param fadeIn default time for fadeIn * @param pitch
* @param fadeOut default time for fadeOut * default pitch (1 = unchanged)
* @param gain
* default gain (0-1)
* @param fadeIn
* default time for fadeIn
* @param fadeOut
* default time for fadeOut
*/ */
public void addLoop(String key, String resource, double pitch, double gain, double fadeIn, double fadeOut) public void addLoop(String key, String resource, double pitch, double gain, double fadeIn, double fadeOut)
{ {
@ -147,14 +156,16 @@ public class SoundSystem extends DelegatingBusClient {
p.setFadeTimes(fadeIn, fadeOut); p.setFadeTimes(fadeIn, fadeOut);
loops.put(key, p); loops.put(key, p);
} }
/** /**
* Create {@link AudioX} for a resource * Create {@link AudioX} for a resource
* *
* @param res a resource name * @param res
* a resource name
* @return the resource * @return the resource
* @throws IllegalArgumentException if resource is already registered * @throws IllegalArgumentException
* if resource is already registered
*/ */
private AudioX getResource(String res) private AudioX getResource(String res)
{ {
@ -163,12 +174,13 @@ public class SoundSystem extends DelegatingBusClient {
resources.add(a); resources.add(a);
return a; return a;
} }
/** /**
* Get a loop player for key * Get a loop player for key
* *
* @param key sound key * @param key
* sound key
* @return loop player * @return loop player
*/ */
public LoopPlayer getLoop(String key) public LoopPlayer getLoop(String key)
@ -180,12 +192,13 @@ public class SoundSystem extends DelegatingBusClient {
} }
return p; return p;
} }
/** /**
* Get a effect player for key * Get a effect player for key
* *
* @param key sound key * @param key
* sound key
* @return effect player * @return effect player
*/ */
public EffectPlayer getEffect(String key) public EffectPlayer getEffect(String key)
@ -197,8 +210,8 @@ public class SoundSystem extends DelegatingBusClient {
} }
return p; return p;
} }
/** /**
* Fade out all loops (ie. for screen transitions) * Fade out all loops (ie. for screen transitions)
*/ */
@ -208,65 +221,72 @@ public class SoundSystem extends DelegatingBusClient {
p.fadeOut(); p.fadeOut();
} }
} }
/** /**
* Fade in a loop (with default time) * Fade in a loop (with default time)
* *
* @param key sound key * @param key
* sound key
*/ */
public void fadeInLoop(String key) public void fadeInLoop(String key)
{ {
getLoop(key).fadeIn(); getLoop(key).fadeIn();
} }
/** /**
* Fade in a loop * Fade in a loop
* *
* @param key sound key * @param key
* @param seconds fade-in duration * sound key
* @param seconds
* fade-in duration
*/ */
public void fadeInLoop(String key, double seconds) public void fadeInLoop(String key, double seconds)
{ {
getLoop(key).fadeIn(seconds); getLoop(key).fadeIn(seconds);
} }
/** /**
* Fade out a loop (with default time) * Fade out a loop (with default time)
* *
* @param key sound key * @param key
* sound key
*/ */
public void fadeOutLoop(String key) public void fadeOutLoop(String key)
{ {
getLoop(key).fadeOut(); getLoop(key).fadeOut();
} }
/** /**
* Fade out a loop * Fade out a loop
* *
* @param key sound key * @param key
* @param seconds fade-out duration * sound key
* @param seconds
* fade-out duration
*/ */
public void fadeOutLoop(String key, double seconds) public void fadeOutLoop(String key, double seconds)
{ {
getLoop(key).fadeOut(seconds); getLoop(key).fadeOut(seconds);
} }
/** /**
* Pause a loop * Pause a loop
* *
* @param key sound key * @param key
* sound key
*/ */
public void pauseLoop(String key) public void pauseLoop(String key)
{ {
getLoop(key).pause(); getLoop(key).pause();
} }
/** /**
* Pause all loops (leave volume unchanged) * Pause all loops (leave volume unchanged)
*/ */
@ -276,45 +296,49 @@ public class SoundSystem extends DelegatingBusClient {
p.pause(); p.pause();
} }
} }
/** /**
* Resume a loop * Resume a loop
* *
* @param key sound key * @param key
* sound key
*/ */
public void resumeLoop(String key) public void resumeLoop(String key)
{ {
getLoop(key).resume(); getLoop(key).resume();
} }
/** /**
* Set level of master volume * Set level of master volume
* *
* @param d level * @param d
* level
*/ */
public void setMasterVolume(double d) public void setMasterVolume(double d)
{ {
masterVolume.set(d); masterVolume.set(d);
} }
/** /**
* Set level of effects volume * Set level of effects volume
* *
* @param d level * @param d
* level
*/ */
public void setEffectsVolume(double d) public void setEffectsVolume(double d)
{ {
effectsVolume.set(d); effectsVolume.set(d);
} }
/** /**
* Set level of music volume * Set level of music volume
* *
* @param d level * @param d
* level
*/ */
public void setMusicVolume(double d) public void setMusicVolume(double d)
{ {

@ -1,6 +1,5 @@
package mightypork.rogue.tasks; package mightypork.rogue.tasks;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -16,20 +15,20 @@ import mightypork.utils.logging.Log;
public class TaskTakeScreenshot implements Runnable { public class TaskTakeScreenshot implements Runnable {
private BufferedImage image; private BufferedImage image;
public TaskTakeScreenshot(DisplaySystem disp) { public TaskTakeScreenshot(DisplaySystem disp) {
this.image = disp.takeScreenshot(); this.image = disp.takeScreenshot();
} }
@Override @Override
public void run() public void run()
{ {
String fname = getUniqueScreenshotName(); String fname = getUniqueScreenshotName();
// generate unique filename // generate unique filename
File file; File file;
int index = 0; int index = 0;
@ -38,11 +37,11 @@ public class TaskTakeScreenshot implements Runnable {
if (!file.exists()) break; if (!file.exists()) break;
index++; index++;
} }
Log.f3("Saving screenshot to file: " + file); Log.f3("Saving screenshot to file: " + file);
String format = "PNG"; String format = "PNG";
// save to disk // save to disk
try { try {
ImageIO.write(image, format, file); ImageIO.write(image, format, file);
@ -50,12 +49,12 @@ public class TaskTakeScreenshot implements Runnable {
Log.e("Failed to save screenshot.", e); Log.e("Failed to save screenshot.", e);
} }
} }
private String getUniqueScreenshotName() private String getUniqueScreenshotName()
{ {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
return df.format(new Date()); return df.format(new Date());
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.testing; package mightypork.rogue.testing;
import mightypork.rogue.display.constraints.Bounding; import mightypork.rogue.display.constraints.Bounding;
import mightypork.rogue.display.constraints.Constraint; import mightypork.rogue.display.constraints.Constraint;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
@ -8,56 +7,56 @@ import mightypork.utils.math.coord.Rect;
public class TestConstraints { public class TestConstraints {
public static void main(String[] args) public static void main(String[] args)
{ {
Bounding context = new Bounding() { Bounding context = new Bounding() {
@Override @Override
public Rect getRect() public Rect getRect()
{ {
return Rect.fromSize(new Coord(0, 0), new Coord(400, 300)); return Rect.fromSize(new Coord(0, 0), new Coord(400, 300));
} }
}; };
class Navbar extends Constraint { class Navbar extends Constraint {
private double height; private double height;
public Navbar(Bounding context, double height) { public Navbar(Bounding context, double height) {
super(context); super(context);
this.height = height; this.height = height;
} }
@Override @Override
public Rect getRect() public Rect getRect()
{ {
return Rect.fromSize(origin().setY(size().y - height), size().setY(height)); return Rect.fromSize(origin().setY(size().y - height), size().setY(height));
} }
} }
class TileHorizontal extends Constraint { class TileHorizontal extends Constraint {
private int count; private int count;
private int tile; private int tile;
public TileHorizontal(Bounding context, int tileCount, int aTile) { public TileHorizontal(Bounding context, int tileCount, int aTile) {
super(context); super(context);
this.count = tileCount; this.count = tileCount;
setTile(aTile); setTile(aTile);
} }
public void setTile(int aTile) public void setTile(int aTile)
{ {
if (aTile > count) throw new IndexOutOfBoundsException("Tile count exceeded: " + aTile + " max: " + count); if (aTile > count) throw new IndexOutOfBoundsException("Tile count exceeded: " + aTile + " max: " + count);
this.tile = aTile; this.tile = aTile;
} }
@Override @Override
public Rect getRect() public Rect getRect()
{ {
@ -65,20 +64,20 @@ public class TestConstraints {
return Rect.fromSize(origin().add(size.x * tile, 0), size); return Rect.fromSize(origin().add(size.x * tile, 0), size);
} }
} }
Navbar nb = new Navbar(context, 100); Navbar nb = new Navbar(context, 100);
TileHorizontal tile = new TileHorizontal(nb, 5, 0); TileHorizontal tile = new TileHorizontal(nb, 5, 0);
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
tile.setTile(i); tile.setTile(i);
System.out.println(tile.getRect()); System.out.println(tile.getRect());
} }
System.out.println("nb:" + nb.getRect()); System.out.println("nb:" + nb.getRect());
System.out.println("ctx:" + context.getRect()); System.out.println("ctx:" + context.getRect());
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.testing; package mightypork.rogue.testing;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -14,16 +13,16 @@ import mightypork.utils.patterns.subscription.clients.ToggleableClient;
public class TestMsgbus { public class TestMsgbus {
public static void main(String[] args) public static void main(String[] args)
{ {
Log.create("runtime", new File("."), 0); Log.create("runtime", new File("."), 0);
MessageBus bus = new MessageBus(); MessageBus bus = new MessageBus();
bus.createChannel(StringMessage.class, StringMessage.Listener.class); bus.createChannel(StringMessage.class, StringMessage.Listener.class);
bus.createChannel(IntMessage.class, IntMessage.Listener.class); bus.createChannel(IntMessage.class, IntMessage.Listener.class);
Delegator deleg1 = new Delegator("Deleg1"); Delegator deleg1 = new Delegator("Deleg1");
Delegator deleg2 = new Delegator("Deleg2"); Delegator deleg2 = new Delegator("Deleg2");
Toggleable togg1 = new Toggleable("Tog1"); Toggleable togg1 = new Toggleable("Tog1");
@ -31,61 +30,61 @@ public class TestMsgbus {
Toggleable plain1 = new Toggleable("Plain1"); Toggleable plain1 = new Toggleable("Plain1");
Toggleable plain2 = new Toggleable("Plain2"); Toggleable plain2 = new Toggleable("Plain2");
Toggleable plain3 = new Toggleable("Plain3"); Toggleable plain3 = new Toggleable("Plain3");
PlainInt pint = new PlainInt("Ints"); PlainInt pint = new PlainInt("Ints");
PlainBoth pboth = new PlainBoth("Both"); PlainBoth pboth = new PlainBoth("Both");
bus.subscribe(deleg1); bus.subscribe(deleg1);
deleg1.clients.add(togg1); deleg1.clients.add(togg1);
deleg1.clients.add(plain2); deleg1.clients.add(plain2);
deleg1.clients.add(deleg2); deleg1.clients.add(deleg2);
deleg1.clients.add(pint); deleg1.clients.add(pint);
deleg2.clients.add(deleg1); deleg2.clients.add(deleg1);
deleg2.clients.add(togg1); deleg2.clients.add(togg1);
deleg2.clients.add(plain3); deleg2.clients.add(plain3);
deleg2.clients.add(pboth); deleg2.clients.add(pboth);
bus.subscribe(plain1); bus.subscribe(plain1);
bus.subscribe(togg2); bus.subscribe(togg2);
bus.broadcast(new StringMessage("<MSG>")); bus.broadcast(new StringMessage("<MSG>"));
bus.broadcast(new IntMessage(7)); bus.broadcast(new IntMessage(7));
bus.broadcast(new IntMessage(13)); bus.broadcast(new IntMessage(13));
deleg2.delegating = false; deleg2.delegating = false;
bus.broadcast(new IntMessage(44)); bus.broadcast(new IntMessage(44));
deleg2.delegating = true; deleg2.delegating = true;
bus.broadcast(new IntMessage(45)); bus.broadcast(new IntMessage(45));
} }
} }
class Delegator extends Plain implements DelegatingClient { class Delegator extends Plain implements DelegatingClient {
List<Object> clients = new ArrayList<Object>(); List<Object> clients = new ArrayList<Object>();
boolean delegating = true; boolean delegating = true;
public Delegator(String name) { public Delegator(String name) {
super(name); super(name);
} }
@Override @Override
public Collection<Object> getChildClients() public Collection<Object> getChildClients()
{ {
return clients; return clients;
} }
@Override @Override
public boolean doesDelegate() public boolean doesDelegate()
{ {
@ -95,15 +94,15 @@ class Delegator extends Plain implements DelegatingClient {
class Toggleable extends Plain implements ToggleableClient { class Toggleable extends Plain implements ToggleableClient {
boolean subscribing = true; boolean subscribing = true;
public Toggleable(String name) { public Toggleable(String name) {
super(name); super(name);
} }
@Override @Override
public boolean doesSubscribe() public boolean doesSubscribe()
{ {
@ -113,15 +112,15 @@ class Toggleable extends Plain implements ToggleableClient {
class Plain implements StringMessage.Listener { class Plain implements StringMessage.Listener {
String name; String name;
public Plain(String name) { public Plain(String name) {
this.name = name; this.name = name;
} }
@Override @Override
public void receive(StringMessage message) public void receive(StringMessage message)
{ {
@ -131,15 +130,15 @@ class Plain implements StringMessage.Listener {
class PlainInt implements IntMessage.Listener { class PlainInt implements IntMessage.Listener {
String name; String name;
public PlainInt(String name) { public PlainInt(String name) {
this.name = name; this.name = name;
} }
@Override @Override
public void receive(IntMessage message) public void receive(IntMessage message)
{ {
@ -149,22 +148,22 @@ class PlainInt implements IntMessage.Listener {
class PlainBoth implements IntMessage.Listener, StringMessage.Listener { class PlainBoth implements IntMessage.Listener, StringMessage.Listener {
String name; String name;
public PlainBoth(String name) { public PlainBoth(String name) {
this.name = name; this.name = name;
} }
@Override @Override
public void receive(IntMessage message) public void receive(IntMessage message)
{ {
System.out.println(name + " (both-INT) RECV: " + message.i); System.out.println(name + " (both-INT) RECV: " + message.i);
} }
@Override @Override
public void receive(StringMessage message) public void receive(StringMessage message)
{ {
@ -174,20 +173,21 @@ class PlainBoth implements IntMessage.Listener, StringMessage.Listener {
class StringMessage implements Handleable<StringMessage.Listener> { class StringMessage implements Handleable<StringMessage.Listener> {
String s; String s;
StringMessage(String str) { StringMessage(String str) {
this.s = str; this.s = str;
} }
public interface Listener { public interface Listener {
public void receive(StringMessage message); public void receive(StringMessage message);
} }
@Override @Override
public void handleBy(Listener handler) public void handleBy(Listener handler)
{ {
@ -197,20 +197,21 @@ class StringMessage implements Handleable<StringMessage.Listener> {
class IntMessage implements Handleable<IntMessage.Listener> { class IntMessage implements Handleable<IntMessage.Listener> {
int i; int i;
IntMessage(int i) { IntMessage(int i) {
this.i = i; this.i = i;
} }
public interface Listener { public interface Listener {
public void receive(IntMessage message); public void receive(IntMessage message);
} }
@Override @Override
public void handleBy(Listener handler) public void handleBy(Listener handler)
{ {

@ -1,6 +1,5 @@
package mightypork.rogue.textures; package mightypork.rogue.textures;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
import java.io.IOException; import java.io.IOException;
@ -18,10 +17,10 @@ import org.newdawn.slick.util.ResourceLoader;
* @author MightyPork * @author MightyPork
*/ */
public class TextureManager { public class TextureManager {
private static Texture lastBinded = null; private static Texture lastBinded = null;
/** /**
* Load texture * Load texture
* *
@ -32,28 +31,30 @@ public class TextureManager {
{ {
try { try {
String ext = resourcePath.substring(resourcePath.length() - 4); String ext = resourcePath.substring(resourcePath.length() - 4);
Texture texture = TextureLoader.getTexture(ext.toUpperCase(), ResourceLoader.getResourceAsStream(resourcePath)); Texture texture = TextureLoader.getTexture(ext.toUpperCase(), ResourceLoader.getResourceAsStream(resourcePath));
if (texture != null) { if (texture != null) {
return texture; return texture;
} }
Log.w("Texture " + resourcePath + " could not be loaded."); Log.w("Texture " + resourcePath + " could not be loaded.");
return null; return null;
} catch (IOException e) { } catch (IOException e) {
Log.e("Loading of texture " + resourcePath + " failed.", e); Log.e("Loading of texture " + resourcePath + " failed.", e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/** /**
* Bind texture * Bind texture
* *
* @param texture the texture * @param texture
* @throws RuntimeException if not loaded yet * the texture
* @throws RuntimeException
* if not loaded yet
*/ */
public static void bind(Texture texture) throws RuntimeException public static void bind(Texture texture) throws RuntimeException
{ {
@ -63,8 +64,8 @@ public class TextureManager {
lastBinded = texture; lastBinded = texture;
} }
} }
/** /**
* Unbind all * Unbind all
*/ */

@ -1,6 +1,5 @@
package mightypork.rogue.textures; package mightypork.rogue.textures;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
import org.newdawn.slick.opengl.Texture; import org.newdawn.slick.opengl.Texture;
@ -14,12 +13,12 @@ import org.newdawn.slick.opengl.Texture;
* @author MightyPork * @author MightyPork
*/ */
public class Textures { public class Textures {
protected static Texture logo; protected static Texture logo;
private static final String GUI = "res/images/gui/"; private static final String GUI = "res/images/gui/";
/** /**
* Load what's needed for splash * Load what's needed for splash
*/ */
@ -29,12 +28,12 @@ public class Textures {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
logo = TextureManager.load(GUI + "logo.png"); logo = TextureManager.load(GUI + "logo.png");
Tx.initForSplash(); Tx.initForSplash();
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
Tx.init(); Tx.init();
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.textures; package mightypork.rogue.textures;
// TODO rewrite // TODO rewrite
/** /**
@ -9,22 +8,22 @@ package mightypork.rogue.textures;
* @author MightyPork * @author MightyPork
*/ */
public class Tx { public class Tx {
// logo // logo
public static TxQuad LOGO; public static TxQuad LOGO;
public static void initForSplash() public static void initForSplash()
{ {
// splash logo // splash logo
LOGO = TxQuad.fromSize(Textures.logo, 15, 9, 226, 132); LOGO = TxQuad.fromSize(Textures.logo, 15, 9, 226, 132);
} }
public static void init() public static void init()
{ {
// title image (word art) // title image (word art)
} }
} }

@ -1,6 +1,5 @@
package mightypork.rogue.textures; package mightypork.rogue.textures;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
@ -13,58 +12,70 @@ import org.newdawn.slick.opengl.Texture;
* @author MightyPork * @author MightyPork
*/ */
public class TxQuad { public class TxQuad {
/** The texture */ /** The texture */
public Texture tx; public Texture tx;
/** Coords in texture (pixels) */ /** Coords in texture (pixels) */
public Rect uvs; public Rect uvs;
/** Quad size */ /** Quad size */
public Coord size; public Coord size;
/** /**
* Create TxQuad from left top coord and rect size * Create TxQuad from left top coord and rect size
* *
* @param tx texture * @param tx
* @param x1 left top X * texture
* @param y1 left top Y * @param x1
* @param width area width * left top X
* @param height area height * @param y1
* left top Y
* @param width
* area width
* @param height
* area height
* @return new TxQuad * @return new TxQuad
*/ */
public static TxQuad fromSize(Texture tx, int x1, int y1, int width, int height) public static TxQuad fromSize(Texture tx, int x1, int y1, int width, int height)
{ {
return new TxQuad(tx, x1, y1, x1 + width, y1 + height); return new TxQuad(tx, x1, y1, x1 + width, y1 + height);
} }
/** /**
* @param tx Texture * @param tx
* @param uvs Rect of texturwe UVs (pixels - from left top) * Texture
* @param uvs
* Rect of texturwe UVs (pixels - from left top)
*/ */
public TxQuad(Texture tx, Rect uvs) { public TxQuad(Texture tx, Rect uvs) {
this.tx = tx; this.tx = tx;
this.uvs = uvs.copy(); this.uvs = uvs.copy();
this.size = uvs.getSize(); this.size = uvs.getSize();
} }
/** /**
* Make of coords * Make of coords
* *
* @param tx texture * @param tx
* @param x1 x1 * texture
* @param y1 y1 * @param x1
* @param x2 x2 * x1
* @param y2 y2 * @param y1
* y1
* @param x2
* x2
* @param y2
* y2
*/ */
public TxQuad(Texture tx, int x1, int y1, int x2, int y2) { public TxQuad(Texture tx, int x1, int y1, int x2, int y2) {
this.tx = tx; this.tx = tx;
this.uvs = new Rect(x1, y1, x2, y2); this.uvs = new Rect(x1, y1, x2, y2);
this.size = uvs.getSize(); this.size = uvs.getSize();
} }
public TxQuad copy() public TxQuad copy()
{ {
return new TxQuad(tx, uvs); return new TxQuad(tx, uvs);

File diff suppressed because it is too large Load Diff

@ -1,13 +1,12 @@
package mightypork.rogue.util; package mightypork.rogue.util;
/** /**
* Utils class * Utils class
* *
* @author MightyPork * @author MightyPork
*/ */
public class Utils { public class Utils {
public static Thread runAsThread(Runnable r) public static Thread runAsThread(Runnable r)
{ {
Thread t = new Thread(r); Thread t = new Thread(r);

@ -1,6 +1,5 @@
package mightypork.utils.files; package mightypork.utils.files;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -16,89 +15,90 @@ import mightypork.utils.logging.Log;
public class FileTreeDiff { public class FileTreeDiff {
private static final byte[] BUFFER = new byte[2048]; private static final byte[] BUFFER = new byte[2048];
private Checksum ck1 = new Adler32(); private Checksum ck1 = new Adler32();
private Checksum ck2 = new Adler32(); private Checksum ck2 = new Adler32();
private boolean logging = true; private boolean logging = true;
private List<Tuple<File>> compared = new ArrayList<Tuple<File>>(); private List<Tuple<File>> compared = new ArrayList<Tuple<File>>();
private Comparator<File> fileFirstSorter = new Comparator<File>() { private Comparator<File> fileFirstSorter = new Comparator<File>() {
@Override @Override
public int compare(File o1, File o2) public int compare(File o1, File o2)
{ {
if (!o1.isDirectory() && o2.isDirectory()) return -1; if (!o1.isDirectory() && o2.isDirectory()) return -1;
if (o1.isDirectory() && !o2.isDirectory()) return 1; if (o1.isDirectory() && !o2.isDirectory()) return 1;
return o1.getName().compareTo(o2.getName()); return o1.getName().compareTo(o2.getName());
} }
}; };
public void enableLogging(boolean state) public void enableLogging(boolean state)
{ {
logging = state; logging = state;
} }
public boolean areEqual(File dir1, File dir2) public boolean areEqual(File dir1, File dir2)
{ {
if (logging) Log.f3("Comparing directory trees:\n 1. " + dir1 + "\n 2. " + dir2); if (logging) Log.f3("Comparing directory trees:\n 1. " + dir1 + "\n 2. " + dir2);
try { try {
compared.clear(); compared.clear();
buildList(dir1, dir2); buildList(dir1, dir2);
calcChecksum(); calcChecksum();
if (logging) Log.f3("No difference found."); if (logging) Log.f3("No difference found.");
return true; return true;
} catch (NotEqualException e) { } catch (NotEqualException e) {
if (logging) Log.f3("Difference found:\n" + e.getMessage()); if (logging) Log.f3("Difference found:\n" + e.getMessage());
return false; return false;
} }
} }
private void calcChecksum() throws NotEqualException private void calcChecksum() throws NotEqualException
{ {
FileInputStream in1, in2; FileInputStream in1, in2;
CheckedInputStream cin1 = null, cin2 = null; CheckedInputStream cin1 = null, cin2 = null;
for (Tuple<File> pair : compared) { for (Tuple<File> pair : compared) {
try { try {
ck1.reset(); ck1.reset();
ck2.reset(); ck2.reset();
in1 = new FileInputStream(pair.a); in1 = new FileInputStream(pair.a);
in2 = new FileInputStream(pair.b); in2 = new FileInputStream(pair.b);
cin1 = new CheckedInputStream(in1, ck1); cin1 = new CheckedInputStream(in1, ck1);
cin2 = new CheckedInputStream(in2, ck2); cin2 = new CheckedInputStream(in2, ck2);
while (true) { while (true) {
int read1 = cin1.read(BUFFER); int read1 = cin1.read(BUFFER);
int read2 = cin2.read(BUFFER); int read2 = cin2.read(BUFFER);
if (read1 != read2 || ck1.getValue() != ck2.getValue()) { if (read1 != read2 || ck1.getValue() != ck2.getValue()) {
throw new NotEqualException("Bytes differ:\n" + pair.a + "\n" + pair.b); throw new NotEqualException("Bytes differ:\n" + pair.a + "\n" + pair.b);
} }
if (read1 == -1) break; if (read1 == -1) break;
} }
} catch (IOException e) {} finally { } catch (IOException e) {
} finally {
try { try {
if (cin1 != null) cin1.close(); if (cin1 != null) cin1.close();
} catch (IOException e) { } catch (IOException e) {
// ignore // ignore
} }
try { try {
if (cin1 != null) cin1.close(); if (cin1 != null) cin1.close();
} catch (IOException e) { } catch (IOException e) {
@ -107,57 +107,59 @@ public class FileTreeDiff {
} }
} }
} }
private void buildList(File f1, File f2) throws NotEqualException private void buildList(File f1, File f2) throws NotEqualException
{ {
if (f1.isDirectory() != f2.isDirectory()) throw new NotEqualException("isDirectory differs:\n" + f1 + "\n" + f2); if (f1.isDirectory() != f2.isDirectory()) throw new NotEqualException("isDirectory differs:\n" + f1 + "\n" + f2);
if (f1.isFile() && f2.isFile()) { if (f1.isFile() && f2.isFile()) {
if (f1.length() != f2.length()) throw new NotEqualException("Sizes differ:\n" + f1 + "\n" + f2); if (f1.length() != f2.length()) throw new NotEqualException("Sizes differ:\n" + f1 + "\n" + f2);
} }
if (f1.isDirectory()) { if (f1.isDirectory()) {
File[] children1 = f1.listFiles(); File[] children1 = f1.listFiles();
File[] children2 = f2.listFiles(); File[] children2 = f2.listFiles();
Arrays.sort(children1, fileFirstSorter); Arrays.sort(children1, fileFirstSorter);
Arrays.sort(children2, fileFirstSorter); Arrays.sort(children2, fileFirstSorter);
if (children1.length != children2.length) throw new NotEqualException("Child counts differ:\n" + f1 + "\n" + f2); if (children1.length != children2.length) throw new NotEqualException("Child counts differ:\n" + f1 + "\n" + f2);
for (int i = 0; i < children1.length; i++) { for (int i = 0; i < children1.length; i++) {
File ch1 = children1[i]; File ch1 = children1[i];
File ch2 = children2[i]; File ch2 = children2[i];
if (!ch1.getName().equals(ch2.getName())) throw new NotEqualException("Filenames differ:\n" + ch1 + "\n" + ch2); if (!ch1.getName().equals(ch2.getName())) throw new NotEqualException("Filenames differ:\n" + ch1 + "\n" + ch2);
buildList(ch1, ch2); buildList(ch1, ch2);
} }
} else { } else {
compared.add(new Tuple<File>(f1, f2)); compared.add(new Tuple<File>(f1, f2));
} }
} }
private class NotEqualException extends Exception { private class NotEqualException extends Exception {
public NotEqualException(String msg) { public NotEqualException(String msg) {
super(msg); super(msg);
} }
} }
private class Tuple<T> { private class Tuple<T> {
public T a; public T a;
public T b; public T b;
public Tuple(T a, T b) { public Tuple(T a, T b) {
this.a = a; this.a = a;
this.b = b; this.b = b;
} }
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.files; package mightypork.utils.files;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -11,61 +10,73 @@ import mightypork.utils.string.validation.StringFilter;
public class FileUtils { public class FileUtils {
/** /**
* Copy directory recursively. * Copy directory recursively.
* *
* @param source source file * @param source
* @param target target file * source file
* @throws IOException on error * @param target
* target file
* @throws IOException
* on error
*/ */
public static void copyDirectory(File source, File target) throws IOException public static void copyDirectory(File source, File target) throws IOException
{ {
copyDirectory(source, target, null, null); copyDirectory(source, target, null, null);
} }
/** /**
* Copy directory recursively - advanced variant. * Copy directory recursively - advanced variant.
* *
* @param source source file * @param source
* @param target target file * source file
* @param filter filter accepting only files and dirs to be copied * @param target
* @param filesCopied list into which all the target files will be added * target file
* @throws IOException on error * @param filter
* filter accepting only files and dirs to be copied
* @param filesCopied
* list into which all the target files will be added
* @throws IOException
* on error
*/ */
public static void copyDirectory(File source, File target, FileFilter filter, List<File> filesCopied) throws IOException public static void copyDirectory(File source, File target, FileFilter filter, List<File> filesCopied) throws IOException
{ {
if (!source.exists()) return; if (!source.exists()) return;
if (source.isDirectory()) { if (source.isDirectory()) {
if (!target.exists()) { if (!target.exists()) {
target.mkdir(); target.mkdir();
} }
String[] children = source.list(); String[] children = source.list();
for (int i = 0; i < children.length; i++) { for (int i = 0; i < children.length; i++) {
copyDirectory(new File(source, children[i]), new File(target, children[i]), filter, filesCopied); copyDirectory(new File(source, children[i]), new File(target, children[i]), filter, filesCopied);
} }
} else { } else {
if (filter != null && !filter.accept(source)) { if (filter != null && !filter.accept(source)) {
return; return;
} }
if (filesCopied != null) filesCopied.add(target); if (filesCopied != null) filesCopied.add(target);
copyFile(source, target); copyFile(source, target);
} }
} }
/** /**
* List directory recursively * List directory recursively
* *
* @param source source file * @param source
* @param filter filter accepting only files and dirs to be copied (or null) * source file
* @param files list of the found files * @param filter
* @throws IOException on error * filter accepting only files and dirs to be copied (or null)
* @param files
* list of the found files
* @throws IOException
* on error
*/ */
public static void listDirectoryRecursive(File source, StringFilter filter, List<File> files) throws IOException public static void listDirectoryRecursive(File source, StringFilter filter, List<File> files) throws IOException
{ {
@ -74,33 +85,36 @@ public class FileUtils {
for (int i = 0; i < children.length; i++) { for (int i = 0; i < children.length; i++) {
listDirectoryRecursive(new File(source, children[i]), filter, files); listDirectoryRecursive(new File(source, children[i]), filter, files);
} }
} else { } else {
if (filter != null && !filter.accept(source.getAbsolutePath())) { if (filter != null && !filter.accept(source.getAbsolutePath())) {
return; return;
} }
files.add(source); files.add(source);
} }
} }
/** /**
* Copy file using streams. Make sure target directory exists! * Copy file using streams. Make sure target directory exists!
* *
* @param source source file * @param source
* @param target target file * source file
* @throws IOException on error * @param target
* target file
* @throws IOException
* on error
*/ */
public static void copyFile(File source, File target) throws IOException public static void copyFile(File source, File target) throws IOException
{ {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
try { try {
in = new FileInputStream(source); in = new FileInputStream(source);
out = new FileOutputStream(target); out = new FileOutputStream(target);
copyStream(in, out); copyStream(in, out);
} finally { } finally {
try { try {
@ -115,38 +129,43 @@ public class FileUtils {
} }
} }
} }
/** /**
* Copy bytes from input to output stream, leaving out stream open * Copy bytes from input to output stream, leaving out stream open
* *
* @param in input stream * @param in
* @param out output stream * input stream
* @throws IOException on error * @param out
* output stream
* @throws IOException
* on error
*/ */
public static void copyStream(InputStream in, OutputStream out) throws IOException public static void copyStream(InputStream in, OutputStream out) throws IOException
{ {
if (in == null) { if (in == null) {
throw new NullPointerException("Input stream is null"); throw new NullPointerException("Input stream is null");
} }
if (out == null) { if (out == null) {
throw new NullPointerException("Output stream is null"); throw new NullPointerException("Output stream is null");
} }
byte[] buf = new byte[2048]; byte[] buf = new byte[2048];
int len; int len;
while ((len = in.read(buf)) > 0) { while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len); out.write(buf, 0, len);
} }
} }
/** /**
* Improved delete * Improved delete
* *
* @param path deleted path * @param path
* @param recursive recursive delete * deleted path
* @param recursive
* recursive delete
* @return success * @return success
*/ */
public static boolean delete(File path, boolean recursive) public static boolean delete(File path, boolean recursive)
@ -154,50 +173,54 @@ public class FileUtils {
if (!path.exists()) { if (!path.exists()) {
return true; return true;
} }
if (!recursive || !path.isDirectory()) return path.delete(); if (!recursive || !path.isDirectory()) return path.delete();
String[] list = path.list(); String[] list = path.list();
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
if (!delete(new File(path, list[i]), true)) return false; if (!delete(new File(path, list[i]), true)) return false;
} }
return path.delete(); return path.delete();
} }
/** /**
* Read entire file to a string. * Read entire file to a string.
* *
* @param file file * @param file
* file
* @return file contents * @return file contents
* @throws IOException * @throws IOException
*/ */
public static String fileToString(File file) throws IOException public static String fileToString(File file) throws IOException
{ {
FileInputStream fin = new FileInputStream(file); FileInputStream fin = new FileInputStream(file);
return streamToString(fin); return streamToString(fin);
} }
/** /**
* Get files in a folder (create folder if needed) * Get files in a folder (create folder if needed)
* *
* @param dir folder * @param dir
* folder
* @return list of files * @return list of files
*/ */
public static List<File> listDirectory(File dir) public static List<File> listDirectory(File dir)
{ {
return FileUtils.listDirectory(dir, null); return FileUtils.listDirectory(dir, null);
} }
/** /**
* Get files in a folder (create folder if needed) * Get files in a folder (create folder if needed)
* *
* @param dir folder * @param dir
* @param filter file filter * folder
* @param filter
* file filter
* @return list of files * @return list of files
*/ */
public static List<File> listDirectory(File dir, FileFilter filter) public static List<File> listDirectory(File dir, FileFilter filter)
@ -207,9 +230,9 @@ public class FileUtils {
} catch (RuntimeException e) { } catch (RuntimeException e) {
Log.e("Error creating folder " + dir, e); Log.e("Error creating folder " + dir, e);
} }
List<File> list = new ArrayList<File>(); List<File> list = new ArrayList<File>();
try { try {
for (File f : dir.listFiles(filter)) { for (File f : dir.listFiles(filter)) {
list.add(f); list.add(f);
@ -217,35 +240,36 @@ public class FileUtils {
} catch (Exception e) { } catch (Exception e) {
Log.e("Error listing folder " + dir, e); Log.e("Error listing folder " + dir, e);
} }
return list; return list;
} }
/** /**
* Remove extension. * Remove extension.
* *
* @param file file * @param file
* file
* @return filename without extension * @return filename without extension
*/ */
public static String[] getFilenameParts(File file) public static String[] getFilenameParts(File file)
{ {
return getFilenameParts(file.getName()); return getFilenameParts(file.getName());
} }
public static String getExtension(File file) public static String getExtension(File file)
{ {
return getExtension(file.getName()); return getExtension(file.getName());
} }
public static String getExtension(String file) public static String getExtension(String file)
{ {
return StringUtils.fromLastChar(file, '.'); return StringUtils.fromLastChar(file, '.');
} }
/** /**
* Remove extension. * Remove extension.
* *
@ -255,41 +279,44 @@ public class FileUtils {
public static String[] getFilenameParts(String filename) public static String[] getFilenameParts(String filename)
{ {
String ext, name; String ext, name;
try { try {
ext = StringUtils.fromLastDot(filename); ext = StringUtils.fromLastDot(filename);
} catch (StringIndexOutOfBoundsException e) { } catch (StringIndexOutOfBoundsException e) {
ext = ""; ext = "";
} }
try { try {
name = StringUtils.toLastDot(filename); name = StringUtils.toLastDot(filename);
} catch (StringIndexOutOfBoundsException e) { } catch (StringIndexOutOfBoundsException e) {
name = ""; name = "";
Log.w("Error extracting extension from file " + filename); Log.w("Error extracting extension from file " + filename);
} }
return new String[] { name, ext }; return new String[] { name, ext };
} }
/** /**
* Read entire input stream to a string, and close it. * Read entire input stream to a string, and close it.
* *
* @param in input stream * @param in
* input stream
* @return file contents * @return file contents
*/ */
public static String streamToString(InputStream in) public static String streamToString(InputStream in)
{ {
return streamToString(in, -1); return streamToString(in, -1);
} }
/** /**
* Read input stream to a string, and close it. * Read input stream to a string, and close it.
* *
* @param in input stream * @param in
* @param lines max number of lines (-1 to disable limit) * input stream
* @param lines
* max number of lines (-1 to disable limit)
* @return file contents * @return file contents
*/ */
public static String streamToString(InputStream in, int lines) public static String streamToString(InputStream in, int lines)
@ -298,10 +325,10 @@ public class FileUtils {
Log.e(new NullPointerException("Null stream to be converted to String.")); Log.e(new NullPointerException("Null stream to be converted to String."));
return ""; // to avoid NPE's return ""; // to avoid NPE's
} }
BufferedReader br = null; BufferedReader br = null;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String line; String line;
try { try {
int cnt = 0; int cnt = 0;
@ -310,11 +337,11 @@ public class FileUtils {
sb.append(line + "\n"); sb.append(line + "\n");
cnt++; cnt++;
} }
if (cnt == lines && lines > 0) { if (cnt == lines && lines > 0) {
sb.append("--- end of preview ---\n"); sb.append("--- end of preview ---\n");
} }
} catch (IOException e) { } catch (IOException e) {
Log.e(e); Log.e(e);
} finally { } finally {
@ -324,15 +351,15 @@ public class FileUtils {
// ignore // ignore
} }
} }
return sb.toString(); return sb.toString();
} }
public static InputStream stringToStream(String text) public static InputStream stringToStream(String text)
{ {
if (text == null) return null; if (text == null) return null;
try { try {
return new ByteArrayInputStream(text.getBytes("UTF-8")); return new ByteArrayInputStream(text.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
@ -340,161 +367,170 @@ public class FileUtils {
return null; return null;
} }
} }
public static InputStream getResource(String path) public static InputStream getResource(String path)
{ {
return FileUtils.class.getResourceAsStream(path); return FileUtils.class.getResourceAsStream(path);
} }
public static String getResourceAsString(String path) public static String getResourceAsString(String path)
{ {
return streamToString(FileUtils.class.getResourceAsStream(path)); return streamToString(FileUtils.class.getResourceAsStream(path));
} }
/** /**
* Save string to file * Save string to file
* *
* @param file file * @param file
* @param text string * file
* @throws IOException on error * @param text
* string
* @throws IOException
* on error
*/ */
public static void stringToFile(File file, String text) throws IOException public static void stringToFile(File file, String text) throws IOException
{ {
PrintStream out = null; PrintStream out = null;
try { try {
out = new PrintStream(new FileOutputStream(file), false, "UTF-8"); out = new PrintStream(new FileOutputStream(file), false, "UTF-8");
out.print(text); out.print(text);
out.flush(); out.flush();
} finally { } finally {
if (out != null) out.close(); if (out != null) out.close();
} }
} }
public static void deleteEmptyDirs(File base) public static void deleteEmptyDirs(File base)
{ {
for (File f : listDirectory(base)) { for (File f : listDirectory(base)) {
if (!f.isDirectory()) continue; if (!f.isDirectory()) continue;
deleteEmptyDirs(f); deleteEmptyDirs(f);
List<File> children = listDirectory(f); List<File> children = listDirectory(f);
if (children.size() == 0) { if (children.size() == 0) {
f.delete(); f.delete();
continue; continue;
} }
} }
} }
/** /**
* Replace special characters with place holders in a filename. * Replace special characters with place holders in a filename.
* *
* @param filestring filename string * @param filestring
* filename string
* @return escaped * @return escaped
*/ */
public static String escapeFileString(String filestring) public static String escapeFileString(String filestring)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (char c : filestring.toCharArray()) { for (char c : filestring.toCharArray()) {
switch (c) { switch (c) {
case '%': case '%':
sb.append("%%"); sb.append("%%");
break; break;
case '.': case '.':
sb.append("%d"); sb.append("%d");
break; break;
default: default:
sb.append(c); sb.append(c);
} }
} }
return sb.toString(); return sb.toString();
} }
/** /**
* Unescape filename string obtained by escapeFileString(). * Unescape filename string obtained by escapeFileString().
* *
* @param filestring escaped string * @param filestring
* escaped string
* @return clean string * @return clean string
*/ */
public static String unescapeFileString(String filestring) public static String unescapeFileString(String filestring)
{ {
filestring = filestring.replace("%d", "."); filestring = filestring.replace("%d", ".");
filestring = filestring.replace("%%", "%"); filestring = filestring.replace("%%", "%");
return filestring; return filestring;
} }
/** /**
* Escape filename, keeping the same extension * Escape filename, keeping the same extension
* *
* @param filename filename * @param filename
* filename
* @return escaped * @return escaped
*/ */
public static String escapeFilename(String filename) public static String escapeFilename(String filename)
{ {
String[] parts = getFilenameParts(filename); String[] parts = getFilenameParts(filename);
return escapeFileString(parts[0]) + "." + parts[1]; return escapeFileString(parts[0]) + "." + parts[1];
} }
/** /**
* Unescape filename, keeping the same extension * Unescape filename, keeping the same extension
* *
* @param filename escaped filename * @param filename
* escaped filename
* @return unesaped * @return unesaped
*/ */
public static String unescapeFilename(String filename) public static String unescapeFilename(String filename)
{ {
String[] parts = getFilenameParts(filename); String[] parts = getFilenameParts(filename);
return unescapeFileString(parts[0]) + "." + parts[1]; return unescapeFileString(parts[0]) + "." + parts[1];
} }
public static String getBasename(String name) public static String getBasename(String name)
{ {
return StringUtils.toLastChar(StringUtils.fromLastChar(name, '/'), '.'); return StringUtils.toLastChar(StringUtils.fromLastChar(name, '/'), '.');
} }
public static String getFilename(String name) public static String getFilename(String name)
{ {
return StringUtils.fromLastChar(name, '/'); return StringUtils.fromLastChar(name, '/');
} }
/** /**
* Copy resource to file * Copy resource to file
* *
* @param resname resource name * @param resname
* @param file out file * resource name
* @param file
* out file
* @throws IOException * @throws IOException
*/ */
public static void resourceToFile(String resname, File file) throws IOException public static void resourceToFile(String resname, File file) throws IOException
{ {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
try { try {
in = FileUtils.getResource(resname); in = FileUtils.getResource(resname);
out = new FileOutputStream(file); out = new FileOutputStream(file);
FileUtils.copyStream(in, out); FileUtils.copyStream(in, out);
} finally { } finally {
try { try {
@ -502,21 +538,22 @@ public class FileUtils {
} catch (IOException e) { } catch (IOException e) {
// ignore // ignore
} }
try { try {
if (out != null) out.close(); if (out != null) out.close();
} catch (IOException e) { } catch (IOException e) {
// ignore // ignore
} }
} }
} }
/** /**
* Get resource as string, safely closing streams. * Get resource as string, safely closing streams.
* *
* @param resname resource name * @param resname
* resource name
* @return resource as string, empty string on failure * @return resource as string, empty string on failure
*/ */
public static String resourceToString(String resname) public static String resourceToString(String resname)

@ -1,36 +1,34 @@
package mightypork.utils.files; package mightypork.utils.files;
import java.io.File; import java.io.File;
public class OsUtils { public class OsUtils {
public static enum EnumOS public static enum EnumOS {
{
linux, macos, solaris, unknown, windows; linux, macos, solaris, unknown, windows;
public boolean isLinux() public boolean isLinux()
{ {
return this == linux || this == solaris; return this == linux || this == solaris;
} }
public boolean isMac() public boolean isMac()
{ {
return this == macos; return this == macos;
} }
public boolean isWindows() public boolean isWindows()
{ {
return this == windows; return this == windows;
} }
} }
private static EnumOS cachedOs; private static EnumOS cachedOs;
/** /**
* Get App dir, ensure it exists * Get App dir, ensure it exists
* *
@ -41,8 +39,8 @@ public class OsUtils {
{ {
return getWorkDir(dirname, true); return getWorkDir(dirname, true);
} }
/** /**
* Get App sub-folder * Get App sub-folder
* *
@ -54,17 +52,17 @@ public class OsUtils {
public static File getWorkDir(String dirname, String subfolderName, boolean create) public static File getWorkDir(String dirname, String subfolderName, boolean create)
{ {
File f = new File(getWorkDir(dirname), subfolderName); File f = new File(getWorkDir(dirname), subfolderName);
if (!f.exists() && create) { if (!f.exists() && create) {
if (!f.mkdirs()) { if (!f.mkdirs()) {
throw new RuntimeException("Could not create."); throw new RuntimeException("Could not create.");
} }
} }
return f; return f;
} }
/** /**
* Get App sub-folder, create * Get App sub-folder, create
* *
@ -76,65 +74,65 @@ public class OsUtils {
{ {
return getWorkDir(dirname, subfolderName, true); return getWorkDir(dirname, subfolderName, true);
} }
public static EnumOS getOs() public static EnumOS getOs()
{ {
if (cachedOs != null) return cachedOs; if (cachedOs != null) return cachedOs;
String s = System.getProperty("os.name").toLowerCase(); String s = System.getProperty("os.name").toLowerCase();
if (s.contains("win")) { if (s.contains("win")) {
cachedOs = EnumOS.windows; cachedOs = EnumOS.windows;
} else if (s.contains("mac")) { } else if (s.contains("mac")) {
cachedOs = EnumOS.macos; cachedOs = EnumOS.macos;
} else if (s.contains("linux") || s.contains("unix")) { } else if (s.contains("linux") || s.contains("unix")) {
cachedOs = EnumOS.linux; cachedOs = EnumOS.linux;
} else if (s.contains("solaris") || s.contains("sunos")) { } else if (s.contains("solaris") || s.contains("sunos")) {
cachedOs = EnumOS.solaris; cachedOs = EnumOS.solaris;
} else { } else {
cachedOs = EnumOS.unknown; cachedOs = EnumOS.unknown;
} }
return cachedOs; return cachedOs;
} }
private static File getWorkDir(String dirname, boolean create) private static File getWorkDir(String dirname, boolean create)
{ {
String userhome = System.getProperty("user.home", "."); String userhome = System.getProperty("user.home", ".");
File file; File file;
switch (getOs()) { switch (getOs()) {
case linux: case linux:
case solaris: case solaris:
file = new File(userhome, "." + dirname + '/'); file = new File(userhome, "." + dirname + '/');
break; break;
case windows: case windows:
String appdata = System.getenv("APPDATA"); String appdata = System.getenv("APPDATA");
if (appdata != null) { if (appdata != null) {
file = new File(appdata, "." + dirname + '/'); file = new File(appdata, "." + dirname + '/');
} else { } else {
file = new File(userhome, "." + dirname + '/'); file = new File(userhome, "." + dirname + '/');
} }
break; break;
case macos: case macos:
file = new File(userhome, "Library/Application Support/" + dirname); file = new File(userhome, "Library/Application Support/" + dirname);
break; break;
default: default:
file = new File(userhome, dirname + "/"); file = new File(userhome, dirname + "/");
break; break;
} }
if (!file.exists() || !file.isDirectory()) { if (!file.exists() || !file.isDirectory()) {
if (create) { if (create) {
if (!file.mkdirs()) { if (!file.mkdirs()) {
@ -142,8 +140,8 @@ public class OsUtils {
} }
} }
} }
return file; return file;
} }
} }

File diff suppressed because it is too large Load Diff

@ -1,6 +1,5 @@
package mightypork.utils.files; package mightypork.utils.files;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -22,161 +21,166 @@ import mightypork.utils.logging.Log;
* @author MightyPork * @author MightyPork
*/ */
public class SimpleConfig { public class SimpleConfig {
/** /**
* Load list from file * Load list from file
* *
* @param file file * @param file
* file
* @return map of keys and values * @return map of keys and values
* @throws IOException * @throws IOException
*/ */
public static List<String> listFromFile(File file) throws IOException public static List<String> listFromFile(File file) throws IOException
{ {
String fileText = FileUtils.fileToString(file); String fileText = FileUtils.fileToString(file);
return listFromString(fileText); return listFromString(fileText);
} }
/** /**
* Load map from file * Load map from file
* *
* @param file file * @param file
* file
* @return map of keys and values * @return map of keys and values
* @throws IOException * @throws IOException
*/ */
public static Map<String, String> mapFromFile(File file) throws IOException public static Map<String, String> mapFromFile(File file) throws IOException
{ {
String fileText = FileUtils.fileToString(file); String fileText = FileUtils.fileToString(file);
return mapFromString(fileText); return mapFromString(fileText);
} }
/** /**
* Load list from string * Load list from string
* *
* @param text text of the file * @param text
* text of the file
* @return map of keys and values * @return map of keys and values
*/ */
public static List<String> listFromString(String text) public static List<String> listFromString(String text)
{ {
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
String[] groupsLines = text.split("\n"); String[] groupsLines = text.split("\n");
for (String s : groupsLines) { for (String s : groupsLines) {
// ignore invalid lines // ignore invalid lines
if (s.length() == 0) continue; if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith("//")) continue; if (s.startsWith("#") || s.startsWith("//")) continue;
// NULL value // NULL value
if (s.equalsIgnoreCase("NULL")) s = null; if (s.equalsIgnoreCase("NULL")) s = null;
if (s != null) s = s.replace("\\n", "\n"); if (s != null) s = s.replace("\\n", "\n");
// save extracted key-value pair // save extracted key-value pair
list.add(s); list.add(s);
} }
return list; return list;
} }
/** /**
* Load map from string * Load map from string
* *
* @param text text of the file * @param text
* text of the file
* @return map of keys and values * @return map of keys and values
*/ */
public static Map<String, String> mapFromString(String text) public static Map<String, String> mapFromString(String text)
{ {
LinkedHashMap<String, String> pairs = new LinkedHashMap<String, String>(); LinkedHashMap<String, String> pairs = new LinkedHashMap<String, String>();
String[] groupsLines = text.split("\n"); String[] groupsLines = text.split("\n");
for (String s : groupsLines) { for (String s : groupsLines) {
// ignore invalid lines // ignore invalid lines
if (s.length() == 0) continue; if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith("//")) continue; if (s.startsWith("#") || s.startsWith("//")) continue;
if (!s.contains("=")) continue; if (!s.contains("=")) continue;
// split and trim // split and trim
String[] parts = s.split("="); String[] parts = s.split("=");
for (int i = 0; i < parts.length; i++) { for (int i = 0; i < parts.length; i++) {
parts[i] = parts[i].trim(); parts[i] = parts[i].trim();
} }
// check if both parts are valid // check if both parts are valid
if (parts.length == 0) { if (parts.length == 0) {
Log.w("Bad line in config file: " + s); Log.w("Bad line in config file: " + s);
continue; continue;
} }
if (parts.length == 1) { if (parts.length == 1) {
parts = new String[] { parts[0], "" }; parts = new String[] { parts[0], "" };
} }
if (parts.length != 2) { if (parts.length != 2) {
Log.w("Bad line in config file: " + s); Log.w("Bad line in config file: " + s);
continue; continue;
} }
// NULL value // NULL value
if (parts[0].equalsIgnoreCase("NULL")) parts[0] = null; if (parts[0].equalsIgnoreCase("NULL")) parts[0] = null;
if (parts[1].equalsIgnoreCase("NULL")) parts[1] = null; if (parts[1].equalsIgnoreCase("NULL")) parts[1] = null;
if (parts[0] != null) parts[0] = parts[0].replace("\\n", "\n"); if (parts[0] != null) parts[0] = parts[0].replace("\\n", "\n");
if (parts[1] != null) parts[1] = parts[1].replace("\\n", "\n"); if (parts[1] != null) parts[1] = parts[1].replace("\\n", "\n");
// save extracted key-value pair // save extracted key-value pair
pairs.put(parts[0], parts[1]); pairs.put(parts[0], parts[1]);
} }
return pairs; return pairs;
} }
/** /**
* Save map to file * Save map to file
* *
* @param target * @param target
* @param data * @param data
* @param allowNulls allow nulls. * @param allowNulls
* allow nulls.
* @throws IOException * @throws IOException
*/ */
public static void mapToFile(File target, Map<String, String> data, boolean allowNulls) throws IOException public static void mapToFile(File target, Map<String, String> data, boolean allowNulls) throws IOException
{ {
List<String> lines = new ArrayList<String>(); List<String> lines = new ArrayList<String>();
for (Entry<String, String> e : data.entrySet()) { for (Entry<String, String> e : data.entrySet()) {
String key = e.getKey(); String key = e.getKey();
String value = e.getValue(); String value = e.getValue();
if (!allowNulls && (key == null || value == null || key.length() == 0 || value.length() == 0)) continue; if (!allowNulls && (key == null || value == null || key.length() == 0 || value.length() == 0)) continue;
if (key == null) key = "NULL"; if (key == null) key = "NULL";
if (value == null) value = "NULL"; if (value == null) value = "NULL";
key = key.replace("\n", "\\n"); key = key.replace("\n", "\\n");
value = value.replace("\n", "\\n"); value = value.replace("\n", "\\n");
lines.add(key + " = " + value); lines.add(key + " = " + value);
} }
String text = ""; //# File written by SimpleConfig String text = ""; // # File written by SimpleConfig
for (String s : lines) { for (String s : lines) {
if (text.length() > 0) text += "\n"; if (text.length() > 0) text += "\n";
text += s; text += s;
} }
FileUtils.stringToFile(target, text); FileUtils.stringToFile(target, text);
} }
/** /**
* Save list to file * Save list to file
* *
@ -186,19 +190,19 @@ public class SimpleConfig {
*/ */
public static void listToFile(File target, List<String> data) throws IOException public static void listToFile(File target, List<String> data) throws IOException
{ {
String text = ""; //# File written by SimpleConfig String text = ""; // # File written by SimpleConfig
for (String s : data) { for (String s : data) {
if (text.length() > 0) text += "\n"; if (text.length() > 0) text += "\n";
if (s == null) s = "NULL"; if (s == null) s = "NULL";
s = s.replace("\n", "\\n"); s = s.replace("\n", "\\n");
text += s; text += s;
} }
FileUtils.stringToFile(target, text); FileUtils.stringToFile(target, text);
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.files; package mightypork.utils.files;
import java.io.*; import java.io.*;
import java.util.HashSet; import java.util.HashSet;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@ -15,29 +14,32 @@ import mightypork.utils.logging.Log;
* @author MightyPork * @author MightyPork
*/ */
public class ZipBuilder { public class ZipBuilder {
private ZipOutputStream out; private ZipOutputStream out;
private HashSet<String> included = new HashSet<String>(); private HashSet<String> included = new HashSet<String>();
/** /**
* @param target target zip file * @param target
* @throws FileNotFoundException if the file is directory or cannot be * target zip file
* created * @throws FileNotFoundException
* if the file is directory or cannot be created
*/ */
public ZipBuilder(File target) throws FileNotFoundException { public ZipBuilder(File target) throws FileNotFoundException {
target.getParentFile().mkdirs(); target.getParentFile().mkdirs();
FileOutputStream dest = new FileOutputStream(target); FileOutputStream dest = new FileOutputStream(target);
out = new ZipOutputStream(new BufferedOutputStream(dest)); out = new ZipOutputStream(new BufferedOutputStream(dest));
} }
/** /**
* Add stream to a path * Add stream to a path
* *
* @param path path * @param path
* @param in stream * path
* @param in
* stream
* @throws IOException * @throws IOException
*/ */
public void addStream(String path, InputStream in) throws IOException public void addStream(String path, InputStream in) throws IOException
@ -48,18 +50,20 @@ public class ZipBuilder {
return; // ignore return; // ignore
} }
included.add(path); included.add(path);
out.putNextEntry(new ZipEntry(path)); out.putNextEntry(new ZipEntry(path));
FileUtils.copyStream(in, out); FileUtils.copyStream(in, out);
} }
/** /**
* Add string as a file * Add string as a file
* *
* @param path path * @param path
* @param text text to write * path
* @param text
* text to write
* @throws IOException * @throws IOException
*/ */
public void addString(String path, String text) throws IOException public void addString(String path, String text) throws IOException
@ -67,19 +71,21 @@ public class ZipBuilder {
path = preparePath(path); path = preparePath(path);
if (included.contains(path)) return; // ignore if (included.contains(path)) return; // ignore
included.add(path); included.add(path);
out.putNextEntry(new ZipEntry(path)); out.putNextEntry(new ZipEntry(path));
InputStream in = FileUtils.stringToStream(text); InputStream in = FileUtils.stringToStream(text);
FileUtils.copyStream(in, out); FileUtils.copyStream(in, out);
} }
/** /**
* Add resource obtained via FileUtils.getResource() * Add resource obtained via FileUtils.getResource()
* *
* @param path path * @param path
* @param resPath resource path * path
* @param resPath
* resource path
* @throws IOException * @throws IOException
*/ */
public void addResource(String path, String resPath) throws IOException public void addResource(String path, String resPath) throws IOException
@ -87,30 +93,31 @@ public class ZipBuilder {
path = preparePath(path); path = preparePath(path);
if (included.contains(path)) return; // ignore if (included.contains(path)) return; // ignore
included.add(path); included.add(path);
out.putNextEntry(new ZipEntry(path)); out.putNextEntry(new ZipEntry(path));
InputStream in = FileUtils.getResource(resPath); InputStream in = FileUtils.getResource(resPath);
FileUtils.copyStream(in, out); FileUtils.copyStream(in, out);
} }
/** /**
* Normalize path * Normalize path
* *
* @param path original path * @param path
* original path
* @return normalized path * @return normalized path
*/ */
private String preparePath(String path) private String preparePath(String path)
{ {
path = path.replace("\\", "/"); path = path.replace("\\", "/");
if (path.charAt(0) == '/') path = path.substring(1); if (path.charAt(0) == '/') path = path.substring(1);
return path; return path;
} }
/** /**
* Close the zip stream * Close the zip stream
* *

@ -1,6 +1,5 @@
package mightypork.utils.files; package mightypork.utils.files;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.File; import java.io.File;
@ -21,16 +20,19 @@ import mightypork.utils.string.validation.StringFilter;
* @author MightyPork * @author MightyPork
*/ */
public class ZipUtils { public class ZipUtils {
private static final int BUFFER_SIZE = 2048; private static final int BUFFER_SIZE = 2048;
/** /**
* Extract zip file to target directory * Extract zip file to target directory
* *
* @param file zip file * @param file
* @param outputDir target directory * zip file
* @param filter string filter (will be used to test entry names (paths)) * @param outputDir
* target directory
* @param filter
* string filter (will be used to test entry names (paths))
* @return list of entries extracted (paths) * @return list of entries extracted (paths)
* @throws IOException * @throws IOException
*/ */
@ -39,66 +41,71 @@ public class ZipUtils {
ZipFile zip = null; ZipFile zip = null;
try { try {
zip = new ZipFile(file); zip = new ZipFile(file);
return extractZip(zip, outputDir, filter); return extractZip(zip, outputDir, filter);
} finally { } finally {
try { try {
if (zip != null) zip.close(); if (zip != null) zip.close();
} catch (IOException e) { } catch (IOException e) {
//ignore // ignore
} }
} }
} }
/** /**
* Extract zip file to target directory * Extract zip file to target directory
* *
* @param zip open zip file * @param zip
* @param outputDir target directory * open zip file
* @param filter string filter (will be used to test entry names (paths)) * @param outputDir
* target directory
* @param filter
* string filter (will be used to test entry names (paths))
* @return list of entries extracted (paths) * @return list of entries extracted (paths)
* @throws IOException * @throws IOException
*/ */
public static List<String> extractZip(ZipFile zip, File outputDir, StringFilter filter) throws IOException public static List<String> extractZip(ZipFile zip, File outputDir, StringFilter filter) throws IOException
{ {
ArrayList<String> files = new ArrayList<String>(); ArrayList<String> files = new ArrayList<String>();
outputDir.mkdirs(); outputDir.mkdirs();
Enumeration<? extends ZipEntry> zipFileEntries = zip.entries(); Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
// process each entry // process each entry
while (zipFileEntries.hasMoreElements()) { while (zipFileEntries.hasMoreElements()) {
ZipEntry entry = zipFileEntries.nextElement(); ZipEntry entry = zipFileEntries.nextElement();
// parse filename and path // parse filename and path
String entryPath = entry.getName(); String entryPath = entry.getName();
File destFile = new File(outputDir, entryPath); File destFile = new File(outputDir, entryPath);
File destinationParent = destFile.getParentFile(); File destinationParent = destFile.getParentFile();
if (entry.isDirectory() || (filter != null && !filter.accept(entryPath))) continue; if (entry.isDirectory() || (filter != null && !filter.accept(entryPath))) continue;
// make sure directories exist // make sure directories exist
destinationParent.mkdirs(); destinationParent.mkdirs();
if (!entry.isDirectory()) { if (!entry.isDirectory()) {
extractZipEntry(zip, entry, destFile); extractZipEntry(zip, entry, destFile);
files.add(entryPath); files.add(entryPath);
} }
} }
return files; return files;
} }
/** /**
* Read zip entries and add their paths to a list * Read zip entries and add their paths to a list
* *
* @param zipFile open zip file * @param zipFile
* open zip file
* @return list of entry names * @return list of entry names
* @throws IOException on error * @throws IOException
* on error
*/ */
public static List<String> listZip(File zipFile) throws IOException public static List<String> listZip(File zipFile) throws IOException
{ {
@ -110,84 +117,93 @@ public class ZipUtils {
try { try {
if (zip != null) zip.close(); if (zip != null) zip.close();
} catch (IOException e) { } catch (IOException e) {
//ignore // ignore
} }
} }
} }
/** /**
* Read zip entries and add their paths to a list * Read zip entries and add their paths to a list
* *
* @param zip open zip file * @param zip
* open zip file
* @return list of entry names * @return list of entry names
* @throws IOException on error * @throws IOException
* on error
*/ */
public static List<String> listZip(ZipFile zip) throws IOException public static List<String> listZip(ZipFile zip) throws IOException
{ {
ArrayList<String> files = new ArrayList<String>(); ArrayList<String> files = new ArrayList<String>();
Enumeration<? extends ZipEntry> zipFileEntries = zip.entries(); Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
// process each entry // process each entry
while (zipFileEntries.hasMoreElements()) { while (zipFileEntries.hasMoreElements()) {
ZipEntry entry = zipFileEntries.nextElement(); ZipEntry entry = zipFileEntries.nextElement();
if (!entry.isDirectory()) { if (!entry.isDirectory()) {
files.add(entry.getName()); files.add(entry.getName());
} }
} }
return files; return files;
} }
/** /**
* Extract one zip entry to target file * Extract one zip entry to target file
* *
* @param zip open zip file * @param zip
* @param entry entry from the zip file * open zip file
* @param destFile destination file ((NOT directory!) * @param entry
* @throws IOException on error * entry from the zip file
* @param destFile
* destination file ((NOT directory!)
* @throws IOException
* on error
*/ */
public static void extractZipEntry(ZipFile zip, ZipEntry entry, File destFile) throws IOException public static void extractZipEntry(ZipFile zip, ZipEntry entry, File destFile) throws IOException
{ {
destFile.getParentFile().mkdirs(); destFile.getParentFile().mkdirs();
BufferedInputStream is = null; BufferedInputStream is = null;
FileOutputStream fos = null; FileOutputStream fos = null;
BufferedOutputStream dest = null; BufferedOutputStream dest = null;
try { try {
is = new BufferedInputStream(zip.getInputStream(entry)); is = new BufferedInputStream(zip.getInputStream(entry));
fos = new FileOutputStream(destFile); fos = new FileOutputStream(destFile);
dest = new BufferedOutputStream(fos, BUFFER_SIZE); dest = new BufferedOutputStream(fos, BUFFER_SIZE);
FileUtils.copyStream(is, dest); FileUtils.copyStream(is, dest);
} finally { } finally {
try { try {
if (is != null) is.close(); if (is != null) is.close();
} catch (IOException e) { } catch (IOException e) {
//ignore // ignore
} }
try { try {
if (dest != null) dest.close(); if (dest != null) dest.close();
} catch (IOException e) { } catch (IOException e) {
//ignore // ignore
} }
} }
} }
/** /**
* Load zip entry to String * Load zip entry to String
* *
* @param zip open zip file * @param zip
* @param entry entry from the zip file * open zip file
* @param entry
* entry from the zip file
* @return loaded string * @return loaded string
* @throws IOException on error * @throws IOException
* on error
*/ */
public static String zipEntryToString(ZipFile zip, ZipEntry entry) throws IOException public static String zipEntryToString(ZipFile zip, ZipEntry entry) throws IOException
{ {
@ -200,16 +216,16 @@ public class ZipUtils {
try { try {
if (is != null) is.close(); if (is != null) is.close();
} catch (IOException e) { } catch (IOException e) {
//ignore // ignore
} }
} }
} }
public static boolean entryExists(File selectedFile, String string) public static boolean entryExists(File selectedFile, String string)
{ {
ZipFile zf = null; ZipFile zf = null;
try { try {
zf = new ZipFile(selectedFile); zf = new ZipFile(selectedFile);
return zf.getEntry(string) != null; return zf.getEntry(string) != null;
@ -219,9 +235,9 @@ public class ZipUtils {
try { try {
if (zf != null) zf.close(); if (zf != null) zf.close();
} catch (IOException e) { } catch (IOException e) {
//ignore // ignore
} }
} }
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -14,15 +13,16 @@ import java.util.ArrayList;
* @param <T> * @param <T>
*/ */
public abstract class AbstractIonList<T> extends ArrayList<T> implements Ionizable { public abstract class AbstractIonList<T> extends ArrayList<T> implements Ionizable {
@Override @Override
public void ionRead(InputStream in) throws IonException public void ionRead(InputStream in) throws IonException
{ {
try { try {
while (true) { while (true) {
byte b = StreamUtils.readByte(in); byte b = StreamUtils.readByte(in);
if (b == IonMarks.ENTRY) { if (b == IonMarks.ENTRY) {
@SuppressWarnings("unchecked")
T value = (T) Ion.readObject(in); T value = (T) Ion.readObject(in);
add(value); add(value);
} else if (b == IonMarks.END) { } else if (b == IonMarks.END) {
@ -36,8 +36,8 @@ public abstract class AbstractIonList<T> extends ArrayList<T> implements Ionizab
throw new IonException("Error reading ion list", e); throw new IonException("Error reading ion list", e);
} }
} }
@Override @Override
public void ionWrite(OutputStream out) throws IonException public void ionWrite(OutputStream out) throws IonException
{ {
@ -53,27 +53,31 @@ public abstract class AbstractIonList<T> extends ArrayList<T> implements Ionizab
throw new IonException("Error reading ion map", e); throw new IonException("Error reading ion map", e);
} }
} }
/** /**
* Read custom data of this AbstractIonList implementation * Read custom data of this AbstractIonList implementation
* *
* @param in input stream * @param in
* input stream
*/ */
public void ionReadCustomData(InputStream in) public void ionReadCustomData(InputStream in)
{} {
}
/** /**
* Write custom data of this AbstractIonList implementation * Write custom data of this AbstractIonList implementation
* *
* @param out output stream * @param out
* output stream
*/ */
public void ionWriteCustomData(OutputStream out) public void ionWriteCustomData(OutputStream out)
{} {
}
@Override @Override
public abstract byte ionMark(); public abstract byte ionMark();
} }

@ -1,6 +1,5 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -14,21 +13,21 @@ import java.util.LinkedHashMap;
* @param <V> * @param <V>
*/ */
public abstract class AbstractIonMap<V> extends LinkedHashMap<String, V> implements Ionizable { public abstract class AbstractIonMap<V> extends LinkedHashMap<String, V> implements Ionizable {
@Override @Override
public V get(Object key) public V get(Object key)
{ {
return super.get(key); return super.get(key);
} }
@Override @Override
public V put(String key, V value) public V put(String key, V value)
{ {
return super.put(key, value); return super.put(key, value);
} }
@Override @Override
public void ionRead(InputStream in) throws IonException public void ionRead(InputStream in) throws IonException
{ {
@ -37,13 +36,11 @@ public abstract class AbstractIonMap<V> extends LinkedHashMap<String, V> impleme
byte b = StreamUtils.readByte(in); byte b = StreamUtils.readByte(in);
if (b == IonMarks.ENTRY) { if (b == IonMarks.ENTRY) {
String key = StreamUtils.readStringBytes(in); String key = StreamUtils.readStringBytes(in);
V value;
try { @SuppressWarnings("unchecked")
value = (V) Ion.readObject(in); V value = (V) Ion.readObject(in);
put(key, value); put(key, value);
} catch (IonException e) {
e.printStackTrace();
}
} else if (b == IonMarks.END) { } else if (b == IonMarks.END) {
break; break;
} else { } else {
@ -55,8 +52,8 @@ public abstract class AbstractIonMap<V> extends LinkedHashMap<String, V> impleme
throw new IonException("Error reading ion map", e); throw new IonException("Error reading ion map", e);
} }
} }
@Override @Override
public void ionWrite(OutputStream out) throws IonException public void ionWrite(OutputStream out) throws IonException
{ {
@ -72,30 +69,34 @@ public abstract class AbstractIonMap<V> extends LinkedHashMap<String, V> impleme
throw new IonException("Error reading ion map", e); throw new IonException("Error reading ion map", e);
} }
} }
/** /**
* Read custom data of this AbstractIonMap implementation * Read custom data of this AbstractIonMap implementation
* *
* @param in input stream * @param in
* input stream
*/ */
public void ionReadCustomData(InputStream in) public void ionReadCustomData(InputStream in)
{} {
}
/** /**
* Write custom data of this AbstractIonMap implementation * Write custom data of this AbstractIonMap implementation
* *
* @param out output stream * @param out
* output stream
*/ */
public void ionWriteCustomData(OutputStream out) public void ionWriteCustomData(OutputStream out)
{} {
}
@Override @Override
public byte ionMark() public byte ionMark()
{ {
return IonMarks.MAP; return IonMarks.MAP;
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
import java.io.*; import java.io.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -14,10 +13,10 @@ import mightypork.utils.math.Calc;
* @author MightyPork * @author MightyPork
*/ */
public class Ion { public class Ion {
/** Ionizables<Mark, Class> */ /** Ionizables<Mark, Class> */
private static Map<Byte, Class<?>> customIonizables = new HashMap<Byte, Class<?>>(); private static Map<Byte, Class<?>> customIonizables = new HashMap<Byte, Class<?>>();
// register default ionizables // register default ionizables
static { static {
try { try {
@ -27,13 +26,15 @@ public class Ion {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* Register new Ionizable for direct reconstructing. * Register new Ionizable for direct reconstructing.
* *
* @param mark byte mark to be used, see {@link IonMarks} for reference. * @param mark
* @param objClass class of the registered Ionizable * byte mark to be used, see {@link IonMarks} for reference.
* @param objClass
* class of the registered Ionizable
* @throws IonException * @throws IonException
*/ */
public static void registerIonizable(byte mark, Class<?> objClass) throws IonException public static void registerIonizable(byte mark, Class<?> objClass) throws IonException
@ -43,12 +44,13 @@ public class Ion {
} }
customIonizables.put(mark, objClass); customIonizables.put(mark, objClass);
} }
/** /**
* Load Ion object from file. * Load Ion object from file.
* *
* @param file file path * @param file
* file path
* @return the loaded object * @return the loaded object
* @throws IonException * @throws IonException
*/ */
@ -56,14 +58,16 @@ public class Ion {
{ {
return fromFile(new File(file)); return fromFile(new File(file));
} }
/** /**
* Load Ion object from file. * Load Ion object from file.
* *
* @param file file * @param file
* file
* @return the loaded object * @return the loaded object
* @throws IonException on failure * @throws IonException
* on failure
*/ */
public static Object fromFile(File file) throws IonException public static Object fromFile(File file) throws IonException
{ {
@ -72,7 +76,7 @@ public class Ion {
in = new FileInputStream(file); in = new FileInputStream(file);
Object obj = fromStream(in); Object obj = fromStream(in);
return obj; return obj;
} catch (IOException e) { } catch (IOException e) {
throw new IonException("Error loading ION file.", e); throw new IonException("Error loading ION file.", e);
} finally { } finally {
@ -85,12 +89,13 @@ public class Ion {
} }
} }
} }
/** /**
* Load Ion object from stream. * Load Ion object from stream.
* *
* @param in input stream * @param in
* input stream
* @return the loaded object * @return the loaded object
* @throws IonException * @throws IonException
*/ */
@ -98,26 +103,30 @@ public class Ion {
{ {
return readObject(in); return readObject(in);
} }
/** /**
* Store Ion object to file. * Store Ion object to file.
* *
* @param path file path * @param path
* @param obj object to store * file path
* @param obj
* object to store
* @throws IonException * @throws IonException
*/ */
public static void toFile(String path, Object obj) throws IonException public static void toFile(String path, Object obj) throws IonException
{ {
toFile(new File(path), obj); toFile(new File(path), obj);
} }
/** /**
* Store Ion object to file. * Store Ion object to file.
* *
* @param path file path * @param path
* @param obj object to store * file path
* @param obj
* object to store
* @throws IonException * @throws IonException
*/ */
public static void toFile(File path, Object obj) throws IonException public static void toFile(File path, Object obj) throws IonException
@ -126,13 +135,13 @@ public class Ion {
try { try {
String f = path.toString(); String f = path.toString();
File dir = new File(f.substring(0, f.lastIndexOf(File.separator))); File dir = new File(f.substring(0, f.lastIndexOf(File.separator)));
dir.mkdirs(); dir.mkdirs();
out = new FileOutputStream(path); out = new FileOutputStream(path);
toStream(out, obj); toStream(out, obj);
out.flush(); out.flush();
out.close(); out.close();
} catch (Exception e) { } catch (Exception e) {
@ -145,28 +154,31 @@ public class Ion {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
/** /**
* Store Ion object to output stream. * Store Ion object to output stream.
* *
* @param out output stream * * @param out
* @param obj object to store * output stream *
* @param obj
* object to store
* @throws IonException * @throws IonException
*/ */
public static void toStream(OutputStream out, Object obj) throws IonException public static void toStream(OutputStream out, Object obj) throws IonException
{ {
writeObject(out, obj); writeObject(out, obj);
} }
/** /**
* Read single ionizable or primitive object from input stream * Read single ionizable or primitive object from input stream
* *
* @param in input stream * @param in
* input stream
* @return the loaded object * @return the loaded object
* @throws IonException * @throws IonException
*/ */
@ -188,7 +200,7 @@ public class Ion {
ion.ionRead(in); ion.ionRead(in);
return ion; return ion;
} }
switch (b) { switch (b) {
case IonMarks.BOOLEAN: case IonMarks.BOOLEAN:
return StreamUtils.readBoolean(in); return StreamUtils.readBoolean(in);
@ -216,13 +228,15 @@ public class Ion {
throw new IonException("Error loading ION file: ", e); throw new IonException("Error loading ION file: ", e);
} }
} }
/** /**
* Write single ionizable or primitive object to output stream * Write single ionizable or primitive object to output stream
* *
* @param out output stream * @param out
* @param obj stored object * output stream
* @param obj
* stored object
* @throws IonException * @throws IonException
*/ */
public static void writeObject(OutputStream out, Object obj) throws IonException public static void writeObject(OutputStream out, Object obj) throws IonException
@ -233,66 +247,66 @@ public class Ion {
((Ionizable) obj).ionWrite(out); ((Ionizable) obj).ionWrite(out);
return; return;
} }
if (obj instanceof Boolean) { if (obj instanceof Boolean) {
out.write(IonMarks.BOOLEAN); out.write(IonMarks.BOOLEAN);
StreamUtils.writeBoolean(out, (Boolean) obj); StreamUtils.writeBoolean(out, (Boolean) obj);
return; return;
} }
if (obj instanceof Byte) { if (obj instanceof Byte) {
out.write(IonMarks.BYTE); out.write(IonMarks.BYTE);
StreamUtils.writeByte(out, (Byte) obj); StreamUtils.writeByte(out, (Byte) obj);
return; return;
} }
if (obj instanceof Character) { if (obj instanceof Character) {
out.write(IonMarks.CHAR); out.write(IonMarks.CHAR);
StreamUtils.writeChar(out, (Character) obj); StreamUtils.writeChar(out, (Character) obj);
return; return;
} }
if (obj instanceof Short) { if (obj instanceof Short) {
out.write(IonMarks.SHORT); out.write(IonMarks.SHORT);
StreamUtils.writeShort(out, (Short) obj); StreamUtils.writeShort(out, (Short) obj);
return; return;
} }
if (obj instanceof Integer) { if (obj instanceof Integer) {
out.write(IonMarks.INT); out.write(IonMarks.INT);
StreamUtils.writeInt(out, (Integer) obj); StreamUtils.writeInt(out, (Integer) obj);
return; return;
} }
if (obj instanceof Long) { if (obj instanceof Long) {
out.write(IonMarks.LONG); out.write(IonMarks.LONG);
StreamUtils.writeLong(out, (Long) obj); StreamUtils.writeLong(out, (Long) obj);
return; return;
} }
if (obj instanceof Float) { if (obj instanceof Float) {
out.write(IonMarks.FLOAT); out.write(IonMarks.FLOAT);
StreamUtils.writeFloat(out, (Float) obj); StreamUtils.writeFloat(out, (Float) obj);
return; return;
} }
if (obj instanceof Double) { if (obj instanceof Double) {
out.write(IonMarks.DOUBLE); out.write(IonMarks.DOUBLE);
StreamUtils.writeDouble(out, (Double) obj); StreamUtils.writeDouble(out, (Double) obj);
return; return;
} }
if (obj instanceof String) { if (obj instanceof String) {
out.write(IonMarks.STRING); out.write(IonMarks.STRING);
StreamUtils.writeString(out, (String) obj); StreamUtils.writeString(out, (String) obj);
return; return;
} }
throw new IonException(Calc.cname(obj) + " can't be stored in Ion storage."); throw new IonException(Calc.cname(obj) + " can't be stored in Ion storage.");
} catch (IOException e) { } catch (IOException e) {
throw new IonException("Could not store " + obj, e); throw new IonException("Could not store " + obj, e);
} }
} }
} }

@ -1,25 +1,24 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
public class IonException extends Exception { public class IonException extends Exception {
public IonException() { public IonException() {
super(); super();
} }
public IonException(String message, Throwable cause) { public IonException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public IonException(String message) { public IonException(String message) {
super(message); super(message);
} }
public IonException(Throwable cause) { public IonException(Throwable cause) {
super(cause); super(cause);
} }
} }

@ -1,133 +1,132 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
/** /**
* Ionizable Arraylist * Ionizable Arraylist
* *
* @author MightyPork * @author MightyPork
*/ */
public class IonList extends AbstractIonList<Object> implements Ionizable { public class IonList extends AbstractIonList<Object> implements Ionizable {
public Ionizable getIonizable(int index) throws IonException public Ionizable getIonizable(int index) throws IonException
{ {
return (Ionizable) getCheckType(index, Ionizable.class); return (Ionizable) getCheckType(index, Ionizable.class);
} }
public boolean getBoolean(int index) throws IonException public boolean getBoolean(int index) throws IonException
{ {
return (Boolean) getCheckType(index, Boolean.class); return (Boolean) getCheckType(index, Boolean.class);
} }
public byte getByte(int index) throws IonException public byte getByte(int index) throws IonException
{ {
return (Byte) getCheckType(index, Byte.class); return (Byte) getCheckType(index, Byte.class);
} }
public char getChar(int index) throws IonException public char getChar(int index) throws IonException
{ {
return (Character) getCheckType(index, Character.class); return (Character) getCheckType(index, Character.class);
} }
public short getShort(int index) throws IonException public short getShort(int index) throws IonException
{ {
return (Short) getCheckType(index, Short.class); return (Short) getCheckType(index, Short.class);
} }
public int getInt(int index) throws IonException public int getInt(int index) throws IonException
{ {
return (Integer) getCheckType(index, Integer.class); return (Integer) getCheckType(index, Integer.class);
} }
public long getLong(int index) throws IonException public long getLong(int index) throws IonException
{ {
return (Long) getCheckType(index, Long.class); return (Long) getCheckType(index, Long.class);
} }
public float getFloat(int index) throws IonException public float getFloat(int index) throws IonException
{ {
return (Float) getCheckType(index, Float.class); return (Float) getCheckType(index, Float.class);
} }
public double getDouble(int index) throws IonException public double getDouble(int index) throws IonException
{ {
return (Double) getCheckType(index, Double.class); return (Double) getCheckType(index, Double.class);
} }
public String getString(int index) throws IonException public String getString(int index) throws IonException
{ {
return (String) getCheckType(index, String.class); return (String) getCheckType(index, String.class);
} }
public void addIonizable(Ionizable o) throws IonException public void addIonizable(Ionizable o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addBoolean(boolean o) throws IonException public void addBoolean(boolean o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addByte(byte o) throws IonException public void addByte(byte o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addChar(char o) throws IonException public void addChar(char o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addShort(short o) throws IonException public void addShort(short o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addInt(int o) throws IonException public void addInt(int o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addLong(long o) throws IonException public void addLong(long o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addFloat(float o) throws IonException public void addFloat(float o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addDouble(double o) throws IonException public void addDouble(double o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public void addString(String o) throws IonException public void addString(String o) throws IonException
{ {
addCheckNull(o); addCheckNull(o);
} }
public Object getCheckType(int index, Class<?> type) throws IonException public Object getCheckType(int index, Class<?> type) throws IonException
{ {
try { try {
@ -140,18 +139,18 @@ public class IonList extends AbstractIonList<Object> implements Ionizable {
throw new IonException("Out of bounds"); throw new IonException("Out of bounds");
} }
} }
private void addCheckNull(Object o) throws IonException private void addCheckNull(Object o) throws IonException
{ {
if (o == null) throw new IonException("Cannot store null"); if (o == null) throw new IonException("Cannot store null");
} }
@Override @Override
public byte ionMark() public byte ionMark()
{ {
return IonMarks.LIST; return IonMarks.LIST;
} }
} }

@ -1,156 +1,155 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
/** /**
* Ionizable HashMap * Ionizable HashMap
* *
* @author MightyPork * @author MightyPork
*/ */
public class IonMap extends AbstractIonMap<Object> implements Ionizable { public class IonMap extends AbstractIonMap<Object> implements Ionizable {
public boolean getBoolean(String key) public boolean getBoolean(String key)
{ {
return (Boolean) get(key); return (Boolean) get(key);
} }
public boolean getBool(String key) public boolean getBool(String key)
{ {
return (Boolean) get(key); return (Boolean) get(key);
} }
public byte getByte(String key) public byte getByte(String key)
{ {
return (Byte) get(key); return (Byte) get(key);
} }
public char getChar(String key) public char getChar(String key)
{ {
return (Character) get(key); return (Character) get(key);
} }
public short getShort(String key) public short getShort(String key)
{ {
return (Short) get(key); return (Short) get(key);
} }
public int getInt(String key) public int getInt(String key)
{ {
return (Integer) get(key); return (Integer) get(key);
} }
public long getLong(String key) public long getLong(String key)
{ {
return (Long) get(key); return (Long) get(key);
} }
public float getFloat(String key) public float getFloat(String key)
{ {
return (Float) get(key); return (Float) get(key);
} }
public double getDouble(String key) public double getDouble(String key)
{ {
return (Double) get(key); return (Double) get(key);
} }
public String getString(String key) public String getString(String key)
{ {
return (String) get(key); return (String) get(key);
} }
@Override @Override
public Object get(Object arg0) public Object get(Object arg0)
{ {
return super.get(arg0); return super.get(arg0);
} }
public void putBoolean(String key, boolean num) public void putBoolean(String key, boolean num)
{ {
put(key, num); put(key, num);
} }
public void putBool(String key, boolean num) public void putBool(String key, boolean num)
{ {
put(key, num); put(key, num);
} }
public void putByte(String key, int num) public void putByte(String key, int num)
{ {
put(key, (byte) num); put(key, (byte) num);
} }
public void putChar(String key, char num) public void putChar(String key, char num)
{ {
put(key, num); put(key, num);
} }
public void putCharacter(String key, char num) public void putCharacter(String key, char num)
{ {
put(key, num); put(key, num);
} }
public void putShort(String key, int num) public void putShort(String key, int num)
{ {
put(key, num); put(key, num);
} }
public void putInt(String key, int num) public void putInt(String key, int num)
{ {
put(key, num); put(key, num);
} }
public void putInteger(String key, int num) public void putInteger(String key, int num)
{ {
put(key, num); put(key, num);
} }
public void putLong(String key, long num) public void putLong(String key, long num)
{ {
put(key, num); put(key, num);
} }
public void putFloat(String key, double num) public void putFloat(String key, double num)
{ {
put(key, (float) num); put(key, (float) num);
} }
public void putDouble(String key, double num) public void putDouble(String key, double num)
{ {
put(key, num); put(key, num);
} }
public void putString(String key, String num) public void putString(String key, String num)
{ {
put(key, num); put(key, num);
} }
@Override @Override
public byte ionMark() public byte ionMark()
{ {
return IonMarks.MAP; return IonMarks.MAP;
} }
} }

@ -1,57 +1,56 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
/** /**
* Byte marks used to structure data in Ion files. * Byte marks used to structure data in Ion files.
* *
* @author MightyPork * @author MightyPork
*/ */
public class IonMarks { public class IonMarks {
/** Null value */ /** Null value */
public static final byte NULL = 0; public static final byte NULL = 0;
/** Boolean value */ /** Boolean value */
public static final byte BOOLEAN = 1; public static final byte BOOLEAN = 1;
/** Byte value */ /** Byte value */
public static final byte BYTE = 2; public static final byte BYTE = 2;
/** Character value */ /** Character value */
public static final byte CHAR = 3; public static final byte CHAR = 3;
/** Short value */ /** Short value */
public static final byte SHORT = 4; public static final byte SHORT = 4;
/** Integer value */ /** Integer value */
public static final byte INT = 5; public static final byte INT = 5;
/** Long value */ /** Long value */
public static final byte LONG = 6; public static final byte LONG = 6;
/** Float value */ /** Float value */
public static final byte FLOAT = 7; public static final byte FLOAT = 7;
/** Double value */ /** Double value */
public static final byte DOUBLE = 8; public static final byte DOUBLE = 8;
/** String value */ /** String value */
public static final byte STRING = 9; public static final byte STRING = 9;
/** List value (begin) - contains entries, ends with END */ /** List value (begin) - contains entries, ends with END */
public static final byte LIST = 10; public static final byte LIST = 10;
/** Map value (begin) - contains entries, ends with END */ /** Map value (begin) - contains entries, ends with END */
public static final byte MAP = 11; public static final byte MAP = 11;
/** /**
* List / Map entry<br> * List / Map entry<br>
* In list directly followed by entry value. In map followed by (string) key * In list directly followed by entry value. In map followed by (string) key
* and the entry value. * and the entry value.
*/ */
public static final byte ENTRY = 12; public static final byte ENTRY = 12;
/** End of List / Map */ /** End of List / Map */
public static final byte END = 13; public static final byte END = 13;
} }

@ -1,6 +1,5 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -13,27 +12,29 @@ import java.io.OutputStream;
* @author MightyPork * @author MightyPork
*/ */
public interface Ionizable { public interface Ionizable {
/** /**
* Load data from the input stream. Mark has already been read, begin * Load data from the input stream. Mark has already been read, begin
* reading right after it. * reading right after it.
* *
* @param in input stream * @param in
* input stream
* @throws IonException * @throws IonException
*/ */
public void ionRead(InputStream in) throws IonException; public void ionRead(InputStream in) throws IonException;
/** /**
* Store data to output stream. mark has already been written, begin right * Store data to output stream. mark has already been written, begin right
* after it. * after it.
* *
* @param out Output stream * @param out
* Output stream
* @throws IonException * @throws IonException
*/ */
public void ionWrite(OutputStream out) throws IonException; public void ionWrite(OutputStream out) throws IonException;
/** /**
* Get Ion mark byte. * Get Ion mark byte.
* *

@ -1,13 +1,12 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
/** /**
* Optional ionizable * Optional ionizable
* *
* @author MightyPork * @author MightyPork
*/ */
public interface IonizableOptional extends Ionizable { public interface IonizableOptional extends Ionizable {
/** /**
* Get if this ionizable should be saved to a list * Get if this ionizable should be saved to a list
* *

@ -1,6 +1,5 @@
package mightypork.utils.files.ion; package mightypork.utils.files.ion;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -13,99 +12,99 @@ import java.nio.ByteBuffer;
* @author MightyPork * @author MightyPork
*/ */
public class StreamUtils { public class StreamUtils {
private static ByteBuffer bi = ByteBuffer.allocate(Integer.SIZE / 8); private static ByteBuffer bi = ByteBuffer.allocate(Integer.SIZE / 8);
private static ByteBuffer bd = ByteBuffer.allocate(Double.SIZE / 8); private static ByteBuffer bd = ByteBuffer.allocate(Double.SIZE / 8);
private static ByteBuffer bf = ByteBuffer.allocate(Float.SIZE / 8); private static ByteBuffer bf = ByteBuffer.allocate(Float.SIZE / 8);
private static ByteBuffer bc = ByteBuffer.allocate(Character.SIZE / 8); private static ByteBuffer bc = ByteBuffer.allocate(Character.SIZE / 8);
private static ByteBuffer bl = ByteBuffer.allocate(Long.SIZE / 8); private static ByteBuffer bl = ByteBuffer.allocate(Long.SIZE / 8);
private static ByteBuffer bs = ByteBuffer.allocate(Short.SIZE / 8); private static ByteBuffer bs = ByteBuffer.allocate(Short.SIZE / 8);
private static byte[] ai = new byte[Integer.SIZE / 8]; private static byte[] ai = new byte[Integer.SIZE / 8];
private static byte[] ad = new byte[Double.SIZE / 8]; private static byte[] ad = new byte[Double.SIZE / 8];
private static byte[] af = new byte[Float.SIZE / 8]; private static byte[] af = new byte[Float.SIZE / 8];
private static byte[] ac = new byte[Character.SIZE / 8]; private static byte[] ac = new byte[Character.SIZE / 8];
private static byte[] al = new byte[Long.SIZE / 8]; private static byte[] al = new byte[Long.SIZE / 8];
private static byte[] as = new byte[Short.SIZE / 8]; private static byte[] as = new byte[Short.SIZE / 8];
// CONVERSIONS // CONVERSIONS
private static byte[] convBool(boolean bool) private static byte[] convBool(boolean bool)
{ {
return new byte[] { (byte) (bool ? 1 : 0) }; return new byte[] { (byte) (bool ? 1 : 0) };
} }
private static byte[] convByte(byte num) private static byte[] convByte(byte num)
{ {
return new byte[] { num }; return new byte[] { num };
} }
private static byte[] convChar(char num) private static byte[] convChar(char num)
{ {
bc.clear(); bc.clear();
bc.putChar(num); bc.putChar(num);
return bc.array(); return bc.array();
} }
private static byte[] convShort(short num) private static byte[] convShort(short num)
{ {
bs.clear(); bs.clear();
bs.putShort(num); bs.putShort(num);
return bs.array(); return bs.array();
} }
private static byte[] convInt(int num) private static byte[] convInt(int num)
{ {
bi.clear(); bi.clear();
bi.putInt(num); bi.putInt(num);
return bi.array(); return bi.array();
} }
private static byte[] convLong(long num) private static byte[] convLong(long num)
{ {
bl.clear(); bl.clear();
bl.putLong(num); bl.putLong(num);
return bl.array(); return bl.array();
} }
private static byte[] convFloat(float num) private static byte[] convFloat(float num)
{ {
bf.clear(); bf.clear();
bf.putFloat(num); bf.putFloat(num);
return bf.array(); return bf.array();
} }
private static byte[] convDouble(double num) private static byte[] convDouble(double num)
{ {
bd.clear(); bd.clear();
bd.putDouble(num); bd.putDouble(num);
return bd.array(); return bd.array();
} }
private static byte[] convString(String str) private static byte[] convString(String str)
{ {
char[] chars = str.toCharArray(); char[] chars = str.toCharArray();
ByteBuffer bstr = ByteBuffer.allocate((Character.SIZE / 8) * chars.length + (Character.SIZE / 8)); ByteBuffer bstr = ByteBuffer.allocate((Character.SIZE / 8) * chars.length + (Character.SIZE / 8));
for (char c : chars) { for (char c : chars) {
bstr.putChar(c); bstr.putChar(c);
} }
bstr.putChar((char) 0); bstr.putChar((char) 0);
return bstr.array(); return bstr.array();
} }
private static byte[] convString_b(String str) private static byte[] convString_b(String str)
{ {
char[] chars = str.toCharArray(); char[] chars = str.toCharArray();
@ -114,133 +113,133 @@ public class StreamUtils {
bstr.put((byte) c); bstr.put((byte) c);
} }
bstr.put((byte) 0); bstr.put((byte) 0);
return bstr.array(); return bstr.array();
} }
public static void writeBoolean(OutputStream out, boolean num) throws IOException public static void writeBoolean(OutputStream out, boolean num) throws IOException
{ {
out.write(convBool(num)); out.write(convBool(num));
} }
public static void writeByte(OutputStream out, byte num) throws IOException public static void writeByte(OutputStream out, byte num) throws IOException
{ {
out.write(convByte(num)); out.write(convByte(num));
} }
public static void writeChar(OutputStream out, char num) throws IOException public static void writeChar(OutputStream out, char num) throws IOException
{ {
out.write(convChar(num)); out.write(convChar(num));
} }
public static void writeShort(OutputStream out, short num) throws IOException public static void writeShort(OutputStream out, short num) throws IOException
{ {
out.write(convShort(num)); out.write(convShort(num));
} }
public static void writeInt(OutputStream out, int num) throws IOException public static void writeInt(OutputStream out, int num) throws IOException
{ {
out.write(convInt(num)); out.write(convInt(num));
} }
public static void writeLong(OutputStream out, long num) throws IOException public static void writeLong(OutputStream out, long num) throws IOException
{ {
out.write(convLong(num)); out.write(convLong(num));
} }
public static void writeFloat(OutputStream out, float num) throws IOException public static void writeFloat(OutputStream out, float num) throws IOException
{ {
out.write(convFloat(num)); out.write(convFloat(num));
} }
public static void writeDouble(OutputStream out, double num) throws IOException public static void writeDouble(OutputStream out, double num) throws IOException
{ {
out.write(convDouble(num)); out.write(convDouble(num));
} }
public static void writeString(OutputStream out, String str) throws IOException public static void writeString(OutputStream out, String str) throws IOException
{ {
out.write(convString(str)); out.write(convString(str));
} }
public static void writeStringBytes(OutputStream out, String str) throws IOException public static void writeStringBytes(OutputStream out, String str) throws IOException
{ {
out.write(convString_b(str)); out.write(convString_b(str));
} }
// READING // READING
public static boolean readBoolean(InputStream in) throws IOException public static boolean readBoolean(InputStream in) throws IOException
{ {
return in.read() > 0; return in.read() > 0;
} }
public static byte readByte(InputStream in) throws IOException public static byte readByte(InputStream in) throws IOException
{ {
return (byte) in.read(); return (byte) in.read();
} }
public static char readChar(InputStream in) throws IOException public static char readChar(InputStream in) throws IOException
{ {
in.read(ac, 0, ac.length); in.read(ac, 0, ac.length);
ByteBuffer buf = ByteBuffer.wrap(ac); ByteBuffer buf = ByteBuffer.wrap(ac);
return buf.getChar(); return buf.getChar();
} }
public static short readShort(InputStream in) throws IOException public static short readShort(InputStream in) throws IOException
{ {
in.read(as, 0, as.length); in.read(as, 0, as.length);
ByteBuffer buf = ByteBuffer.wrap(as); ByteBuffer buf = ByteBuffer.wrap(as);
return buf.getShort(); return buf.getShort();
} }
public static long readLong(InputStream in) throws IOException public static long readLong(InputStream in) throws IOException
{ {
in.read(al, 0, al.length); in.read(al, 0, al.length);
ByteBuffer buf = ByteBuffer.wrap(al); ByteBuffer buf = ByteBuffer.wrap(al);
return buf.getLong(); return buf.getLong();
} }
public static int readInt(InputStream in) throws IOException public static int readInt(InputStream in) throws IOException
{ {
in.read(ai, 0, ai.length); in.read(ai, 0, ai.length);
ByteBuffer buf = ByteBuffer.wrap(ai); ByteBuffer buf = ByteBuffer.wrap(ai);
return buf.getInt(); return buf.getInt();
} }
public static float readFloat(InputStream in) throws IOException public static float readFloat(InputStream in) throws IOException
{ {
in.read(af, 0, af.length); in.read(af, 0, af.length);
ByteBuffer buf = ByteBuffer.wrap(af); ByteBuffer buf = ByteBuffer.wrap(af);
return buf.getFloat(); return buf.getFloat();
} }
public static double readDouble(InputStream in) throws IOException public static double readDouble(InputStream in) throws IOException
{ {
in.read(ad, 0, ad.length); in.read(ad, 0, ad.length);
ByteBuffer buf = ByteBuffer.wrap(ad); ByteBuffer buf = ByteBuffer.wrap(ad);
return buf.getDouble(); return buf.getDouble();
} }
public static String readString(InputStream in) throws IOException public static String readString(InputStream in) throws IOException
{ {
String s = ""; String s = "";
@ -250,8 +249,8 @@ public class StreamUtils {
} }
return s; return s;
} }
public static String readStringBytes(InputStream in) throws IOException public static String readStringBytes(InputStream in) throws IOException
{ {
String s = ""; String s = "";
@ -261,5 +260,5 @@ public class StreamUtils {
} }
return s; return s;
} }
} }

@ -1,133 +1,144 @@
package mightypork.utils.logging; package mightypork.utils.logging;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
public class Log { public class Log {
/** enable static logging */ /** enable static logging */
private static boolean esl = true; private static boolean esl = true;
/** /**
* Log FINE message in main logger * Log FINE message in main logger
* *
* @param msg message * @param msg
* message
*/ */
public static void f1(String msg) public static void f1(String msg)
{ {
if (esl && main != null) main.f1(msg); if (esl && main != null) main.f1(msg);
} }
/** /**
* Log FINER message in main logger * Log FINER message in main logger
* *
* @param msg message * @param msg
* message
*/ */
public static void f2(String msg) public static void f2(String msg)
{ {
if (esl && main != null) main.f2(msg); if (esl && main != null) main.f2(msg);
} }
/** /**
* Log FINEST message in main logger * Log FINEST message in main logger
* *
* @param msg message * @param msg
* message
*/ */
public static void f3(String msg) public static void f3(String msg)
{ {
if (esl && main != null) main.f3(msg); if (esl && main != null) main.f3(msg);
} }
/** /**
* Log INFO message in main logger * Log INFO message in main logger
* *
* @param msg message * @param msg
* message
*/ */
public static void i(String msg) public static void i(String msg)
{ {
if (esl && main != null) main.i(msg); if (esl && main != null) main.i(msg);
} }
/** /**
* Log WARNING message in main logger * Log WARNING message in main logger
* *
* @param msg message * @param msg
* message
*/ */
public static void w(String msg) public static void w(String msg)
{ {
if (esl && main != null) main.w(msg); if (esl && main != null) main.w(msg);
} }
/** /**
* Log ERROR message in main logger * Log ERROR message in main logger
* *
* @param msg message * @param msg
* message
*/ */
public static void e(String msg) public static void e(String msg)
{ {
if (esl && main != null) main.e(msg); if (esl && main != null) main.e(msg);
} }
/** /**
* Log EXCEPTION and ERROR message in main logger * Log EXCEPTION and ERROR message in main logger
* *
* @param msg message * @param msg
* @param thrown thrown exception * message
* @param thrown
* thrown exception
*/ */
public static void e(String msg, Throwable thrown) public static void e(String msg, Throwable thrown)
{ {
if (esl && main != null) main.e(msg, thrown); if (esl && main != null) main.e(msg, thrown);
} }
/** /**
* Log EXCEPTION in main logger * Log EXCEPTION in main logger
* *
* @param thrown thrown exception * @param thrown
* thrown exception
*/ */
public static void e(Throwable thrown) public static void e(Throwable thrown)
{ {
if (esl && main != null) main.e(thrown); if (esl && main != null) main.e(thrown);
} }
public static void enable(boolean flag) public static void enable(boolean flag)
{ {
if (esl && main != null) main.enable(flag); if (esl && main != null) main.enable(flag);
} }
/** /**
* Enable / disable static log delegate methods * Enable / disable static log delegate methods
* *
* @param flag enable * @param flag
* enable
*/ */
public static void enableStaticLogging(boolean flag) public static void enableStaticLogging(boolean flag)
{ {
esl = flag; esl = flag;
} }
private static HashMap<String, LogInstance> logs = new HashMap<String, LogInstance>(); private static HashMap<String, LogInstance> logs = new HashMap<String, LogInstance>();
private static LogInstance main = null; private static LogInstance main = null;
/** /**
* Create a logger. If this is the first logger made, then it'll be made * Create a logger. If this is the first logger made, then it'll be made
* available via the static methods. * available via the static methods.
* *
* @param logName log name (used for filename, must be application-unique) * @param logName
* @param logsDir directory to store logs in * log name (used for filename, must be application-unique)
* @param oldLogsCount number of old logs to keep, -1 for infinite, 0 for * @param logsDir
* none. * directory to store logs in
* @param oldLogsCount
* number of old logs to keep, -1 for infinite, 0 for none.
* @return the created Log instance * @return the created Log instance
*/ */
public static synchronized LogInstance create(String logName, File logsDir, int oldLogsCount) public static synchronized LogInstance create(String logName, File logsDir, int oldLogsCount)
@ -136,18 +147,20 @@ public class Log {
LogInstance log = new LogInstance(logName, logsDir, oldLogsCount); LogInstance log = new LogInstance(logName, logsDir, oldLogsCount);
if (main == null) main = log; if (main == null) main = log;
logs.put(logName, log); logs.put(logName, log);
return log; return log;
} }
/** /**
* Create a logger. If this is the first logger made, then it'll be made * Create a logger. If this is the first logger made, then it'll be made
* available via the static methods.<br> * available via the static methods.<br>
* Old logs will be kept. * Old logs will be kept.
* *
* @param logName log name (used for filename, must be application-unique) * @param logName
* @param logsDir directory to store logs in * log name (used for filename, must be application-unique)
* @param logsDir
* directory to store logs in
* @return the created Log instance * @return the created Log instance
*/ */
public static synchronized LogInstance create(String logName, File logsDir) public static synchronized LogInstance create(String logName, File logsDir)
@ -156,24 +169,24 @@ public class Log {
LogInstance log = new LogInstance(logName, logsDir, -1); LogInstance log = new LogInstance(logName, logsDir, -1);
if (main == null) main = log; if (main == null) main = log;
logs.put(logName, log); logs.put(logName, log);
return log; return log;
} }
public int addMonitor(LogMonitor mon) public int addMonitor(LogMonitor mon)
{ {
if (main == null) throw new IllegalStateException("Main logger not initialized."); if (main == null) throw new IllegalStateException("Main logger not initialized.");
return main.addMonitor(mon); return main.addMonitor(mon);
} }
public void removeMonitor(int id) public void removeMonitor(int id)
{ {
if (main == null) throw new IllegalStateException("Main logger not initialized."); if (main == null) throw new IllegalStateException("Main logger not initialized.");
main.removeMonitor(id); main.removeMonitor(id);
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.logging; package mightypork.utils.logging;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -27,131 +26,132 @@ import mightypork.utils.files.FileUtils;
* @copy (c) 2014 * @copy (c) 2014
*/ */
public class LogInstance { public class LogInstance {
/** log file */ /** log file */
private File file; private File file;
/** Log name */ /** Log name */
private String name; private String name;
/** Number of old logs to keep */ /** Number of old logs to keep */
private int logs_to_keep; private int logs_to_keep;
/** Logs dir */ /** Logs dir */
private File dir; private File dir;
/** Logger instance. */ /** Logger instance. */
private Logger logger; private Logger logger;
/** Logging enabled */ /** Logging enabled */
private boolean enabled = true; private boolean enabled = true;
private boolean sysout = true; private boolean sysout = true;
private int monitorId = 0; private int monitorId = 0;
private HashMap<Integer, LogMonitor> monitors = new HashMap<Integer, LogMonitor>(); private HashMap<Integer, LogMonitor> monitors = new HashMap<Integer, LogMonitor>();
private LogToSysoutMonitor sysoutMonitor; private LogToSysoutMonitor sysoutMonitor;
public LogInstance(String name, File dir, int oldLogCount) { public LogInstance(String name, File dir, int oldLogCount) {
this.name = name; this.name = name;
this.file = new File(dir, name + getSuffix()); this.file = new File(dir, name + getSuffix());
this.dir = dir; this.dir = dir;
this.logs_to_keep = oldLogCount; this.logs_to_keep = oldLogCount;
init(); init();
} }
/** /**
* Prepare logs for logging * Prepare logs for logging
*/ */
private void init() private void init()
{ {
logger = Logger.getLogger(name); logger = Logger.getLogger(name);
cleanup(); cleanup();
FileHandler handler = null; FileHandler handler = null;
try { try {
handler = new FileHandler(file.getPath()); handler = new FileHandler(file.getPath());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Failed to init log", e); throw new RuntimeException("Failed to init log", e);
} }
handler.setFormatter(new LogFormatter()); handler.setFormatter(new LogFormatter());
logger.addHandler(handler); logger.addHandler(handler);
enabled = true; enabled = true;
sysoutMonitor = new LogToSysoutMonitor(); sysoutMonitor = new LogToSysoutMonitor();
addMonitor(sysoutMonitor); addMonitor(sysoutMonitor);
logger.setUseParentHandlers(false); logger.setUseParentHandlers(false);
logger.setLevel(Level.ALL); logger.setLevel(Level.ALL);
logger.info("Main logger initialized."); logger.info("Main logger initialized.");
logger.info((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date())); logger.info((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date()));
} }
private void cleanup() private void cleanup()
{ {
if (logs_to_keep == 0) return; // overwrite if (logs_to_keep == 0) return; // overwrite
for (File f : FileUtils.listDirectory(file.getParentFile())) { for (File f : FileUtils.listDirectory(file.getParentFile())) {
if (!f.isFile()) continue; if (!f.isFile()) continue;
if (f.equals(file)) { if (f.equals(file)) {
Date d = new Date(f.lastModified()); Date d = new Date(f.lastModified());
String fbase = name + '_' + (new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")).format(d); String fbase = name + '_' + (new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")).format(d);
String suff = getSuffix(); String suff = getSuffix();
String cntStr = ""; String cntStr = "";
File f2; File f2;
for (int cnt = 0; (f2 = new File(dir, fbase + cntStr + suff)).exists(); cntStr = "_" + (++cnt)); for (int cnt = 0; (f2 = new File(dir, fbase + cntStr + suff)).exists(); cntStr = "_" + (++cnt));
f.renameTo(f2); f.renameTo(f2);
} }
} }
if (logs_to_keep == -1) return; // keep all if (logs_to_keep == -1) return; // keep all
List<File> oldLogs = FileUtils.listDirectory(dir, new FileFilter() { List<File> oldLogs = FileUtils.listDirectory(dir, new FileFilter() {
@Override @Override
public boolean accept(File f) public boolean accept(File f)
{ {
if (f.isDirectory()) return false; if (f.isDirectory()) return false;
if (!f.getName().endsWith(getSuffix())) return false; if (!f.getName().endsWith(getSuffix())) return false;
if (!f.getName().startsWith(name)) return false; if (!f.getName().startsWith(name)) return false;
return true; return true;
} }
}); });
Collections.sort(oldLogs, new Comparator<File>() { Collections.sort(oldLogs, new Comparator<File>() {
@Override @Override
public int compare(File o1, File o2) public int compare(File o1, File o2)
{ {
return o1.getName().compareTo(o2.getName()); return o1.getName().compareTo(o2.getName());
} }
}); });
for (int i = 0; i < oldLogs.size() - logs_to_keep; i++) { for (int i = 0; i < oldLogs.size() - logs_to_keep; i++) {
oldLogs.get(i).delete(); oldLogs.get(i).delete();
} }
} }
/** /**
* Add log monitor * Add log monitor
* *
* @param mon monitor * @param mon
* monitor
* @return assigned ID * @return assigned ID
*/ */
public synchronized int addMonitor(LogMonitor mon) public synchronized int addMonitor(LogMonitor mon)
@ -161,131 +161,143 @@ public class LogInstance {
monitors.put(id, mon); monitors.put(id, mon);
return id; return id;
} }
/** /**
* Remove a monitor by ID * Remove a monitor by ID
* *
* @param id monitor ID * @param id
* monitor ID
*/ */
public synchronized void removeMonitor(int id) public synchronized void removeMonitor(int id)
{ {
monitors.remove(id); monitors.remove(id);
} }
/** /**
* Enable logging. * Enable logging.
* *
* @param flag do enable logging * @param flag
* do enable logging
*/ */
public void enable(boolean flag) public void enable(boolean flag)
{ {
enabled = flag; enabled = flag;
} }
/** /**
* Enable printing logs to sysout * Enable printing logs to sysout
* *
* @param flag do enable logging * @param flag
* do enable logging
*/ */
public void enableSysout(boolean flag) public void enableSysout(boolean flag)
{ {
sysout = flag; sysout = flag;
sysoutMonitor.enable(sysout); sysoutMonitor.enable(sysout);
} }
/** /**
* Log FINE message * Log FINE message
* *
* @param msg message * @param msg
* message
*/ */
public void f1(String msg) public void f1(String msg)
{ {
if (enabled) logger.log(Level.FINE, msg); if (enabled) logger.log(Level.FINE, msg);
} }
/** /**
* Log FINER message * Log FINER message
* *
* @param msg message * @param msg
* message
*/ */
public void f2(String msg) public void f2(String msg)
{ {
if (enabled) logger.log(Level.FINER, msg); if (enabled) logger.log(Level.FINER, msg);
} }
/** /**
* Log FINEST message * Log FINEST message
* *
* @param msg message * @param msg
* message
*/ */
public void f3(String msg) public void f3(String msg)
{ {
if (enabled) logger.log(Level.FINEST, msg); if (enabled) logger.log(Level.FINEST, msg);
} }
/** /**
* Log INFO message * Log INFO message
* *
* @param msg message * @param msg
* message
*/ */
public void i(String msg) public void i(String msg)
{ {
if (enabled) logger.log(Level.INFO, msg); if (enabled) logger.log(Level.INFO, msg);
} }
/** /**
* Log WARNING message (less severe than ERROR) * Log WARNING message (less severe than ERROR)
* *
* @param msg message * @param msg
* message
*/ */
public void w(String msg) public void w(String msg)
{ {
if (enabled) logger.log(Level.WARNING, msg); if (enabled) logger.log(Level.WARNING, msg);
} }
/** /**
* Log ERROR message * Log ERROR message
* *
* @param msg message * @param msg
* message
*/ */
public void e(String msg) public void e(String msg)
{ {
if (enabled) logger.log(Level.SEVERE, msg); if (enabled) logger.log(Level.SEVERE, msg);
} }
/** /**
* Log THROWING message * Log THROWING message
* *
* @param msg message * @param msg
* @param thrown thrown exception * message
* @param thrown
* thrown exception
*/ */
public void e(String msg, Throwable thrown) public void e(String msg, Throwable thrown)
{ {
if (enabled) logger.log(Level.SEVERE, msg + "\n" + getStackTrace(thrown)); if (enabled) logger.log(Level.SEVERE, msg + "\n" + getStackTrace(thrown));
} }
/** /**
* Log exception thrown * Log exception thrown
* *
* @param thrown thrown exception * @param thrown
* thrown exception
*/ */
public void e(Throwable thrown) public void e(Throwable thrown)
{ {
if (enabled) logger.log(Level.SEVERE, getStackTrace(thrown)); if (enabled) logger.log(Level.SEVERE, getStackTrace(thrown));
} }
/** /**
* Get stack trace from throwable * Get stack trace from throwable
* *
@ -301,7 +313,8 @@ public class LogInstance {
sw.flush(); sw.flush();
return sw.toString(); return sw.toString();
} }
/** /**
* PowerCraft Log file formatter. * PowerCraft Log file formatter.
* *
@ -309,25 +322,25 @@ public class LogInstance {
* @copy (c) 2012 * @copy (c) 2012
*/ */
private class LogFormatter extends Formatter { private class LogFormatter extends Formatter {
/** Newline string constant */ /** Newline string constant */
private final String nl = System.getProperty("line.separator"); private final String nl = System.getProperty("line.separator");
@Override @Override
public String format(LogRecord record) public String format(LogRecord record)
{ {
StringBuffer buf = new StringBuffer(180); StringBuffer buf = new StringBuffer(180);
if (record.getMessage().equals("\n")) { if (record.getMessage().equals("\n")) {
return nl; return nl;
} }
if (record.getMessage().charAt(0) == '\n') { if (record.getMessage().charAt(0) == '\n') {
buf.append(nl); buf.append(nl);
record.setMessage(record.getMessage().substring(1)); record.setMessage(record.getMessage().substring(1));
} }
Level level = record.getLevel(); Level level = record.getLevel();
String trail = "[ ? ]"; String trail = "[ ? ]";
if (level == Level.FINE) { if (level == Level.FINE) {
@ -348,14 +361,14 @@ public class LogInstance {
if (level == Level.WARNING) { if (level == Level.WARNING) {
trail = "[!W!] "; trail = "[!W!] ";
} }
record.setMessage(record.getMessage().replaceAll("\n", nl + trail)); record.setMessage(record.getMessage().replaceAll("\n", nl + trail));
buf.append(trail); buf.append(trail);
buf.append(formatMessage(record)); buf.append(formatMessage(record));
buf.append(nl); buf.append(nl);
Throwable throwable = record.getThrown(); Throwable throwable = record.getThrown();
if (throwable != null) { if (throwable != null) {
buf.append("at "); buf.append("at ");
@ -363,25 +376,25 @@ public class LogInstance {
buf.append('.'); buf.append('.');
buf.append(record.getSourceMethodName()); buf.append(record.getSourceMethodName());
buf.append(nl); buf.append(nl);
StringWriter sink = new StringWriter(); StringWriter sink = new StringWriter();
throwable.printStackTrace(new PrintWriter(sink, true)); throwable.printStackTrace(new PrintWriter(sink, true));
buf.append(sink.toString()); buf.append(sink.toString());
buf.append(nl); buf.append(nl);
} }
String str = buf.toString(); String str = buf.toString();
for (LogMonitor mon : monitors.values()) { for (LogMonitor mon : monitors.values()) {
mon.log(level, str); mon.log(level, str);
} }
return str; return str;
} }
} }
/** /**
* @return log filename suffix (incl. dot) * @return log filename suffix (incl. dot)
*/ */

@ -1,13 +1,12 @@
package mightypork.utils.logging; package mightypork.utils.logging;
import java.util.logging.Level; import java.util.logging.Level;
public interface LogMonitor { public interface LogMonitor {
public void log(Level level, String message); public void log(Level level, String message);
public void enable(boolean enable); public void enable(boolean enable);
} }

@ -1,31 +1,30 @@
package mightypork.utils.logging; package mightypork.utils.logging;
import java.util.logging.Level; import java.util.logging.Level;
public class LogToSysoutMonitor implements LogMonitor { public class LogToSysoutMonitor implements LogMonitor {
private boolean enabled = true; private boolean enabled = true;
@Override @Override
public void log(Level level, String message) public void log(Level level, String message)
{ {
if (!enabled) return; if (!enabled) return;
if (level == Level.FINE || level == Level.FINER || level == Level.FINEST || level == Level.INFO) { if (level == Level.FINE || level == Level.FINER || level == Level.FINEST || level == Level.INFO) {
System.out.print(message); System.out.print(message);
} else if (level == Level.SEVERE || level == Level.WARNING) { } else if (level == Level.SEVERE || level == Level.WARNING) {
System.err.print(message); System.err.print(message);
} }
} }
@Override @Override
public void enable(boolean enable) public void enable(boolean enable)
{ {
this.enabled = enable; this.enabled = enable;
} }
} }

File diff suppressed because it is too large Load Diff

@ -1,6 +1,5 @@
package mightypork.utils.math; package mightypork.utils.math;
import mightypork.utils.math.Calc.Deg; import mightypork.utils.math.Calc.Deg;
import mightypork.utils.math.Calc.Rad; import mightypork.utils.math.Calc.Rad;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
@ -12,38 +11,43 @@ import mightypork.utils.math.coord.Coord;
* @author MightyPork * @author MightyPork
*/ */
public class Polar { public class Polar {
/** angle in radians */ /** angle in radians */
private double angle = 0; private double angle = 0;
/** distance in units */ /** distance in units */
private double radius = 0; private double radius = 0;
/** /**
* Create a polar * Create a polar
* *
* @param angle angle in RAD * @param angle
* @param distance distance from origin * angle in RAD
* @param distance
* distance from origin
*/ */
public Polar(double angle, double distance) { public Polar(double angle, double distance) {
this(angle, false, distance); this(angle, false, distance);
} }
/** /**
* Create a polar * Create a polar
* *
* @param angle angle * @param angle
* @param deg angle is in DEG * angle
* @param distance radius * @param deg
* angle is in DEG
* @param distance
* radius
*/ */
public Polar(double angle, boolean deg, double distance) { public Polar(double angle, boolean deg, double distance) {
this.radius = distance; this.radius = distance;
this.angle = deg ? Deg.toRad(angle) : angle; this.angle = deg ? Deg.toRad(angle) : angle;
} }
/** /**
* @return angle in RAD * @return angle in RAD
*/ */
@ -51,8 +55,8 @@ public class Polar {
{ {
return angle; return angle;
} }
/** /**
* @return angle in DEG * @return angle in DEG
*/ */
@ -60,26 +64,28 @@ public class Polar {
{ {
return Rad.toDeg(angle); return Rad.toDeg(angle);
} }
/** /**
* @param angle angle in RAD * @param angle
* angle in RAD
*/ */
public void setAngle(double angle) public void setAngle(double angle)
{ {
this.angle = angle; this.angle = angle;
} }
/** /**
* @param angle angle in DEG * @param angle
* angle in DEG
*/ */
public void setAngleDeg(double angle) public void setAngleDeg(double angle)
{ {
this.angle = Deg.toRad(angle); this.angle = Deg.toRad(angle);
} }
/** /**
* @return radius * @return radius
*/ */
@ -87,42 +93,46 @@ public class Polar {
{ {
return radius; return radius;
} }
/** /**
* @param r radius * @param r
* radius
*/ */
public void setRadius(double r) public void setRadius(double r)
{ {
this.radius = r; this.radius = r;
} }
/** /**
* Make polar from coord * Make polar from coord
* *
* @param coord coord * @param coord
* coord
* @return polar * @return polar
*/ */
public static Polar fromCoord(Coord coord) public static Polar fromCoord(Coord coord)
{ {
return new Polar(Math.atan2(coord.y, coord.x), Math.sqrt(Calc.square(coord.x) + Calc.square(coord.y))); return new Polar(Math.atan2(coord.y, coord.x), Math.sqrt(Calc.square(coord.x) + Calc.square(coord.y)));
} }
/** /**
* Make polar from coords * Make polar from coords
* *
* @param x x coord * @param x
* @param y y coord * x coord
* @param y
* y coord
* @return polar * @return polar
*/ */
public static Polar fromCoord(double x, double y) public static Polar fromCoord(double x, double y)
{ {
return Polar.fromCoord(new Coord(x, y)); return Polar.fromCoord(new Coord(x, y));
} }
/** /**
* Get coord from polar * Get coord from polar
* *
@ -132,15 +142,15 @@ public class Polar {
{ {
return new Coord(radius * Math.cos(angle), radius * Math.sin(angle)); return new Coord(radius * Math.cos(angle), radius * Math.sin(angle));
} }
@Override @Override
public String toString() public String toString()
{ {
return "Polar(" + angle + "rad, " + radius + ")"; return "Polar(" + angle + "rad, " + radius + ")";
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
@ -153,8 +163,8 @@ public class Polar {
result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + (int) (temp ^ (temp >>> 32));
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {

@ -1,6 +1,5 @@
package mightypork.utils.math; package mightypork.utils.math;
import java.util.Random; import java.util.Random;
@ -10,24 +9,27 @@ import java.util.Random;
* @author MightyPork * @author MightyPork
*/ */
public class Range { public class Range {
private double min = 0; private double min = 0;
private double max = 1; private double max = 1;
private static Random rand = new Random(); private static Random rand = new Random();
/** /**
* Implicit range constructor 0-1 * Implicit range constructor 0-1
*/ */
public Range() {} public Range() {
}
/** /**
* Create new range * Create new range
* *
* @param min min number * @param min
* @param max max number * min number
* @param max
* max number
*/ */
public Range(double min, double max) { public Range(double min, double max) {
if (min > max) { if (min > max) {
@ -38,19 +40,20 @@ public class Range {
this.min = min; this.min = min;
this.max = max; this.max = max;
} }
/** /**
* Create new range * Create new range
* *
* @param minmax min = max number * @param minmax
* min = max number
*/ */
public Range(double minmax) { public Range(double minmax) {
this.min = minmax; this.min = minmax;
this.max = minmax; this.max = minmax;
} }
/** /**
* Get random integer from range * Get random integer from range
* *
@ -60,8 +63,8 @@ public class Range {
{ {
return (int) (Math.round(min) + rand.nextInt((int) (Math.round(max) - Math.round(min)) + 1)); return (int) (Math.round(min) + rand.nextInt((int) (Math.round(max) - Math.round(min)) + 1));
} }
/** /**
* Get random double from this range * Get random double from this range
* *
@ -71,8 +74,8 @@ public class Range {
{ {
return min + rand.nextDouble() * (max - min); return min + rand.nextDouble() * (max - min);
} }
/** /**
* Get min * Get min
* *
@ -82,8 +85,8 @@ public class Range {
{ {
return min; return min;
} }
/** /**
* Get max * Get max
* *
@ -93,8 +96,8 @@ public class Range {
{ {
return max; return max;
} }
/** /**
* Get min * Get min
* *
@ -104,8 +107,8 @@ public class Range {
{ {
return (int) min; return (int) min;
} }
/** /**
* Get max * Get max
* *
@ -115,37 +118,39 @@ public class Range {
{ {
return (int) max; return (int) max;
} }
/** /**
* Set min * Set min
* *
* @param min min value * @param min
* min value
*/ */
public void setMin(double min) public void setMin(double min)
{ {
this.min = min; this.min = min;
} }
/** /**
* Set max * Set max
* *
* @param max max value * @param max
* max value
*/ */
public void setMax(double max) public void setMax(double max)
{ {
this.max = max; this.max = max;
} }
@Override @Override
public String toString() public String toString()
{ {
return "Range(" + min + ";" + max + ")"; return "Range(" + min + ";" + max + ")";
} }
/** /**
* Get identical copy * Get identical copy
* *
@ -155,32 +160,35 @@ public class Range {
{ {
return new Range(min, max); return new Range(min, max);
} }
/** /**
* Set to value of other range * Set to value of other range
* *
* @param other copied range * @param other
* copied range
*/ */
public void setTo(Range other) public void setTo(Range other)
{ {
if (other == null) return; if (other == null) return;
min = other.min; min = other.min;
max = other.max; max = other.max;
if (min > max) { if (min > max) {
double t = min; double t = min;
min = max; min = max;
max = t; max = t;
} }
} }
/** /**
* Set to min-max values * Set to min-max values
* *
* @param min min value * @param min
* @param max max value * min value
* @param max
* max value
*/ */
public void setTo(double min, double max) public void setTo(double min, double max)
{ {
@ -189,9 +197,9 @@ public class Range {
min = max; min = max;
max = t; max = t;
} }
this.min = min; this.min = min;
this.max = max; this.max = max;
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.math.color; package mightypork.utils.math.color;
import java.awt.Color; import java.awt.Color;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
@ -12,21 +11,22 @@ import mightypork.utils.math.Calc;
* @author MightyPork * @author MightyPork
*/ */
public class HSV { public class HSV {
/** H */ /** H */
public double h; public double h;
/** S */ /** S */
public double s; public double s;
/** V */ /** V */
public double v; public double v;
/** /**
* Create black color 0,0,0 * Create black color 0,0,0
*/ */
public HSV() {} public HSV() {
}
/** /**
* Color from HSV 0-1 * Color from HSV 0-1
* *
@ -40,8 +40,8 @@ public class HSV {
this.v = v.doubleValue(); this.v = v.doubleValue();
norm(); norm();
} }
/** /**
* @return hue 0-1 * @return hue 0-1
*/ */
@ -49,8 +49,8 @@ public class HSV {
{ {
return h; return h;
} }
/** /**
* @return saturation 0-1 * @return saturation 0-1
*/ */
@ -58,8 +58,8 @@ public class HSV {
{ {
return s; return s;
} }
/** /**
* @return value/brightness 0-1 * @return value/brightness 0-1
*/ */
@ -67,12 +67,13 @@ public class HSV {
{ {
return v; return v;
} }
/** /**
* Set color to other color * Set color to other color
* *
* @param copied copied color * @param copied
* copied color
* @return this * @return this
*/ */
public HSV setTo(HSV copied) public HSV setTo(HSV copied)
@ -80,18 +81,21 @@ public class HSV {
h = copied.h; h = copied.h;
s = copied.s; s = copied.s;
v = copied.v; v = copied.v;
norm(); norm();
return this; return this;
} }
/** /**
* Set to H,S,V 0-1 * Set to H,S,V 0-1
* *
* @param h hue * @param h
* @param s saturation * hue
* @param v value * @param s
* saturation
* @param v
* value
* @return this * @return this
*/ */
public HSV setTo(Number h, Number s, Number v) public HSV setTo(Number h, Number s, Number v)
@ -102,8 +106,8 @@ public class HSV {
norm(); norm();
return this; return this;
} }
/** /**
* Fix numbers out of range 0-1 * Fix numbers out of range 0-1
*/ */
@ -113,8 +117,8 @@ public class HSV {
s = Calc.clampd(s, 0, 1); s = Calc.clampd(s, 0, 1);
v = Calc.clampd(v, 0, 1); v = Calc.clampd(v, 0, 1);
} }
/** /**
* Convert to RGB * Convert to RGB
* *
@ -123,32 +127,33 @@ public class HSV {
public RGB toRGB() public RGB toRGB()
{ {
norm(); norm();
int rgb = Color.HSBtoRGB((float) h, (float) s, (float) v); int rgb = Color.HSBtoRGB((float) h, (float) s, (float) v);
return RGB.fromHex(rgb); return RGB.fromHex(rgb);
} }
/** /**
* Make from RGB * Make from RGB
* *
* @param color RGB * @param color
* RGB
* @return HSV * @return HSV
*/ */
public static HSV fromRGB(RGB color) public static HSV fromRGB(RGB color)
{ {
return color.toHSV(); return color.toHSV();
} }
@Override @Override
public String toString() public String toString()
{ {
return "HSV[" + h + ";" + s + ";" + v + "]"; return "HSV[" + h + ";" + s + ";" + v + "]";
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
@ -156,15 +161,15 @@ public class HSV {
if (!(obj instanceof HSV)) return false; if (!(obj instanceof HSV)) return false;
return ((HSV) obj).h == h && ((HSV) obj).s == s && ((HSV) obj).v == v; return ((HSV) obj).h == h && ((HSV) obj).s == s && ((HSV) obj).v == v;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return Double.valueOf(h).hashCode() ^ Double.valueOf(s).hashCode() ^ Double.valueOf(v).hashCode(); return Double.valueOf(h).hashCode() ^ Double.valueOf(s).hashCode() ^ Double.valueOf(v).hashCode();
} }
/** /**
* Get a copy * Get a copy
* *

@ -1,6 +1,5 @@
package mightypork.utils.math.color; package mightypork.utils.math.color;
import java.awt.Color; import java.awt.Color;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
@ -12,7 +11,7 @@ import mightypork.utils.math.Calc;
* @author MightyPork * @author MightyPork
*/ */
public class RGB { public class RGB {
/** White */ /** White */
public static final RGB WHITE = new RGB(1, 1, 1); public static final RGB WHITE = new RGB(1, 1, 1);
/** Black */ /** Black */
@ -33,7 +32,7 @@ public class RGB {
public static final RGB ORANGE = new RGB(1, 0.6, 0); public static final RGB ORANGE = new RGB(1, 0.6, 0);
/** no color (alpha=0) */ /** no color (alpha=0) */
public static final RGB TRANSPARENT = new RGB(0, 0, 0, 0); public static final RGB TRANSPARENT = new RGB(0, 0, 0, 0);
/** R */ /** R */
public double r; public double r;
/** G */ /** G */
@ -42,30 +41,33 @@ public class RGB {
public double b; public double b;
/** ALPHA */ /** ALPHA */
public double a = 1; public double a = 1;
/** /**
* Create black color 0,0,0 * Create black color 0,0,0
*/ */
public RGB() {} public RGB() {
}
/** /**
* Get copy with custom alpha * Get copy with custom alpha
* *
* @param alpha alpha to set * @param alpha
* alpha to set
* @return copy w/ alpha * @return copy w/ alpha
*/ */
public RGB setAlpha(double alpha) public RGB setAlpha(double alpha)
{ {
return copy().setAlpha_ip(alpha); return copy().setAlpha_ip(alpha);
} }
/** /**
* set alpha IP * set alpha IP
* *
* @param alpha alpha to set * @param alpha
* alpha to set
* @return this * @return this
*/ */
public RGB setAlpha_ip(double alpha) public RGB setAlpha_ip(double alpha)
@ -74,8 +76,8 @@ public class RGB {
norm(); norm();
return this; return this;
} }
/** /**
* Get copy. * Get copy.
* *
@ -85,24 +87,26 @@ public class RGB {
{ {
return new RGB(r, g, b, a); return new RGB(r, g, b, a);
} }
/** /**
* Get copy with alpha multiplied by custom value * Get copy with alpha multiplied by custom value
* *
* @param alpha alpha to set * @param alpha
* alpha to set
* @return copy w/ alpha * @return copy w/ alpha
*/ */
public RGB mulAlpha(double alpha) public RGB mulAlpha(double alpha)
{ {
return copy().mulAlpha_ip(alpha); return copy().mulAlpha_ip(alpha);
} }
/** /**
* Multiply alpha by given number * Multiply alpha by given number
* *
* @param alpha alpha multiplier * @param alpha
* alpha multiplier
* @return this * @return this
*/ */
public RGB mulAlpha_ip(double alpha) public RGB mulAlpha_ip(double alpha)
@ -111,14 +115,17 @@ public class RGB {
norm(); norm();
return this; return this;
} }
/** /**
* Color from RGB 0-1 * Color from RGB 0-1
* *
* @param r red * @param r
* @param g green * red
* @param b blue * @param g
* green
* @param b
* blue
*/ */
public RGB(Number r, Number g, Number b) { public RGB(Number r, Number g, Number b) {
this.r = r.doubleValue(); this.r = r.doubleValue();
@ -126,15 +133,19 @@ public class RGB {
this.b = b.doubleValue(); this.b = b.doubleValue();
norm(); norm();
} }
/** /**
* Color from RGB 0-1 * Color from RGB 0-1
* *
* @param r red * @param r
* @param g green * red
* @param b blue * @param g
* @param a alpha * green
* @param b
* blue
* @param a
* alpha
*/ */
public RGB(Number r, Number g, Number b, Number a) { public RGB(Number r, Number g, Number b, Number a) {
this.r = r.doubleValue(); this.r = r.doubleValue();
@ -143,44 +154,49 @@ public class RGB {
this.a = a.doubleValue(); this.a = a.doubleValue();
norm(); norm();
} }
/** /**
* Color from hex 0xRRGGBB * Color from hex 0xRRGGBB
* *
* @param hex hex integer * @param hex
* hex integer
*/ */
public RGB(int hex) { public RGB(int hex) {
setTo(RGB.fromHex(hex)); setTo(RGB.fromHex(hex));
norm(); norm();
} }
/** /**
* Color from hex 0xRRGGBB * Color from hex 0xRRGGBB
* *
* @param hex hex integer * @param hex
* @param alpha alpha color * hex integer
* @param alpha
* alpha color
*/ */
public RGB(int hex, double alpha) { public RGB(int hex, double alpha) {
setTo(RGB.fromHex(hex)); setTo(RGB.fromHex(hex));
a = alpha; a = alpha;
norm(); norm();
} }
/** /**
* Color from other RGB and alpha channel * Color from other RGB and alpha channel
* *
* @param color other RGB color * @param color
* @param alpha new alpha channel * other RGB color
* @param alpha
* new alpha channel
*/ */
public RGB(RGB color, double alpha) { public RGB(RGB color, double alpha) {
setTo(color); setTo(color);
setAlpha_ip(alpha); setAlpha_ip(alpha);
} }
/** /**
* @return red channel 0-1 * @return red channel 0-1
*/ */
@ -188,8 +204,8 @@ public class RGB {
{ {
return r; return r;
} }
/** /**
* @return green channel 0-1 * @return green channel 0-1
*/ */
@ -197,8 +213,8 @@ public class RGB {
{ {
return g; return g;
} }
/** /**
* @return blue channel 0-1 * @return blue channel 0-1
*/ */
@ -206,8 +222,8 @@ public class RGB {
{ {
return b; return b;
} }
/** /**
* @return alpha 0-1 * @return alpha 0-1
*/ */
@ -215,12 +231,13 @@ public class RGB {
{ {
return a; return a;
} }
/** /**
* Set color to other color * Set color to other color
* *
* @param copied copied color * @param copied
* copied color
* @return this * @return this
*/ */
public RGB setTo(RGB copied) public RGB setTo(RGB copied)
@ -229,16 +246,17 @@ public class RGB {
g = copied.g; g = copied.g;
b = copied.b; b = copied.b;
a = copied.a; a = copied.a;
norm(); norm();
return this; return this;
} }
/** /**
* Set to represent hex color * Set to represent hex color
* *
* @param hex hex integer RRGGBB * @param hex
* hex integer RRGGBB
* @return this * @return this
*/ */
public RGB setTo(int hex) public RGB setTo(int hex)
@ -247,15 +265,19 @@ public class RGB {
norm(); norm();
return this; return this;
} }
/** /**
* Set to R,G,B 0-1 * Set to R,G,B 0-1
* *
* @param r red * @param r
* @param g green * red
* @param b blue * @param g
* @param a alpha * green
* @param b
* blue
* @param a
* alpha
* @return this * @return this
*/ */
public RGB setTo(Number r, Number g, Number b, Number a) public RGB setTo(Number r, Number g, Number b, Number a)
@ -267,14 +289,17 @@ public class RGB {
norm(); norm();
return this; return this;
} }
/** /**
* Set to R,G,B 0-1 * Set to R,G,B 0-1
* *
* @param r red * @param r
* @param g green * red
* @param b blue * @param g
* green
* @param b
* blue
* @return this * @return this
*/ */
public RGB setTo(Number r, Number g, Number b) public RGB setTo(Number r, Number g, Number b)
@ -286,8 +311,8 @@ public class RGB {
norm(); norm();
return this; return this;
} }
/** /**
* Fix numbers out of range 0-1 * Fix numbers out of range 0-1
* *
@ -301,8 +326,8 @@ public class RGB {
a = Calc.clampd(a, 0, 1); a = Calc.clampd(a, 0, 1);
return this; return this;
} }
/** /**
* Get hex value 0xRRGGBB * Get hex value 0xRRGGBB
* *
@ -315,8 +340,8 @@ public class RGB {
int bi = (int) Math.round(b * 255); int bi = (int) Math.round(b * 255);
return (ri << 16) | (gi << 8) | bi; return (ri << 16) | (gi << 8) | bi;
} }
/** /**
* Convert to HSV * Convert to HSV
* *
@ -328,12 +353,13 @@ public class RGB {
Color.RGBtoHSB((int) (r * 255), (int) (g * 255), (int) (b * 255), hsv); Color.RGBtoHSB((int) (r * 255), (int) (g * 255), (int) (b * 255), hsv);
return new HSV(hsv[0], hsv[1], hsv[2]); return new HSV(hsv[0], hsv[1], hsv[2]);
} }
/** /**
* Create color from hex 0xRRGGBB * Create color from hex 0xRRGGBB
* *
* @param hex hex RRGGBB * @param hex
* hex RRGGBB
* @return the new color * @return the new color
*/ */
public static RGB fromHex(int hex) public static RGB fromHex(int hex)
@ -343,27 +369,28 @@ public class RGB {
int ri = (hex >> 16) & 0xff; int ri = (hex >> 16) & 0xff;
return new RGB(ri / 255D, gi / 255D, bi / 255D); return new RGB(ri / 255D, gi / 255D, bi / 255D);
} }
/** /**
* Make from HSV * Make from HSV
* *
* @param color HSV color * @param color
* HSV color
* @return RGB * @return RGB
*/ */
public static RGB fromHSV(HSV color) public static RGB fromHSV(HSV color)
{ {
return color.toRGB(); return color.toRGB();
} }
@Override @Override
public String toString() public String toString()
{ {
return "RGB[" + r + ";" + g + ";" + b + ";" + a + "]"; return "RGB[" + r + ";" + g + ";" + b + ";" + a + "]";
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
@ -371,12 +398,12 @@ public class RGB {
if (!(obj instanceof RGB)) return false; if (!(obj instanceof RGB)) return false;
return ((RGB) obj).r == r && ((RGB) obj).g == g && ((RGB) obj).b == b && ((RGB) obj).a == a; return ((RGB) obj).r == r && ((RGB) obj).g == g && ((RGB) obj).b == b && ((RGB) obj).a == a;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return Double.valueOf(r).hashCode() ^ Double.valueOf(g).hashCode() ^ Double.valueOf(b).hashCode() ^ Double.valueOf(a).hashCode(); return Double.valueOf(r).hashCode() ^ Double.valueOf(g).hashCode() ^ Double.valueOf(b).hashCode() ^ Double.valueOf(a).hashCode();
} }
} }

File diff suppressed because it is too large Load Diff

@ -1,6 +1,5 @@
package mightypork.utils.math.coord; package mightypork.utils.math.coord;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
import mightypork.utils.time.Updateable; import mightypork.utils.time.Updateable;
@ -11,17 +10,18 @@ import mightypork.utils.time.Updateable;
* @author MightyPork * @author MightyPork
*/ */
public class CoordAnimated extends Coord implements Updateable { public class CoordAnimated extends Coord implements Updateable {
private double animTime = 0; private double animTime = 0;
private Coord offs; private Coord offs;
private Coord start; private Coord start;
private double time = 0; private double time = 0;
/** /**
* Update delta timing * Update delta timing
* *
* @param delta delta time to add * @param delta
* delta time to add
*/ */
@Override @Override
public void update(double delta) public void update(double delta)
@ -35,8 +35,8 @@ public class CoordAnimated extends Coord implements Updateable {
start.setTo(this); start.setTo(this);
} }
} }
/** /**
* Remember position (other changes will be for animation) * Remember position (other changes will be for animation)
*/ */
@ -47,12 +47,13 @@ public class CoordAnimated extends Coord implements Updateable {
start.setTo(this); start.setTo(this);
offs = Coord.zero(); offs = Coord.zero();
} }
/** /**
* Start animation * Start animation
* *
* @param time anim length * @param time
* anim length
*/ */
public void animStart(double time) public void animStart(double time)
{ {
@ -62,8 +63,8 @@ public class CoordAnimated extends Coord implements Updateable {
animTime = 0; animTime = 0;
offs = start.vecTo(this); offs = start.vecTo(this);
} }
/** /**
* Stop animation, assign to current value * Stop animation, assign to current value
*/ */
@ -73,8 +74,8 @@ public class CoordAnimated extends Coord implements Updateable {
animRemember(); animRemember();
animTime = 0; animTime = 0;
} }
/** /**
* Get if animation is finished * Get if animation is finished
* *
@ -84,8 +85,8 @@ public class CoordAnimated extends Coord implements Updateable {
{ {
return animTime >= time; return animTime >= time;
} }
/** /**
* Get current value (animated) * Get current value (animated)
* *
@ -94,13 +95,13 @@ public class CoordAnimated extends Coord implements Updateable {
public Coord animGetCurrent() public Coord animGetCurrent()
{ {
if (time == 0) return copy(); // avoid zero division if (time == 0) return copy(); // avoid zero division
if (start == null) start = new Coord(); if (start == null) start = new Coord();
if (offs == null) offs = new Coord(); if (offs == null) offs = new Coord();
if (animIsFinished()) return this; if (animIsFinished()) return this;
return start.add(offs.mul(animTime / time)); return start.add(offs.mul(animTime / time));
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.math.coord; package mightypork.utils.math.coord;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
@ -10,167 +9,193 @@ import mightypork.utils.math.Calc;
* @author MightyPork * @author MightyPork
*/ */
public class Rect { public class Rect {
/** Rect [0, 0, 1, 1] */ /** Rect [0, 0, 1, 1] */
public static final Rect ONE = new Rect(0, 0, 1, 1); public static final Rect ONE = new Rect(0, 0, 1, 1);
/** Rect all zeros */ /** Rect all zeros */
public static final Rect ZERO = new Rect(0, 0, 0, 0); public static final Rect ZERO = new Rect(0, 0, 0, 0);
/** /**
* Rectangle from size * Rectangle from size
* *
* @param min min coord * @param min
* @param size rect size * min coord
* @param size
* rect size
* @return the rect * @return the rect
*/ */
public static Rect fromSize(Coord min, Coord size) public static Rect fromSize(Coord min, Coord size)
{ {
return fromSize(min, size.xi(), size.yi()); return fromSize(min, size.xi(), size.yi());
} }
/** /**
* Make rect from min coord and size * Make rect from min coord and size
* *
* @param min min coord * @param min
* @param width size x * min coord
* @param height size y * @param width
* size x
* @param height
* size y
* @return the new rect * @return the new rect
*/ */
public static Rect fromSize(Coord min, double width, double height) public static Rect fromSize(Coord min, double width, double height)
{ {
return new Rect(min, min.add(width, height)); return new Rect(min, min.add(width, height));
} }
/** /**
* Rectangle from size * Rectangle from size
* *
* @param x min X * @param x
* @param y min Y * min X
* @param size rect size * @param y
* min Y
* @param size
* rect size
* @return the rect * @return the rect
*/ */
public static Rect fromSize(int x, int y, Coord size) public static Rect fromSize(int x, int y, Coord size)
{ {
return fromSize(x, y, size.x, size.y); return fromSize(x, y, size.x, size.y);
} }
/** /**
* Make rect from min coord and size * Make rect from min coord and size
* *
* @param xMin min x * @param xMin
* @param yMin min y * min x
* @param width size x * @param yMin
* @param height size y * min y
* @param width
* size x
* @param height
* size y
* @return the new rect * @return the new rect
*/ */
public static Rect fromSize(double xMin, double yMin, double width, double height) public static Rect fromSize(double xMin, double yMin, double width, double height)
{ {
return new Rect(xMin, yMin, xMin + width, yMin + height); return new Rect(xMin, yMin, xMin + width, yMin + height);
} }
/** Lowest coordinates xy */ /** Lowest coordinates xy */
protected Coord min = new Coord(); protected Coord min = new Coord();
/** Highest coordinates xy */ /** Highest coordinates xy */
protected Coord max = new Coord(); protected Coord max = new Coord();
/** /**
* New Rect [0, 0, 0, 0] * New Rect [0, 0, 0, 0]
*/ */
public Rect() { public Rect() {
this(0, 0, 0, 0); this(0, 0, 0, 0);
} }
/** /**
* Rect [0, 0, size.x, size.y] * Rect [0, 0, size.x, size.y]
* *
* @param size size coord * @param size
* size coord
*/ */
public Rect(Coord size) { public Rect(Coord size) {
this(0, 0, size.x, size.y); this(0, 0, size.x, size.y);
} }
/** /**
* New rect of two coords * New rect of two coords
* *
* @param c1 coord 1 * @param c1
* @param c2 coord 2 * coord 1
* @param c2
* coord 2
*/ */
public Rect(Coord c1, Coord c2) { public Rect(Coord c1, Coord c2) {
this(c1.x, c1.y, c2.x, c2.y); this(c1.x, c1.y, c2.x, c2.y);
} }
/** /**
* New Rect * New Rect
* *
* @param x1 lower x * @param x1
* @param y1 lower y * lower x
* @param x2 upper x * @param y1
* @param y2 upper y * lower y
* @param x2
* upper x
* @param y2
* upper y
*/ */
public Rect(double x1, double y1, double x2, double y2) { public Rect(double x1, double y1, double x2, double y2) {
setTo(x1, y1, x2, y2); setTo(x1, y1, x2, y2);
} }
/** /**
* Rect [0, 0, x, y] * Rect [0, 0, x, y]
* *
* @param x width * @param x
* @param y height * width
* @param y
* height
*/ */
public Rect(double x, double y) { public Rect(double x, double y) {
this(0, 0, x, y); this(0, 0, x, y);
} }
/** /**
* New rect as a copy of other rect * New rect as a copy of other rect
* *
* @param r other rect * @param r
* other rect
*/ */
public Rect(Rect r) { public Rect(Rect r) {
this(r.min.x, r.min.y, r.max.x, r.max.y); this(r.min.x, r.min.y, r.max.x, r.max.y);
} }
/** /**
* Get offset copy (add) * Get offset copy (add)
* *
* @param move offset vector * @param move
* offset vector
* @return offset copy * @return offset copy
*/ */
public Rect add(Coord move) public Rect add(Coord move)
{ {
return copy().add_ip(move); return copy().add_ip(move);
} }
/** /**
* Add X and Y to all coordinates in a copy * Add X and Y to all coordinates in a copy
* *
* @param x x to add * @param x
* @param y y to add * x to add
* @param y
* y to add
* @return copy changed * @return copy changed
*/ */
public Rect add(double x, double y) public Rect add(double x, double y)
{ {
return add(new Coord(x, y)); return add(new Coord(x, y));
} }
/** /**
* Offset in place (add) * Offset in place (add)
* *
* @param move offset vector * @param move
* offset vector
* @return this * @return this
*/ */
public Rect add_ip(Coord move) public Rect add_ip(Coord move)
@ -179,21 +204,23 @@ public class Rect {
max.add_ip(move); max.add_ip(move);
return this; return this;
} }
/** /**
* Add X and Y to all coordinates in place * Add X and Y to all coordinates in place
* *
* @param x x to add * @param x
* @param y y to add * x to add
* @param y
* y to add
* @return this * @return this
*/ */
public Rect add_ip(double x, double y) public Rect add_ip(double x, double y)
{ {
return add_ip(new Coord(x, y)); return add_ip(new Coord(x, y));
} }
/** /**
* Get a copy * Get a copy
* *
@ -203,8 +230,8 @@ public class Rect {
{ {
return new Rect(this); return new Rect(this);
} }
/** /**
* Get copy with the same center and height=0 * Get copy with the same center and height=0
* *
@ -214,8 +241,8 @@ public class Rect {
{ {
return new Rect(getCenterLeft(), getCenterRight()); return new Rect(getCenterLeft(), getCenterRight());
} }
/** /**
* Get copy with the same center and width=0 * Get copy with the same center and width=0
* *
@ -225,8 +252,8 @@ public class Rect {
{ {
return new Rect(getCenterDown(), getCenterTop()); return new Rect(getCenterDown(), getCenterTop());
} }
/** /**
* Get rect center * Get rect center
* *
@ -236,8 +263,8 @@ public class Rect {
{ {
return min.midTo(max); return min.midTo(max);
} }
/** /**
* Get center of the lower edge. * Get center of the lower edge.
* *
@ -247,8 +274,8 @@ public class Rect {
{ {
return new Coord((max.x + min.x) / 2, min.y); return new Coord((max.x + min.x) / 2, min.y);
} }
/** /**
* Get center of the left edge. * Get center of the left edge.
* *
@ -258,8 +285,8 @@ public class Rect {
{ {
return new Coord(min.x, (max.y + min.y) / 2); return new Coord(min.x, (max.y + min.y) / 2);
} }
/** /**
* Get center of the right edge. * Get center of the right edge.
* *
@ -269,8 +296,8 @@ public class Rect {
{ {
return new Coord(max.x, (max.y + min.y) / 2); return new Coord(max.x, (max.y + min.y) / 2);
} }
/** /**
* Get center of the top edge. * Get center of the top edge.
* *
@ -280,8 +307,8 @@ public class Rect {
{ {
return new Coord((max.x + min.x) / 2, max.y); return new Coord((max.x + min.x) / 2, max.y);
} }
/** /**
* Get bottom edge rect * Get bottom edge rect
* *
@ -291,8 +318,8 @@ public class Rect {
{ {
return new Rect(getLeftBottom(), getRightBottom()); return new Rect(getLeftBottom(), getRightBottom());
} }
/** /**
* Get left edge rect * Get left edge rect
* *
@ -302,8 +329,8 @@ public class Rect {
{ {
return new Rect(getLeftBottom(), getLeftTop()); return new Rect(getLeftBottom(), getLeftTop());
} }
/** /**
* Get right edge rect * Get right edge rect
* *
@ -313,8 +340,8 @@ public class Rect {
{ {
return new Rect(getRightBottom(), getRightTop()); return new Rect(getRightBottom(), getRightTop());
} }
/** /**
* Get top edge rect * Get top edge rect
* *
@ -324,8 +351,8 @@ public class Rect {
{ {
return new Rect(getLeftTop(), getRightTop()); return new Rect(getLeftTop(), getRightTop());
} }
/** /**
* Get left bottom * Get left bottom
* *
@ -335,8 +362,8 @@ public class Rect {
{ {
return new Coord(min.x, min.y); return new Coord(min.x, min.y);
} }
/** /**
* Get left top * Get left top
* *
@ -346,8 +373,8 @@ public class Rect {
{ {
return new Coord(min.x, max.y); return new Coord(min.x, max.y);
} }
/** /**
* @return highest coordinates xy * @return highest coordinates xy
*/ */
@ -355,8 +382,8 @@ public class Rect {
{ {
return max; return max;
} }
/** /**
* @return lowest coordinates xy * @return lowest coordinates xy
*/ */
@ -364,8 +391,8 @@ public class Rect {
{ {
return min; return min;
} }
/** /**
* Get right bottom * Get right bottom
* *
@ -375,8 +402,8 @@ public class Rect {
{ {
return new Coord(max.x, min.y); return new Coord(max.x, min.y);
} }
/** /**
* Get right top * Get right top
* *
@ -386,8 +413,8 @@ public class Rect {
{ {
return new Coord(max.x, max.y); return new Coord(max.x, max.y);
} }
/** /**
* Get size (width, height) as (x,y) * Get size (width, height) as (x,y)
* *
@ -397,37 +424,41 @@ public class Rect {
{ {
return new Coord(Math.abs(min.x - max.x), Math.abs(min.y - max.y)); return new Coord(Math.abs(min.x - max.x), Math.abs(min.y - max.y));
} }
/** /**
* Grow to sides in copy * Grow to sides in copy
* *
* @param grow grow size (added to each side) * @param grow
* grow size (added to each side)
* @return grown copy * @return grown copy
*/ */
public Rect grow(Coord grow) public Rect grow(Coord grow)
{ {
return copy().grow_ip(grow); return copy().grow_ip(grow);
} }
/** /**
* Grow to sides in copy * Grow to sides in copy
* *
* @param x x to add * @param x
* @param y y to add * x to add
* @param y
* y to add
* @return grown copy * @return grown copy
*/ */
public Rect grow(double x, double y) public Rect grow(double x, double y)
{ {
return copy().grow_ip(x, y); return copy().grow_ip(x, y);
} }
/** /**
* Grow to sides in place * Grow to sides in place
* *
* @param grow grow size (added to each side) * @param grow
* grow size (added to each side)
* @return this * @return this
*/ */
public Rect grow_ip(Coord grow) public Rect grow_ip(Coord grow)
@ -436,13 +467,15 @@ public class Rect {
max.add_ip(grow); max.add_ip(grow);
return this; return this;
} }
/** /**
* Grow to sides in place * Grow to sides in place
* *
* @param x x to add * @param x
* @param y y to add * x to add
* @param y
* y to add
* @return this * @return this
*/ */
public Rect grow_ip(double x, double y) public Rect grow_ip(double x, double y)
@ -451,24 +484,26 @@ public class Rect {
max.add_ip(x, y); max.add_ip(x, y);
return this; return this;
} }
/** /**
* Grow down in copy * Grow down in copy
* *
* @param down added pixels * @param down
* added pixels
* @return grown copy * @return grown copy
*/ */
public Rect growDown(double down) public Rect growDown(double down)
{ {
return copy().growDown_ip(down); return copy().growDown_ip(down);
} }
/** /**
* Grow down in place * Grow down in place
* *
* @param down added pixels * @param down
* added pixels
* @return this * @return this
*/ */
public Rect growDown_ip(double down) public Rect growDown_ip(double down)
@ -476,24 +511,26 @@ public class Rect {
min.sub_ip(0, down); min.sub_ip(0, down);
return this; return this;
} }
/** /**
* Grow to left in copy * Grow to left in copy
* *
* @param left added pixels * @param left
* added pixels
* @return grown copy * @return grown copy
*/ */
public Rect growLeft(double left) public Rect growLeft(double left)
{ {
return copy().growLeft_ip(left); return copy().growLeft_ip(left);
} }
/** /**
* Grow to left in place * Grow to left in place
* *
* @param left added pixels * @param left
* added pixels
* @return this * @return this
*/ */
public Rect growLeft_ip(double left) public Rect growLeft_ip(double left)
@ -501,24 +538,26 @@ public class Rect {
min.sub_ip(left, 0); min.sub_ip(left, 0);
return this; return this;
} }
/** /**
* Grow to right in copy * Grow to right in copy
* *
* @param right added pixels * @param right
* added pixels
* @return grown copy * @return grown copy
*/ */
public Rect growRight(double right) public Rect growRight(double right)
{ {
return copy().growRight_ip(right); return copy().growRight_ip(right);
} }
/** /**
* Grow to right in place * Grow to right in place
* *
* @param right added pixels * @param right
* added pixels
* @return this * @return this
*/ */
public Rect growRight_ip(double right) public Rect growRight_ip(double right)
@ -526,24 +565,26 @@ public class Rect {
max.add_ip(right, 0); max.add_ip(right, 0);
return this; return this;
} }
/** /**
* Grow up in copy * Grow up in copy
* *
* @param add added pixels * @param add
* added pixels
* @return grown copy * @return grown copy
*/ */
public Rect growUp(double add) public Rect growUp(double add)
{ {
return copy().growUp_ip(add); return copy().growUp_ip(add);
} }
/** /**
* Grow up in place * Grow up in place
* *
* @param add added pixels * @param add
* added pixels
* @return this * @return this
*/ */
public Rect growUp_ip(double add) public Rect growUp_ip(double add)
@ -551,49 +592,54 @@ public class Rect {
max.add_ip(0, add); max.add_ip(0, add);
return this; return this;
} }
/** /**
* Check if point is inside this rectangle * Check if point is inside this rectangle
* *
* @param point point to test * @param point
* point to test
* @return is inside * @return is inside
*/ */
public boolean isInside(Coord point) public boolean isInside(Coord point)
{ {
return Calc.inRange(point.x, min.x, max.x) && Calc.inRange(point.y, min.y, max.y); return Calc.inRange(point.x, min.x, max.x) && Calc.inRange(point.y, min.y, max.y);
} }
/** /**
* Multiply in copy * Multiply in copy
* *
* @param factor multiplier * @param factor
* multiplier
* @return offset copy * @return offset copy
*/ */
public Rect mul(double factor) public Rect mul(double factor)
{ {
return copy().mul_ip(factor); return copy().mul_ip(factor);
} }
/** /**
* Multiply by number (useful for centered rects) * Multiply by number (useful for centered rects)
* *
* @param x x multiplier * @param x
* @param y y multiplier * x multiplier
* @param y
* y multiplier
* @return copy multiplied * @return copy multiplied
*/ */
public Rect mul(double x, double y) public Rect mul(double x, double y)
{ {
return copy().mul_ip(x, y); return copy().mul_ip(x, y);
} }
/** /**
* Multiply coord in place * Multiply coord in place
* *
* @param factor multiplier * @param factor
* multiplier
* @return this * @return this
*/ */
public Rect mul_ip(double factor) public Rect mul_ip(double factor)
@ -602,13 +648,15 @@ public class Rect {
max.mul_ip(factor); max.mul_ip(factor);
return this; return this;
} }
/** /**
* Multiply coord in place * Multiply coord in place
* *
* @param x multiplier x * @param x
* @param y multiplier y * multiplier x
* @param y
* multiplier y
* @return this * @return this
*/ */
public Rect mul_ip(double x, double y) public Rect mul_ip(double x, double y)
@ -617,8 +665,8 @@ public class Rect {
max.mul_ip(x, y, 1); max.mul_ip(x, y, 1);
return this; return this;
} }
/** /**
* Round coords in copy * Round coords in copy
* *
@ -628,8 +676,8 @@ public class Rect {
{ {
return new Rect(min.round(), max.round()); return new Rect(min.round(), max.round());
} }
/** /**
* Round this in place * Round this in place
* *
@ -641,26 +689,31 @@ public class Rect {
max.round_ip(); max.round_ip();
return this; return this;
} }
/** /**
* Set to [0,0,coord.x,coord.y] * Set to [0,0,coord.x,coord.y]
* *
* @param coord size coord * @param coord
* size coord
*/ */
public void setTo(Coord coord) public void setTo(Coord coord)
{ {
setTo(0, 0, coord.x, coord.y); setTo(0, 0, coord.x, coord.y);
} }
/** /**
* Set to coordinates * Set to coordinates
* *
* @param x1 lower x * @param x1
* @param y1 lower y * lower x
* @param x2 upper x * @param y1
* @param y2 upper y * lower y
* @param x2
* upper x
* @param y2
* upper y
*/ */
public void setTo(double x1, double y1, double x2, double y2) public void setTo(double x1, double y1, double x2, double y2)
{ {
@ -669,62 +722,69 @@ public class Rect {
max.x = Calc.max(x1, x2); max.x = Calc.max(x1, x2);
max.y = Calc.max(y1, y2); max.y = Calc.max(y1, y2);
} }
/** /**
* Set to other rect's coordinates * Set to other rect's coordinates
* *
* @param r other rect * @param r
* other rect
*/ */
public void setTo(Rect r) public void setTo(Rect r)
{ {
min.setTo(r.min); min.setTo(r.min);
max.setTo(r.max); max.setTo(r.max);
} }
/** /**
* Subtract X and Y from all coordinates in a copy * Subtract X and Y from all coordinates in a copy
* *
* @param x x to subtract * @param x
* @param y y to subtract * x to subtract
* @param y
* y to subtract
* @return copy changed * @return copy changed
*/ */
public Rect sub(double x, double y) public Rect sub(double x, double y)
{ {
return sub(new Coord(x, y)); return sub(new Coord(x, y));
} }
/** /**
* Get offset copy (subtract) * Get offset copy (subtract)
* *
* @param move offset vector * @param move
* offset vector
* @return offset copy * @return offset copy
*/ */
public Rect sub(Coord move) public Rect sub(Coord move)
{ {
return copy().sub_ip(move); return copy().sub_ip(move);
} }
/** /**
* Subtract X and Y from all coordinates in place * Subtract X and Y from all coordinates in place
* *
* @param x x to subtract * @param x
* @param y y to subtract * x to subtract
* @param y
* y to subtract
* @return this * @return this
*/ */
public Rect sub_ip(double x, double y) public Rect sub_ip(double x, double y)
{ {
return sub_ip(new Coord(x, y)); return sub_ip(new Coord(x, y));
} }
/** /**
* Offset in place (subtract) * Offset in place (subtract)
* *
* @param move offset vector * @param move
* offset vector
* @return this * @return this
*/ */
public Rect sub_ip(Coord move) public Rect sub_ip(Coord move)
@ -733,15 +793,15 @@ public class Rect {
max.sub_ip(move); max.sub_ip(move);
return this; return this;
} }
@Override @Override
public String toString() public String toString()
{ {
return String.format("[( %4d, %4d )-( %4d, %4d )]", (int) min.x, (int) min.y, (int) max.x, (int) max.y); return String.format("[( %4d, %4d )-( %4d, %4d )]", (int) min.x, (int) min.y, (int) max.x, (int) max.y);
} }
/** /**
* @return lower x * @return lower x
*/ */
@ -749,8 +809,8 @@ public class Rect {
{ {
return min.x; return min.x;
} }
/** /**
* @return upper x * @return upper x
*/ */
@ -758,8 +818,8 @@ public class Rect {
{ {
return max.x; return max.x;
} }
/** /**
* @return lower y * @return lower y
*/ */
@ -767,8 +827,8 @@ public class Rect {
{ {
return min.y; return min.y;
} }
/** /**
* @return upper y * @return upper y
*/ */

@ -1,106 +1,115 @@
package mightypork.utils.math.easing; package mightypork.utils.math.easing;
/** /**
* EasingFunction function. * EasingFunction function.
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class Easing { public abstract class Easing {
/** /**
* Get value at time t. * Get value at time t.
* *
* @param t time parameter (t = 1..1) * @param t
* time parameter (t = 1..1)
* @return value at given t (0..1, can exceed if needed) * @return value at given t (0..1, can exceed if needed)
*/ */
public abstract double get(double t); public abstract double get(double t);
/** /**
* Reverse an easing * Reverse an easing
* *
* @param original original easing * @param original
* original easing
* @return reversed easing * @return reversed easing
*/ */
public static Easing reverse(Easing original) public static Easing reverse(Easing original)
{ {
return new Reverse(original); return new Reverse(original);
} }
/** /**
* Combine two easings * Combine two easings
* *
* @param in initial easing * @param in
* @param out terminal easing * initial easing
* @param out
* terminal easing
* @return product * @return product
*/ */
public static Easing combine(Easing in, Easing out) public static Easing combine(Easing in, Easing out)
{ {
return new Composite(in, out); return new Composite(in, out);
} }
/** /**
* Create "bilinear" easing - compose of straight and reverse. * Create "bilinear" easing - compose of straight and reverse.
* *
* @param in initial easing * @param in
* initial easing
* @return product * @return product
*/ */
public static Easing inOut(Easing in) public static Easing inOut(Easing in)
{ {
return combine(in, reverse(in)); return combine(in, reverse(in));
} }
/** /**
* Reverse EasingFunction * Reverse EasingFunction
* *
* @author MightyPork * @author MightyPork
*/ */
private static class Reverse extends Easing { private static class Reverse extends Easing {
private Easing ea; private Easing ea;
/** /**
* @param in Easing to reverse * @param in
* Easing to reverse
*/ */
public Reverse(Easing in) { public Reverse(Easing in) {
this.ea = in; this.ea = in;
} }
@Override @Override
public double get(double t) public double get(double t)
{ {
return 1 - ea.get(1 - t); return 1 - ea.get(1 - t);
} }
} }
/** /**
* Composite EasingFunction (0-0.5 EasingFunction A, 0.5-1 EasingFunction B) * Composite EasingFunction (0-0.5 EasingFunction A, 0.5-1 EasingFunction B)
* *
* @author MightyPork * @author MightyPork
*/ */
private static class Composite extends Easing { private static class Composite extends Easing {
private Easing in; private Easing in;
private Easing out; private Easing out;
/** /**
* Create a composite EasingFunction * Create a composite EasingFunction
* *
* @param in initial EasingFunction * @param in
* @param out terminal EasingFunction * initial EasingFunction
* @param out
* terminal EasingFunction
*/ */
public Composite(Easing in, Easing out) { public Composite(Easing in, Easing out) {
this.in = in; this.in = in;
this.out = out; this.out = out;
} }
@Override @Override
public double get(double t) public double get(double t)
{ {
@ -108,172 +117,172 @@ public abstract class Easing {
return 0.5 + out.get(2 * t - 1) * 0.5; return 0.5 + out.get(2 * t - 1) * 0.5;
} }
} }
/** No easing; At t=0.5 goes high. */ /** No easing; At t=0.5 goes high. */
public static final Easing NONE = new Easing() { public static final Easing NONE = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return (t < 0.5 ? 0 : 1); return (t < 0.5 ? 0 : 1);
} }
}; };
/** Linear (y=t) easing */ /** Linear (y=t) easing */
public static final Easing LINEAR = new Easing() { public static final Easing LINEAR = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return t; return t;
} }
}; };
/** Quadratic (y=t^2) easing in */ /** Quadratic (y=t^2) easing in */
public static final Easing QUADRATIC_IN = new Easing() { public static final Easing QUADRATIC_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return t * t; return t * t;
} }
}; };
/** Quadratic (y=t^2) easing out */ /** Quadratic (y=t^2) easing out */
public static final Easing QUADRATIC_OUT = reverse(QUADRATIC_IN); public static final Easing QUADRATIC_OUT = reverse(QUADRATIC_IN);
/** Quadratic (y=t^2) easing both */ /** Quadratic (y=t^2) easing both */
public static final Easing QUADRATIC_IN_OUT = inOut(QUADRATIC_IN); public static final Easing QUADRATIC_IN_OUT = inOut(QUADRATIC_IN);
/** Cubic (y=t^3) easing in */ /** Cubic (y=t^3) easing in */
public static final Easing CUBIC_IN = new Easing() { public static final Easing CUBIC_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return t * t * t; return t * t * t;
} }
}; };
/** Cubic (y=t^3) easing out */ /** Cubic (y=t^3) easing out */
public static final Easing CUBIC_OUT = reverse(CUBIC_IN); public static final Easing CUBIC_OUT = reverse(CUBIC_IN);
/** Cubic (y=t^3) easing both */ /** Cubic (y=t^3) easing both */
public static final Easing CUBIC_IN_OUT = inOut(CUBIC_IN); public static final Easing CUBIC_IN_OUT = inOut(CUBIC_IN);
/** Quartic (y=t^4) easing in */ /** Quartic (y=t^4) easing in */
public static final Easing QUARTIC_IN = new Easing() { public static final Easing QUARTIC_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return t * t * t * t; return t * t * t * t;
} }
}; };
/** Quartic (y=t^4) easing out */ /** Quartic (y=t^4) easing out */
public static final Easing QUARTIC_OUT = reverse(QUADRATIC_IN); public static final Easing QUARTIC_OUT = reverse(QUADRATIC_IN);
/** Quartic (y=t^4) easing both */ /** Quartic (y=t^4) easing both */
public static final Easing QUARTIC_IN_OUT = inOut(QUADRATIC_IN); public static final Easing QUARTIC_IN_OUT = inOut(QUADRATIC_IN);
/** Quintic (y=t^5) easing in */ /** Quintic (y=t^5) easing in */
public static final Easing QUINTIC_IN = new Easing() { public static final Easing QUINTIC_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return t * t * t * t * t; return t * t * t * t * t;
} }
}; };
/** Quintic (y=t^5) easing out */ /** Quintic (y=t^5) easing out */
public static final Easing QUINTIC_OUT = reverse(QUINTIC_IN); public static final Easing QUINTIC_OUT = reverse(QUINTIC_IN);
/** Quintic (y=t^5) easing both */ /** Quintic (y=t^5) easing both */
public static final Easing QUINTIC_IN_OUT = inOut(QUINTIC_IN); public static final Easing QUINTIC_IN_OUT = inOut(QUINTIC_IN);
/** Sine easing in */ /** Sine easing in */
public static final Easing SINE_IN = new Easing() { public static final Easing SINE_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return 1 - Math.cos(t * (Math.PI / 2)); return 1 - Math.cos(t * (Math.PI / 2));
} }
}; };
/** Sine easing out */ /** Sine easing out */
public static final Easing SINE_OUT = reverse(SINE_IN); public static final Easing SINE_OUT = reverse(SINE_IN);
/** Sine easing both */ /** Sine easing both */
public static final Easing SINE_IN_OUT = inOut(SINE_IN); public static final Easing SINE_IN_OUT = inOut(SINE_IN);
/** Exponential easing in */ /** Exponential easing in */
public static final Easing EXPO_IN = new Easing() { public static final Easing EXPO_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return Math.pow(2, 10 * (t - 1)); return Math.pow(2, 10 * (t - 1));
} }
}; };
/** Exponential easing out */ /** Exponential easing out */
public static final Easing EXPO_OUT = reverse(EXPO_IN); public static final Easing EXPO_OUT = reverse(EXPO_IN);
/** Exponential easing both */ /** Exponential easing both */
public static final Easing EXPO_IN_OUT = inOut(EXPO_IN); public static final Easing EXPO_IN_OUT = inOut(EXPO_IN);
/** Circular easing in */ /** Circular easing in */
public static final Easing CIRC_IN = new Easing() { public static final Easing CIRC_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
return 1 - Math.sqrt(1 - t * t); return 1 - Math.sqrt(1 - t * t);
} }
}; };
/** Circular easing out */ /** Circular easing out */
public static final Easing CIRC_OUT = reverse(CIRC_IN); public static final Easing CIRC_OUT = reverse(CIRC_IN);
/** Circular easing both */ /** Circular easing both */
public static final Easing CIRC_IN_OUT = inOut(CIRC_IN); public static final Easing CIRC_IN_OUT = inOut(CIRC_IN);
/** Bounce easing in */ /** Bounce easing in */
public static final Easing BOUNCE_OUT = new Easing() { public static final Easing BOUNCE_OUT = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
if (t < (1 / 2.75f)) { if (t < (1 / 2.75f)) {
return (7.5625f * t * t); return (7.5625f * t * t);
} else if (t < (2 / 2.75f)) { } else if (t < (2 / 2.75f)) {
t -= (1.5f / 2.75f); t -= (1.5f / 2.75f);
return (7.5625f * t * t + 0.75f); return (7.5625f * t * t + 0.75f);
} else if (t < (2.5 / 2.75)) { } else if (t < (2.5 / 2.75)) {
t -= (2.25f / 2.75f); t -= (2.25f / 2.75f);
return (7.5625f * t * t + 0.9375f); return (7.5625f * t * t + 0.9375f);
} else { } else {
t -= (2.625f / 2.75f); t -= (2.625f / 2.75f);
return (7.5625f * t * t + 0.984375f); return (7.5625f * t * t + 0.984375f);
} }
} }
}; };
/** Bounce easing out */ /** Bounce easing out */
public static final Easing BOUNCE_IN = reverse(BOUNCE_OUT); public static final Easing BOUNCE_IN = reverse(BOUNCE_OUT);
/** Bounce easing both */ /** Bounce easing both */
public static final Easing BOUNCE_IN_OUT = inOut(BOUNCE_IN); public static final Easing BOUNCE_IN_OUT = inOut(BOUNCE_IN);
/** Back easing in */ /** Back easing in */
public static final Easing BACK_IN = new Easing() { public static final Easing BACK_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
@ -281,31 +290,31 @@ public abstract class Easing {
return t * t * ((s + 1) * t - s); return t * t * ((s + 1) * t - s);
} }
}; };
/** Back easing out */ /** Back easing out */
public static final Easing BACK_OUT = reverse(BACK_IN); public static final Easing BACK_OUT = reverse(BACK_IN);
/** Back easing both */ /** Back easing both */
public static final Easing BACK_IN_OUT = inOut(BACK_IN); public static final Easing BACK_IN_OUT = inOut(BACK_IN);
/** Elastic easing in */ /** Elastic easing in */
public static final Easing ELASTIC_IN = new Easing() { public static final Easing ELASTIC_IN = new Easing() {
@Override @Override
public double get(double t) public double get(double t)
{ {
if (t == 0) return 0; if (t == 0) return 0;
if (t == 1) return 1; if (t == 1) return 1;
double p = .3f; double p = .3f;
double s = p / 4; double s = p / 4;
return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
} }
}; };
/** Elastic easing out */ /** Elastic easing out */
public static final Easing ELASTIC_OUT = reverse(ELASTIC_IN); public static final Easing ELASTIC_OUT = reverse(ELASTIC_IN);
/** Elastic easing both */ /** Elastic easing both */
public static final Easing ELASTIC_IN_OUT = inOut(ELASTIC_IN); public static final Easing ELASTIC_IN_OUT = inOut(ELASTIC_IN);
} }

@ -1,6 +1,5 @@
package mightypork.utils.objects; package mightypork.utils.objects;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
import mightypork.utils.math.Range; import mightypork.utils.math.Range;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
@ -13,12 +12,14 @@ import mightypork.utils.math.coord.Coord;
* @author MightyPork * @author MightyPork
*/ */
public class Convertor { public class Convertor {
/** /**
* Get INTEGER * Get INTEGER
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return integer * @return integer
*/ */
public static int getInteger(Object o, Integer def) public static int getInteger(Object o, Integer def)
@ -29,17 +30,20 @@ public class Convertor {
if (o instanceof Number) return ((Number) o).intValue(); if (o instanceof Number) return ((Number) o).intValue();
if (o instanceof Range) return ((Range) o).randInt(); if (o instanceof Range) return ((Range) o).randInt();
if (o instanceof Boolean) return ((Boolean) o) ? 1 : 0; if (o instanceof Boolean) return ((Boolean) o) ? 1 : 0;
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {
}
Log.w("Cannot convert " + o + " to Integer."); Log.w("Cannot convert " + o + " to Integer.");
return def; return def;
} }
/** /**
* Get DOUBLE * Get DOUBLE
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return double * @return double
*/ */
public static double getDouble(Object o, Double def) public static double getDouble(Object o, Double def)
@ -50,17 +54,20 @@ public class Convertor {
if (o instanceof Number) return ((Number) o).doubleValue(); if (o instanceof Number) return ((Number) o).doubleValue();
if (o instanceof Range) return ((Range) o).randDouble(); if (o instanceof Range) return ((Range) o).randDouble();
if (o instanceof Boolean) return ((Boolean) o) ? 1 : 0; if (o instanceof Boolean) return ((Boolean) o) ? 1 : 0;
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {
}
Log.w("Cannot convert " + o + " to Double."); Log.w("Cannot convert " + o + " to Double.");
return def; return def;
} }
/** /**
* Get FLOAT * Get FLOAT
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return float * @return float
*/ */
public static double getFloat(Object o, Float def) public static double getFloat(Object o, Float def)
@ -68,23 +75,26 @@ public class Convertor {
try { try {
if (o == null) return def; if (o == null) return def;
if (o instanceof Number) return ((Number) o).floatValue(); if (o instanceof Number) return ((Number) o).floatValue();
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {
}
Log.w("Cannot convert " + o + " to Float."); Log.w("Cannot convert " + o + " to Float.");
return def; return def;
} }
/** /**
* Get BOOLEAN * Get BOOLEAN
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return boolean * @return boolean
*/ */
public static boolean getBoolean(Object o, Boolean def) public static boolean getBoolean(Object o, Boolean def)
{ {
if (o == null) return def; if (o == null) return def;
if (o instanceof String) { if (o instanceof String) {
String s = ((String) o).trim().toLowerCase(); String s = ((String) o).trim().toLowerCase();
if (s.equals("0")) return false; if (s.equals("0")) return false;
@ -92,31 +102,34 @@ public class Convertor {
try { try {
double n = Double.parseDouble(s); double n = Double.parseDouble(s);
return n != 0; return n != 0;
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {
}
if (s.equals("true")) return true; if (s.equals("true")) return true;
if (s.equals("yes")) return true; if (s.equals("yes")) return true;
if (s.equals("y")) return true; if (s.equals("y")) return true;
if (s.equals("enabled")) return true; if (s.equals("enabled")) return true;
if (s.equals("false")) return false; if (s.equals("false")) return false;
if (s.equals("no")) return false; if (s.equals("no")) return false;
if (s.equals("n")) return false; if (s.equals("n")) return false;
if (s.equals("disabled")) return true; if (s.equals("disabled")) return true;
} }
if (o instanceof Boolean) return ((Boolean) o).booleanValue(); if (o instanceof Boolean) return ((Boolean) o).booleanValue();
if (o instanceof Number) return ((Number) o).intValue() != 0; if (o instanceof Number) return ((Number) o).intValue() != 0;
Log.w("Cannot convert " + o + " to Boolean."); Log.w("Cannot convert " + o + " to Boolean.");
return def; return def;
} }
/** /**
* Get STRING * Get STRING
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return String * @return String
*/ */
public static String getString(Object o, String def) public static String getString(Object o, String def)
@ -126,14 +139,16 @@ public class Convertor {
Log.w("Cannot convert " + o + " to String."); Log.w("Cannot convert " + o + " to String.");
return o.toString(); return o.toString();
} }
/** /**
* Get AI_COORD<br> * Get AI_COORD<br>
* Converts special constants to magic coordinate instances. * Converts special constants to magic coordinate instances.
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return AiCoord * @return AiCoord
*/ */
public static Coord getCoord(Object o, Coord def) public static Coord getCoord(Object o, Coord def)
@ -142,7 +157,7 @@ public class Convertor {
if (o == null) return def; if (o == null) return def;
if (o instanceof String) { if (o instanceof String) {
String s = ((String) o).trim().toUpperCase(); String s = ((String) o).trim().toUpperCase();
// colon to semicolon // colon to semicolon
s = s.replace(':', ';'); s = s.replace(':', ';');
// comma to semicolon // comma to semicolon
@ -159,13 +174,15 @@ public class Convertor {
Log.w("Cannot convert " + o + " to Coord."); Log.w("Cannot convert " + o + " to Coord.");
return def; return def;
} }
/** /**
* Get RANGE * Get RANGE
* *
* @param o object * @param o
* @param def default value * object
* @param def
* default value
* @return AiCoord * @return AiCoord
*/ */
public static Range getRange(Object o, Range def) public static Range getRange(Object o, Range def)
@ -175,7 +192,7 @@ public class Convertor {
if (o instanceof Number) return new Range(((Number) o).doubleValue(), ((Number) o).doubleValue()); if (o instanceof Number) return new Range(((Number) o).doubleValue(), ((Number) o).doubleValue());
if (o instanceof String) { if (o instanceof String) {
String s = ((String) o).trim(); String s = ((String) o).trim();
// colon to semicolon // colon to semicolon
s = s.replace(',', ':'); s = s.replace(',', ':');
// comma to dot. // comma to dot.
@ -187,97 +204,105 @@ public class Convertor {
String[] parts = s.split("[:]"); String[] parts = s.split("[:]");
if (parts.length == 2) return new Range(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())); if (parts.length == 2) return new Range(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim()));
return new Range(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[0].trim())); return new Range(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[0].trim()));
} }
if (o instanceof Range) return (Range) o; if (o instanceof Range) return (Range) o;
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {
}
Log.w("Cannot convert " + o + " to Range."); Log.w("Cannot convert " + o + " to Range.");
return def; return def;
} }
/** /**
* Get INTEGER * Get INTEGER
* *
* @param o object * @param o
* object
* @return integer * @return integer
*/ */
public static int getInteger(Object o) public static int getInteger(Object o)
{ {
return getInteger(o, 0); return getInteger(o, 0);
} }
/** /**
* Get DOUBLE * Get DOUBLE
* *
* @param o object * @param o
* object
* @return double * @return double
*/ */
public static double getDouble(Object o) public static double getDouble(Object o)
{ {
return getDouble(o, 0d); return getDouble(o, 0d);
} }
/** /**
* Get FLOAT * Get FLOAT
* *
* @param o object * @param o
* object
* @return float * @return float
*/ */
public static double getFloat(Object o) public static double getFloat(Object o)
{ {
return getFloat(o, 0f); return getFloat(o, 0f);
} }
/** /**
* Get BOOLEAN * Get BOOLEAN
* *
* @param o object * @param o
* object
* @return boolean * @return boolean
*/ */
public static boolean getBoolean(Object o) public static boolean getBoolean(Object o)
{ {
return getBoolean(o, false); return getBoolean(o, false);
} }
/** /**
* Get STRING * Get STRING
* *
* @param o object * @param o
* object
* @return String * @return String
*/ */
public static String getString(Object o) public static String getString(Object o)
{ {
return getString(o, ""); return getString(o, "");
} }
/** /**
* Get AI_COORD (if special string constant is present instead, build coord * Get AI_COORD (if special string constant is present instead, build coord
* of it) * of it)
* *
* @param o object * @param o
* object
* @return AiCoord * @return AiCoord
*/ */
public static Coord getCoord(Object o) public static Coord getCoord(Object o)
{ {
return getCoord(o, Coord.zero()); return getCoord(o, Coord.zero());
} }
/** /**
* Get RANGE * Get RANGE
* *
* @param o object * @param o
* object
* @return AiCoord * @return AiCoord
*/ */
public static Range getRange(Object o) public static Range getRange(Object o)
{ {
return getRange(o, new Range()); return getRange(o, new Range());
} }
} }

@ -1,28 +1,29 @@
package mightypork.utils.objects; package mightypork.utils.objects;
/** /**
* Mutable object * Mutable object
* *
* @author MightyPork * @author MightyPork
* @param <T> type * @param <T>
* type
*/ */
public class Mutable<T> { public class Mutable<T> {
/** The wrapped value */ /** The wrapped value */
private T o = null; private T o = null;
/** /**
* New mutable object * New mutable object
* *
* @param o value * @param o
* value
*/ */
public Mutable(T o) { public Mutable(T o) {
this.o = o; this.o = o;
} }
/** /**
* Get the wrapped value * Get the wrapped value
* *
@ -32,19 +33,20 @@ public class Mutable<T> {
{ {
return o; return o;
} }
/** /**
* Set value * Set value
* *
* @param o new value to set * @param o
* new value to set
*/ */
public void set(T o) public void set(T o)
{ {
this.o = o; this.o = o;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
@ -53,15 +55,15 @@ public class Mutable<T> {
result = prime * result + ((o == null) ? 0 : o.hashCode()); result = prime * result + ((o == null) ? 0 : o.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
if (this == obj) return true; if (this == obj) return true;
if (obj == null) return false; if (obj == null) return false;
if (!(obj instanceof Mutable)) return false; if (!(obj instanceof Mutable)) return false;
Mutable<?> other = (Mutable<?>) obj; Mutable<?> other = (Mutable<?>) obj;
if (o == null) { if (o == null) {
if (other.o != null) return false; if (other.o != null) return false;
@ -70,8 +72,8 @@ public class Mutable<T> {
} }
return true; return true;
} }
@Override @Override
public String toString() public String toString()
{ {

@ -1,6 +1,5 @@
package mightypork.utils.objects; package mightypork.utils.objects;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -11,7 +10,7 @@ import java.util.Map.Entry;
* @author MightyPork * @author MightyPork
*/ */
public class ObjectUtils { public class ObjectUtils {
public static Object fallback(Object... options) public static Object fallback(Object... options)
{ {
for (Object o : options) { for (Object o : options) {
@ -19,51 +18,56 @@ public class ObjectUtils {
} }
return null; // error return null; // error
} }
/** /**
* Sort a map by keys, maintaining key-value pairs. * Sort a map by keys, maintaining key-value pairs.
* *
* @param map map to be sorted * @param map
* @param comparator a comparator, or null for natural ordering * map to be sorted
* @param comparator
* a comparator, or null for natural ordering
* @return linked hash map with sorted entries * @return linked hash map with sorted entries
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public static <K extends Comparable, V extends Comparable> Map<K, V> sortByKeys(Map<K, V> map, final Comparator<K> comparator) public static <K extends Comparable, V extends Comparable> Map<K, V> sortByKeys(Map<K, V> map, final Comparator<K> comparator)
{ {
List<K> keys = new LinkedList<K>(map.keySet()); List<K> keys = new LinkedList<K>(map.keySet());
if (comparator == null) { if (comparator == null) {
Collections.sort(keys); Collections.sort(keys);
} else { } else {
Collections.sort(keys, comparator); Collections.sort(keys, comparator);
} }
// LinkedHashMap will keep the keys in the order they are inserted // LinkedHashMap will keep the keys in the order they are inserted
// which is currently sorted on natural ordering // which is currently sorted on natural ordering
Map<K, V> sortedMap = new LinkedHashMap<K, V>(); Map<K, V> sortedMap = new LinkedHashMap<K, V>();
for (K key : keys) { for (K key : keys) {
sortedMap.put(key, map.get(key)); sortedMap.put(key, map.get(key));
} }
return sortedMap; return sortedMap;
} }
/** /**
* Sort a map by values, maintaining key-value pairs. * Sort a map by values, maintaining key-value pairs.
* *
* @param map map to be sorted * @param map
* @param comparator a comparator, or null for natural ordering * map to be sorted
* @param comparator
* a comparator, or null for natural ordering
* @return linked hash map with sorted entries * @return linked hash map with sorted entries
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static <K extends Comparable, V extends Comparable> Map<K, V> sortByValues(Map<K, V> map, final Comparator<V> comparator) public static <K extends Comparable, V extends Comparable> Map<K, V> sortByValues(Map<K, V> map, final Comparator<V> comparator)
{ {
List<Map.Entry<K, V>> entries = new LinkedList<Map.Entry<K, V>>(map.entrySet()); List<Map.Entry<K, V>> entries = new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K, V>>() { Collections.sort(entries, new Comparator<Map.Entry<K, V>>() {
@SuppressWarnings("unchecked")
@Override @Override
public int compare(Entry<K, V> o1, Entry<K, V> o2) public int compare(Entry<K, V> o1, Entry<K, V> o2)
{ {
@ -71,23 +75,23 @@ public class ObjectUtils {
return comparator.compare(o1.getValue(), o2.getValue()); return comparator.compare(o1.getValue(), o2.getValue());
} }
}); });
// LinkedHashMap will keep the keys in the order they are inserted // LinkedHashMap will keep the keys in the order they are inserted
// which is currently sorted on natural ordering // which is currently sorted on natural ordering
Map<K, V> sortedMap = new LinkedHashMap<K, V>(); Map<K, V> sortedMap = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : entries) { for (Map.Entry<K, V> entry : entries) {
sortedMap.put(entry.getKey(), entry.getValue()); sortedMap.put(entry.getKey(), entry.getValue());
} }
return sortedMap; return sortedMap;
} }
public static String arrayToString(Object[] arr) public static String arrayToString(Object[] arr)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append('['); sb.append('[');
boolean first = true; boolean first = true;
for (Object o : arr) { for (Object o : arr) {
@ -95,11 +99,11 @@ public class ObjectUtils {
sb.append(o.toString()); sb.append(o.toString());
} }
sb.append(']'); sb.append(']');
return sb.toString(); return sb.toString();
} }
public static <T extends Object> List<T> arrayToList(T[] objs) public static <T extends Object> List<T> arrayToList(T[] objs)
{ {
ArrayList<T> list = new ArrayList<T>(); ArrayList<T> list = new ArrayList<T>();

@ -1,6 +1,5 @@
package mightypork.utils.objects; package mightypork.utils.objects;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
@ -9,34 +8,38 @@ import mightypork.utils.math.Calc;
* *
* @author MightyPork * @author MightyPork
* @copy (c) 2012 * @copy (c) 2012
* @param <T1> 1st object class * @param <T1>
* @param <T2> 2nd object class * 1st object class
* @param <T2>
* 2nd object class
*/ */
public class Pair<T1, T2> { public class Pair<T1, T2> {
/** /**
* 1st object * 1st object
*/ */
public T1 first; public T1 first;
/** /**
* 2nd object * 2nd object
*/ */
public T2 second; public T2 second;
/** /**
* Make structure of 2 objects * Make structure of 2 objects
* *
* @param first 1st object * @param first
* @param second 2nd object * 1st object
* @param second
* 2nd object
*/ */
public Pair(T1 first, T2 second) { public Pair(T1 first, T2 second) {
this.first = first; this.first = first;
this.second = second; this.second = second;
} }
/** /**
* @return 1st object * @return 1st object
*/ */
@ -44,8 +47,8 @@ public class Pair<T1, T2> {
{ {
return first; return first;
} }
/** /**
* @return 2nd object * @return 2nd object
*/ */
@ -53,26 +56,26 @@ public class Pair<T1, T2> {
{ {
return second; return second;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
if (obj == null) { if (obj == null) {
return false; return false;
} }
if (!this.getClass().equals(obj.getClass())) { if (!this.getClass().equals(obj.getClass())) {
return false; return false;
} }
Pair<?, ?> t = (Pair<?, ?>) obj; Pair<?, ?> t = (Pair<?, ?>) obj;
return Calc.areObjectsEqual(first, t.first) && Calc.areObjectsEqual(second, t.second); return Calc.areObjectsEqual(first, t.first) && Calc.areObjectsEqual(second, t.second);
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
@ -81,12 +84,12 @@ public class Pair<T1, T2> {
hash += (second == null ? 0 : second.hashCode()); hash += (second == null ? 0 : second.hashCode());
return hash; return hash;
} }
@Override @Override
public String toString() public String toString()
{ {
return "PAIR{" + first + "," + second + "}"; return "PAIR{" + first + "," + second + "}";
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.objects; package mightypork.utils.objects;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
@ -9,31 +8,37 @@ import mightypork.utils.math.Calc;
* *
* @author MightyPork * @author MightyPork
* @copy (c) 2012 * @copy (c) 2012
* @param <T1> 1st object class * @param <T1>
* @param <T2> 2nd object class * 1st object class
* @param <T3> 3rd object class * @param <T2>
* 2nd object class
* @param <T3>
* 3rd object class
*/ */
public class Triad<T1, T2, T3> extends Pair<T1, T2> { public class Triad<T1, T2, T3> extends Pair<T1, T2> {
/** /**
* 3rd object * 3rd object
*/ */
public T3 third; public T3 third;
/** /**
* Make structure of 3 objects * Make structure of 3 objects
* *
* @param objA 1st object * @param objA
* @param objB 2nd object * 1st object
* @param objC 3rd object * @param objB
* 2nd object
* @param objC
* 3rd object
*/ */
public Triad(T1 objA, T2 objB, T3 objC) { public Triad(T1 objA, T2 objB, T3 objC) {
super(objA, objB); super(objA, objB);
third = objC; third = objC;
} }
/** /**
* @return 3rd object * @return 3rd object
*/ */
@ -41,40 +46,41 @@ public class Triad<T1, T2, T3> extends Pair<T1, T2> {
{ {
return third; return third;
} }
/** /**
* Set 1st object * Set 1st object
* *
* @param obj 1st object * @param obj
* 1st object
*/ */
public void setThird(T3 obj) public void setThird(T3 obj)
{ {
third = obj; third = obj;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
if (!super.equals(obj)) return false; if (!super.equals(obj)) return false;
return Calc.areObjectsEqual(third, ((Triad<?, ?, ?>) obj).third); return Calc.areObjectsEqual(third, ((Triad<?, ?, ?>) obj).third);
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return super.hashCode() + (third == null ? 0 : third.hashCode()); return super.hashCode() + (third == null ? 0 : third.hashCode());
} }
@Override @Override
public String toString() public String toString()
{ {
return "TRIAD{" + first + "," + second + "," + third + "}"; return "TRIAD{" + first + "," + second + "," + third + "}";
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.objects; package mightypork.utils.objects;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@ -26,28 +25,33 @@ import java.util.Map;
* </pre> * </pre>
* *
* @author MightyPork * @author MightyPork
* @param <K> Type for Map keys * @param <K>
* @param <V> Type for Map values * Type for Map keys
* @param <V>
* Type for Map values
*/ */
public class VarargsParser<K, V> { public class VarargsParser<K, V> {
/** /**
* Parse array of vararg key, value pairs to a LinkedHashMap. * Parse array of vararg key, value pairs to a LinkedHashMap.
* *
* @param args varargs * @param args
* varargs
* @return LinkedHashMap * @return LinkedHashMap
* @throws ClassCastException in case of incompatible type in the array * @throws ClassCastException
* @throws IllegalArgumentException in case of invalid array length (odd) * in case of incompatible type in the array
* @throws IllegalArgumentException
* in case of invalid array length (odd)
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Map<K, V> parse(Object... args) throws ClassCastException, IllegalArgumentException public Map<K, V> parse(Object... args) throws ClassCastException, IllegalArgumentException
{ {
LinkedHashMap<K, V> attrs = new LinkedHashMap<K, V>(); LinkedHashMap<K, V> attrs = new LinkedHashMap<K, V>();
if (args.length % 2 != 0) { if (args.length % 2 != 0) {
throw new IllegalArgumentException("Odd number of elements in varargs map!"); throw new IllegalArgumentException("Odd number of elements in varargs map!");
} }
K key = null; K key = null;
for (Object o : args) { for (Object o : args) {
if (key == null) { if (key == null) {
@ -58,7 +62,7 @@ public class VarargsParser<K, V> {
key = null; key = null;
} }
} }
return attrs; return attrs;
} }
} }

@ -1,13 +1,12 @@
package mightypork.utils.patterns; package mightypork.utils.patterns;
/** /**
* Object that can be destroyed (free resources etc) * Object that can be destroyed (free resources etc)
* *
* @author MightyPork * @author MightyPork
*/ */
public interface Destroyable { public interface Destroyable {
/** /**
* Destroy this object * Destroy this object
*/ */

@ -1,18 +1,19 @@
package mightypork.utils.patterns.subscription; package mightypork.utils.patterns.subscription;
/** /**
* Something that can be handled by HANDLER. * Something that can be handled by HANDLER.
* *
* @author MightyPork * @author MightyPork
* @param <HANDLER> handler type * @param <HANDLER>
* handler type
*/ */
public interface Handleable<HANDLER> { public interface Handleable<HANDLER> {
/** /**
* Ask handler to handle this message. * Ask handler to handle this message.
* *
* @param handler handler instance * @param handler
* handler instance
*/ */
public void handleBy(HANDLER handler); public void handleBy(HANDLER handler);
} }

@ -1,6 +1,5 @@
package mightypork.utils.patterns.subscription; package mightypork.utils.patterns.subscription;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -13,19 +12,20 @@ import mightypork.utils.logging.Log;
* @author MightyPork * @author MightyPork
*/ */
final public class MessageBus { final public class MessageBus {
private Collection<MessageChannel<?, ?>> channels = new LinkedHashSet<MessageChannel<?, ?>>(); private Collection<MessageChannel<?, ?>> channels = new LinkedHashSet<MessageChannel<?, ?>>();
private Collection<Object> clients = new LinkedHashSet<Object>(); private Collection<Object> clients = new LinkedHashSet<Object>();
private boolean warn_unsent = true; private boolean warn_unsent = true;
/** /**
* Add a {@link MessageChannel} to this bus.<br> * Add a {@link MessageChannel} to this bus.<br>
* If a channel of matching types is already added, it is returned instead. * If a channel of matching types is already added, it is returned instead.
* *
* @param channel channel to be added * @param channel
* channel to be added
* @return the channel that's now in the bus * @return the channel that's now in the bus
*/ */
public MessageChannel<?, ?> addChannel(MessageChannel<?, ?> channel) public MessageChannel<?, ?> addChannel(MessageChannel<?, ?> channel)
@ -37,72 +37,76 @@ final public class MessageBus {
return ch; return ch;
} }
} }
channels.add(channel); channels.add(channel);
return channel; return channel;
} }
/** /**
* Remove a {@link MessageChannel} from this bus * Remove a {@link MessageChannel} from this bus
* *
* @param channel true if channel was removed * @param channel
* true if channel was removed
*/ */
public void removeChannel(MessageChannel<?, ?> channel) public void removeChannel(MessageChannel<?, ?> channel)
{ {
channels.remove(channel); channels.remove(channel);
} }
/** /**
* Broadcast a message * Broadcast a message
* *
* @param message message * @param message
* message
* @return true if message was accepted by at least one channel * @return true if message was accepted by at least one channel
*/ */
public boolean broadcast(Object message) public boolean broadcast(Object message)
{ {
boolean sent = false; boolean sent = false;
for (MessageChannel<?, ?> b : channels) { for (MessageChannel<?, ?> b : channels) {
sent |= b.broadcast(message, clients); sent |= b.broadcast(message, clients);
} }
if (!sent && warn_unsent) Log.w("Message not accepted by any channel: " + message); if (!sent && warn_unsent) Log.w("Message not accepted by any channel: " + message);
return sent; return sent;
} }
/** /**
* Connect a client to the bus. The client will be connected to all current * Connect a client to the bus. The client will be connected to all current
* and future channels, until removed from the bus. * and future channels, until removed from the bus.
* *
* @param client the client * @param client
* the client
* @return true on success * @return true on success
*/ */
public boolean subscribe(Object client) public boolean subscribe(Object client)
{ {
if (client == null) return false; if (client == null) return false;
clients.add(client); clients.add(client);
return true; return true;
} }
/** /**
* Disconnect a client from the bus. * Disconnect a client from the bus.
* *
* @param client the client * @param client
* the client
*/ */
public void unsubscribe(Object client) public void unsubscribe(Object client)
{ {
clients.remove(client); clients.remove(client);
} }
/** /**
* Enable logging of unsent messages * Enable logging of unsent messages
* *
@ -112,13 +116,15 @@ final public class MessageBus {
{ {
this.warn_unsent = enable; this.warn_unsent = enable;
} }
/** /**
* Add a channel for given message and client type. * Add a channel for given message and client type.
* *
* @param messageClass message type * @param messageClass
* @param clientClass client type * message type
* @param clientClass
* client type
* @return the created channel instance * @return the created channel instance
*/ */
public <F_MESSAGE extends Handleable<F_CLIENT>, F_CLIENT> MessageChannel<?, ?> createChannel(Class<F_MESSAGE> messageClass, Class<F_CLIENT> clientClass) public <F_MESSAGE extends Handleable<F_CLIENT>, F_CLIENT> MessageChannel<?, ?> createChannel(Class<F_MESSAGE> messageClass, Class<F_CLIENT> clientClass)
@ -126,5 +132,5 @@ final public class MessageBus {
MessageChannel<F_MESSAGE, F_CLIENT> bc = new MessageChannel<F_MESSAGE, F_CLIENT>(messageClass, clientClass); MessageChannel<F_MESSAGE, F_CLIENT> bc = new MessageChannel<F_MESSAGE, F_CLIENT>(messageClass, clientClass);
return addChannel(bc); return addChannel(bc);
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.patterns.subscription; package mightypork.utils.patterns.subscription;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@ -13,64 +12,68 @@ import mightypork.utils.patterns.subscription.clients.ToggleableClient;
* Message channel, module of {@link MessageBus} * Message channel, module of {@link MessageBus}
* *
* @author MightyPork * @author MightyPork
* @param <MESSAGE> message type * @param <MESSAGE>
* @param <CLIENT> client (subscriber) type * message type
* @param <CLIENT>
* client (subscriber) type
*/ */
final public class MessageChannel<MESSAGE extends Handleable<CLIENT>, CLIENT> { final public class MessageChannel<MESSAGE extends Handleable<CLIENT>, CLIENT> {
private Class<CLIENT> clientClass; private Class<CLIENT> clientClass;
private Class<MESSAGE> messageClass; private Class<MESSAGE> messageClass;
public MessageChannel(Class<MESSAGE> messageClass, Class<CLIENT> clientClass) { public MessageChannel(Class<MESSAGE> messageClass, Class<CLIENT> clientClass) {
if (messageClass == null || clientClass == null) throw new NullPointerException("Null Message or Client class."); if (messageClass == null || clientClass == null) throw new NullPointerException("Null Message or Client class.");
this.clientClass = clientClass; this.clientClass = clientClass;
this.messageClass = messageClass; this.messageClass = messageClass;
} }
/** /**
* Try to broadcast a message.<br> * Try to broadcast a message.<br>
* If message is of wrong type, <code>false</code> is returned. * If message is of wrong type, <code>false</code> is returned.
* *
* @param message a message to be sent * @param message
* @param clients collection of clients * a message to be sent
* @param clients
* collection of clients
* @return true if message was accepted by this channel * @return true if message was accepted by this channel
*/ */
public boolean broadcast(Object message, Collection<Object> clients) public boolean broadcast(Object message, Collection<Object> clients)
{ {
if (!canBroadcast(message)) return false; if (!canBroadcast(message)) return false;
MESSAGE evt = messageClass.cast(message); MESSAGE evt = messageClass.cast(message);
doBroadcast(evt, clients, new HashSet<Object>()); doBroadcast(evt, clients, new HashSet<Object>());
return true; return true;
} }
private void doBroadcast(MESSAGE message, Collection<Object> clients, Collection<Object> processed) private void doBroadcast(MESSAGE message, Collection<Object> clients, Collection<Object> processed)
{ {
for (Object client : clients) { for (Object client : clients) {
// circular reference check // circular reference check
if (processed.contains(client)) { if (processed.contains(client)) {
Log.w("Client already served (subscribing twice?)"); Log.w("Client already served (subscribing twice?)");
continue; continue;
} }
processed.add(client); processed.add(client);
// opt-out // opt-out
if (client instanceof ToggleableClient) { if (client instanceof ToggleableClient) {
if (!((ToggleableClient) client).doesSubscribe()) { if (!((ToggleableClient) client).doesSubscribe()) {
continue; continue;
} }
} }
sendTo(client, message); sendTo(client, message);
if (client instanceof DelegatingClient) { if (client instanceof DelegatingClient) {
if (((DelegatingClient) client).doesDelegate()) { if (((DelegatingClient) client).doesDelegate()) {
doBroadcast(message, ((DelegatingClient) client).getChildClients(), processed); doBroadcast(message, ((DelegatingClient) client).getChildClients(), processed);
@ -78,13 +81,15 @@ final public class MessageChannel<MESSAGE extends Handleable<CLIENT>, CLIENT> {
} }
} }
} }
/** /**
* Send a message to a client. * Send a message to a client.
* *
* @param client target client * @param client
* @param message message to send * target client
* @param message
* message to send
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void sendTo(Object client, MESSAGE message) private void sendTo(Object client, MESSAGE message)
@ -93,21 +98,22 @@ final public class MessageChannel<MESSAGE extends Handleable<CLIENT>, CLIENT> {
((Handleable<CLIENT>) message).handleBy((CLIENT) client); ((Handleable<CLIENT>) message).handleBy((CLIENT) client);
} }
} }
/** /**
* Check if the given message can be broadcasted by this * Check if the given message can be broadcasted by this
* {@link MessageChannel} * {@link MessageChannel}
* *
* @param message event object * @param message
* event object
* @return can be broadcasted * @return can be broadcasted
*/ */
public boolean canBroadcast(Object message) public boolean canBroadcast(Object message)
{ {
return message != null && messageClass.isInstance(message); return message != null && messageClass.isInstance(message);
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
@ -117,8 +123,8 @@ final public class MessageChannel<MESSAGE extends Handleable<CLIENT>, CLIENT> {
result = prime * result + ((messageClass == null) ? 0 : messageClass.hashCode()); result = prime * result + ((messageClass == null) ? 0 : messageClass.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
@ -134,25 +140,27 @@ final public class MessageChannel<MESSAGE extends Handleable<CLIENT>, CLIENT> {
} else if (!messageClass.equals(other.messageClass)) return false; } else if (!messageClass.equals(other.messageClass)) return false;
return true; return true;
} }
@Override @Override
public String toString() public String toString()
{ {
return "CHANNEL( " + messageClass.getSimpleName() + " -> " + clientClass.getSimpleName() + " )"; return "CHANNEL( " + messageClass.getSimpleName() + " -> " + clientClass.getSimpleName() + " )";
} }
/** /**
* Create an instance for given types * Create an instance for given types
* *
* @param messageClass event class * @param messageClass
* @param clientClass client class * event class
* @param clientClass
* client class
* @return the broadcaster * @return the broadcaster
*/ */
public static <F_MESSAGE extends Handleable<F_CLIENT>, F_CLIENT> MessageChannel<F_MESSAGE, F_CLIENT> create(Class<F_MESSAGE> messageClass, Class<F_CLIENT> clientClass) public static <F_MESSAGE extends Handleable<F_CLIENT>, F_CLIENT> MessageChannel<F_MESSAGE, F_CLIENT> create(Class<F_MESSAGE> messageClass, Class<F_CLIENT> clientClass)
{ {
return new MessageChannel<F_MESSAGE, F_CLIENT>(messageClass, clientClass); return new MessageChannel<F_MESSAGE, F_CLIENT>(messageClass, clientClass);
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.patterns.subscription.clients; package mightypork.utils.patterns.subscription.clients;
import java.util.Collection; import java.util.Collection;
@ -10,16 +9,16 @@ import java.util.Collection;
* @author MightyPork * @author MightyPork
*/ */
public interface DelegatingClient { public interface DelegatingClient {
/** /**
* @return collection of child clients. Can not be null. * @return collection of child clients. Can not be null.
*/ */
public Collection<Object> getChildClients(); public Collection<Object> getChildClients();
/** /**
* @return true if delegating is active * @return true if delegating is active
*/ */
public boolean doesDelegate(); public boolean doesDelegate();
} }

@ -1,16 +1,15 @@
package mightypork.utils.patterns.subscription.clients; package mightypork.utils.patterns.subscription.clients;
/** /**
* Client that can toggle receiving messages. * Client that can toggle receiving messages.
* *
* @author MightyPork * @author MightyPork
*/ */
public interface ToggleableClient { public interface ToggleableClient {
/** /**
* @return true if the client wants to receive messages * @return true if the client wants to receive messages
*/ */
public boolean doesSubscribe(); public boolean doesSubscribe();
} }

@ -1,19 +1,21 @@
package mightypork.utils.string; package mightypork.utils.string;
/** /**
* General purpose string utilities * General purpose string utilities
* *
* @author MightyPork * @author MightyPork
*/ */
public class StringUtils { public class StringUtils {
/** /**
* Get if string is in array * Get if string is in array
* *
* @param needle checked string * @param needle
* @param case_sensitive case sensitive comparision * checked string
* @param haystack array of possible values * @param case_sensitive
* case sensitive comparision
* @param haystack
* array of possible values
* @return is in array * @return is in array
*/ */
public static boolean isInArray(String needle, boolean case_sensitive, String... haystack) public static boolean isInArray(String needle, boolean case_sensitive, String... haystack)
@ -30,38 +32,39 @@ public class StringUtils {
return false; return false;
} }
} }
public static String fromLastDot(String s) public static String fromLastDot(String s)
{ {
return fromLastChar(s, '.'); return fromLastChar(s, '.');
} }
public static String toLastDot(String s) public static String toLastDot(String s)
{ {
return toLastChar(s, '.'); return toLastChar(s, '.');
} }
public static String fromLastChar(String s, char c) public static String fromLastChar(String s, char c)
{ {
if (s == null) return null; if (s == null) return null;
return s.substring(s.lastIndexOf(c) + 1, s.length()); return s.substring(s.lastIndexOf(c) + 1, s.length());
} }
public static String toLastChar(String s, char c) public static String toLastChar(String s, char c)
{ {
if (s == null) return null; if (s == null) return null;
return s.substring(0, s.lastIndexOf(c)); return s.substring(0, s.lastIndexOf(c));
} }
/** /**
* Repeat a string * Repeat a string
* *
* @param repeated string * @param repeated
* string
* @param count * @param count
* @return output * @return output
*/ */
@ -72,37 +75,41 @@ public class StringUtils {
s += repeated; s += repeated;
return s; return s;
} }
/** /**
* convert string to a same-length sequence of # marks * convert string to a same-length sequence of # marks
* *
* @param password password * @param password
* password
* @return encoded * @return encoded
*/ */
public static String passwordify(String password) public static String passwordify(String password)
{ {
return passwordify(password, "*"); return passwordify(password, "*");
} }
/** /**
* convert string to a same-length sequence of chars * convert string to a same-length sequence of chars
* *
* @param password password * @param password
* @param replacing character used in output * password
* @param replacing
* character used in output
* @return encoded * @return encoded
*/ */
public static String passwordify(String password, String replacing) public static String passwordify(String password, String replacing)
{ {
return repeat(replacing, password.length()); return repeat(replacing, password.length());
} }
/** /**
* Get ordinal version of numbers (1 = 1st, 5 = 5th etc.) * Get ordinal version of numbers (1 = 1st, 5 = 5th etc.)
* *
* @param number number * @param number
* number
* @return ordinal, string * @return ordinal, string
*/ */
public static String numberToOrdinal(int number) public static String numberToOrdinal(int number)
@ -114,12 +121,13 @@ public class StringUtils {
} }
return number + "th"; return number + "th";
} }
/** /**
* Format number with thousands separated by a dot. * Format number with thousands separated by a dot.
* *
* @param number number * @param number
* number
* @return string 12.004.225 * @return string 12.004.225
*/ */
public static String formatInt(long number) public static String formatInt(long number)
@ -133,35 +141,35 @@ public class StringUtils {
if (cnt % 3 == 0 && i > 0) out = dot + out; if (cnt % 3 == 0 && i > 0) out = dot + out;
cnt++; cnt++;
} }
return out; return out;
} }
public static boolean isValidFilenameChar(char ch) public static boolean isValidFilenameChar(char ch)
{ {
return isValidFilenameString(Character.toString(ch)); return isValidFilenameString(Character.toString(ch));
} }
public static boolean isValidFilenameString(String filename) public static boolean isValidFilenameString(String filename)
{ {
return filename.matches("[a-zA-Z0-9 +\\-.,_%@#!]+"); return filename.matches("[a-zA-Z0-9 +\\-.,_%@#!]+");
} }
public static boolean isValidIdentifierChar(char ch) public static boolean isValidIdentifierChar(char ch)
{ {
return isValidIdentifierString(Character.toString(ch)); return isValidIdentifierString(Character.toString(ch));
} }
public static boolean isValidIdentifierString(String filename) public static boolean isValidIdentifierString(String filename)
{ {
return filename.matches("[a-zA-Z0-9._]+"); return filename.matches("[a-zA-Z0-9._]+");
} }
public static String ellipsisStart(String orig, int length) public static String ellipsisStart(String orig, int length)
{ {
if (orig.length() > length) { if (orig.length() > length) {
@ -169,8 +177,8 @@ public class StringUtils {
} }
return orig; return orig;
} }
public static String ellipsisEnd(String orig, int length) public static String ellipsisEnd(String orig, int length)
{ {
if (orig.length() > length) { if (orig.length() > length) {

@ -1,7 +1,6 @@
package mightypork.utils.string.validation; package mightypork.utils.string.validation;
public interface CharValidator { public interface CharValidator {
public boolean isValid(char c); public boolean isValid(char c);
} }

@ -1,20 +1,19 @@
package mightypork.utils.string.validation; package mightypork.utils.string.validation;
public class CharValidatorRegex implements CharValidator { public class CharValidatorRegex implements CharValidator {
private String formula; private String formula;
public CharValidatorRegex(String regex) { public CharValidatorRegex(String regex) {
this.formula = regex; this.formula = regex;
} }
@Override @Override
public boolean isValid(char c) public boolean isValid(char c)
{ {
return Character.toString(c).matches(formula); return Character.toString(c).matches(formula);
} }
} }

@ -1,20 +1,19 @@
package mightypork.utils.string.validation; package mightypork.utils.string.validation;
public class CharValidatorWhitelist implements CharValidator { public class CharValidatorWhitelist implements CharValidator {
private String whitelist; private String whitelist;
public CharValidatorWhitelist(String allowed) { public CharValidatorWhitelist(String allowed) {
this.whitelist = allowed; this.whitelist = allowed;
} }
@Override @Override
public boolean isValid(char c) public boolean isValid(char c)
{ {
return whitelist.contains(Character.toString(c)); return whitelist.contains(Character.toString(c));
} }
} }

@ -1,6 +1,5 @@
package mightypork.utils.string.validation; package mightypork.utils.string.validation;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
@ -11,35 +10,36 @@ import java.io.FileFilter;
* @author MightyPork * @author MightyPork
*/ */
public class FileSuffixFilter implements FileFilter { public class FileSuffixFilter implements FileFilter {
/** Array of allowed suffixes */ /** Array of allowed suffixes */
private String[] suffixes = null; private String[] suffixes = null;
/** /**
* Suffix filter * Suffix filter
* *
* @param suffixes var-args allowed suffixes, case insensitive * @param suffixes
* var-args allowed suffixes, case insensitive
*/ */
public FileSuffixFilter(String... suffixes) { public FileSuffixFilter(String... suffixes) {
this.suffixes = suffixes; this.suffixes = suffixes;
} }
@Override @Override
public boolean accept(File pathname) public boolean accept(File pathname)
{ {
if (!pathname.isFile()) return false; if (!pathname.isFile()) return false;
String fname = pathname.getName().toLowerCase().trim(); String fname = pathname.getName().toLowerCase().trim();
for (String suffix : suffixes) { for (String suffix : suffixes) {
if (fname.endsWith(suffix.toLowerCase().trim())) { if (fname.endsWith(suffix.toLowerCase().trim())) {
return true; return true;
} }
} }
return false; return false;
} }
} }

@ -1,10 +1,9 @@
package mightypork.utils.string.validation; package mightypork.utils.string.validation;
public class FilenameCharValidator extends CharValidatorRegex { public class FilenameCharValidator extends CharValidatorRegex {
public FilenameCharValidator() { public FilenameCharValidator() {
super("[a-zA-Z0-9 +\\-.,_%@#$!'\"]"); super("[a-zA-Z0-9 +\\-.,_%@#$!'\"]");
} }
} }

@ -1,12 +1,11 @@
package mightypork.utils.string.validation; package mightypork.utils.string.validation;
/** /**
* Utility interface for string filters (accepting filepaths and similar) * Utility interface for string filters (accepting filepaths and similar)
* *
* @author MightyPork * @author MightyPork
*/ */
public interface StringFilter { public interface StringFilter {
public boolean accept(String entry); public boolean accept(String entry);
} }

@ -1,6 +1,5 @@
package mightypork.utils.time; package mightypork.utils.time;
/** /**
* Class for counting FPS in games.<br> * Class for counting FPS in games.<br>
* This class can be used also as a simple frequency meter - output is in Hz. * This class can be used also as a simple frequency meter - output is in Hz.
@ -8,14 +7,14 @@ package mightypork.utils.time;
* @author MightyPork * @author MightyPork
*/ */
public class FpsMeter { public class FpsMeter {
private long frames = 0; private long frames = 0;
private long drops = 0; private long drops = 0;
private long lastTimeMillis = System.currentTimeMillis(); private long lastTimeMillis = System.currentTimeMillis();
private long lastSecFPS = 0; private long lastSecFPS = 0;
private long lastSecDrop = 0; private long lastSecDrop = 0;
/** /**
* @return current second's FPS * @return current second's FPS
*/ */
@ -23,8 +22,8 @@ public class FpsMeter {
{ {
return lastSecFPS; return lastSecFPS;
} }
/** /**
* Notification that frame was rendered * Notification that frame was rendered
*/ */
@ -39,19 +38,20 @@ public class FpsMeter {
} }
frames++; frames++;
} }
/** /**
* Notification that some frames have been dropped * Notification that some frames have been dropped
* *
* @param dropped dropped frames * @param dropped
* dropped frames
*/ */
public void drop(int dropped) public void drop(int dropped)
{ {
drops += dropped; drops += dropped;
} }
/** /**
* @return current second's dropped frames * @return current second's dropped frames
*/ */

@ -1,23 +1,22 @@
package mightypork.utils.time; package mightypork.utils.time;
public interface Pauseable { public interface Pauseable {
/** /**
* Pause operation * Pause operation
*/ */
public void pause(); public void pause();
/** /**
* Resume operation * Resume operation
*/ */
public void resume(); public void resume();
/** /**
* @return paused state * @return paused state
*/ */
public boolean isPaused(); public boolean isPaused();
} }

@ -1,26 +1,25 @@
package mightypork.utils.time; package mightypork.utils.time;
/** /**
* Timer for delta timing * Timer for delta timing
* *
* @author MightyPork * @author MightyPork
*/ */
public class TimerDelta { public class TimerDelta {
private long lastFrame; private long lastFrame;
private static final long SECOND = 1000000000; // a million nanoseconds private static final long SECOND = 1000000000; // a million nanoseconds
/** /**
* New delta timer * New delta timer
*/ */
public TimerDelta() { public TimerDelta() {
lastFrame = System.nanoTime(); lastFrame = System.nanoTime();
} }
/** /**
* Get current time in NS * Get current time in NS
* *
@ -30,8 +29,8 @@ public class TimerDelta {
{ {
return System.nanoTime(); return System.nanoTime();
} }
/** /**
* Get time since the last "getDelta()" call. * Get time since the last "getDelta()" call.
* *

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save