-
Notifications
You must be signed in to change notification settings - Fork 0
Home
DataKeeper is a thread-safe singleton.
Data d = Data.Instance; To set an object by a string key use method Set or use indexer:
public void Set(string key, object value);
public object this[string key] { get; set; }Set will put a value to a model and call all triggers OnChange binded with this key.
Triggers can be OnChange and OnRemove. Also you can specify additional conditions for execution by TriggerType.
[Flags]
public enum TriggerType
{
Before = 1,
After = 2,
Both = Before | After
}There are two ways to bind a key with an action:
- First one is to use
Bind<Method>Field:
public void BindChangeField(string key, Action action, TriggerType triggerType = TriggerType.After);
public void BindRemoveField(string key, Action action, TriggerType triggerType = TriggerType.Before);string key = "some_key";
Data.Instance.BindChangeField(key, () => Console.WriteLine($"Value by {key} is updated")); // Call trigger after changind by default
Data.Instance.BindChangeField(key,
() => Console.WriteLine($"Value by {key} is updated"),
TriggerType.After); // Equivalent to the previous call
Data.Instance.BindChangeField(key, SomeAction, TriggerType.Before); // Call it before Set(key, newValue)
// Similarly for Remove
Data.Instance.BindRemoveField(key, SomeAction); // TriggerType.Before by default
Data.Instance.BindRemoveField(key, SomeAction, TriggerType.After); // TriggerType.Before by default- Second one is to use setter-only indexer:
Data data = Data.Instance;
data[key, BindType.OnChange, TriggerType.After] = () => { ... };Where BindType is enum flags:
[Flags]
public enum BindType
{
OnChange = 1,
OnRemove = 2,
OnAll = OnChange | OnRemove
}To unbind actions by a key use:
public void Unbind(string key); // Unbind all triggers both OnChange and OnRemove
// Or specify what type you would like to unbind
public void Unbind(string key, BindType bindType, TriggerType triggerType);Currently there is no way to unbind one action by some id. May be this feature will be relesed in future.
Getters may return an object or cast it to user-specified type. Notice, all getters may throw KeyNotFoundException or ArgumentNullException if key is null or doesn't exist in the model.
// Returns object without casting
public object Get(string key);
public object this[string key] { get; set; }
public object this[string key, object @default] { get; } // getter with default valueMethods with casting may also throw InvalidCastException:
public int GetInt(string key);
public double GetDouble(string key);
public bool GetBool(string key);
// And you can also get a value by type of T
public T Get<T>(string key);All casting-getters have overloads with default value and can't throw neither KeyNotFoundException, ArgumentNullException nor InvalidCastException. They return this defaul value if there is not key, or cast is invalid:
public int GetInt(string key, int @default);
public double GetDouble(string key, double @default);
public bool GetBool(string key, bool @default);
public T Get<T>(string key, T @default);Some getters return value in any case.
public string GetString(string key, string @default = ""); // returns Value.ToString() or @default
public Type GetType(string key); // returns Value.GetType() or nullIf you manipulate numeric types you may like increasers/decreasers:
public void Increase(string key, int valueToIncrease = 1);
public void Increase(string key, float valueToIncrease = 1f);
public void Increase(string key, double valueToIncrease = 1.0);
public void Decrease(string key, int valueToDecrease = 1);
public void Decrease(string key, float valueToDecrease = 1f);
public void Decrease(string key, double valueToDecrease = 1.0);If value by key is not of type of valueToDecrease it can't change value.
In case there is no such key the increaser/decreaser put valueToIncrease/valueToDecrease to the model.
To avoid errors with overloads specify a specific type:
string intKey = "intKey", doubleKey = "doubleKey";
Data.Inctance.Increase(intKey , (int) 3);
Data.Inctance.Decrease(doubleKey , (double) 6);Often we need to free space. DataKeeper allows us to bind Remove with actions (see Binders).
All the triggers associated with the key will remain.
Below is an example of code that does not allow you to delete data if the user does not have rights.
string key = "key_to_double";
Data.Instance.BindRemoveField(key, () =>
{
Log.Warning($"An attempt was made to remove data for the \'{key}\' key!");
var d = Data.Instance.GetDouble(key, double.NaN);
if (double.IsNaN(d) || Data.Instance.GetBool("user_has_deletion_rights", true))
{
Log.Success("There are permissions to delete!");
Data.Instance.Set(key + "_cancel_deletion", double.NaN);
}
else
{
Log.Error("No permission to delete! The data will be returned!");
Data.Instance.Set(key + "_cancel_deletion", d);
}
});
Data.Instance.BindRemoveField(key, () =>
{
var d = Data.Instance.GetDouble(key + "_cancel_deletion", double.NaN);
if(!double.IsNaN(d))
Data.Instance.Set(key, d);
Data.Instance.Clear(key + "_cancel_deletion");
}, TriggerType.After);Now if the value of user_has_deletion_rights is false then our data will be restored in the model while removing.
To delete both data and triggers use Clear(string key):
Data.Instance.Clear("some_key");
Data.Instance.Clear(); // Will delete the entire model. All keys, triggers and values.Clear(key) is equivalent to calling Remove(key) then Unbind(key) or vice versa: Unbind(key) then Remove(key).
DataKeeper doesn't implement any of IEnumerable, ICollection or IDictionary interfaces, but some functions and getters comes from this:
int count = Data.Instance.Count; // returns count of keys in the model (getter-only)
public bool ContainsKey(string key); // returns true if key is in modelBut there is a way to get a collection of Keys of the model:
public IReadOnlyCollection<string> Keys { get; }You can enumerate over Keys and use LINQ over it.
foreach (string key in Data.Instance.Keys) { ... }
Data.Instance.Keys.Select(key => ...);
Data.Instance.Keys.Where(key => ...);
// etc