[java] The best way to call methods

Started by
14 comments, last by moregames 23 years, 5 months ago
Say you have 1000 commands a user can enter thru a prompt to your game. If then/case would seem abit lame. What''s the best way to look up a command and execute it. For example: Add command to key, and add the method to value in a Hashtable. Query command from hastable and execute its value if found.

Well you get the idea, how would you accomplish this without a major speed slowdown. If you have the time to type in the 4-5 lines code it requires that would be a even greater deed. Thanks!
Advertisement
The answer depends on whether your commands are single key commands or whether they console commands (with multiple key strokes).

If only one keystroke:
1. I would make an array with a method at each key. And at run time simply go to the correct field (for instance by ascii value) and run the method there.
I.e. make an array of some "interface Command" with a method "execute()". During initialization you put object implementing Command into the array and at run time you just say commandarray[key].execute() and thats it.

If full commnds:
2. I would make Trie data structure. If you don''t know what that is then just stick to your hash table idea. Trie''s are better for this I think but you will have find info on it yourself because it takes to long to explain it here. The advantage of Tries is that you can perform the search for the command *while* the user types it in and you do not have to wait until the user is done typing lowering response time.

Jacob Marner
Jacob Marner, M.Sc.Console Programmer, Deadline Games
quote:commandarray[key].execute()


Ok so what is commandarray[key]? A string?

like:

String test="testmethod()";

test.execute();

What package is execute part of? I can''t find it.
I will try to describe was felonius was meaning by an array of "interface Command" because it is a rather slick way to do this (Command is one of the design patterns in the Gang of Four''s Design Patterns book):

1. You create the interface Command which consists of only one method - execute()

2. You make your 1000 commands objects that implement Command (therefore, they must implement the execute() method)

3. You create your array of Command objects and felonius has suggested you make the index the ascii value of the key - therefore, when you get a keypressed event, you can just get the ascii value and call the commandarray[key].execute() method

Hope this helps
Hi latrube,

Your description of what I meant are quite right. Thanks.

The only exception is that the Command interface here has very little to do with the Command design pattern in Gamma et al.''s book on Design Patterns (great book. Read it people if you haven''t!).

The Command design pattern focuses on remembering a command history to make commands undo''able. This is not the issue here, as can seen from your own description.

I see however, why the term Command might cause you to believe there is a connection:
* the semntics of command is the same (something that is executed when a certain input is given).
* the Command interface is identical to the interface of the same name in the Command design pattern.
* the Command design pattern can be used with the issue discussed here to add a undo/redo option to the interface. So that might be worth a thought, moregames.

Jacob Marner
Jacob Marner, M.Sc.Console Programmer, Deadline Games
OK,
so you have a hash like {command}->{methodName}, a command object to hold command and command params:
public class CommandObj
{
public String command;
public String param;
}
you object with the command methods in it is called Commands and the methods return int;
and a vector of command objects {{commandObj},{commandObj},{commandObj}}:

you can do somthing like (PS this is an exapmle please _don''t_ comment on syntax):

  for (int i = 0; i < commands.size(); i++){    //get the command object from the command list    CommandObj myCommandObj = elementAt(i);    //get the command method name from the command to methodname hash    String methodName = commandHash.get(myCommand.command);    int result;    Class c = Commands.class;    //one String param (the command param/value)    Class[] parameterTypes = new Class[] {String.class};    Method commandMethod;    //build list of method params/args    Object[] arguments = new Object[] {myCommandObj.param};    try     {        commandMethod = c.getMethod(methodName, parameterTypes);	//fire off the method        result = (int)commandMethod.invoke(arguments);    }     catch (NoSuchMethodException e)     {        System.out.println(e);    }     catch (IllegalAccessException e)     {                       System.out.println(e);                   }     catch (InvocationTargetException e)     {        System.out.println(e);    }}  


Bobbin, the algorithm you have given is good if your have multiple commands that each consists of several keystrokes.

If that was the case then the use of a hash map is not ideal. The use of a Trie is much better and more efficient.

Anyway, I think that moregames only has single keystroke commands and that they come one at the time.

And besides using Java reflection is really slow and should be avoided at all costs, besides it is generally bad style if not aboslutely essential for the purpose. The use of interfaces and virtual methods should be preferred any day.

Jacob Marner

Edited by - felonius on November 15, 2000 10:11:22 AM
Jacob Marner, M.Sc.Console Programmer, Deadline Games
Just wanted to let you know that a Trie data structure takes up a good amount of memory (not terribly but a good bit compared to other methods). Instead, I would use a Patricia Tree. It is a modification of the Trie which is much more space efficient and just as fast.

"Now go away or I shall taunt you a second time"
- Monty Python and the Holy Grail
themGames Productions

Patricia trees?

I don't know that one. Do you have a source were I can read it. I have several books on algorithms and data structures but they don't cover it. Can you give a short summary of what it does?

Tries aren't that bad (given I haven't seen Patricia trees). There only one node for each character in the tree and each node can be very small, depending on the implementation method used to represent children. You do not have to have pointers to all potential children, but could for instance have a liked list of children.

When used for string look up tries has the advantage that you can do the look up while the user is typing.
I would place a character in each node and traverse the trie one level down for each character typed.

With this method you will essentially have a finite state machine parser (like the one used in parsers to parse regular expressions) that is just as efficient.

Jacob Marner

Edited by - felonius on November 15, 2000 3:08:39 PM
Jacob Marner, M.Sc.Console Programmer, Deadline Games
quote:Anyway, I think that moregames only has single keystroke commands and that they come one at the time.


Ok so Trie is better for single keystrokes, but if this is not the case and commands arrive as strings would hash map be the best?

This topic is closed to new replies.

Advertisement