#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") );
// Set a value in the config cache, but not in any config source
void Config::set_string( string setting, string value )
{
+ if(!is_config_cache_loaded()) return;
+
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->replace_or_push_back(cv);
THEKERNEL->call_event(ON_CONFIG_RELOAD);
}
// 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);
-}
-
// 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);
}
+
return result;
}
#ifndef CONFIG_H
#define CONFIG_H
-#include "ConfigCache.h"
using namespace std;
#include <vector>
class ConfigValue;
class ConfigSource;
+class ConfigCache;
class Config : public Module {
public:
void on_module_loaded();
void on_console_line_received( void* argument );
- void config_cache_load();
+ void config_cache_load(bool parse= true);
void config_cache_clear();
void set_string( string setting , string value);
- ConfigValue* value(uint16_t check_sum);
- ConfigValue* value(uint16_t check_sum_a, uint16_t check_sum_b);
- ConfigValue* value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c );
+ ConfigValue* value(uint16_t check_sum_a, uint16_t check_sum_b= 0, uint16_t check_sum_c= 0 );
ConfigValue* value(uint16_t check_sums[3] );
void get_module_list(vector<uint16_t>* list, uint16_t family);
+ bool is_config_cache_loaded() { return config_cache != NULL; }; // Whether or not the cache is currently popluated
+ friend class Configurator;
+
+ private:
bool has_characters(uint16_t check_sum, string str );
- ConfigCache config_cache; // A cache in which ConfigValues are kept
+ ConfigCache* config_cache; // A cache in which ConfigValues are kept
vector<ConfigSource*> config_sources; // A list of all possible coniguration sources
- bool config_cache_loaded; // Whether or not the cache is currently popluated
};
#endif
#include "ConfigCache.h"
#include "ConfigValue.h"
+#include "libs/StreamOutput.h"
+
+ConfigCache::ConfigCache()
+{
+}
+
+ConfigCache::~ConfigCache()
+{
+ clear();
+}
+
+void ConfigCache::clear()
+{
+ for (ConfigValue *i : store) {
+ delete i;
+ }
+ vector<ConfigValue*>().swap(store); // makes sure the vector releases its memory
+}
+
// If we find an existing value, replace it, otherwise, push it at the back of the list
void ConfigCache::replace_or_push_back(ConfigValue *new_value)
{
bool value_exists = false;
+
// For each already existing element
- for( unsigned int i = 1; i < this->size(); i++) {
+ for(ConfigValue*& i: store) {
// If this configvalue matches the checksum
bool match = true;
unsigned int counter = 0;
while( counter < 3 && new_value->check_sums[counter] != 0x0000 ) {
- if(this->at(i)->check_sums[counter] != new_value->check_sums[counter] ) {
+ if(i->check_sums[counter] != new_value->check_sums[counter] ) {
match = false;
break;
}
counter++;
}
- if( match == false ) {
+ if( !match ) {
continue;
}
value_exists = true;
// Replace with the provided value
- delete this->at(i);
- this->at(i) = new_value;
+ i= new_value;
break;
}
// Value does not already exists, add to the list
- if( value_exists == false ) {
- this->push_back(new_value);
+ if( !value_exists ) {
+ store.push_back(new_value);
+ }
+
+}
+
+ConfigValue *ConfigCache::lookup(const uint16_t *check_sums) const
+{
+ for( ConfigValue *cv : store) {
+ if(memcmp(check_sums, cv->check_sums, sizeof(cv->check_sums)) == 0)
+ return cv;
}
+ return NULL;
+}
+
+void ConfigCache::collect(uint16_t family, uint16_t cs, vector<uint16_t> *list)
+{
+ for( ConfigValue *value : store ) {
+ if( value->check_sums[2] == cs && value->check_sums[0] == family ) {
+ // We found a module enable for this family, add it's number
+ list->push_back(value->check_sums[1]);
+ }
+ }
+}
+
+void ConfigCache::dump(StreamOutput *stream)
+{
+ int l= 1;
+ for( ConfigValue *v : store ) {
+ stream->printf("%3d - %04X %04X %04X : '%s' - found: %d, default: %d, default-double: %f, default-int: %d\n",
+ l++, v->check_sums[0], v->check_sums[1], v->check_sums[2], v->value.c_str(), v->found, v->default_set, v->default_double, v->default_int );
+ }
}
using namespace std;
#include <vector>
+#include <stdint.h>
class ConfigValue;
+class StreamOutput;
-class ConfigCache : public std::vector<ConfigValue*> {
+class ConfigCache {
public:
- ConfigCache(){}
+ ConfigCache();
+ ~ConfigCache();
+ void clear();
+
+ void add(ConfigValue* v) { store.push_back(v); }
+
+ // lookup and return the entru that matches the check sums,return NULL if not found
+ ConfigValue *lookup(const uint16_t *check_sums) const;
+
+ // collect enabled checksums of the given family
+ void collect(uint16_t family, uint16_t cs, vector<uint16_t> *list);
// If we find an existing value, replace it, otherwise, push it at the back of the list
void replace_or_push_back(ConfigValue* new_value);
+ // used for debugging, dumps the cache to a stream
+ void dump(StreamOutput *stream);
+
+ private:
+ vector<ConfigValue*> store;
};
#include "Pwm.h"
-#define printErrorandExit(...) THEKERNEL->streams->printf(__VA_ARGS__); exit(1);
+#define printErrorandExit(...) THEKERNEL->streams->printf(__VA_ARGS__); // exit(1);
#include <vector>
#include <stdio.h>
this->check_sums[0] = 0x0000;
this->check_sums[1] = 0x0000;
this->check_sums[2] = 0x0000;
+ this->default_double= 0.0F;
+ this->default_int= 0;
+ this->value= "";
+}
+
+ConfigValue::ConfigValue(uint16_t *cs) {
+ memcpy(this->check_sums, cs, sizeof(this->check_sums));
+ this->found = false;
+ this->default_set = false;
+ this->value= "";
+}
+
+ConfigValue::ConfigValue(const ConfigValue& to_copy)
+{
+ this->found = to_copy.found;
+ this->default_set = to_copy.default_set;
+ memcpy(this->check_sums, to_copy.check_sums, sizeof(this->check_sums));
+ this->value.assign(to_copy.value);
+}
+
+ConfigValue& ConfigValue::operator= (const ConfigValue& to_copy)
+{
+ if( this != &to_copy ){
+ this->found = to_copy.found;
+ this->default_set = to_copy.default_set;
+ memcpy(this->check_sums, to_copy.check_sums, sizeof(this->check_sums));
+ this->value.assign(to_copy.value);
+ }
+ return *this;
}
ConfigValue *ConfigValue::required()
{
- if( this->found == true ) {
- return this;
- } else {
+ if( !this->found ) {
printErrorandExit("could not find config setting, please see http://smoothieware.org/configuring-smoothie\r\n");
}
+ return this;
}
float ConfigValue::as_number()
} else {
char *endptr = NULL;
string str = remove_non_number(this->value);
- float result = strtof(str.c_str(), &endptr);
- if( endptr <= str.c_str() ) {
- printErrorandExit("config setting with value '%s' and checksums[%u,%u,%u] is not a valid number, please see http://smoothieware.org/configuring-smoothie\r\n", this->value.c_str(), this->check_sums[0], this->check_sums[1], this->check_sums[2] );
+ const char *cp= str.c_str();
+ float result = strtof(cp, &endptr);
+ if( endptr <= cp ) {
+ printErrorandExit("config setting with value '%s' and checksums[%04X,%04X,%04X] is not a valid number, please see http://smoothieware.org/configuring-smoothie\r\n", this->value.c_str(), this->check_sums[0], this->check_sums[1], this->check_sums[2] );
}
return result;
}
} else {
char *endptr = NULL;
string str = remove_non_number(this->value);
- int result = strtol(str.c_str(), &endptr, 10);
- if( endptr <= str.c_str() ) {
- printErrorandExit("config setting with value '%s' and checksums[%u,%u,%u] is not a valid number, please see http://smoothieware.org/configuring-smoothie\r\n", this->value.c_str(), this->check_sums[0], this->check_sums[1], this->check_sums[2] );
+ const char *cp= str.c_str();
+ int result = strtol(cp, &endptr, 10);
+ if( endptr <= cp ) {
+ printErrorandExit("config setting with value '%s' and checksums[%04X,%04X,%04X] is not a valid int, please see http://smoothieware.org/configuring-smoothie\r\n", this->value.c_str(), this->check_sums[0], this->check_sums[1], this->check_sums[2] );
}
return result;
}
bool ConfigValue::as_bool()
{
if( this->found == false && this->default_set == true ) {
- return this->default_double;
+ return this->default_int;
} else {
- if( this->value.find_first_of("ty1") != string::npos ) {
- return true;
- } else {
- return false;
- }
+ return this->value.find_first_of("ty1") != string::npos;
}
}
{
this->default_set = true;
this->default_int = val;
- this->default_double = val;
+ this->default_double = val; // we need to set both becuase sometimes an integer is passed when it should be a float
return this;
}
return this;
}
-bool ConfigValue::has_characters( string mask )
+bool ConfigValue::has_characters( const char *mask )
{
if( this->value.find_first_of(mask) != string::npos ) {
return true;
bool ConfigValue::is_inverted()
{
- return this->has_characters(string("!"));
+ return this->has_characters("!");
}
#ifndef CONFIGVALUE_H
#define CONFIGVALUE_H
-using namespace std;
#include <string>
+using std::string;
class ConfigValue{
public:
ConfigValue();
+ ConfigValue(uint16_t *check_sums);
+ ConfigValue(const ConfigValue& to_copy);
+ ConfigValue& operator= (const ConfigValue& to_copy);
ConfigValue* required();
float as_number();
int as_int();
- string as_string();
bool as_bool();
+ string as_string();
ConfigValue* by_default(float val);
ConfigValue* by_default(string val);
ConfigValue* by_default(int val);
- bool has_characters( string mask );
bool is_inverted();
+
+ friend class ConfigCache;
+ friend class Config;
+ friend class ConfigSource;
+ friend class Configurator;
+
+ private:
+ bool has_characters( const char* mask );
+ string value;
int default_int;
float default_double;
uint16_t check_sums[3];
- string value;
bool found;
bool default_set;
};
#include "version.h"
#include "system_LPC17xx.h"
+#include "mbed.h"
+
#define second_usb_serial_enable_checksum CHECKSUM("second_usb_serial_enable")
#define disable_msd_checksum CHECKSUM("msd_disable")
#define disable_leds_checksum CHECKSUM("leds_disable")
leds[i]= 0;
}
+ Timer timer;
+ timer.start();
+ float begin, end;
+ begin = timer.read();
+
Kernel* kernel = new Kernel();
kernel->streams->printf("Smoothie Running @%ldMHz\r\n", SystemCoreClock / 1000000);
}
}
+ end = timer.read();
+ kernel->streams->printf("boot time= %f\n", end-begin);
+
uint16_t cnt= 0;
// Main loop
while(1){
// Preset values for various common types of thermistors
ConfigValue* thermistor = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, thermistor_checksum);
- if( thermistor->value.compare("EPCOS100K" ) == 0 ){ // Default
- }else if( thermistor->value.compare("RRRF100K" ) == 0 ){ this->beta = 3960;
- }else if( thermistor->value.compare("RRRF10K" ) == 0 ){ this->beta = 3964; this->r0 = 10000; this->r1 = 680; this->r2 = 1600;
- }else if( thermistor->value.compare("Honeywell100K") == 0 ){ this->beta = 3974;
- }else if( thermistor->value.compare("Semitec" ) == 0 ){ this->beta = 4267;
- }else if( thermistor->value.compare("HT100K" ) == 0 ){ this->beta = 3990; }
+ if( thermistor->as_string().compare("EPCOS100K" ) == 0 ){ // Default
+ }else if( thermistor->as_string().compare("RRRF100K" ) == 0 ){ this->beta = 3960;
+ }else if( thermistor->as_string().compare("RRRF10K" ) == 0 ){ this->beta = 3964; this->r0 = 10000; this->r1 = 680; this->r2 = 1600;
+ }else if( thermistor->as_string().compare("Honeywell100K") == 0 ){ this->beta = 3974;
+ }else if( thermistor->as_string().compare("Semitec" ) == 0 ){ this->beta = 4267;
+ }else if( thermistor->as_string().compare("HT100K" ) == 0 ){ this->beta = 3990; }
// Preset values are overriden by specified values
this->r0 = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, r0_checksum )->by_default(this->r0 )->as_number(); // Stated resistance eg. 100K
#include "ConfigSource.h"
#include "FileConfigSource.h"
#include "ConfigValue.h"
+#include "ConfigCache.h"
#define CONF_NONE 0
#define CONF_ROM 1
#define config_set_command_checksum CHECKSUM("config-set")
#define config_load_command_checksum CHECKSUM("config-load")
-void Configurator::on_module_loaded(){
+void Configurator::on_module_loaded()
+{
this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
-// this->register_for_event(ON_GCODE_RECEIVED);
-// this->register_for_event(ON_MAIN_LOOP);
+ // this->register_for_event(ON_GCODE_RECEIVED);
+ // this->register_for_event(ON_MAIN_LOOP);
}
// When a new line is received, check if it is a command, and if it is, act upon it
-void Configurator::on_console_line_received( void* argument ){
- SerialMessage new_message = *static_cast<SerialMessage*>(argument);
+void Configurator::on_console_line_received( void *argument )
+{
+ SerialMessage new_message = *static_cast<SerialMessage *>(argument);
// ignore comments
if(new_message.message[0] == ';') return;
string possible_command = new_message.message;
// We don't compare to a string but to a checksum of that string, this saves some space in flash memory
- uint16_t check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient
+ uint16_t check_sum = get_checksum( possible_command.substr(0, possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient
// Act depending on command
if (check_sum == config_get_command_checksum)
}
// Process and respond to eeprom gcodes (M50x)
-void Configurator::on_gcode_received(void* argument){
- Gcode* gcode = static_cast<Gcode*>(argument);
- if( gcode->has_letter('G') ){
+void Configurator::on_gcode_received(void *argument)
+{
+ Gcode *gcode = static_cast<Gcode *>(argument);
+ if( gcode->has_letter('G') ) {
int code = gcode->get_value('G');
- switch( code ){
+ switch( code ) {
}
- }
- else if( gcode->has_letter('M') ){
+ } else if( gcode->has_letter('M') ) {
int code = gcode->get_value('M');
- switch( code ){
+ switch( code ) {
}
}
}
-void Configurator::on_main_loop(void* argument){}
+void Configurator::on_main_loop(void *argument) {}
// Output a ConfigValue from the specified ConfigSource to the stream
-void Configurator::config_get_command( string parameters, StreamOutput* stream ){
+void Configurator::config_get_command( string parameters, StreamOutput *stream )
+{
string source = shift_parameter(parameters);
string setting = shift_parameter(parameters);
- if (setting == "") { // output live setting
+ if (setting == "") { // output settings from the config-cache
setting = source;
source = "";
uint16_t setting_checksums[3];
get_checksums(setting_checksums, setting );
- ConfigValue* cv = THEKERNEL->config->value(setting_checksums);
- string value = "";
- if(cv->found){
- value = cv->as_string();
- stream->printf( "live: %s is set to %s\r\n", setting.c_str(), value.c_str() );
- }else{
- stream->printf( "live: %s is not in config\r\n", setting.c_str());
+ THEKERNEL->config->config_cache_load(); // need to load config cache first as it is unloaded after booting
+ ConfigValue *cv = THEKERNEL->config->value(setting_checksums);
+ if(cv != NULL && cv->found) {
+ string value = cv->as_string();
+ stream->printf( "cached: %s is set to %s\r\n", setting.c_str(), value.c_str() );
+ } else {
+ stream->printf( "cached: %s is not in config\r\n", setting.c_str());
}
+ THEKERNEL->config->config_cache_clear();
- } else { // output setting from specified source
+ } else { // output setting from specified source by parsing the config file
uint16_t source_checksum = get_checksum( source );
uint16_t setting_checksums[3];
get_checksums(setting_checksums, setting );
- for(unsigned int i=0; i < THEKERNEL->config->config_sources.size(); i++){
- if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ){
+ for(unsigned int i = 0; i < THEKERNEL->config->config_sources.size(); i++) {
+ if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ) {
string value = THEKERNEL->config->config_sources[i]->read(setting_checksums);
- if(value.empty()){
+ if(value.empty()) {
stream->printf( "%s: %s is not in config\r\n", source.c_str(), setting.c_str() );
- }else{
+ } else {
stream->printf( "%s: %s is set to %s\r\n", source.c_str(), setting.c_str(), value.c_str() );
}
break;
}
// Write the specified setting to the specified ConfigSource
-void Configurator::config_set_command( string parameters, StreamOutput* stream ){
+void Configurator::config_set_command( string parameters, StreamOutput *stream )
+{
string source = shift_parameter(parameters);
string setting = shift_parameter(parameters);
string value = shift_parameter(parameters);
- if(source.empty() || setting.empty()|| value.empty()) {
+ if(source.empty() || setting.empty() || value.empty()) {
stream->printf( "Usage: config-set source setting value # where source is sd, setting is the key and value is the new value\r\n" );
return;
}
uint16_t source_checksum = get_checksum(source);
- for(unsigned int i=0; i < THEKERNEL->config->config_sources.size(); i++){
- if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ){
+ for(unsigned int i = 0; i < THEKERNEL->config->config_sources.size(); i++) {
+ if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ) {
if(THEKERNEL->config->config_sources[i]->write(setting, value)) {
stream->printf( "%s: %s has been set to %s\r\n", source.c_str(), setting.c_str(), value.c_str() );
- }else{
+ } else {
stream->printf( "%s: %s not enough space to overwrite existing key/value\r\n", source.c_str(), setting.c_str() );
}
return;
*/
}
-// Reload config values from the specified ConfigSource
-void Configurator::config_load_command( string parameters, StreamOutput* stream ){
+// Reload config values from the specified ConfigSource, NOTE this probably does not work anymore
+// also used for debugging by dumping the config-cache
+void Configurator::config_load_command( string parameters, StreamOutput *stream )
+{
string source = shift_parameter(parameters);
- if(source == ""){
+ if(source == "load") {
+ THEKERNEL->config->config_cache_load();
+ stream->printf( "config cache loaded\r\n" );
+
+ } else if(source == "unload") {
+ THEKERNEL->config->config_cache_clear();
+ stream->printf( "config cache unloaded\r\n" );
+
+ } else if(source == "dump") {
+ THEKERNEL->config->config_cache_load();
+ THEKERNEL->config->config_cache->dump(stream);
+ THEKERNEL->config->config_cache_clear();
+
+ } else if(source == "checksum") {
+ string key = shift_parameter(parameters);
+ uint16_t cs[3];
+ get_checksums(cs, key);
+ stream->printf( "checksum of %s = %02X %02X %02X\n", key.c_str(), cs[0], cs[1], cs[2]);
+
+ } else if(source == "") {
THEKERNEL->config->config_cache_load();
THEKERNEL->call_event(ON_CONFIG_RELOAD);
stream->printf( "Reloaded settings\r\n" );
- } else if(file_exists(source)){
+ THEKERNEL->config->config_cache_clear();
+
+ } else if(file_exists(source)) {
FileConfigSource fcs(source, "userfile");
- fcs.transfer_values_to_cache(&THEKERNEL->config->config_cache);
+ THEKERNEL->config->config_cache_load(false);
+ fcs.transfer_values_to_cache(THEKERNEL->config->config_cache);
THEKERNEL->call_event(ON_CONFIG_RELOAD);
stream->printf( "Loaded settings from %s\r\n", source.c_str() );
+ THEKERNEL->config->config_cache_clear();
+
} else {
uint16_t source_checksum = get_checksum(source);
- for(unsigned int i=0; i < THEKERNEL->config->config_sources.size(); i++){
- if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ){
- THEKERNEL->config->config_sources[i]->transfer_values_to_cache(&THEKERNEL->config->config_cache);
+ for(unsigned int i = 0; i < THEKERNEL->config->config_sources.size(); i++) {
+ if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ) {
+ THEKERNEL->config->config_cache_load(false);
+ THEKERNEL->config->config_sources[i]->transfer_values_to_cache(THEKERNEL->config->config_cache);
THEKERNEL->call_event(ON_CONFIG_RELOAD);
stream->printf( "Loaded settings from %s\r\n", source.c_str() );
+ THEKERNEL->config->config_cache_clear();
break;
}
}