< index
< 7. File parser
< 7.4 Standard data types

=====================================
7.5 Using custom data types
=====================================

> 7.6 Using the default parser listener
Warning ! This uses some undocumented features of libtcod. Use it only if you know what you're doing...
The libtcod parser allows you to add your own data types. You can provide up to 16 custom datatype parsers that will read data from the text file and convert it into a TCOD_value_t union (using either an existing field or the generic custom field).
Custom data types are not supported with the python version of the library.

typedef TCOD_value_t (*TCOD_parser_custom_t)(TCOD_lex_t *lex, TCOD_parser_listener_t *listener, TCOD_parser_struct_t str, char *name);

C++ : TCOD_value_type_t TCODParser::newCustomType(TCOD_parser_custom_t custom_type_parser)
C   : TCOD_value_type_t TCOD_parser_new_custom_type(TCOD_parser_t parser,TCOD_parser_custom_t custom_type_parser)

This function associate a datatype parser with a new TCOD type. It returns the corresponding TCOD type between TCOD_TYPE_CUSTOM00 and TCOD_TYPE_CUSTOM15 or TCOD_TYPE_NONE if there are no more custom types available.
ParameterDescription
parserIn the C version, the parser handler, returned by TCOD_parser_new.
custom_type_parserA function pointer to the new datatype parser.

The custom datatype parser has following parameters :
ParameterDescription
lexThe libtcod generic lexical parser. This part is not yet documented.
listenerThe parser listener, mainly to call the error callback.
strThe structure type currently being parsed.
nameThe name of the property to parse.

The data must be fetched from the file using the lex object. The best way to understand how it work is to read the TCOD_parse_xxx_value functions in the parser_c.c source file. If you don't want to mess with the TCODLex class, you'd better put your custom value in a double-quote limited string so that you only have to manually parse it inside lex->tok (see TCOD_parse_color_value or TCOD_parse_dice_value for examples). Your custom parser can still use existing datatype parsers :

TCOD_value_t TCOD_parse_bool_value();
TCOD_value_t TCOD_parse_char_value();
TCOD_value_t TCOD_parse_integer_value();
TCOD_value_t TCOD_parse_float_value();
TCOD_value_t TCOD_parse_string_value();
TCOD_value_t TCOD_parse_color_value();
TCOD_value_t TCOD_parse_dice_value();

Example of a (very simple) custom parser :
In TCOD, certain objects must have a special color that represent the sun color. Obviously, it depends on the time of the day, so I can't put r,g,b values in the config file. So I override the color parser to add a special "sun" value :

// custom color parser. handle "sun" value
// World::sunColor is a special color that is replaced at runtime by the actual sun color
TCOD_value_t customColorParser(TCOD_lex_t *lex, TCOD_parser_listener_t *listener, TCOD_parser_struct_t def, char *propname) {
	if ( strcmp(lex->tok,"sun") == 0 ) {
		TCOD_value_t ret;
		ret.col.r = World::sunColor.r;
		ret.col.g = World::sunColor.g;
		ret.col.b = World::sunColor.b;
		return ret;
	}
	return TCOD_parse_color_value();
}


This custom parser is registered before running the parser :

TCOD_value_type_t customColor = parser.newCustomType(customColorParser);


I can now define properties using this custom type :

TCODParserStruct *feat = parser.newStructure("feature");
feat->addProperty("color",customColor,false);

insert a comment