Author: bonefish Date: 2009-11-05 18:32:16 +0100 (Thu, 05 Nov 2009) New Revision: 33903 Changeset: http://dev.haiku-os.org/changeset/33903/haiku Added: haiku/trunk/src/apps/debugger/settings/generic/ haiku/trunk/src/apps/debugger/settings/generic/Setting.cpp haiku/trunk/src/apps/debugger/settings/generic/Setting.h haiku/trunk/src/apps/debugger/settings/generic/Settings.cpp haiku/trunk/src/apps/debugger/settings/generic/Settings.h haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.cpp haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.h Log: Classes to describe settings in a generic way. Added: haiku/trunk/src/apps/debugger/settings/generic/Setting.cpp =================================================================== --- haiku/trunk/src/apps/debugger/settings/generic/Setting.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/settings/generic/Setting.cpp 2009-11-05 17:32:16 UTC (rev 33903) @@ -0,0 +1,265 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "Setting.h" + +#include <new> + + +// #pragma mark - Setting + + +Setting::~Setting() +{ +} + + +// #pragma mark - BoolSetting + + +setting_type +BoolSetting::Type() const +{ + return SETTING_TYPE_BOOL; +} + + +BVariant +BoolSetting::DefaultValue() const +{ + return DefaultBoolValue(); +} + + +// #pragma mark - SettingsOption + + +SettingsOption::~SettingsOption() +{ +} + + +// #pragma mark - OptionsSetting + + +setting_type +OptionsSetting::Type() const +{ + return SETTING_TYPE_OPTIONS; +} + + +BVariant +OptionsSetting::DefaultValue() const +{ + SettingsOption* option = DefaultOption(); + return option != NULL + ? BVariant(option->ID(), B_VARIANT_DONT_COPY_DATA) : BVariant(); +} + + +// #pragma mark - RangeSetting + + +setting_type +RangeSetting::Type() const +{ + return SETTING_TYPE_RANGE; +} + + +// #pragma mark - AbstractSetting + + +AbstractSetting::AbstractSetting(const BString& id, const BString& name) + : + fID(id), + fName(name) +{ +} + + +const char* +AbstractSetting::ID() const +{ + return fID; +} + + +const char* +AbstractSetting::Name() const +{ + return fName; +} + + +// #pragma mark - BoolSettingImpl + + +BoolSettingImpl::BoolSettingImpl(const BString& id, const BString& name, + bool defaultValue) + : + AbstractSetting(id, name), + fDefaultValue(defaultValue) +{ +} + + +bool +BoolSettingImpl::DefaultBoolValue() const +{ + return fDefaultValue; +} + + +// #pragma mark - OptionsSettingImpl + + +class OptionsSettingImpl::Option : public SettingsOption { +public: + Option(const BString& id, const BString& name) + { + } + + virtual const char* ID() const + { + return fID; + } + + virtual const char* Name() const + { + return fName; + } + +private: + BString fID; + BString fName; +}; + + +OptionsSettingImpl::OptionsSettingImpl(const BString& id, const BString& name) + : + AbstractSetting(id, name), + fDefaultOption(NULL) +{ +} + + +OptionsSettingImpl::~OptionsSettingImpl() +{ + SetDefaultOption(NULL); + + for (int32 i = 0; SettingsOption* option = fOptions.ItemAt(i); i++) + option->ReleaseReference(); +} + + +SettingsOption* +OptionsSettingImpl::DefaultOption() const +{ + return fDefaultOption != NULL ? fDefaultOption : fOptions.ItemAt(0); +} + + +int32 +OptionsSettingImpl::CountOptions() const +{ + return fOptions.CountItems(); +} + + +SettingsOption* +OptionsSettingImpl::OptionAt(int32 index) const +{ + return fOptions.ItemAt(index); +} + + +SettingsOption* +OptionsSettingImpl::OptionByID(const char* id) const +{ + for (int32 i = 0; SettingsOption* option = fOptions.ItemAt(i); i++) { + if (strcmp(option->ID(), id) == 0) + return option; + } + + return NULL; +} + + +bool +OptionsSettingImpl::AddOption(SettingsOption* option) +{ + if (!fOptions.AddItem(option)) + return false; + + option->AddReference(); + return true; +} + + +bool +OptionsSettingImpl::AddOption(const BString& id, const BString& name) +{ + Option* option = new(std::nothrow) Option(id, name); + if (option == NULL) + return false; + Reference<Option> optionReference(option, true); + + return AddOption(option); +} + + +void +OptionsSettingImpl::SetDefaultOption(SettingsOption* option) +{ + if (option == fDefaultOption) + return; + + if (fDefaultOption != NULL) + fDefaultOption->ReleaseReference(); + + fDefaultOption = option; + + if (fDefaultOption != NULL) + fDefaultOption->AcquireReference(); +} + + +// #pragma mark - RangeSettingImpl + + +RangeSettingImpl::RangeSettingImpl(const BString& id, const BString& name, + const BVariant& lowerBound, const BVariant& upperBound, + const BVariant& defaultValue) + : + AbstractSetting(id, name), + fLowerBound(lowerBound), + fUpperBound(upperBound), + fDefaultValue(defaultValue) +{ +} + + +BVariant +RangeSettingImpl::DefaultValue() const +{ + return fDefaultValue; +} + + +BVariant +RangeSettingImpl::LowerBound() const +{ + return fLowerBound; +} + + +BVariant +RangeSettingImpl::UpperBound() const +{ + return fUpperBound; +} Added: haiku/trunk/src/apps/debugger/settings/generic/Setting.h =================================================================== --- haiku/trunk/src/apps/debugger/settings/generic/Setting.h (rev 0) +++ haiku/trunk/src/apps/debugger/settings/generic/Setting.h 2009-11-05 17:32:16 UTC (rev 33903) @@ -0,0 +1,152 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef SETTING_H +#define SETTING_H + + +#include <String.h> + +#include <ObjectList.h> +#include <Referenceable.h> +#include <Variant.h> + + +enum setting_type { + SETTING_TYPE_BOOL, + SETTING_TYPE_OPTIONS, + SETTING_TYPE_RANGE +}; + + +class Setting : public BReferenceable { +public: + virtual ~Setting(); + + virtual setting_type Type() const = 0; + virtual const char* ID() const = 0; + virtual const char* Name() const = 0; + + virtual BVariant DefaultValue() const = 0; +}; + + +class BoolSetting : public virtual Setting { +public: + virtual setting_type Type() const; + + virtual BVariant DefaultValue() const; + + virtual bool DefaultBoolValue() const = 0; +}; + + +class SettingsOption : public BReferenceable { +public: + virtual ~SettingsOption(); + + virtual const char* ID() const = 0; + virtual const char* Name() const = 0; +}; + + +class OptionsSetting : public virtual Setting { +public: + virtual setting_type Type() const; + + virtual BVariant DefaultValue() const; + + virtual int32 CountOptions() const = 0; + virtual SettingsOption* OptionAt(int32 index) const = 0; + virtual SettingsOption* OptionByID(const char* id) const = 0; + + virtual SettingsOption* DefaultOption() const = 0; +}; + + +class RangeSetting : public virtual Setting { +public: + virtual setting_type Type() const; + + virtual BVariant LowerBound() const = 0; + virtual BVariant UpperBound() const = 0; +}; + + +class AbstractSetting : public virtual Setting { +public: + AbstractSetting(const BString& id, + const BString& name); + + virtual const char* ID() const; + virtual const char* Name() const; + +private: + BString fID; + BString fName; +}; + + +class BoolSettingImpl : public AbstractSetting, public BoolSetting { +public: + BoolSettingImpl(const BString& id, + const BString& name, bool defaultValue); + + virtual bool DefaultBoolValue() const; + +private: + bool fDefaultValue; +}; + + +class OptionsSettingImpl : public AbstractSetting, public OptionsSetting { +public: + OptionsSettingImpl(const BString& id, + const BString& name); + virtual ~OptionsSettingImpl(); + + virtual SettingsOption* DefaultOption() const; + + virtual int32 CountOptions() const; + virtual SettingsOption* OptionAt(int32 index) const; + virtual SettingsOption* OptionByID(const char* id) const; + + bool AddOption(SettingsOption* option); + bool AddOption(const BString& id, + const BString& name); + + void SetDefaultOption(SettingsOption* option); + +private: + class Option; + + typedef BObjectList<SettingsOption> OptionList; + +private: + OptionList fOptions; + SettingsOption* fDefaultOption; +}; + + +class RangeSettingImpl : public AbstractSetting, public RangeSetting { +public: + RangeSettingImpl(const BString& id, + const BString& name, + const BVariant& lowerBound, + const BVariant& upperBound, + const BVariant& defaultValue); + + virtual BVariant DefaultValue() const; + + virtual BVariant LowerBound() const; + virtual BVariant UpperBound() const; + +private: + BVariant fLowerBound; + BVariant fUpperBound; + BVariant fDefaultValue; +}; + + +#endif // SETTING_H Added: haiku/trunk/src/apps/debugger/settings/generic/Settings.cpp =================================================================== --- haiku/trunk/src/apps/debugger/settings/generic/Settings.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/settings/generic/Settings.cpp 2009-11-05 17:32:16 UTC (rev 33903) @@ -0,0 +1,115 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "Settings.h" + +#include <AutoLocker.h> + +#include "SettingsDescription.h" + + +// #pragma mark - Settings + + +Settings::Settings(SettingsDescription* description) + : + fLock("settings"), + fDescription(description) +{ + fDescription->AcquireReference(); +} + + +Settings::~Settings() +{ + fDescription->ReleaseReference(); +} + + +status_t +Settings::Init() +{ + return fLock.InitCheck(); +} + + +BVariant +Settings::Value(Setting* setting) const +{ + AutoLocker<BLocker> locker(fLock); + + BVariant value; + return value.SetFromMessage(fValues, setting->ID()) == B_OK + ? value : setting->DefaultValue(); +} + + +BVariant +Settings::Value(const char* settingID) const +{ + AutoLocker<BLocker> locker(fLock); + + BVariant value; + if (value.SetFromMessage(fValues, settingID) == B_OK) + return value; + + Setting* setting = fDescription->SettingByID(settingID); + return setting != NULL ? setting->DefaultValue() : value; +} + + +bool +Settings::SetValue(Setting* setting, const BVariant& value) +{ + AutoLocker<BLocker> locker(fLock); + + // remove the message field and re-add it with the new value + const char* fieldName = setting->ID(); + fValues.RemoveName(fieldName); + + bool success = value.AddToMessage(fValues, fieldName) == B_OK; + + // notify the listeners + int32 count = fListeners.CountItems(); + for (int32 i = count - 1; i >= 0; i--) + fListeners.ItemAt(i)->SettingValueChanged(setting); + + return success; +} + + +SettingsOption* +Settings::OptionValue(OptionsSetting* setting) const +{ + BVariant value = Value(setting); + return value.Type() == B_STRING_TYPE + ? setting->OptionByID(value.ToString()) + : setting->DefaultOption(); +} + + +bool +Settings::AddListener(Listener* listener) +{ + AutoLocker<BLocker> locker(fLock); + return fListeners.AddItem(listener); +} + + +void +Settings::RemoveListener(Listener* listener) +{ + AutoLocker<BLocker> locker(fLock); + fListeners.RemoveItem(listener); +} + + +// #pragma mark - Listener + + +Settings::Listener::~Listener() +{ +} Added: haiku/trunk/src/apps/debugger/settings/generic/Settings.h =================================================================== --- haiku/trunk/src/apps/debugger/settings/generic/Settings.h (rev 0) +++ haiku/trunk/src/apps/debugger/settings/generic/Settings.h 2009-11-05 17:32:16 UTC (rev 33903) @@ -0,0 +1,71 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef SETTINGS_H +#define SETTINGS_H + + +#include <Locker.h> +#include <Message.h> + +#include <ObjectList.h> +#include <Referenceable.h> +#include <Variant.h> + +#include "Setting.h" + + +class SettingsDescription; + + +class Settings : public BReferenceable { +public: + class Listener; + +public: + Settings(SettingsDescription* description); + virtual ~Settings(); + + status_t Init(); + + bool Lock() { return fLock.Lock(); } + void Unlock() { fLock.Unlock(); } + + SettingsDescription* Description() const { return fDescription; } + const BMessage& Message() const { return fValues; } + + BVariant Value(Setting* setting) const; + BVariant Value(const char* settingID) const; + bool SetValue(Setting* setting, + const BVariant& value); + + bool BoolValue(BoolSetting* setting) const + { return Value(setting).ToBool(); } + SettingsOption* OptionValue(OptionsSetting* setting) const; + BVariant RangeValue(RangeSetting* setting) const + { return Value(setting); } + + bool AddListener(Listener* listener); + void RemoveListener(Listener* listener); + +private: + typedef BObjectList<Listener> ListenerList; + +private: + mutable BLocker fLock; + SettingsDescription* fDescription; + BMessage fValues; + ListenerList fListeners; +}; + + +class Settings::Listener { +public: + virtual ~Listener(); + + virtual void SettingValueChanged(Setting* setting) = 0; +}; + + +#endif // SETTINGS_H Added: haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.cpp =================================================================== --- haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.cpp 2009-11-05 17:32:16 UTC (rev 33903) @@ -0,0 +1,58 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "SettingsDescription.h" + +#include "Setting.h" + + +SettingsDescription::SettingsDescription() +{ +} + + +SettingsDescription::~SettingsDescription() +{ + for (int32 i = 0; Setting* setting = SettingAt(i); i++) + setting->ReleaseReference(); +} + + +int32 +SettingsDescription::CountSettings() const +{ + return fSettings.CountItems(); +} + + +Setting* +SettingsDescription::SettingAt(int32 index) const +{ + return fSettings.ItemAt(index); +} + + +Setting* +SettingsDescription::SettingByID(const char* id) const +{ + for (int32 i = 0; Setting* setting = fSettings.ItemAt(i); i++) { + if (strcmp(setting->ID(), id) == 0) + return setting; + } + + return NULL; +} + + +bool +SettingsDescription::AddSetting(Setting* setting) +{ + if (!fSettings.AddItem(setting)) + return false; + + setting->AcquireReference(); + return true; +} Added: haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.h =================================================================== --- haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.h (rev 0) +++ haiku/trunk/src/apps/debugger/settings/generic/SettingsDescription.h 2009-11-05 17:32:16 UTC (rev 33903) @@ -0,0 +1,35 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef SETTINGS_DESCRIPTION_H +#define SETTINGS_DESCRIPTION_H + + +#include <ObjectList.h> +#include <Referenceable.h> + + +class Setting; + + +class SettingsDescription : public BReferenceable { +public: + SettingsDescription(); + virtual ~SettingsDescription(); + + int32 CountSettings() const; + Setting* SettingAt(int32 index) const; + Setting* SettingByID(const char* id) const; + + bool AddSetting(Setting* setting); + +private: + typedef BObjectList<Setting> SettingsList; + +private: + SettingsList fSettings; +}; + + +#endif // SETTINGS_DESCRIPTION_H