refactors
[clinton/Smoothieware.git] / src / libs / Config.cpp
index b2d9bc0..9036b34 100644 (file)
@@ -19,96 +19,80 @@ using namespace std;
 #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;
+Config::Config()
+{
+    this->config_cache = NULL;
 
     // Config source for firm config found in src/config.default
-    this->config_sources.push_back( new FirmConfigSource() );
+    this->config_sources.push_back( new FirmConfigSource("firm") );
 
     // Config source for */config files
-    FileConfigSourcefcs = NULL;
+    FileConfigSource *fcs = NULL;
     if( file_exists("/local/config") )
-        fcs = new FileConfigSource("/local/config", LOCAL_CONFIGSOURCE_CHECKSUM);
+        fcs = new FileConfigSource("/local/config", "local");
     else if( file_exists("/local/config.txt") )
-        fcs = new FileConfigSource("/local/config.txt", LOCAL_CONFIGSOURCE_CHECKSUM);
-    if( fcs != NULL ){
+        fcs = new FileConfigSource("/local/config.txt", "local");
+    if( fcs != NULL ) {
         this->config_sources.push_back( fcs );
         fcs = NULL;
     }
     if( file_exists("/sd/config") )
-       fcs = new FileConfigSource("/sd/config",    SD_CONFIGSOURCE_CHECKSUM   );
+        fcs = new FileConfigSource("/sd/config", "sd");
     else if( file_exists("/sd/config.txt") )
-       fcs = new FileConfigSource("/sd/config.txt",    SD_CONFIGSOURCE_CHECKSUM   );
+        fcs = new FileConfigSource("/sd/config.txt", "sd");
     if( fcs != NULL )
         this->config_sources.push_back( fcs );
-
-    // Pre-load the config cache
-    this->config_cache_load();
-
 }
 
-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 ){
-    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->kernel->call_event(ON_CONFIG_RELOAD);
+Config::Config(ConfigSource *cs)
+{
+    this->config_cache = NULL;
+    this->config_sources.push_back( cs );
 }
 
-// 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]);
-        }
+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)
+{
+    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( unsigned int i = 0; i < this->config_sources.size(); i++ ){
-        ConfigSource* source = this->config_sources[i];
-        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(){
-    while( ! this->config_cache.empty() ){
-        delete this->config_cache.back();
-        this->config_cache.pop_back();
-    }
-    this->config_cache_loaded = false;
+void Config::config_cache_clear()
+{
+    delete this->config_cache;
+    this->config_cache= NULL;
 }
 
 // Three ways to read a value from the config, depending on adress length
-ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c ){
+ConfigValue *Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c )
+{
     uint16_t check_sums[3];
     check_sums[0] = check_sum_a;
     check_sums[1] = check_sum_b;
@@ -116,51 +100,29 @@ ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t
     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[]){
-    ConfigValue* result = this->config_cache[0];
-    bool cache_preloaded = this->config_cache_loaded;
-    if( !cache_preloaded ){ this->config_cache_load(); }
-
-    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;
+ConfigValue *Config::value(uint16_t check_sums[])
+{
+    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;
 }