/* Copyright (c) 2013 yvt This file is part of OpenSpades. OpenSpades is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenSpades is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSpades. If not, see . */ #pragma once #include #include #include #include namespace spades { enum class SettingItemFlags { None = 0 }; inline SettingItemFlags operator|(SettingItemFlags lhs, SettingItemFlags rhs) { using T = std::underlying_type::type; return (SettingItemFlags)(static_cast(lhs) | static_cast(rhs)); } inline SettingItemFlags &operator|=(SettingItemFlags &lhs, SettingItemFlags rhs) { using T = std::underlying_type::type; lhs = (SettingItemFlags)(static_cast(lhs) | static_cast(rhs)); return lhs; } struct SettingItemDescriptor { const std::string defaultValue; const SettingItemFlags flags; SettingItemDescriptor(const std::string &defaultValue = std::string(), SettingItemFlags flags = SettingItemFlags::None) : defaultValue(defaultValue), flags(flags) {} bool operator==(const SettingItemDescriptor &o) const { return defaultValue == o.defaultValue && flags == o.flags; } bool operator!=(const SettingItemDescriptor &o) const { return !(*this == o); } }; class ISettingItemListener { protected: ISettingItemListener() = default; virtual ~ISettingItemListener() {} public: virtual void SettingChanged(const std::string &name) = 0; }; class Settings { struct Item { std::string name; std::string string; float value; int intValue; const SettingItemDescriptor *descriptor; bool defaults; std::vector listeners; void Load(); void Set(const std::string &); void Set(int); void Set(float); void NotifyChange(); }; std::map items; bool loaded; Settings(); Item *GetItem(const std::string &name, const SettingItemDescriptor *descriptor); void Save(); public: static Settings *GetInstance(); class ItemHandle { Item *item; public: ItemHandle(const std::string &name, const SettingItemDescriptor *descriptor); void operator=(const std::string &); void operator=(int); void operator=(float); operator std::string(); operator float(); operator int(); operator bool(); const char *CString(); const SettingItemDescriptor &GetDescriptor(); void AddListener(ISettingItemListener *); void RemoveListener(ISettingItemListener *); }; void Load(); void Flush(); std::vector GetAllItemNames(); }; /* template class Setting: public Settings::ItemHandle { public: Setting(): Settings::ItemHandle(name, def, desc){ } };*/ static inline bool operator==(const std::string &str, Settings::ItemHandle &handle) { return str == (std::string)handle; } // Define SettingItemDescriptor with external linkage so duplicates are // detected as linker errors. #define DEFINE_SPADES_SETTING(name, ...) \ spades::SettingItemDescriptor name##_desc{__VA_ARGS__}; \ static spades::Settings::ItemHandle name(#name, &name##_desc) #define SPADES_SETTING(name) static spades::Settings::ItemHandle name(#name, nullptr) }