[Top] [Contents] [Index] [ ? ]

Game Input Parser



This document describes libgameinput by Clinton Ebadi

This document applies to version 0.3.1 of libgameinput

1. Introduction   
2. Tutorial    Programming Tutorial

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

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.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. Tutorial

2.1 Example Program   
2.2 Detailed Description of Test Program    Detailed Description of the Example

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.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

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: " <&#60; 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 (" <&#60; k.key << ") not found\n";
    }
  }

  std::cout << std::endl;
  return 0;

}


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

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: " <&#60; 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 (" <&#60; 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.


[Top] [Contents] [Index] [ ? ]

Table of Contents

1. Introduction
2. Tutorial
2.1 Example Program
2.2 Detailed Description of Test Program

[Top] [Contents] [Index] [ ? ]

Short Table of Contents

1. Introduction
2. Tutorial

[Top] [Contents] [Index] [ ? ]

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:

This document was generated by Clinton K. Ebadi on December, 8 2001 using texi2html