Jump to content
  • Advertisement

fae

Member
  • Content Count

    8
  • Joined

  • Last visited

Everything posted by fae

  1. Have you already analysed that the delay is really caused by Java garbage collection? If not, I'd really recommend analysing the problem more thoroughly before committing to any changes. There are lots of other possible causes for such delays when presenting game data to the end user, e.g. preparing the graphics context, establishing and initialising buffers in an OpenGL application etc. However we can't really speculate on these as we don't know what type of an application you have and what libraries and frameworks you're using. Depending on the environment and SDK you could already have a suitable tool for analysing this, see http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/intro.html and http://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html. IF the problem really is with GC, the recommendations above are really good. Other viable solution could be explicitly calling System.gc after the init is done. This basically asks the system to perform GC (note that it doesn't force it, the JVM is free to ignore the request). Depending on the situation this could prevent the GC from happening during the actual game logic. However the other approaches highlighted above are usually more appropriate as they limit any further GCs during the game.
  2. Agree with rip-off 100%. As it is the code is really difficult to read and understand. This particular issue with the NullPointerException was relatively easy to find - the trace had the exact line number and I could just look at the row and check which references can potentially cause the exception. But had it been e.g. a logic issue with some processing results.. As a next step for refactoring I'd even suggest that you move the command processing completely outside the "command switch" if you're going to have many different commands. I'd even go there with the current number of commands as that allows for easier testing and re-use of the said commands. This could be something like this (extending on rip-off's excellent example): public class CommandSwitch { /** * Map containing all supported commands. */ private final java.util.Map<String, CommandProcessor> commandMap; public CommandSwitch() { commandMap = new java.util.Hashtable<String, CommandProcessor>(); } /** * Adds a new command to the switch. This can be called from whatever container/controller * you're having. */ public void addCommandProcessor(String command, CommandProcessor processor) { commandMap.put(command, processor); } public void logError(String error) { System.out.println("ERROR - " + error); } public void printUsage(CommandSender sender, String usage) { System.out.println("To " + sender + ": " + usage); } public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if (!(sender instanceof Player)) { logError("Invalid sender: " + sender); return false; } Player player = (Player) sender; String commandName = cmd.getName(); if (!commandName.equalsIgnoreCase("mc_web")) { printUsage(player, "Unrecognised command: " + commandName); return false; } if (args.length < 2) { printUsage(player, "Not enough arguments: " + args.length); return false; } String target = args[0]; String verb = args[1]; CommandProcessor processor = commandMap.get(target); if(processor != null) { return processor.processCommand(target, verb); } printUsage(player, "Don't understand: " + target + " " + verb); return false; } public static void main(String[] args) { CommandSwitch handler = new CommandSwitch(); handler.addCommandProcessor("money", new MoneyCommand()); handler.addCommandProcessor("item", new ItemCommand()); handler.addCommandProcessor("account", new AccountCommand()); CommandSender sender = new Player(); handler.onCommand(sender, new Command("mc_web"), "Money Label", new String[] { "money", "deposit" } ); handler.onCommand(sender, new Command("mc_web"), "Item Label", new String[] { "item", "deposit" } ); handler.onCommand(sender, new Command("mc_web"), "Unknown", new String[] { "invalid", "deposit" } ); } /** * These should be outside the class, now internal just to make the example standalone */ public static interface CommandProcessor { public boolean processCommand(String name, String verb); } public static class MoneyCommand implements CommandProcessor { public boolean processCommand(String name, String verb) { System.out.println("MONEY: " + name + ", " + verb); return true; } } public static class ItemCommand implements CommandProcessor { public boolean processCommand(String name, String verb) { System.out.println("ITEM: " + name + ", " + verb); return true; } } public static class AccountCommand implements CommandProcessor { public boolean processCommand(String name, String verb) { System.out.println("ACCOUNT: " + name + ", " + verb); return true; } } public static class CommandSender { /* whatever */ } public static class Player extends CommandSender { /* whatever */ } public static class Command { private final String name; public Command(final String name) { this.name = name; } public String getName() { return name; } /* whatever */ } } The code is still lacking, it doesn't e.g. verify input values for nullness, but should give you a good idea of what I'm proposing. The design is actually according to "Command" design pattern, but I wouldn't recommend getting wild with different design patterns yet.
  3. You have "trim" in your while loop which wasn't there in the original post: while ( ( Line = br.readLine().trim() ) != null ) { ... } On the last iteration the trim is called on a null String, which causes the NullPointerException. Move the trim inside the loop as you had in your original example.
  4. Also before writing your own class loader I'd recommend you check out URLClassLoader, see http://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html With URL class loader you can load files from directories or jars in your file system, e.g. [source lang="java"]URLClassLoader classLoader = new URLClassLoader(new URL[]{ new URL("file:///pathToMy.jar") }, ClassLoader.getSystemClassLoader()); Object instance = classLoader.loadClass("package.AndNameOfMyClass").newInstance();[/source]
  5. Good stuff! I was actually just looking for a simple C image loader (for any common file format) and this seems to fit the bill quite nicely. Couple of suggestions though:[list] [*]Check the return value on malloc and fail-fast if malloc didn't succeed [*]Check the return value on those fread and fseek calls and fail gracefully if they're not what you'd expect. You never know what you're reading [*]Maybe do a sanity check on data->width, data->height, data->depth after reading? In case I'll pass a non-TGA file these may get insanely high. [*]Change the load function signature to "TGADATA* load_tga_data([b]const[/b] char *file)". I may have a const string with the file path and with strict compiler setting I wouldn't be able to use that as path otherwise. [/list] Anyway thanks for the writeup and code!
  6. fae

    C Do/While Loop problem

    Am I missing something? Because the way I read that, there's no looping, and if there's no looping, it's purpose is entirely different than the looping version, in which case you don't do the same thing... [/quote] No you're absolutely correct. I was just focusing on the scoping part of Nypyren's post. However now that you mentioned I probably misinterpreted Nypyren's reason for the block as the topic of the discussion is loops after all..
  7. fae

    C Do/While Loop problem

    I sometime do the same thing, but without "for". I consider this a bit safer approach as it doesn't hit you so bad when you forget the break: { // stuff int result = whatever; if (result == x) // other stuff }
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!