1 /* 2 Copyright (c) 2013 yvt 3 4 This file is part of OpenSpades. 5 6 OpenSpades is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 OpenSpades is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with OpenSpades. If not, see <http://www.gnu.org/licenses/>. 18 19 */ 20 21 #pragma once 22 23 #include <map> 24 #include <string> 25 #include <type_traits> 26 #include <vector> 27 28 namespace spades { 29 enum class SettingItemFlags { None = 0 }; 30 31 inline SettingItemFlags operator|(SettingItemFlags lhs, SettingItemFlags rhs) 32 33 { 34 using T = std::underlying_type<SettingItemFlags>::type; 35 return (SettingItemFlags)(static_cast<T>(lhs) | static_cast<T>(rhs)); 36 } 37 38 inline SettingItemFlags &operator|=(SettingItemFlags &lhs, SettingItemFlags rhs) { 39 using T = std::underlying_type<SettingItemFlags>::type; 40 lhs = (SettingItemFlags)(static_cast<T>(lhs) | static_cast<T>(rhs)); 41 return lhs; 42 } 43 44 struct SettingItemDescriptor { 45 const std::string defaultValue; 46 const SettingItemFlags flags; 47 48 SettingItemDescriptor(const std::string &defaultValue = std::string(), 49 SettingItemFlags flags = SettingItemFlags::None) defaultValueSettingItemDescriptor50 : defaultValue(defaultValue), flags(flags) {} 51 52 bool operator==(const SettingItemDescriptor &o) const { 53 return defaultValue == o.defaultValue && flags == o.flags; 54 } 55 bool operator!=(const SettingItemDescriptor &o) const { return !(*this == o); } 56 }; 57 58 class ISettingItemListener { 59 protected: 60 ISettingItemListener() = default; ~ISettingItemListener()61 virtual ~ISettingItemListener() {} 62 63 public: 64 virtual void SettingChanged(const std::string &name) = 0; 65 }; 66 67 class Settings { 68 struct Item { 69 std::string name; 70 std::string string; 71 float value; 72 int intValue; 73 74 const SettingItemDescriptor *descriptor; 75 bool defaults; 76 77 std::vector<ISettingItemListener *> listeners; 78 79 void Load(); 80 void Set(const std::string &); 81 void Set(int); 82 void Set(float); 83 84 void NotifyChange(); 85 }; 86 std::map<std::string, Item *> items; 87 bool loaded; 88 Settings(); 89 90 Item *GetItem(const std::string &name, const SettingItemDescriptor *descriptor); 91 92 void Save(); 93 94 public: 95 static Settings *GetInstance(); 96 97 class ItemHandle { 98 Item *item; 99 100 public: 101 ItemHandle(const std::string &name, const SettingItemDescriptor *descriptor); 102 void operator=(const std::string &); 103 void operator=(int); 104 void operator=(float); 105 operator std::string(); 106 operator float(); 107 operator int(); 108 operator bool(); 109 const char *CString(); 110 111 const SettingItemDescriptor &GetDescriptor(); 112 113 /** 114 * Returns whether this config variable is used and defined by the program 115 * or not. 116 */ 117 bool IsUnknown(); 118 119 void AddListener(ISettingItemListener *); 120 void RemoveListener(ISettingItemListener *); 121 }; 122 123 void Load(); 124 void Flush(); 125 std::vector<std::string> GetAllItemNames(); 126 }; 127 /* 128 template<const char *name, const char *def> 129 class Setting: public Settings::ItemHandle { 130 public: 131 Setting(): Settings::ItemHandle(name, def, desc){ 132 } 133 };*/ 134 135 static inline bool operator==(const std::string &str, Settings::ItemHandle &handle) { 136 return str == (std::string)handle; 137 } 138 139 // Define SettingItemDescriptor with external linkage so duplicates are 140 // detected as linker errors. 141 #define DEFINE_SPADES_SETTING(name, ...) \ 142 spades::SettingItemDescriptor name##_desc{__VA_ARGS__}; \ 143 static spades::Settings::ItemHandle name(#name, &name##_desc) 144 145 #define SPADES_SETTING(name) static spades::Settings::ItemHandle name(#name, nullptr) 146 } 147