// $Id: SettingImpl.hh 5770 2006-10-12 11:09:22Z m9710797 $ #ifndef SETTING_HH #define SETTING_HH #include "Setting.hh" #include "SettingsConfig.hh" #include "MSXException.hh" #include "CommandController.hh" namespace openmsx { template class SettingChecker; template class SettingImpl : public Setting, public POLICY { public: typedef POLICY Policy; typedef typename POLICY::Type Type; SettingImpl(CommandController& commandController, const std::string& name, const std::string& description, const Type& initialValue, SaveSetting save); template SettingImpl(CommandController& commandController, const std::string& name, const std::string& description, const Type& initialValue, SaveSetting save, T1 extra1, T2 extra2); virtual ~SettingImpl(); /** Gets the current value of this setting. */ Type getValue() const; /** Changes the current value of this setting. * If the given value is invalid, it will be mapped to the closest * valid value. * If that is not appropriate or possible, * the value of this setting will not change. * @param newValue The new value. */ void setValue(Type newValue); /** Get the default value of this setting */ const Type& getDefaultValue() const; /** Set a new default value */ void setRestoreValue(const Type& value); /** */ void setChecker(SettingChecker* checker); // virtual methods from Setting class virtual std::string getTypeString() const; virtual std::string getValueString() const; virtual std::string getDefaultValueString() const; virtual std::string getRestoreValueString() const; virtual void setValueString(const std::string& valueString); virtual void restoreDefault(); virtual bool hasDefaultValue() const; virtual void tabCompletion(std::vector& tokens) const; virtual void additionalInfo(TclObject& result) const; private: void init(); void setValue2(Type newValue, bool check); void setValueString2(const std::string& valueString, bool check); Type value; const Type defaultValue; Type restoreValue; SettingChecker* checker; }; template class SettingChecker { public: virtual void check(SettingImpl& setting, typename SettingImpl::Type& value) = 0; protected: virtual ~SettingChecker() {} }; template SettingImpl::SettingImpl( CommandController& commandController, const std::string& name, const std::string& description, const Type& initialValue, SaveSetting save) : Setting(commandController, name, description, save) , POLICY(commandController) , value(initialValue), defaultValue(initialValue) , restoreValue(initialValue) , checker(NULL) { init(); } template template SettingImpl::SettingImpl( CommandController& commandController, const std::string& name, const std::string& description, const Type& initialValue, SaveSetting save, T1 extra1, T2 extra2) : Setting(commandController, name, description, save) , POLICY(commandController, extra1, extra2) , value(initialValue), defaultValue(initialValue) , restoreValue(initialValue) , checker(NULL) { init(); } template void SettingImpl::init() { CommandController& commandController = Setting::getCommandController(); SettingsConfig& settingsConfig = commandController.getSettingsConfig(); if (needLoadSave()) { const XMLElement* config = settingsConfig.findChild("settings"); if (config) { const XMLElement* elem = config->findChildWithAttribute( "setting", "id", getName()); if (elem) { try { setValueString2(elem->getData(), false); } catch (MSXException& e) { // saved value no longer valid, just keep default } } } } commandController.registerSetting(*this); } template SettingImpl::~SettingImpl() { CommandController& commandController = Setting::getCommandController(); SettingsConfig& settingsConfig = commandController.getSettingsConfig(); sync(settingsConfig); commandController.unregisterSetting(*this); } template typename SettingImpl::Type SettingImpl::getValue() const { return POLICY::checkGetValue(value); } template void SettingImpl::setValue(Type newValue) { setValue2(newValue, true); } template void SettingImpl::setValue2(Type newValue, bool check) { if (check) { POLICY::checkSetValue(newValue); } if (checker) { checker->check(*this, newValue); } if (newValue != value) { value = newValue; notify(); } } template const typename SettingImpl::Type& SettingImpl::getDefaultValue() const { return defaultValue; } template void SettingImpl::setRestoreValue(const Type& value) { restoreValue = value; } template void SettingImpl::setChecker(SettingChecker* checker_) { checker = checker_; if (checker) { setValue(getValue()); } } template std::string SettingImpl::getTypeString() const { return POLICY::getTypeString(); } template std::string SettingImpl::getValueString() const { return POLICY::toString(getValue()); } template std::string SettingImpl::getDefaultValueString() const { return POLICY::toString(getDefaultValue()); } template std::string SettingImpl::getRestoreValueString() const { return POLICY::toString(restoreValue); } template void SettingImpl::setValueString(const std::string& valueString) { setValueString2(valueString, true); } template void SettingImpl::setValueString2(const std::string& valueString, bool check) { setValue2(POLICY::fromString(valueString), check); } template void SettingImpl::restoreDefault() { setValue(restoreValue); } template bool SettingImpl::hasDefaultValue() const { return getValue() == getDefaultValue(); } template void SettingImpl::tabCompletion(std::vector& tokens) const { POLICY::tabCompletion(tokens); } template void SettingImpl::additionalInfo(TclObject& result) const { POLICY::additionalInfo(result); } } // namespace openmsx #endif