project_files/frontlib/model/scheme.c
changeset 7497 7e1d72fc03c7
parent 7482 d70a5b0d1190
child 10017 de822cd3df3a
equal deleted inserted replaced
7494:e65adfc99f15 7497:7e1d72fc03c7
    20 #include "scheme.h"
    20 #include "scheme.h"
    21 
    21 
    22 #include "../util/inihelper.h"
    22 #include "../util/inihelper.h"
    23 #include "../util/logging.h"
    23 #include "../util/logging.h"
    24 #include "../util/util.h"
    24 #include "../util/util.h"
    25 #include "../util/refcounter.h"
       
    26 
    25 
    27 #include <stdio.h>
    26 #include <stdio.h>
    28 #include <stdlib.h>
    27 #include <stdlib.h>
    29 #include <limits.h>
    28 #include <limits.h>
    30 #include <string.h>
    29 #include <string.h>
    31 
    30 
    32 static void flib_metascheme_destroy(flib_metascheme *meta) {
    31 flib_scheme *flib_scheme_create(const char *schemeName) {
    33 	if(meta) {
       
    34 		if(meta->settings) {
       
    35 			for(int i=0; i<meta->settingCount; i++) {
       
    36 				free(meta->settings[i].name);
       
    37 				free(meta->settings[i].engineCommand);
       
    38 			}
       
    39 			free(meta->settings);
       
    40 		}
       
    41 		if(meta->mods) {
       
    42 			for(int i=0; i<meta->modCount; i++) {
       
    43 				free(meta->mods[i].name);
       
    44 			}
       
    45 			free(meta->mods);
       
    46 		}
       
    47 		free(meta);
       
    48 	}
       
    49 }
       
    50 
       
    51 static flib_metascheme *flib_metascheme_from_ini_handleError(flib_metascheme *result, flib_ini *ini) {
       
    52 	flib_metascheme_destroy(result);
       
    53 	flib_ini_destroy(ini);
       
    54 	return NULL;
       
    55 }
       
    56 
       
    57 static int readMetaSettingSections(flib_ini *ini, flib_metascheme *result, int limit) {
       
    58 	while(result->settingCount<limit) {
       
    59 		char sectionName[32];
       
    60 		if(snprintf(sectionName, sizeof(sectionName), "setting%i", result->settingCount) <= 0) {
       
    61 			return -1;
       
    62 		}
       
    63 		if(!flib_ini_enter_section(ini, sectionName)) {
       
    64 			flib_metascheme_setting *metasetting = &result->settings[result->settingCount];
       
    65 			result->settingCount++;
       
    66 
       
    67 			bool error = false;
       
    68 			error |= flib_ini_get_str(ini, &metasetting->name, "name");
       
    69 			error |= flib_ini_get_str_opt(ini, &metasetting->engineCommand, "command", NULL);
       
    70 			error |= flib_ini_get_bool(ini, &metasetting->times1000, "times1000");
       
    71 			error |= flib_ini_get_bool(ini, &metasetting->maxMeansInfinity, "maxmeansinfinity");
       
    72 			error |= flib_ini_get_int(ini, &metasetting->min, "min");
       
    73 			error |= flib_ini_get_int(ini, &metasetting->max, "max");
       
    74 			error |= flib_ini_get_int(ini, &metasetting->def, "default");
       
    75 			if(error) {
       
    76 				flib_log_e("Missing or malformed ini parameter in metaconfig, section %s", sectionName);
       
    77 				return -1;
       
    78 			}
       
    79 		} else {
       
    80 			return 0;
       
    81 		}
       
    82 	}
       
    83 	return 0;
       
    84 }
       
    85 
       
    86 static int readMetaModSections(flib_ini *ini, flib_metascheme *result, int limit) {
       
    87 	while(result->modCount<limit) {
       
    88 		char sectionName[32];
       
    89 		if(snprintf(sectionName, sizeof(sectionName), "mod%i", result->modCount) <= 0) {
       
    90 			return -1;
       
    91 		}
       
    92 		if(!flib_ini_enter_section(ini, sectionName)) {
       
    93 			flib_metascheme_mod *metamod = &result->mods[result->modCount];
       
    94 			result->modCount++;
       
    95 
       
    96 			bool error = false;
       
    97 			error |= flib_ini_get_str(ini, &metamod->name, "name");
       
    98 			error |= flib_ini_get_int(ini, &metamod->bitmaskIndex, "bitmaskIndex");
       
    99 			if(error) {
       
   100 				flib_log_e("Missing or malformed ini parameter in metaconfig, section %s", sectionName);
       
   101 				return -1;
       
   102 			}
       
   103 		} else {
       
   104 			return 0;
       
   105 		}
       
   106 	}
       
   107 	return 0;
       
   108 }
       
   109 
       
   110 flib_metascheme *flib_metascheme_from_ini(const char *filename) {
       
   111 	if(log_badargs_if(filename==NULL)) {
       
   112 		return NULL;
       
   113 	}
       
   114 	flib_metascheme *result = flib_metascheme_retain(flib_calloc(1, sizeof(flib_metascheme)));
       
   115 	flib_ini *ini = flib_ini_load(filename);
       
   116 
       
   117 	if(!result || !ini) {
       
   118 		return flib_metascheme_from_ini_handleError(result, ini);
       
   119 	}
       
   120 
       
   121 	// We're overallocating here for simplicity
       
   122 	int sectionCount = flib_ini_get_sectioncount(ini);
       
   123 	result->settingCount = 0;
       
   124 	result->modCount = 0;
       
   125 	result->settings = flib_calloc(sectionCount, sizeof(flib_metascheme_setting));
       
   126 	result->mods = flib_calloc(sectionCount, sizeof(flib_metascheme_mod));
       
   127 
       
   128 	if(!result->settings || !result->mods) {
       
   129 		return flib_metascheme_from_ini_handleError(result, ini);
       
   130 	}
       
   131 
       
   132 	if(readMetaSettingSections(ini, result, sectionCount) || readMetaModSections(ini, result, sectionCount)) {
       
   133 		return flib_metascheme_from_ini_handleError(result, ini);
       
   134 	}
       
   135 
       
   136 	if(result->settingCount+result->modCount != sectionCount) {
       
   137 		flib_log_e("Unknown or non-contiguous sections headers in metaconfig.");
       
   138 		return flib_metascheme_from_ini_handleError(result, ini);
       
   139 	}
       
   140 
       
   141 	flib_ini_destroy(ini);
       
   142 	return result;
       
   143 }
       
   144 
       
   145 flib_metascheme *flib_metascheme_retain(flib_metascheme *metainfo) {
       
   146 	if(metainfo) {
       
   147 		flib_retain(&metainfo->_referenceCount, "flib_metascheme");
       
   148 	}
       
   149 	return metainfo;
       
   150 }
       
   151 
       
   152 void flib_metascheme_release(flib_metascheme *meta) {
       
   153 	if(meta && flib_release(&meta->_referenceCount, "flib_metascheme")) {
       
   154 		flib_metascheme_destroy(meta);
       
   155 	}
       
   156 }
       
   157 
       
   158 flib_scheme *flib_scheme_create(flib_metascheme *meta, const char *schemeName) {
       
   159 	flib_scheme *result = flib_calloc(1, sizeof(flib_scheme));
    32 	flib_scheme *result = flib_calloc(1, sizeof(flib_scheme));
   160 	if(log_badargs_if2(meta==NULL, schemeName==NULL) || result==NULL) {
    33 	if(log_badargs_if(schemeName==NULL) || result==NULL) {
   161 		return NULL;
    34 		return NULL;
   162 	}
    35 	}
   163 
    36 
   164 	result->meta = flib_metascheme_retain(meta);
       
   165 	result->name = flib_strdupnull(schemeName);
    37 	result->name = flib_strdupnull(schemeName);
   166 	result->mods = flib_calloc(meta->modCount, sizeof(*result->mods));
    38 	result->mods = flib_calloc(flib_meta.modCount, sizeof(*result->mods));
   167 	result->settings = flib_calloc(meta->settingCount, sizeof(*result->settings));
    39 	result->settings = flib_calloc(flib_meta.settingCount, sizeof(*result->settings));
   168 
    40 
   169 	if(!result->mods || !result->settings || !result->name) {
    41 	if(!result->mods || !result->settings || !result->name) {
   170 		flib_scheme_destroy(result);
    42 		flib_scheme_destroy(result);
   171 		return NULL;
    43 		return NULL;
   172 	}
    44 	}
   173 
    45 
   174 	for(int i=0; i<meta->settingCount; i++) {
    46 	for(int i=0; i<flib_meta.settingCount; i++) {
   175 		result->settings[i] = meta->settings[i].def;
    47 		result->settings[i] = flib_meta.settings[i].def;
   176 	}
    48 	}
   177 	return result;
    49 	return result;
   178 }
    50 }
   179 
    51 
   180 flib_scheme *flib_scheme_copy(const flib_scheme *scheme) {
    52 flib_scheme *flib_scheme_copy(const flib_scheme *scheme) {
   181 	flib_scheme *result = NULL;
    53 	flib_scheme *result = NULL;
   182 	if(scheme) {
    54 	if(scheme) {
   183 		result = flib_scheme_create(scheme->meta, scheme->name);
    55 		result = flib_scheme_create(scheme->name);
   184 		if(result) {
    56 		if(result) {
   185 			memcpy(result->mods, scheme->mods, scheme->meta->modCount * sizeof(*scheme->mods));
    57 			memcpy(result->mods, scheme->mods, flib_meta.modCount * sizeof(*scheme->mods));
   186 			memcpy(result->settings, scheme->settings, scheme->meta->settingCount * sizeof(*scheme->settings));
    58 			memcpy(result->settings, scheme->settings, flib_meta.settingCount * sizeof(*scheme->settings));
   187 		}
    59 		}
   188 	}
    60 	}
   189 	return result;
    61 	return result;
   190 }
    62 }
   191 
    63 
   192 void flib_scheme_destroy(flib_scheme* scheme) {
    64 void flib_scheme_destroy(flib_scheme* scheme) {
   193 	if(scheme) {
    65 	if(scheme) {
   194 		flib_metascheme_release(scheme->meta);
       
   195 		free(scheme->mods);
    66 		free(scheme->mods);
   196 		free(scheme->settings);
    67 		free(scheme->settings);
   197 		free(scheme->name);
    68 		free(scheme->name);
   198 		free(scheme);
    69 		free(scheme);
   199 	}
    70 	}
   200 }
    71 }
   201 
    72 
   202 bool flib_scheme_get_mod(flib_scheme *scheme, const char *name) {
    73 bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name) {
   203 	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
    74 	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
   204 		for(int i=0; i<scheme->meta->modCount; i++) {
    75 		for(int i=0; i<flib_meta.modCount; i++) {
   205 			if(!strcmp(scheme->meta->mods[i].name, name)) {
    76 			if(!strcmp(flib_meta.mods[i].name, name)) {
   206 				return scheme->mods[i];
    77 				return scheme->mods[i];
   207 			}
    78 			}
   208 		}
    79 		}
   209 		flib_log_e("Unable to find game mod %s", name);
    80 		flib_log_e("Unable to find game mod %s", name);
   210 	}
    81 	}
   211 	return false;
    82 	return false;
   212 }
    83 }
   213 
    84 
   214 int flib_scheme_get_setting(flib_scheme *scheme, const char *name, int def) {
    85 int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def) {
   215 	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
    86 	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
   216 		for(int i=0; i<scheme->meta->settingCount; i++) {
    87 		for(int i=0; i<flib_meta.settingCount; i++) {
   217 			if(!strcmp(scheme->meta->settings[i].name, name)) {
    88 			if(!strcmp(flib_meta.settings[i].name, name)) {
   218 				return scheme->settings[i];
    89 				return scheme->settings[i];
   219 			}
    90 			}
   220 		}
    91 		}
   221 		flib_log_e("Unable to find game setting %s", name);
    92 		flib_log_e("Unable to find game setting %s", name);
   222 	}
    93 	}