From 6c4d113e8c1c2ea5cfd140c2e758b61e2d31ab1b Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Wed, 4 Feb 2015 17:17:35 +0300 Subject: [PATCH] settings API refactoring --- src/dlangui/core/settings.d | 356 +++++++++++++++++++++++++++++++++++- 1 file changed, 353 insertions(+), 3 deletions(-) diff --git a/src/dlangui/core/settings.d b/src/dlangui/core/settings.d index b5898b7c..97884a08 100644 --- a/src/dlangui/core/settings.d +++ b/src/dlangui/core/settings.d @@ -39,6 +39,17 @@ struct SettingArray { return null; return list[index]; } + /// remove by index, returns removed value + Setting remove(int index) { + Setting res = get(index); + if (!res) + return null; + for (int i = index; i < list.length - 1; i++) + list[i] = list[i + 1]; + list[$ - 1] = null; + list.length--; + return res; + } } /// ordered map @@ -52,6 +63,55 @@ struct SettingMap { return null; return list[index]; } + /// get item by key, returns null if key is not found + Setting get(string key) { + auto p = (key in map); + if (!p) + return null; + return list[*p]; + } + Setting set(string key, Setting value, Setting parent) { + value.parent = parent; + auto p = (key in map); + if (p) { + // key is found + list[*p] = value; + } else { + // new value + list ~= value; + map[key] = cast(int)list.length - 1; + } + return value; + } + + /// remove by index, returns removed value + Setting remove(int index) { + Setting res = get(index); + if (!res) + return null; + for (int i = index; i < list.length - 1; i++) + list[i] = list[i + 1]; + list[$ - 1] = null; + list.length--; + string key; + foreach(k, ref v; map) { + if (v == index) { + key = k; + } else if (v > index) { + v--; + } + } + if (key) + map.remove(key); + return res; + } + /// remove by key, returns removed value + Setting remove(string key) { + auto p = (key in map); + if (!p) + return null; + return remove(*p); + } } /// setting object @@ -157,6 +217,27 @@ final class Setting { return null; } } + /// read as string value + inout(string) strDef(string defValue) inout { + final switch(_type) with(SettingType) { + case STRING: + return _store.str; + case INTEGER: + return to!string(_store.integer); + case UINTEGER: + return to!string(_store.uinteger); + case FLOAT: + return to!string(_store.floating); + case TRUE: + return "true"; + case FALSE: + return "false"; + case NULL: + case ARRAY: + case OBJECT: + return defValue; + } + } /// set string value for object @property string str(string v) { if (_type != SettingType.STRING) @@ -226,6 +307,27 @@ final class Setting { return 0; } } + /// read as long value + inout(long) integerDef(long defValue) inout { + final switch(_type) with(SettingType) { + case STRING: + return parseLong(_store.str, defValue); + case INTEGER: + return _store.integer; + case UINTEGER: + return cast(long)_store.uinteger; + case FLOAT: + return cast(long)_store.floating; + case TRUE: + return 1; + case FALSE: + return 0; + case NULL: + case ARRAY: + case OBJECT: + return defValue; + } + } /// set long value for object @property long integer(long v) { if (_type != SettingType.INTEGER) @@ -254,6 +356,27 @@ final class Setting { return 0; } } + /// read as ulong value + inout(long) uintegerDef(ulong defValue) inout { + final switch(_type) with(SettingType) { + case STRING: + return parseULong(_store.str, defValue); + case INTEGER: + return cast(ulong)_store.integer; + case UINTEGER: + return _store.uinteger; + case FLOAT: + return cast(ulong)_store.floating; + case TRUE: + return 1; + case FALSE: + return 0; + case NULL: + case ARRAY: + case OBJECT: + return defValue; + } + } /// set ulong value for object @property ulong uinteger(ulong v) { if (_type != SettingType.UINTEGER) @@ -282,6 +405,27 @@ final class Setting { return 0; } } + /// read as double value with default + inout(double) floatingDef(double defValue) inout { + final switch(_type) with(SettingType) { + case STRING: + return defValue; //parseULong(_store.str); + case INTEGER: + return cast(double)_store.integer; + case UINTEGER: + return cast(double)_store.uinteger; + case FLOAT: + return _store.floating; + case TRUE: + return 1; + case FALSE: + return 0; + case NULL: + case ARRAY: + case OBJECT: + return defValue; + } + } /// set ulong value for object @property double floating(double v) { if (_type != SettingType.FLOAT) @@ -332,6 +476,28 @@ final class Setting { return _store.map && !_store.map.empty; } } + /// read as boolean value + inout(bool) booleanDef(bool defValue) inout { + final switch(_type) with(SettingType) { + case STRING: + return parseBool(_store.str, defValue); + case INTEGER: + return _store.integer != 0; + case UINTEGER: + return _store.uinteger != 0; + case FLOAT: + return _store.floating != 0; + case TRUE: + return true; + case FALSE: + case NULL: + return false; + case ARRAY: + return defValue; + case OBJECT: + return defValue; + } + } /// set bool value for object @property bool boolean(bool v) { if (_type == SettingType.TRUE) { @@ -367,17 +533,74 @@ final class Setting { } } + /// for object returns item by key, null if not found or this setting is not an object + Setting opIndex(string key) { + if (_type == SettingType.OBJECT) { + if (!_store.map) + return null; + return _store.map.get(key); + } else { + return null; + } + } + + /// for array or object remove item by index, returns removed item or null if index is out of bounds or setting is neither array nor object + Setting remove(int index) { + if (_type == SettingType.ARRAY) { + return _store.array.remove(index); + } else if (_type == SettingType.OBJECT) { + if (!_store.map) + return null; + return _store.map.remove(index); + } else { + return null; + } + } + + /// for object remove item by key, returns removed item or null if is not found or setting is not an object + Setting remove(string key) { + if (_type == SettingType.OBJECT) { + if (!_store.map) + return null; + return _store.map.remove(key); + } else { + return null; + } + } + + // assign long value + long opAssign(long value) { + return (integer = value); + } + // assign ulong value + ulong opAssign(ulong value) { + return (uinteger = value); + } + // assign string value + string opAssign(string value) { + return (str = value); + } + // assign bool value + bool opAssign(bool value) { + return (boolean = value); + } + // assign double value + double opAssign(double value) { + return (floating = value); + } + // array methods - /// sets value for item by index + /// sets value for array item by integer index T opIndexAssign(T)(T value, int index) { if (_type != SettingType.ARRAY) clear(SettingType.ARRAY); static if (is(value == Setting)) { _store.array.set(index, value, this); } else { - if (index >= 0 && index < _store.array.list.length) { + Setting item = _store.array.get(index); + if (item) { // existing item - Setting item = _store.array.list[index]; + item = value; } else { // create new item _store.array.set(index, new Setting(value), this); @@ -385,6 +608,133 @@ final class Setting { } return value; } + + // map methods + /// sets value for object item by string key + T opIndexAssign(T)(T value, string key) { + if (_type != SettingType.OBJECT) + clear(SettingType.OBJECT); + if (!_store.map) + _store.map = new SettingMap(); + static if (is(value == Setting)) { + _store.map.set(key, value, this); + } else { + Setting item = _store.map.get(key); + if (item) { + // existing item + item = value; + } else { + // create new item + _store.map.set(key, new Setting(value), this); + } + } + return value; + } + + /// sets long item by index of array or map + long setInteger(int index, long value) { + return opIndexAssign(value, index); + } + /// sets ulong item by index of array or map + ulong setUinteger(int index, ulong value) { + return opIndexAssign(value, index); + } + /// sets bool item by index of array or map + bool setBoolean(int index, bool value) { + return opIndexAssign(value, index); + } + /// sets double item by index of array or map + double setFloating(int index, double value) { + return opIndexAssign(value, index); + } + /// sets str item by index of array or map + string setString(int index, string value) { + return opIndexAssign(value, index); + } + + /// returns long item by index of array or map + long getInteger(int index, long defValue = 0) { + if (auto item = opIndex(index)) + return item.integerDef(defValue); + return defValue; + } + /// returns ulong item by index of array or map + ulong getUinteger(int index, ulong defValue = 0) { + if (auto item = opIndex(index)) + return item.uintegerDef(defValue); + return defValue; + } + /// returns bool item by index of array or map + bool getBoolean(int index, bool defValue = false) { + if (auto item = opIndex(index)) + return item.booleanDef(defValue); + return defValue; + } + /// returns double item by index of array or map + double getFloating(int index, double defValue = 0) { + if (auto item = opIndex(index)) + return item.floatingDef(defValue); + return defValue; + } + /// returns str item by index of array or map + string getString(int index, string defValue = null) { + if (auto item = opIndex(index)) + return item.strDef(defValue); + return defValue; + } + + + /// sets long item of map + long setInteger(string key, long value) { + return opIndexAssign(value, key); + } + /// sets ulong item of map + ulong setUinteger(string key, ulong value) { + return opIndexAssign(value, key); + } + /// sets bool item of map + bool setBoolean(string key, bool value) { + return opIndexAssign(value, key); + } + /// sets double item of map + double setFloating(string key, double value) { + return opIndexAssign(value, key); + } + /// sets str item of map + string setString(string key, string value) { + return opIndexAssign(value, key); + } + + /// returns long item by key from map + long getInteger(string key, long defValue = 0) { + if (auto item = opIndex(key)) + return item.integerDef(defValue); + return defValue; + } + /// returns ulong item by key from map + ulong getUinteger(string key, ulong defValue = 0) { + if (auto item = opIndex(key)) + return item.uintegerDef(defValue); + return defValue; + } + /// returns bool item by key from map + bool getBoolean(string key, bool defValue = false) { + if (auto item = opIndex(key)) + return item.booleanDef(defValue); + return defValue; + } + /// returns double item by key from map + double getFloating(string key, double defValue = 0) { + if (auto item = opIndex(key)) + return item.floatingDef(defValue); + return defValue; + } + /// returns str item by key from map + string getString(string key, string defValue = null) { + if (auto item = opIndex(key)) + return item.strDef(defValue); + return defValue; + } } version (AAA): // comment out