Game Input Parser
This document describes libgameinput by Clinton Ebadi
This document applies to version 0.3.1 of libgameinput
1. Introduction
Libgameparser is a small library intended to be used in text
based games. It provided an easy to use (in the authors
opinion) class game_parser
to register callbacks
and keywords. When a keyword is entered, the callback
associated with it is called. Callbacks can be set up to have
any number of required and optional arguments.
game_parser
throws an exception when the wrong
number of arguments are given. To see a small example of the
library being used, read the 2.
Tutorial.
2. Tutorial
This is a tutorial that covers all of the current library
features. The first section contains a small example program
that goes over all of the features of the library. The second
section goes over the example program block-by-block. You will
find the example program as test.cc
in the source
distribution.
2.1 Example Program
|
#include "input.hh"
#include <cstdlib>
void moo (str_vec, game_parser& p)
{
std::ostream& out = *p.get_output_stream ();
out << "Moo Moo, I am the great cow!\n";
return;
}
void f_foo (str_vec f, game_parser& p)
{
std::ostream& out = *p.get_output_stream ();
out << "Fear my mighty foo, " << f[1] // only required argument
<< ".\n";
const char* bar;
if (f.size() >= 3)
bar = f[2].c_str ();
else {
out << "I'm only good enough for one arg? Fine. I hate you.";
return;
}
out << "My optional arg was " << bar;
return;
}
void quit (str_vec, game_parser& p)
{
std::ostream& out = *p.get_output_stream ();
out << "Exiting\n";
std::exit (0);
return; // will never get here
}
void print (str_vec args, game_parser& parse)
{
std::ostream& temp = *parse.get_output_stream ();
temp << args[1];
return;
}
void get_input (str_vec, game_parser& parse)
{
std::istream& tin = *parse.get_input_stream ();
std::ostream& tout = *parse.get_output_stream ();
tout << "Enter your name: ";
std::string tstring;
tin >> tstring;
tout << "Your name is: " << tstring;
return;
}
void change_del (str_vec arg, game_parser& parser)
{
// this one changes the command delimeter
parser.command_delimeter (arg[1][0]); // use first char of first arg
}
int main () {
game_parser foo;
foo.event_handler ("moo",
game_handler_t (&moo, "Too much moo!",0,0));
// notice how the number of required and optional args can be left
// out if both are 0
foo.event_handler ("quit",
game_handler_t (&quit, "I ONLY NEED ONE ARG!"));
// if opt is 0, it can be left out
foo.event_handler ("print",
game_handler_t (&print, "Print what?",1));
foo.event_handler ("name",
game_handler_t (&get_input, "Give me your name later"));
// foo takes one required argument, and one optional
// for a total of two maximum
foo.event_handler ("foo",
game_handler_t (&f_foo,
"Give me at least one argument, please?",
1, 1));
foo.event_handler ("change",
game_handler_t (&change_del,
"I need an argument to change the delimeter to!",1));
while (true) {
try {
std::cout << std::endl << ">>> ";
foo.get_command ();
}
catch (game_parser::wrong_number_of_args a) {
std::cerr
<< "Error: Wrong number of arguments given to " << a.cmd
<< "! Gave: " << a.given << " Minumum: " << a.min << " Max: "
<< a.max << std::endl
<< a.cmd << " gave this message: " << a.msg;
}
catch (game_parser::key_not_found k) {
std::cerr << "Error: key (" << k.key << ") not found\n";
}
}
std::cout << std::endl;
return 0;
}
|
2.2 Detailed Description of Test Program
This the annotated example program. It is simply meant as a
quick overview of the game_parser
features. This
does not show how to use game_parser
in a larger
system (e.g. a game).
|
#include "input.hh"
#include <cstdlib>
|
This just includes the game_parser
header and
the C standard library (which is used in one of the example
callbacks.
|
void moo (str_vec, game_parser& p)
{
std::ostream& out = *p.get_output_stream ();
out << "Moo Moo, I am the great cow!\n";
return;
}
|
moo
is a standard callback. All callbacks
return void and take two arguments, a str_vec
and
a game_parser
reference. The str_vec
type is simply an alias for
std::vector<std::string>
since that type is
used extensively in the library. moo
uses the
game_parser::get_output_stream
method to extract a
pointer to the std::ostream
the library is using.
It then dereferences it, stores it in out
and then
outputs a line with it.
|
void f_foo (str_vec f, game_parser& p)
{
std::ostream& out = *p.get_output_stream ();
out << "Fear my mighty foo, " << f[1] // only required argument
<< ".\n";
|
f_foo
uses its arguments. The first argument
(index 0) of the str_vec
is always the keyword
that the callback was executed as. You can think of the first
argument to the callback as its argv
. There is no
argc
because str_vec::size()
will
extract the size of the vector. This is one area where
game_parser
needs work: The callback does not tell
the game_parser
how many args it needs; instead it
relies on the user to do that. Since the user of
game_parser
is the one defining the callbacks
(usually), this is not a large problem (yet).
|
const char* bar;
if (f.size() >= 3)
bar = f[2].c_str ();
else {
out << "I'm only good enough for one arg? Fine. I hate you.";
return;
}
out << "My optional arg was " << bar;
return;
}
|
f_foo
takes one optional argument (this is set
when the callback is registered). If the optional argument is
present, f_foo
displays it. If not,
f_foo
tells the user how much it hates the user.
The above code could use std::vector::at()
, but
some (notably the older STL used by GCC < 3.0) standard
libraries lack it (important ones).
|
void quit (str_vec, game_parser& p)
{
std::ostream& out = *p.get_output_stream ();
out << "Exiting\n";
std::exit (0);
return; // will never get here
}
void print (str_vec args, game_parser& parse)
{
std::ostream& temp = *parse.get_output_stream ();
temp << args[1];
return;
}
|
The above callbacks don't show anything new.
quit
will exit the example program and
print
will display its argument.
|
void get_input (str_vec, game_parser& parse)
{
std::istream& tin = *parse.get_input_stream ();
std::ostream& tout = *parse.get_output_stream ();
tout << "Enter your name: ";
std::string tstring;
tin >> tstring;
tout << "Your name is: " << tstring;
return;
}
|
get_input
uses
game_parser::get_input_stream
. This is the same as
game_parser::get_output_stream
, except that it
returns a pointer to the input stream that
game_parser
is using. get_input
then
inputs your name and shows it to you.
|
void change_del (str_vec arg, game_parser& parser)
{
// this one changes the command delimeter
parser.command_delimeter (arg[1][0]); // use first char of first arg
}
|
change_del
calls
game_parser::command_delimeter
and sets it to the
first character of the first argument.
|
int main () {
game_parser foo;
foo.event_handler ("moo",
game_handler_t (&moo, "Too much moo!",0,0));
|
game_parser::event_handler
is the method that
makes game_parser
useful. It takes two arguments,
a keyword and a game_parser_t
. The
game_parser_t
contains a callback pointer, the
error message given when the wrong number of arguments is
given, the number of optional arguments (an unsigned
integer
), and the number of optional arguments. The
constructor for game_parser_t
allows you
initialize one easily.
The number of optional args is a signed
integer
. If you set it to 0, then the callback takes no
optional arguments. If it is set to any number greater than 0,
the callback takes up to that many of optional arguments. If
the number is set to -1, the callback will take any number of
optional arguments.
|
foo.event_handler ("quit",
game_handler_t (&quit, "I ONLY NEED ONE ARG!"));
|
game_handler_t
's constructor sets the required
and optional number of arguments arguments to 0 by default, so
you can leave one or both out if they are 0 (if you have 0
required arguments and 1 optional, you must still put in 0
required). The message given when the wrong number of arguments
is given defaults to an empty string, so you can leave that out
as well if you will not be using it.
|
foo.event_handler ("print",
game_handler_t (&print, "Print what?",1));
foo.event_handler ("name",
game_handler_t (&get_input, "Give me your name later"));
foo.event_handler ("foo",
game_handler_t (&f_foo,
"Give me at least one argument, please?",
1, 1));
foo.event_handler ("change",
game_handler_t (&change_del,
"I need an argument to change
the delimeter to!",1));
|
The rest of the callbacks are registered above.
|
while (true) {
try {
std::cout << std::endl << ">>> ";
foo.get_command ();
}
|
game_parser::get_command()
gets the next
command from the input stream that was set with
game_parser::input_stream
.
|
catch (game_parser::wrong_number_of_args a) {
std::cerr
<< "Error: Wrong number of arguments given to " << a.cmd
<< "! Gave: " << a.given << " Minumum: " << a.min << " Max: "
<< a.max << std::endl
<< a.cmd << " gave this message: " << a.msg;
}
|
game_parser::get_command()
will throw the
exception game_parser::wrong_number_of_args
. This
exception is a struct with the members cmd
,
max
, min
, and given
.
cmd
is a std::string
that represents
the keyword the command was called as. The min
and
max
arguments are the number of arguments that are
needed to succesfully call the command, and the
given
member is the number of arguments that were
actually given.
|
catch (game_parser::key_not_found k) {
std::cerr << "Error: key (" << k.key << ") not found\n";
}
}
|
The exception game_parser::key_not_found
is a
struct that contains a single member---key
.
key
is a std::string
that is the key
that was entered when game_parser::get_command()
was called. This exception indicates that the command entered
was not found.
|
std::cout << std::endl;
return 0;
}
|
For more information on how to use game_parser
see the reference portion of this manual.
Table of Contents
1.
Introduction
2.
Tutorial
2.1
Example Program
2.2
Detailed Description of Test Program
Short Table of Contents
1.
Introduction
2.
Tutorial
About this document
This document was generated using texi2html
The buttons in the navigation panels have the following
meaning:
Button |
Name |
Go to |
From 1.2.3 go to |
[ < ] |
Back |
previous section in reading order |
1.2.2 |
[ > ] |
Forward |
next section in reading order |
1.2.4 |
[ << ] |
FastBack |
previous or up-and-previous section |
1.1 |
[ Up ] |
Up |
up section |
1.2 |
[ >> ] |
FastForward |
next or up-and-next section |
1.3 |
[Top] |
Top |
cover (top) of document |
|
[Contents] |
Contents |
table of contents |
|
[Index] |
Index |
concept index |
|
[ ? ] |
About |
this page |
|
where the Example assumes that the current
position is at Subsubsection One-Two-Three of
a document of the following structure:
- 1. Section One
-
- 1.1 Subsection One-One
-
- 1.2 Subsection One-Two
-
- 1.2.1 Subsubsection One-Two-One
- 1.2.2 Subsubsection One-Two-Two
- 1.2.3 Subsubsection One-Two-Three
<== Current Position
- 1.2.4 Subsubsection One-Two-Four
- 1.3 Subsection One-Three
-
- 1.4 Subsection One-Four
This document was generated by Clinton K.
Ebadi on December, 8 2001 using texi2html