Changed Config to read/write using new Parser and Parser_Objects

dev
Shariq Shah 8 years ago
parent 3354df46bb
commit 4c5bb465b1
  1. 6
      README.md
  2. 2
      build/genie.lua
  3. 11
      src/common/hashmap.c
  4. 1
      src/common/hashmap.h
  5. 5
      src/common/parser.c
  6. 3
      src/common/parser.h
  7. 87
      src/game/config_vars.c
  8. 4
      src/game/main.c

@ -155,7 +155,8 @@
- ## TODO - ## TODO
- Change Config to read/write using new Parser logic - Add array support to variant
- Read/Write keybindings using new parser object
- Store Materials in new format supported by parser - Store Materials in new format supported by parser
- Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards - Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards
- Implement sound/listener loading from scene file - Implement sound/listener loading from scene file
@ -328,4 +329,5 @@
* Removed duplicate parsing logic * Removed duplicate parsing logic
* Fixed bugs in stripping key name for input map * Fixed bugs in stripping key name for input map
* Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that * Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that
* Implmented writing to file through the new Parser and Parser_Object * Implmented writing to file through the new Parser and Parser_Objects
* Changed Config to read/write using new Parser and Parser_Objects

@ -11,6 +11,8 @@ solution "Symmetry"
buildoptions {"-Wall", "-std=c99", "`pkg-config --cflags-only-I sdl2`"} buildoptions {"-Wall", "-std=c99", "`pkg-config --cflags-only-I sdl2`"}
configuration {"windows", "gmake"} configuration {"windows", "gmake"}
postbuildcommands {"rm -rf debug/assets"}
postbuildcommands {"rm -rf release/assets"}
postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets debug/assets"} postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets debug/assets"}
postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets release/assets"} postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets release/assets"}
buildoptions {"-Wall", "-std=c99"} buildoptions {"-Wall", "-std=c99"}

@ -347,3 +347,14 @@ int hashmap_iter_next(struct Hashmap* hashmap, char** key, struct Variant** valu
} }
return 0; return 0;
} }
void hashmap_copy(struct Hashmap* from, struct Hashmap* to)
{
struct Variant* from_val = NULL;
char* from_key = NULL;
HASHMAP_FOREACH(from, from_key, from_val)
{
hashmap_value_set(to, from_key, from_val);
}
}

@ -13,6 +13,7 @@ struct Variant;
struct Hashmap* hashmap_new(void); struct Hashmap* hashmap_new(void);
void hashmap_free(struct Hashmap* hashmap); void hashmap_free(struct Hashmap* hashmap);
void hashmap_copy(struct Hashmap* from, struct Hashmap* to);
void hashmap_value_remove(struct Hashmap* hashmap, const char* key); void hashmap_value_remove(struct Hashmap* hashmap, const char* key);
bool hashmap_value_exists(struct Hashmap* hashmap, const char* key); bool hashmap_value_exists(struct Hashmap* hashmap, const char* key);
void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value); void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value);

@ -13,9 +13,6 @@
#define MAX_LINE_LEN 512 #define MAX_LINE_LEN 512
#define MAX_VALUE_LEN 512 #define MAX_VALUE_LEN 512
static int parser_object_type_from_str(const char* str);
static const char* parser_object_type_to_str(int type);
bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line) bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line)
{ {
if(!file) if(!file)
@ -244,6 +241,7 @@ int parser_object_type_from_str(const char* str)
if(strncmp(str, "Entity", HASH_MAX_KEY_LEN) == 0) object_type = PO_ENTITY; if(strncmp(str, "Entity", HASH_MAX_KEY_LEN) == 0) object_type = PO_ENTITY;
else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL; else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL;
else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL; else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL;
else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG;
return object_type; return object_type;
} }
@ -255,6 +253,7 @@ const char* parser_object_type_to_str(int type)
case PO_ENTITY: return "Entity"; case PO_ENTITY: return "Entity";
case PO_MODEL: return "Model"; case PO_MODEL: return "Model";
case PO_MATERIAL: return "Material"; case PO_MATERIAL: return "Material";
case PO_CONFIG: return "Config";
case PO_UNKNOWN: return "Unknown"; case PO_UNKNOWN: return "Unknown";
default: return "Unknown"; default: return "Unknown";
} }

@ -5,6 +5,7 @@
enum Parser_Object_Type enum Parser_Object_Type
{ {
PO_CONFIG,
PO_ENTITY, PO_ENTITY,
PO_MATERIAL, PO_MATERIAL,
PO_MODEL, PO_MODEL,
@ -30,5 +31,7 @@ void parser_free(struct Parser* parser);
struct Parser* parser_new(void); struct Parser* parser_new(void);
struct Parser_Object* parser_object_new(struct Parser* parser, int type); struct Parser_Object* parser_object_new(struct Parser* parser, int type);
bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename); bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename);
int parser_object_type_from_str(const char* str);
const char* parser_object_type_to_str(int type);
#endif #endif

@ -14,8 +14,6 @@
static struct Hashmap* cvars = NULL; static struct Hashmap* cvars = NULL;
static void config_on_parser_assign(const char* key, const char* value, const char* filename, int current_line);
void config_vars_init(void) void config_vars_init(void)
{ {
cvars = hashmap_new(); cvars = hashmap_new();
@ -46,39 +44,53 @@ struct Hashmap* config_vars_get(void)
return cvars; return cvars;
} }
void config_on_parser_assign(const char* key, const char* value, const char* filename, int current_line)
{
struct Variant* cvar = hashmap_value_get(cvars, key);
if(!cvar)
{
log_warning("Unknown config key '%s' in file %s, line %d", key, filename, current_line);
return;
}
variant_from_str(cvar, value, cvar->type);
}
bool config_vars_load(const char* filename, int directory_type) bool config_vars_load(const char* filename, int directory_type)
{ {
bool success = false;
FILE* config_file = io_file_open(directory_type, filename, "rb"); FILE* config_file = io_file_open(directory_type, filename, "rb");
if(!config_file) if(!config_file)
{ {
log_error("config:vars_load", "Could not open %s", filename); log_error("config:vars_load", "Could not open %s", filename);
return success; return false;
}
struct Parser* parser = parser_load_objects(config_file, filename);
if(!parser)
{
log_error("config_vars:load", "Failed to load config data from %s", filename);
fclose(config_file);
return false;
} }
if(!parser_load(config_file, filename, &config_on_parser_assign, false, 0)) bool config_loaded = false;
for(int i = 0; i < array_len(parser->objects); i++)
{ {
log_error("config_vars:load", "Failed to parse config file %s", filename); struct Parser_Object* object = &parser->objects[i];
if(object->type != PO_CONFIG)
{
log_warning("Unexpected config object type %s in %s", parser_object_type_to_str(object->type), filename);
continue;
} }
else
config_loaded = true;
char* key = NULL;
struct Variant* value = NULL;
char variant_str[MAX_VARIANT_STR_LEN];
HASHMAP_FOREACH(object->data, key, value)
{
struct Variant* existing_val = hashmap_value_get(cvars, key);
if(!existing_val)
{ {
log_message("Loaded config from %s", filename); log_warning("Unkown key '%s' in config file %s", key, filename);
success = true; continue;
} }
variant_copy(existing_val, value);
}
}
if(config_loaded) log_message("Loaded config from %s", filename);
fclose(config_file); fclose(config_file);
return success; return config_loaded;
} }
bool config_vars_save(const char* filename, int directory_type) bool config_vars_save(const char* filename, int directory_type)
@ -91,17 +103,32 @@ bool config_vars_save(const char* filename, int directory_type)
return success; return success;
} }
char* key = NULL; struct Parser* parser = parser_new();
struct Variant* value = NULL; if(!parser)
char variant_str[MAX_VARIANT_STR_LEN];
HASHMAP_FOREACH(cvars, key, value)
{ {
memset(variant_str, '\0', MAX_VARIANT_STR_LEN); log_error("config_vars:save", "Could not create Parser for %s", filename);
variant_to_str(value, variant_str, MAX_VARIANT_STR_LEN); fclose(config_file);
fprintf(config_file, "%s: %s\n", key, variant_str); return false;
} }
log_message("Config file %s written.", filename);
success = true; struct Parser_Object* object = parser_object_new(parser, PO_CONFIG);
if(!object)
{
log_error("config_vars:save", "Could not create Parser_Object for %s", filename);
parser_free(parser);
fclose(config_file);
return false;
}
hashmap_copy(cvars, object->data);
if(!parser_write_objects(parser, config_file, filename))
{
log_error("config_vars:save", "Failed to write config to '%s'", filename);
success = false;
}
parser_free(parser);
fclose(config_file); fclose(config_file);
return success; return success;
} }

@ -176,10 +176,10 @@ bool init(void)
io_file_init(install_path, user_path); io_file_init(install_path, user_path);
free(install_path); free(install_path);
free(user_path); free(user_path);
if(!config_vars_load("config.cfg", DIRT_USER)) if(!config_vars_load("config.symtres", DIRT_USER))
{ {
log_error("main:init", "Could not load config, reverting to defaults"); log_error("main:init", "Could not load config, reverting to defaults");
config_vars_save("config.cfg", DIRT_USER); config_vars_save("config.symtres", DIRT_USER);
} }
if(!platform_init_video()) return false; if(!platform_init_video()) return false;

Loading…
Cancel
Save