• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

# [java] The best way to call methods

## 15 posts in this topic

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!
0

##### Share on other sites
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
0

##### Share on other sites
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.
0

##### Share on other sites
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
0

##### Share on other sites
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
0

##### Share on other sites
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); }}

0

##### Share on other sites
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
0

##### Share on other sites
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

0

##### Share on other sites
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
0

##### Share on other sites
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?
0

##### Share on other sites

For single keystroke commands:
Use the Command interface with execute().

For multistroke commands (Ie. like the console in quake):
Use Tries (or Patricia trees?) finite state machines or even build a real parser. Tries are best for simple commands with no parameters.

Jacob Marner
0

##### Share on other sites
Sorry for being such a newbie... what is Tries? Treemaps? I can''t seem to find Tries in any of my java books. And Patricia Trees as well where can I read about those.
0

##### Share on other sites
What about baseing a consone on python or other scripting languages that compile nativly to java as well as having the ability to evaluate new code on the fly. Seems like a good compromise to me.

import org.python.util.PythonInterpreter;
import org.python.core.*;

public class SimpleEmbedded {
public static void main(String []args)
throws PyException
{
PythonInterpreter interp =
new PythonInterpreter();

System.out.println("Hello, brave new world");
interp.exec("import sys");
interp.exec("print sys");

interp.set("a", new PyInteger(42));
interp.exec("print a");
interp.exec("x = 2+2");
PyObject x = interp.get("x");

System.out.println("x: "+x);
System.out.println("Goodbye, cruel world");
}
}

0

##### Share on other sites
moregames, ignore that Python posting. That is not what you need.

Tries is an abstract datastructure. It is not specific to any specific programming language, but is a structure like lists and maps. List and maps happens already to be implemented in the Java standard library for your convienience but a lot of other structures also exist. One of the goals of programming is to find the structure that best solves the question at hand.

If you want a good introduction to various data structures and algorithms the feature book on the gamedev.net main page at the moment:

Cormen, Leiserson & Rivest: Introduction To Algorithms

is serious and very recommendable. (I just looked Trie up in it, and it don''t seem to be listed, though)

On the net you can find a description of tries at
(for C, but you should be able to understand it)

Jacob Marner
0

##### Share on other sites
quote:

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.

I''m sure it would, but bugger me if I''m going to define one in the reply to a board

quote:
Original post by felonius
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.

Arse! Its worse to hard code commands to methods.
0

##### Share on other sites
quote:
Original post by bobbin
Arse! Its worse to hard code commands to methods.

Hmm, you do have a point, bobbin. Point taken.

Jacob Marner
0