#include "libs/SerialMessage.h"
#include "libs/ConfigSources/FileConfigSource.h"
#include "libs/ConfigSources/FirmConfigSource.h"
+#include "StreamOutputPool.h"
// Add various config sources. Config can be fetched from several places.
// All values are read into a cache, that is then used by modules to read their configuration
Config::Config()
{
- this->config_cache_loaded = false;
+ this->config_cache = NULL;
// Config source for firm config found in src/config.default
this->config_sources.push_back( new FirmConfigSource("firm") );
this->config_sources.push_back( fcs );
}
-void Config::on_module_loaded() {}
-
-void Config::on_console_line_received( void *argument ) {}
-
-// Set a value in the config cache, but not in any config source
-void Config::set_string( string setting, string value )
+Config::Config(ConfigSource *cs)
{
- ConfigValue *cv = new ConfigValue;
- cv->found = true;
- get_checksums(cv->check_sums, setting);
- cv->value = value;
-
- this->config_cache.replace_or_push_back(cv);
+ this->config_cache = NULL;
+ this->config_sources.push_back( cs );
+}
- THEKERNEL->call_event(ON_CONFIG_RELOAD);
+Config::~Config()
+{
+ config_cache_clear();
+ for(auto i : this->config_sources) {
+ delete i;
+ }
}
// Get a list of modules, used by module "pools" that look for the "enable" keyboard to find things like "moduletype.modulename.enable" as the marker of a new instance of a module
void Config::get_module_list(vector<uint16_t> *list, uint16_t family)
{
- for( unsigned int i = 1; i < this->config_cache.size(); i++) {
- ConfigValue *value = this->config_cache.at(i);
- //if( value->check_sums.size() == 3 && value->check_sums.at(2) == CHECKSUM("enable") && value->check_sums.at(0) == family ){
- if( value->check_sums[2] == CHECKSUM("enable") && value->check_sums[0] == family ) {
- // We found a module enable for this family, add it's number
- list->push_back(value->check_sums[1]);
- }
- }
+ this->config_cache->collect(family, CHECKSUM("enable"), list);
}
-
// Command to load config cache into buffer for multiple reads during init
-void Config::config_cache_load()
+void Config::config_cache_load(bool parse)
{
-
// First clear the cache
this->config_cache_clear();
- // First element is a special empty ConfigValue for values not found
- ConfigValue *result = new ConfigValue;
- this->config_cache.push_back(result);
-
- // For each ConfigSource in our stack
- for( ConfigSource *source : this->config_sources ) {
- source->transfer_values_to_cache(&this->config_cache);
+ this->config_cache= new ConfigCache;
+ if(parse) {
+ // For each ConfigSource in our stack
+ for( ConfigSource *source : this->config_sources ) {
+ source->transfer_values_to_cache(this->config_cache);
+ }
}
-
- this->config_cache_loaded = true;
}
// Command to clear the config cache after init
void Config::config_cache_clear()
{
- for (ConfigValue *i : this->config_cache) {
- delete i;
- }
-
- //this->config_cache.clear(); // does not release vector memory
- ConfigCache().swap(this->config_cache); // makes sure the vector releases its memory
- this->config_cache_loaded = false;
+ delete this->config_cache;
+ this->config_cache= NULL;
}
// Three ways to read a value from the config, depending on adress length
return this->value(check_sums);
}
-ConfigValue *Config::value(uint16_t check_sum_a, uint16_t check_sum_b)
-{
- uint16_t check_sums[3];
- check_sums[0] = check_sum_a;
- check_sums[1] = check_sum_b;
- check_sums[2] = 0x0000;
- return this->value(check_sums);
-}
-
-ConfigValue *Config::value(uint16_t check_sum)
-{
- uint16_t check_sums[3];
- check_sums[0] = check_sum;
- check_sums[1] = 0x0000;
- check_sums[2] = 0x0000;
- return this->value(check_sums);
-}
+static ConfigValue dummyValue;
// Get a value from the configuration as a string
// Because we don't like to waste space in Flash with lengthy config parameter names, we take a checksum instead so that the name does not have to be stored
// See get_checksum
ConfigValue *Config::value(uint16_t check_sums[])
{
- bool cache_preloaded = this->config_cache_loaded;
- if( !cache_preloaded ) {
- this->config_cache_load();
- }
- ConfigValue *result = this->config_cache[0];
-
- for( unsigned int i = 1; i < this->config_cache.size(); i++) {
- // If this line matches the checksum
- bool match = true;
- unsigned int counter = 0;
- while(check_sums[counter] != 0x0000 && counter <= 2 ) {
- if(this->config_cache[i]->check_sums[counter] != check_sums[counter] ) {
- match = false;
- break;
- }
- counter++;
- }
- if( match == false ) {
- continue;
- }
- result = this->config_cache[i];
- break;
+ if( !is_config_cache_loaded() ) {
+ THEKERNEL->streams->printf("ERROR: calling value after config cache has been cleared\n");
+ // note this will cause whatever called it to blow up!
+ return NULL;
}
- if( !cache_preloaded ) {
- this->config_cache_clear();
+ ConfigValue *result = this->config_cache->lookup(check_sums);
+
+ if(result == NULL) {
+ // create a dummy value for this to play with, each call requires it's own value not a shared one
+ // result= new ConfigValue(check_sums);
+ // config_cache->add(result);
+ dummyValue.clear();
+ result = &dummyValue;
}
+
return result;
}