diff --git a/appveyor.yml b/appveyor.yml
index 2575913..1e21d8d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 0.18.{build}
+version: 0.19.{build}
branches:
only:
- master
@@ -27,7 +27,7 @@ deploy:
APPVEYOR_REPO_TAG: true
server:
api_key:
- secure: 0yJPCmw0EEE6ea73EEvaB8+TjIhUs0A8wG0dR60FEAu+B/i6x33b0GweDBVyz0PE
+ secure: ZBJLq3pN+Q0n1I99/r9rVbdWuCfAiv7bobV9WYDiMR3ebjIx/3d/AVcYK27zC3vm
skip_symbols: true
symbol_server:
artifact: /.*\.nupkg/
diff --git a/src/OpenRpg.Core/Utils/DefaultRandomizer.cs b/src/OpenRpg.Core/Utils/DefaultRandomizer.cs
index 2c68fa6..435db65 100644
--- a/src/OpenRpg.Core/Utils/DefaultRandomizer.cs
+++ b/src/OpenRpg.Core/Utils/DefaultRandomizer.cs
@@ -2,15 +2,15 @@ namespace OpenRpg.Core.Utils
{
public class DefaultRandomizer : IRandomizer
{
- private System.Random _random;
+ public System.Random NativeRandomizer { get; }
public DefaultRandomizer(System.Random random)
- { _random = random; }
+ { NativeRandomizer = random; }
public int Random(int min, int max)
- { return _random.Next(min, max + 1); }
+ { return NativeRandomizer.Next(min, max + 1); }
public float Random(float min, float max)
- { return (float)_random.NextDouble() * (max - min) + min; }
+ { return (float)NativeRandomizer.NextDouble() * (max - min) + min; }
}
}
\ No newline at end of file
diff --git a/src/OpenRpg.Core/Utils/IRandomizer.cs b/src/OpenRpg.Core/Utils/IRandomizer.cs
index f8b355c..4b14c7e 100644
--- a/src/OpenRpg.Core/Utils/IRandomizer.cs
+++ b/src/OpenRpg.Core/Utils/IRandomizer.cs
@@ -3,6 +3,6 @@ namespace OpenRpg.Core.Utils
public interface IRandomizer
{
int Random(int min, int max);
- float Random(float min, float max);
+ float Random(float min = 0, float max = 1.0f);
}
}
\ No newline at end of file
diff --git a/src/OpenRpg.CurveFunctions/Curves/PassThroughlCurveFunction.cs b/src/OpenRpg.CurveFunctions/Curves/PassThroughCurveFunction.cs
similarity index 66%
rename from src/OpenRpg.CurveFunctions/Curves/PassThroughlCurveFunction.cs
rename to src/OpenRpg.CurveFunctions/Curves/PassThroughCurveFunction.cs
index 7f7b392..a3de47d 100644
--- a/src/OpenRpg.CurveFunctions/Curves/PassThroughlCurveFunction.cs
+++ b/src/OpenRpg.CurveFunctions/Curves/PassThroughCurveFunction.cs
@@ -1,6 +1,6 @@
namespace OpenRpg.CurveFunctions.Curves
{
- public class PassThroughlCurveFunction : ICurveFunction
+ public class PassThroughCurveFunction : ICurveFunction
{
public float Plot(float value)
{ return value; }
diff --git a/src/OpenRpg.CurveFunctions/Extensions/ICurveFunctionExtensions.cs b/src/OpenRpg.CurveFunctions/Extensions/ICurveFunctionExtensions.cs
index 0743602..275510f 100644
--- a/src/OpenRpg.CurveFunctions/Extensions/ICurveFunctionExtensions.cs
+++ b/src/OpenRpg.CurveFunctions/Extensions/ICurveFunctionExtensions.cs
@@ -16,8 +16,7 @@ public static float SanitizeValue(this ICurveFunction curve, float value)
/// The denormalized value from the curve
public static float ScaledPlot(this ICurveFunction curve, float value, float maxValue)
{
- if (value == 0) { return 0; }
- var normalizedValue = value / maxValue;
+ var normalizedValue = (value + float.Epsilon) / maxValue;
var normalizedOutput = curve.Plot(normalizedValue);
return normalizedOutput * maxValue;
}
diff --git a/src/OpenRpg.CurveFunctions/Extensions/IRandomizerExtensions.cs b/src/OpenRpg.CurveFunctions/Extensions/IRandomizerExtensions.cs
new file mode 100644
index 0000000..9c8f230
--- /dev/null
+++ b/src/OpenRpg.CurveFunctions/Extensions/IRandomizerExtensions.cs
@@ -0,0 +1,31 @@
+using System;
+using OpenRpg.Core.Utils;
+
+namespace OpenRpg.CurveFunctions.Extensions
+{
+ public static class IRandomizerExtensions
+ {
+ public static float Random(this IRandomizer randomizer, ICurveFunction curve)
+ {
+ var randomNumber = randomizer.Random();
+ return curve.Plot(randomNumber);
+ }
+
+ public static float Random(this IRandomizer randomizer, ICurveFunction curve, float minValue, float maxValue)
+ {
+ var randomNumber = randomizer.Random(minValue, maxValue);
+ var isNegative = minValue < 0;
+ if (isNegative)
+ {
+ randomNumber = Math.Abs(randomNumber);
+ maxValue = Math.Abs(minValue);
+ }
+
+ var result = curve.ScaledPlot(randomNumber, maxValue);
+ return isNegative ? -result : result;
+ }
+
+ public static int Random(this IRandomizer randomizer, ICurveFunction curve, int minValue, int maxValue)
+ { return (int)Random(randomizer, curve, minValue, (float)maxValue); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.CurveFunctions/OpenRpg.CurveFunctions.csproj b/src/OpenRpg.CurveFunctions/OpenRpg.CurveFunctions.csproj
index 2cdc0f0..2a9b06b 100644
--- a/src/OpenRpg.CurveFunctions/OpenRpg.CurveFunctions.csproj
+++ b/src/OpenRpg.CurveFunctions/OpenRpg.CurveFunctions.csproj
@@ -11,4 +11,8 @@
rpg game-development xna monogame unity godot
+
+
+
+
diff --git a/src/OpenRpg.CurveFunctions/PresetCurves.cs b/src/OpenRpg.CurveFunctions/PresetCurves.cs
index a227582..8bbb5c6 100644
--- a/src/OpenRpg.CurveFunctions/PresetCurves.cs
+++ b/src/OpenRpg.CurveFunctions/PresetCurves.cs
@@ -23,6 +23,6 @@ public class PresetCurves
public static SineCurveFunction InverseSineWave = new SineCurveFunction(-1.0f, 0, 0);
public static StepCurveFunction GreaterThanHalf = new StepCurveFunction(0.5f);
public static StepCurveFunction LessThanHalf = new StepCurveFunction(0.5f, 1.0f, 0.0f);
- public static PassThroughlCurveFunction PassThrough = new PassThroughlCurveFunction();
+ public static PassThroughCurveFunction PassThrough = new PassThroughCurveFunction();
}
}
\ No newline at end of file
diff --git a/src/OpenRpg.Data.Database/DatabaseDataSource.cs b/src/OpenRpg.Data.Database/DatabaseDataSource.cs
new file mode 100644
index 0000000..f90a060
--- /dev/null
+++ b/src/OpenRpg.Data.Database/DatabaseDataSource.cs
@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+using System.Data;
+using Dapper;
+
+namespace OpenRpg.Data.Database
+{
+ public class DatabaseDataSource : IDatabaseDataSource
+ {
+ public IDbConnection Connection { get; }
+
+ public object NativeSource => Connection;
+
+ public DatabaseDataSource(IDbConnection connection)
+ { Connection = connection; }
+
+ public T Get(object id) => Connection.Get(id);
+ public IEnumerable GetAll() => Connection.GetList();
+ public void Create(T data, object id = null) => Connection.Insert(data);
+ public void Update(T data, object id) => Connection.Update(data);
+ public bool Delete(object id) => Connection.Delete(id) > 0;
+ public bool Exists(object id) => Get(id) != null;
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data.Database/IDatabaseDataSource.cs b/src/OpenRpg.Data.Database/IDatabaseDataSource.cs
new file mode 100644
index 0000000..fdd5e7c
--- /dev/null
+++ b/src/OpenRpg.Data.Database/IDatabaseDataSource.cs
@@ -0,0 +1,7 @@
+namespace OpenRpg.Data.Database
+{
+ public interface IDatabaseDataSource : IDataSource
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data.Database/OpenRpg.Data.Database.csproj b/src/OpenRpg.Data.Database/OpenRpg.Data.Database.csproj
new file mode 100644
index 0000000..ad38ce9
--- /dev/null
+++ b/src/OpenRpg.Data.Database/OpenRpg.Data.Database.csproj
@@ -0,0 +1,24 @@
+
+
+
+ 0.0.0
+ net461;netstandard2.0
+ OpenRpg.Data.Database
+ Grofit (LP)
+ https://github.com/openrpg/OpenRpg/blob/master/LICENSE
+ https://github.com/openrpg/OpenRpg
+ An SQL database implementation of the OpenRpg data layer using Dapper
+ rpg game-development repository data xna monogame unity godot
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/OpenRpg.Data.InMemory/Builder/InMemoryDataSourceBuilder.cs b/src/OpenRpg.Data.InMemory/Builder/InMemoryDataSourceBuilder.cs
new file mode 100644
index 0000000..db5130d
--- /dev/null
+++ b/src/OpenRpg.Data.InMemory/Builder/InMemoryDataSourceBuilder.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace OpenRpg.Data.InMemory.Builder
+{
+ public class InMemoryDataSourceBuilder
+ {
+ private readonly Dictionary> Database;
+
+ protected InMemoryDataSourceBuilder(Dictionary> database)
+ {
+ Database = database;
+ }
+
+ public static InMemoryDataSourceBuilder Create()
+ { return new InMemoryDataSourceBuilder(new Dictionary>()); }
+
+ public InMemoryDataSourceBuilder WithData(IEnumerable data, Func keySelector)
+ {
+ var typeOfT = typeof(T);
+ if (!Database.ContainsKey(typeOfT))
+ {
+ var contents = data.ToDictionary(keySelector, x => (object)x);
+ Database.Add(typeOfT, contents);
+ return this;
+ }
+
+ var typeContainer = Database[typeOfT];
+
+ foreach(var element in data)
+ { typeContainer.Add(keySelector(element), element); }
+
+ return this;
+ }
+
+ public IDataSource Build()
+ { return new InMemoryDataSource(Database); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data.InMemory/IInMemoryDataSource.cs b/src/OpenRpg.Data.InMemory/IInMemoryDataSource.cs
new file mode 100644
index 0000000..3638f3d
--- /dev/null
+++ b/src/OpenRpg.Data.InMemory/IInMemoryDataSource.cs
@@ -0,0 +1,7 @@
+namespace OpenRpg.Data.InMemory
+{
+ public interface IInMemoryDataSource : IDataSource
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data.InMemory/InMemoryDataSource.cs b/src/OpenRpg.Data.InMemory/InMemoryDataSource.cs
new file mode 100644
index 0000000..9a8476a
--- /dev/null
+++ b/src/OpenRpg.Data.InMemory/InMemoryDataSource.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace OpenRpg.Data.InMemory
+{
+ public class InMemoryDataSource : IInMemoryDataSource
+ {
+ public Dictionary> Database { get; }
+
+ public object NativeSource => Database;
+
+ public InMemoryDataSource(Dictionary> database = null)
+ { Database = database ?? new Dictionary>(); }
+
+ public T Get(object id) => (T)Database[typeof(T)][id];
+ public IEnumerable GetAll() => Database[typeof(T)].Values.Cast();
+ public void Update(T data, object id) => Database[typeof(T)][id] = data;
+ public bool Delete(object id) => Database[typeof(T)].Remove(id);
+ public bool Exists(object id) => Database[typeof(T)].ContainsKey(id);
+
+ public void Create(T data, object id = null)
+ {
+ if(id == null) { throw new ArgumentNullException(nameof(id), "In Memory DB Requires explicit keys on creation"); }
+ Database[typeof(T)].Add(id, data);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data.InMemory/OpenRpg.Data.InMemory.csproj b/src/OpenRpg.Data.InMemory/OpenRpg.Data.InMemory.csproj
new file mode 100644
index 0000000..2cf977d
--- /dev/null
+++ b/src/OpenRpg.Data.InMemory/OpenRpg.Data.InMemory.csproj
@@ -0,0 +1,19 @@
+
+
+
+ 0.0.0
+ netstandard2.0;net46
+ OpenRpg.Data.InMemory
+ Grofit (LP)
+ https://github.com/openrpg/OpenRpg/blob/master/LICENSE
+ https://github.com/openrpg/OpenRpg
+ An in memory implementation of the OpenRpg data layer
+ rpg game-development repository data xna monogame unity godot
+
+
+
+
+
+
+
+
diff --git a/src/OpenRpg.Data/Conventions/Extensions/RepositoryDataExtensions.cs b/src/OpenRpg.Data/Conventions/Extensions/RepositoryDataExtensions.cs
new file mode 100644
index 0000000..1f34705
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Extensions/RepositoryDataExtensions.cs
@@ -0,0 +1,20 @@
+using OpenRpg.Core.Common;
+using OpenRpg.Data.Conventions.Queries;
+
+namespace OpenRpg.Data.Conventions.Extensions
+{
+ public static class RepositoryDataExtensions
+ {
+ public static T Create(this IRepository repository, T entity) where T : class, IHasDataId
+ { return repository.Query(new CreateEntityQuery(entity, entity.Id)); }
+
+ public static T Update(this IRepository repository, T entity) where T : class, IHasDataId
+ { return repository.Query(new UpdateEntityQuery(entity, entity.Id)); }
+
+ public static bool Delete(this IRepository repository, T entity) where T : class, IHasDataId
+ { return repository.Query(new DeleteEntityQuery(entity.Id)); }
+
+ public static bool Exists(this IRepository repository, T entity) where T : class, IHasDataId
+ { return repository.Query(new EntityExistsQuery(entity.Id)); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Conventions/Extensions/RepositoryExtensions.cs b/src/OpenRpg.Data/Conventions/Extensions/RepositoryExtensions.cs
new file mode 100644
index 0000000..25b7dde
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Extensions/RepositoryExtensions.cs
@@ -0,0 +1,22 @@
+using OpenRpg.Data.Conventions.Queries;
+
+namespace OpenRpg.Data.Conventions.Extensions
+{
+ public static class RepositoryExtensions
+ {
+ public static T Create(this IRepository repository, T entity, object id = null) where T : class
+ { return repository.Query(new CreateEntityQuery(entity, id)); }
+
+ public static T Get(this IRepository repository, object id) where T : class
+ { return repository.Query(new GetEntityQuery(id)); }
+
+ public static T Update(this IRepository repository, T entity, object id) where T : class
+ { return repository.Query(new UpdateEntityQuery(entity, id)); }
+
+ public static bool Delete(this IRepository repository, object id) where T : class
+ { return repository.Query(new DeleteEntityQuery(id)); }
+
+ public static bool Exists(this IRepository repository, object id) where T : class
+ { return repository.Query(new EntityExistsQuery(id)); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Conventions/Queries/CreateEntityQuery.cs b/src/OpenRpg.Data/Conventions/Queries/CreateEntityQuery.cs
new file mode 100644
index 0000000..1067527
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Queries/CreateEntityQuery.cs
@@ -0,0 +1,20 @@
+namespace OpenRpg.Data.Conventions.Queries
+{
+ public class CreateEntityQuery : IQuery
+ {
+ public T Entity { get; }
+ public object Id { get; }
+
+ public CreateEntityQuery(T entity, object id = null)
+ {
+ Entity = entity;
+ Id = id;
+ }
+
+ public T Execute(IDataSource dataSource)
+ {
+ dataSource.Create(Entity, Id);
+ return Entity;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Conventions/Queries/DeleteEntityQuery.cs b/src/OpenRpg.Data/Conventions/Queries/DeleteEntityQuery.cs
new file mode 100644
index 0000000..182e52f
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Queries/DeleteEntityQuery.cs
@@ -0,0 +1,13 @@
+namespace OpenRpg.Data.Conventions.Queries
+{
+ public class DeleteEntityQuery : IQuery
+ {
+ public object Id { get; }
+
+ public DeleteEntityQuery(object id)
+ { Id = id; }
+
+ public bool Execute(IDataSource dataSource)
+ { return dataSource.Delete(Id); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Conventions/Queries/EntityExistsQuery.cs b/src/OpenRpg.Data/Conventions/Queries/EntityExistsQuery.cs
new file mode 100644
index 0000000..fa49b58
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Queries/EntityExistsQuery.cs
@@ -0,0 +1,13 @@
+namespace OpenRpg.Data.Conventions.Queries
+{
+ public class EntityExistsQuery : IQuery
+ {
+ public object Id { get; }
+
+ public EntityExistsQuery(object id)
+ { Id = id; }
+
+ public bool Execute(IDataSource dataSource)
+ { return dataSource.Exists(Id); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Conventions/Queries/GetEntityQuery.cs b/src/OpenRpg.Data/Conventions/Queries/GetEntityQuery.cs
new file mode 100644
index 0000000..62d54a5
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Queries/GetEntityQuery.cs
@@ -0,0 +1,13 @@
+namespace OpenRpg.Data.Conventions.Queries
+{
+ public class GetEntityQuery : IQuery
+ {
+ public object Id { get; }
+
+ public GetEntityQuery(object id)
+ { Id = id; }
+
+ public T Execute(IDataSource dataSource)
+ { return dataSource.Get(Id); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Queries/IFindQuery.cs b/src/OpenRpg.Data/Conventions/Queries/IFindQuery.cs
similarity index 60%
rename from src/OpenRpg.Data/Queries/IFindQuery.cs
rename to src/OpenRpg.Data/Conventions/Queries/IFindQuery.cs
index 2ae3a2e..15f8f8a 100644
--- a/src/OpenRpg.Data/Queries/IFindQuery.cs
+++ b/src/OpenRpg.Data/Conventions/Queries/IFindQuery.cs
@@ -1,12 +1,13 @@
-namespace OpenRpg.Data.Queries
+using System.Collections.Generic;
+
+namespace OpenRpg.Data.Conventions.Queries
{
///
- /// The find query represents a query that finds something specific from the database, it a specific
+ /// The find query represents a query that finds something specific from the data source, it a specific
///
/// Specific Type to return
/// This is meant as a way to return types different to the repository type
- public interface IFindQuery
+ public interface IFindQuery : IQuery>
{
- T Execute(object dataSource);
}
}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Conventions/Queries/UpdateEntityQuery.cs b/src/OpenRpg.Data/Conventions/Queries/UpdateEntityQuery.cs
new file mode 100644
index 0000000..1cbca40
--- /dev/null
+++ b/src/OpenRpg.Data/Conventions/Queries/UpdateEntityQuery.cs
@@ -0,0 +1,20 @@
+namespace OpenRpg.Data.Conventions.Queries
+{
+ public class UpdateEntityQuery : IQuery
+ {
+ public T Entity { get; }
+ public object Id { get; }
+
+ public UpdateEntityQuery(T entity, object id)
+ {
+ Entity = entity;
+ Id = id;
+ }
+
+ public T Execute(IDataSource dataSource)
+ {
+ dataSource.Update(Entity, Id);
+ return Entity;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/DefaultRepository.cs b/src/OpenRpg.Data/DefaultRepository.cs
new file mode 100644
index 0000000..72ee5bb
--- /dev/null
+++ b/src/OpenRpg.Data/DefaultRepository.cs
@@ -0,0 +1,12 @@
+namespace OpenRpg.Data
+{
+ public class DefaultRepository : IRepository
+ {
+ public IDataSource DataSource { get; }
+
+ public DefaultRepository(IDataSource dataSource)
+ { DataSource = dataSource; }
+
+ public T Query(IQuery query) => query.Execute(DataSource);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/InMemoryDataRepository.cs b/src/OpenRpg.Data/Defaults/InMemoryDataRepository.cs
deleted file mode 100644
index f7c8fdc..0000000
--- a/src/OpenRpg.Data/Defaults/InMemoryDataRepository.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Core.Common;
-using OpenRpg.Data.Repositories;
-
-namespace OpenRpg.Data.Defaults
-{
- ///
- /// This is a layer on top of the InMemoryRepository that has awareness of the IHasDataId for Id lookup purposes
- ///
- ///
- public class InMemoryDataRepository : InMemoryRepository, IDataRepository
- where T : IHasDataId
- {
- protected override int GetKeyFromEntity(T entity) => entity.Id;
-
- public InMemoryDataRepository(IEnumerable data) : base(data)
- {}
-
- protected InMemoryDataRepository()
- {}
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/InMemoryRepository.cs b/src/OpenRpg.Data/Defaults/InMemoryRepository.cs
deleted file mode 100644
index f3283ba..0000000
--- a/src/OpenRpg.Data/Defaults/InMemoryRepository.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using OpenRpg.Data.Queries;
-using OpenRpg.Data.Repositories;
-
-namespace OpenRpg.Data.Defaults
-{
- ///
- /// A simple implementation of a repository
- ///
- ///
- /// It is expected that you would provide a populated enumerable to the constructor for most use cases here as the
- /// data source, however you can extend it and built up the data internally if required for hard coded scenarios.
- ///
- /// Entity type
- public abstract class InMemoryRepository : IRepository
- {
- public List Data { get; protected set; }
-
- public InMemoryRepository(IEnumerable data)
- { Data = data.ToList(); }
-
- protected InMemoryRepository()
- { Data = new List(); }
-
- protected abstract K GetKeyFromEntity(T entity);
-
- public void Create(T entry) => Data.Add(entry);
- public T Retrieve(K id) => Data.SingleOrDefault(x => GetKeyFromEntity(x).Equals(id));
- public void Update(T entry) {}
- public void Delete(T entry) => Data.Remove(entry);
-
- public IEnumerable FindAll(IFindAllQuery dataQuery) => dataQuery.Execute(Data);
- public T2 Find(IFindQuery dataQuery) => dataQuery.Execute(Data);
- public object Execute(IExecuteQuery query) => query.Execute(Data);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/Queries/Common/DynamicGetAllQuery.cs b/src/OpenRpg.Data/Defaults/Queries/Common/DynamicGetAllQuery.cs
deleted file mode 100644
index 66e968e..0000000
--- a/src/OpenRpg.Data/Defaults/Queries/Common/DynamicGetAllQuery.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace OpenRpg.Data.Defaults.Queries.Common
-{
- public class DynamicGetAllQuery : FindAllInMemoryQuery
- {
- public Func,IEnumerable> Filter { get; }
-
- public DynamicGetAllQuery(Func,IEnumerable> filter)
- { Filter = filter; }
-
- public override IEnumerable Execute(List dataSource)
- { return Filter(dataSource); }
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/Queries/Common/GetAllQuery.cs b/src/OpenRpg.Data/Defaults/Queries/Common/GetAllQuery.cs
deleted file mode 100644
index 7487b70..0000000
--- a/src/OpenRpg.Data/Defaults/Queries/Common/GetAllQuery.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-
-namespace OpenRpg.Data.Defaults.Queries.Common
-{
- public class GetAllQuery : FindAllInMemoryQuery
- {
- public override IEnumerable Execute(List dataSource)
- { return dataSource; }
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/Queries/Common/GetCountQuery.cs b/src/OpenRpg.Data/Defaults/Queries/Common/GetCountQuery.cs
deleted file mode 100644
index f03eb6a..0000000
--- a/src/OpenRpg.Data/Defaults/Queries/Common/GetCountQuery.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-
-namespace OpenRpg.Data.Defaults.Queries.Common
-{
- public class GetCountQuery : FindInMemoryQuery
- {
- public override int Execute(List dataSource)
- { return dataSource.Count; }
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/Queries/ExecuteInMemoryQuery.cs b/src/OpenRpg.Data/Defaults/Queries/ExecuteInMemoryQuery.cs
deleted file mode 100644
index 2383763..0000000
--- a/src/OpenRpg.Data/Defaults/Queries/ExecuteInMemoryQuery.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Data.Defaults.Queries
-{
- public abstract class ExecuteInMemoryQuery : IExecuteQuery
- {
- public object Execute(object dataSource)
- { return Execute((List) dataSource); }
-
- public abstract object Execute(List dataSource);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/Queries/FindAllInMemoryQuery.cs b/src/OpenRpg.Data/Defaults/Queries/FindAllInMemoryQuery.cs
deleted file mode 100644
index f821fa7..0000000
--- a/src/OpenRpg.Data/Defaults/Queries/FindAllInMemoryQuery.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Data.Defaults.Queries
-{
- public abstract class FindAllInMemoryQuery : IFindAllQuery
- {
- public IEnumerable Execute(object dataSource)
- { return Execute((List) dataSource); }
-
- public abstract IEnumerable Execute(List dataSource);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Defaults/Queries/FindInMemoryQuery.cs b/src/OpenRpg.Data/Defaults/Queries/FindInMemoryQuery.cs
deleted file mode 100644
index a883588..0000000
--- a/src/OpenRpg.Data/Defaults/Queries/FindInMemoryQuery.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Data.Defaults.Queries
-{
- public abstract class FindInMemoryQuery : IFindQuery
- {
- public T Execute(object dataSource)
- { return Execute((List) dataSource); }
-
- public abstract T Execute(List dataSource);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/IDataSource.cs b/src/OpenRpg.Data/IDataSource.cs
new file mode 100644
index 0000000..33dc99c
--- /dev/null
+++ b/src/OpenRpg.Data/IDataSource.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace OpenRpg.Data
+{
+ public interface IDataSource
+ {
+ object NativeSource { get; }
+
+ T Get(object id);
+ IEnumerable GetAll();
+ void Create(T data, object id = null);
+ void Update(T data, object id);
+ bool Delete(object id);
+ bool Exists(object id);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/IQuery.cs b/src/OpenRpg.Data/IQuery.cs
new file mode 100644
index 0000000..8279544
--- /dev/null
+++ b/src/OpenRpg.Data/IQuery.cs
@@ -0,0 +1,7 @@
+namespace OpenRpg.Data
+{
+ public interface IQuery
+ {
+ T Execute(IDataSource dataSource);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/IRepository.cs b/src/OpenRpg.Data/IRepository.cs
new file mode 100644
index 0000000..7a1542b
--- /dev/null
+++ b/src/OpenRpg.Data/IRepository.cs
@@ -0,0 +1,9 @@
+namespace OpenRpg.Data
+{
+ public interface IRepository
+ {
+ IDataSource DataSource { get; }
+
+ T Query(IQuery query);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Queries/IExecuteQuery.cs b/src/OpenRpg.Data/Queries/IExecuteQuery.cs
deleted file mode 100644
index d771c2a..0000000
--- a/src/OpenRpg.Data/Queries/IExecuteQuery.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace OpenRpg.Data.Queries
-{
- ///
- /// Execute queries are for altering data in the repository such as mass updates or deletions
- ///
- public interface IExecuteQuery
- {
- object Execute(object dataSource);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Queries/IFindAllQuery.cs b/src/OpenRpg.Data/Queries/IFindAllQuery.cs
deleted file mode 100644
index 07297a1..0000000
--- a/src/OpenRpg.Data/Queries/IFindAllQuery.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Collections.Generic;
-
-namespace OpenRpg.Data.Queries
-{
- ///
- /// The FindAll Query is meant to represent a way to get a list of results back from the repository
- ///
- /// The data type to return
- public interface IFindAllQuery : IFindQuery>
- { }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Repositories/IDataRepository.cs b/src/OpenRpg.Data/Repositories/IDataRepository.cs
deleted file mode 100644
index a080818..0000000
--- a/src/OpenRpg.Data/Repositories/IDataRepository.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using OpenRpg.Core.Common;
-
-namespace OpenRpg.Data.Repositories
-{
- public interface IDataRepository : IReadDataRepository, IWriteDataRepository where T : IHasDataId
- {}
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Repositories/IReadDataRepository.cs b/src/OpenRpg.Data/Repositories/IReadDataRepository.cs
deleted file mode 100644
index fb4f638..0000000
--- a/src/OpenRpg.Data/Repositories/IReadDataRepository.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using OpenRpg.Core.Common;
-
-namespace OpenRpg.Data.Repositories
-{
- public interface IReadDataRepository : IReadRepository where T : IHasDataId
- {}
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Repositories/IReadRepository.cs b/src/OpenRpg.Data/Repositories/IReadRepository.cs
deleted file mode 100644
index f57c518..0000000
--- a/src/OpenRpg.Data/Repositories/IReadRepository.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Data.Repositories
-{
- public interface IReadRepository
- {
- T Retrieve(K id);
-
- IEnumerable FindAll(IFindAllQuery query);
- T2 Find(IFindQuery query);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Repositories/IRepository.cs b/src/OpenRpg.Data/Repositories/IRepository.cs
deleted file mode 100644
index e24cd0b..0000000
--- a/src/OpenRpg.Data/Repositories/IRepository.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace OpenRpg.Data.Repositories
-{
- public interface IRepository : IReadRepository, IWriteRepository
- {}
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Repositories/IWriteDataRepository.cs b/src/OpenRpg.Data/Repositories/IWriteDataRepository.cs
deleted file mode 100644
index b6b8a8e..0000000
--- a/src/OpenRpg.Data/Repositories/IWriteDataRepository.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using OpenRpg.Core.Common;
-
-namespace OpenRpg.Data.Repositories
-{
- public interface IWriteDataRepository : IWriteRepository where T : IHasDataId
- {}
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Data/Repositories/IWriteRepository.cs b/src/OpenRpg.Data/Repositories/IWriteRepository.cs
deleted file mode 100644
index 04879c7..0000000
--- a/src/OpenRpg.Data/Repositories/IWriteRepository.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Data.Repositories
-{
- public interface IWriteRepository
- {
- object Execute(IExecuteQuery query);
-
- void Create(T entry);
- void Update(T entry);
- void Delete(T entry);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/DataSources/ILocaleDataSource.cs b/src/OpenRpg.Localization/Data/DataSources/ILocaleDataSource.cs
new file mode 100644
index 0000000..67fbbb9
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/DataSources/ILocaleDataSource.cs
@@ -0,0 +1,12 @@
+namespace OpenRpg.Localization.Data.DataSources
+{
+ public interface ILocaleDataSource
+ {
+ object NativeSource { get; }
+ string Get(string localeCode, string key);
+ void Create(string localeCode, string text, string key);
+ void Update(string localeCode, string text, string key);
+ bool Delete(string localeCode, string key);
+ bool Exists(string localeCode, string key);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/DataSources/InMemoryLocaleDataSource.cs b/src/OpenRpg.Localization/Data/DataSources/InMemoryLocaleDataSource.cs
new file mode 100644
index 0000000..6239de2
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/DataSources/InMemoryLocaleDataSource.cs
@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace OpenRpg.Localization.Data.DataSources
+{
+ public class InMemoryLocaleDataSource : ILocaleDataSource
+ {
+ public Dictionary LocaleDatasets { get; }
+ public object NativeSource => LocaleDatasets;
+
+ public InMemoryLocaleDataSource(IEnumerable localeDatasets = null)
+ {
+ LocaleDatasets = localeDatasets?.ToDictionary(x => x.LocaleCode, x => x) ??
+ new Dictionary();
+ }
+
+ public string Get(string localeCode, string key) => LocaleDatasets[localeCode].LocaleData[key];
+ public void Create(string localeCode, string text, string key) => LocaleDatasets[localeCode].LocaleData.Add(key, text);
+ public void Update(string localeCode, string text, string key) => LocaleDatasets[localeCode].LocaleData[key] = text;
+ public bool Delete(string localeCode, string key) => LocaleDatasets[localeCode].LocaleData.Remove(key);
+ public bool Exists(string localeCode, string key) => LocaleDatasets[localeCode].LocaleData.ContainsKey(key);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Extensions/RepositoryExtensions.cs b/src/OpenRpg.Localization/Data/Extensions/RepositoryExtensions.cs
new file mode 100644
index 0000000..a33b996
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Extensions/RepositoryExtensions.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using OpenRpg.Localization.Data.Queries.Conventions;
+using OpenRpg.Localization.Data.Repositories;
+
+namespace OpenRpg.Localization.Data.Extensions
+{
+ public static class LocaleRepositoryExtensions
+ {
+ public static string Create(this ILocaleRepository repository, string text, string id)
+ { return repository.Query(new CreateLocaleQuery(text, id)); }
+
+ public static string Get(this ILocaleRepository repository, string id)
+ { return repository.Query(new GetLocaleQuery(id)); }
+
+ public static IEnumerable GetAll(this ILocaleRepository repository, params string[] ids)
+ { return repository.Query(new GetAllLocalesQuery(ids)); }
+
+ public static string Update(this ILocaleRepository repository, string text, string id)
+ { return repository.Query(new UpdateLocaleQuery(text, id)); }
+
+ public static bool Delete(this ILocaleRepository repository, string id)
+ { return repository.Query(new DeleteLocaleQuery(id)); }
+
+ public static bool Exists(this ILocaleRepository repository, string id)
+ { return repository.Query(new LocaleExistsQuery(id)); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/Conventions/CreateLocaleQuery.cs b/src/OpenRpg.Localization/Data/Queries/Conventions/CreateLocaleQuery.cs
new file mode 100644
index 0000000..ce2716b
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/Conventions/CreateLocaleQuery.cs
@@ -0,0 +1,22 @@
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries.Conventions
+{
+ public class CreateLocaleQuery : ILocaleQuery
+ {
+ public string Text { get; }
+ public string Id { get; }
+
+ public CreateLocaleQuery(string text, string id)
+ {
+ Text = text;
+ Id = id;
+ }
+
+ public string Execute(string localeCode, ILocaleDataSource dataSource)
+ {
+ dataSource.Create(localeCode, Text, Id);
+ return Id;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/Conventions/DeleteLocaleQuery.cs b/src/OpenRpg.Localization/Data/Queries/Conventions/DeleteLocaleQuery.cs
new file mode 100644
index 0000000..8792d69
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/Conventions/DeleteLocaleQuery.cs
@@ -0,0 +1,18 @@
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries.Conventions
+{
+ public class DeleteLocaleQuery : ILocaleQuery
+ {
+ public string Id { get; }
+
+ public DeleteLocaleQuery(string id)
+ { Id = id; }
+
+ public bool Execute(string localeCode, ILocaleDataSource dataSource)
+ {
+ dataSource.Delete(localeCode, Id);
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/Conventions/GetAllLocalesQuery.cs b/src/OpenRpg.Localization/Data/Queries/Conventions/GetAllLocalesQuery.cs
new file mode 100644
index 0000000..291868d
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/Conventions/GetAllLocalesQuery.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using System.Linq;
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries.Conventions
+{
+ public class GetAllLocalesQuery : ILocaleQuery>
+ {
+ public string[] Ids { get; }
+
+ public GetAllLocalesQuery(params string[] ids)
+ { Ids = ids; }
+
+ public IEnumerable Execute(string locale, ILocaleDataSource dataSource)
+ { return Ids.Select(x => dataSource.Get(locale, x)); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/Conventions/GetLocaleQuery.cs b/src/OpenRpg.Localization/Data/Queries/Conventions/GetLocaleQuery.cs
new file mode 100644
index 0000000..aebd983
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/Conventions/GetLocaleQuery.cs
@@ -0,0 +1,15 @@
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries.Conventions
+{
+ public class GetLocaleQuery : ILocaleQuery
+ {
+ public string Id { get; }
+
+ public GetLocaleQuery(string id)
+ { Id = id; }
+
+ public string Execute(string locale, ILocaleDataSource dataSource)
+ { return dataSource.Get(locale, Id); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/Conventions/LocaleExistsQuery.cs b/src/OpenRpg.Localization/Data/Queries/Conventions/LocaleExistsQuery.cs
new file mode 100644
index 0000000..015d635
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/Conventions/LocaleExistsQuery.cs
@@ -0,0 +1,15 @@
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries.Conventions
+{
+ public class LocaleExistsQuery : ILocaleQuery
+ {
+ public string Id { get; }
+
+ public LocaleExistsQuery(string id)
+ { Id = id; }
+
+ public bool Execute(string locale, ILocaleDataSource dataSource)
+ { return dataSource.Exists(locale, Id); }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/Conventions/UpdateLocaleQuery.cs b/src/OpenRpg.Localization/Data/Queries/Conventions/UpdateLocaleQuery.cs
new file mode 100644
index 0000000..77531b9
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/Conventions/UpdateLocaleQuery.cs
@@ -0,0 +1,22 @@
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries.Conventions
+{
+ public class UpdateLocaleQuery : ILocaleQuery
+ {
+ public string Text { get; }
+ public string Key { get; }
+
+ public UpdateLocaleQuery(string text, string key)
+ {
+ Text = text;
+ Key = key;
+ }
+
+ public string Execute(string locale, ILocaleDataSource dataSource)
+ {
+ dataSource.Update(locale, Text, Key);
+ return Key;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Queries/ILocaleQuery.cs b/src/OpenRpg.Localization/Data/Queries/ILocaleQuery.cs
new file mode 100644
index 0000000..7bf82e2
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Queries/ILocaleQuery.cs
@@ -0,0 +1,9 @@
+using OpenRpg.Localization.Data.DataSources;
+
+namespace OpenRpg.Localization.Data.Queries
+{
+ public interface ILocaleQuery
+ {
+ T Execute(string locale, ILocaleDataSource dataSource);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Repositories/ILocaleRepository.cs b/src/OpenRpg.Localization/Data/Repositories/ILocaleRepository.cs
new file mode 100644
index 0000000..8d1b702
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Repositories/ILocaleRepository.cs
@@ -0,0 +1,15 @@
+using OpenRpg.Localization.Data.DataSources;
+using OpenRpg.Localization.Data.Queries;
+
+namespace OpenRpg.Localization.Data.Repositories
+{
+ public interface ILocaleRepository
+ {
+ string CurrentLocaleCode { get; }
+ void ChangeLocale(string localeCode);
+
+ ILocaleDataSource DataSource { get; }
+
+ T Query(ILocaleQuery query);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Data/Repositories/LocaleRepository.cs b/src/OpenRpg.Localization/Data/Repositories/LocaleRepository.cs
new file mode 100644
index 0000000..7ba6ebb
--- /dev/null
+++ b/src/OpenRpg.Localization/Data/Repositories/LocaleRepository.cs
@@ -0,0 +1,22 @@
+using OpenRpg.Localization.Data.DataSources;
+using OpenRpg.Localization.Data.Queries;
+
+namespace OpenRpg.Localization.Data.Repositories
+{
+ public class LocaleRepository : ILocaleRepository
+ {
+ public string CurrentLocaleCode { get; private set; }
+ public ILocaleDataSource DataSource { get; }
+
+ public LocaleRepository(ILocaleDataSource dataSource, string localeCodeToUse)
+ {
+ DataSource = dataSource;
+ CurrentLocaleCode = localeCodeToUse;
+ }
+
+ public void ChangeLocale(string localeCode)
+ { CurrentLocaleCode = localeCode; }
+
+ public T Query(ILocaleQuery query) => query.Execute(CurrentLocaleCode, DataSource);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Queries/GetBatchLocalesQuery.cs b/src/OpenRpg.Localization/Queries/GetBatchLocalesQuery.cs
deleted file mode 100644
index abcaabe..0000000
--- a/src/OpenRpg.Localization/Queries/GetBatchLocalesQuery.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Localization.Queries
-{
- public class GetBatchLocalesQuery : IFindAllQuery
- {
- public IReadOnlyList Ids { get;}
-
- public GetBatchLocalesQuery(IReadOnlyList ids)
- { Ids = ids; }
-
- public IEnumerable Execute(object dataSource)
- {
- var localeStore = dataSource as LocaleDataset;
-
- for (var i = 0; i < Ids.Count; i++)
- { yield return localeStore.LocaleData[Ids[i]]; }
- }
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Repositories/ILocaleRepository.cs b/src/OpenRpg.Localization/Repositories/ILocaleRepository.cs
deleted file mode 100644
index 29aeb40..0000000
--- a/src/OpenRpg.Localization/Repositories/ILocaleRepository.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using OpenRpg.Data.Repositories;
-
-namespace OpenRpg.Localization.Repositories
-{
- public interface ILocaleRepository : IReadRepository
- {
- string LocaleCode { get; }
-
- void ChangeLocale(LocaleDataset dataset);
- bool Has(string id);
- void Create(string id, string text);
- void Update(string id, string text);
- void Delete(string id);
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.Localization/Repositories/LocaleRepository.cs b/src/OpenRpg.Localization/Repositories/LocaleRepository.cs
deleted file mode 100644
index 46108ac..0000000
--- a/src/OpenRpg.Localization/Repositories/LocaleRepository.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Collections.Generic;
-using OpenRpg.Data.Queries;
-
-namespace OpenRpg.Localization.Repositories
-{
- public class LocaleRepository : ILocaleRepository
- {
- public string LocaleCode => LocaleDataset.LocaleCode;
- public LocaleDataset LocaleDataset { get; protected set; }
-
- public LocaleRepository(LocaleDataset localeDataset)
- { LocaleDataset = localeDataset; }
-
- public string Retrieve(string id)
- { return LocaleDataset.LocaleData[id]; }
-
- public void ChangeLocale(LocaleDataset dataset)
- { LocaleDataset = dataset; }
-
- public bool Has(string id)
- { return LocaleDataset.LocaleData.ContainsKey(id); }
-
- public IEnumerable FindAll(IFindAllQuery query)
- { return query.Execute(LocaleDataset); }
-
- public T2 Find(IFindQuery query)
- { return query.Execute(LocaleDataset); }
-
- public void Create(string id, string text)
- { LocaleDataset.LocaleData.Add(id, text); }
-
- public void Update(string id, string text)
- { LocaleDataset.LocaleData[id] = text; }
-
- public void Delete(string id)
- { LocaleDataset.LocaleData.Remove(id); }
- }
-}
\ No newline at end of file
diff --git a/src/OpenRpg.UnitTests/Framework/DefaultKeyedVariablesTests.cs b/src/OpenRpg.UnitTests/Framework/DefaultKeyedVariablesTests.cs
new file mode 100644
index 0000000..350e2cc
--- /dev/null
+++ b/src/OpenRpg.UnitTests/Framework/DefaultKeyedVariablesTests.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using OpenRpg.Core.Variables;
+using Xunit;
+
+namespace OpenRpg.UnitTests.Framework;
+
+public class DefaultKeyedVariablesTests
+{
+ [Fact]
+ public void should_correctly_raise_add_event_on_adding_variables()
+ {
+ var expectedArgs = new VariableEventArgs(1, default, 10);
+ VariableEventArgs actualArgs = null;
+
+ var variables = new DefaultKeyedVariables();
+ variables.OnAdded += (sender, args) => actualArgs = args;
+
+ variables.AddVariable(expectedArgs.VariableType, expectedArgs.NewValue);
+
+ Assert.NotNull(actualArgs);
+ Assert.Equal(expectedArgs.VariableType, actualArgs.VariableType);
+ Assert.Equal(expectedArgs.OldValue, actualArgs.OldValue);
+ Assert.Equal(expectedArgs.NewValue, actualArgs.NewValue);
+
+ Assert.Equal(expectedArgs.NewValue, variables.InternalVariables[expectedArgs.VariableType]);
+ }
+
+ [Fact]
+ public void should_correctly_raise_change_event_on_updating_variables()
+ {
+ var expectedArgs = new VariableEventArgs(1, 10, 100);
+ VariableEventArgs actualArgs = null;
+
+ var variables = new DefaultKeyedVariables(new Dictionary { {1, 10} });
+ variables.OnChanged += (sender, args) => actualArgs = args;
+
+ variables[expectedArgs.VariableType] = expectedArgs.NewValue;
+
+ Assert.NotNull(actualArgs);
+ Assert.Equal(expectedArgs.VariableType, actualArgs.VariableType);
+ Assert.Equal(expectedArgs.OldValue, actualArgs.OldValue);
+ Assert.Equal(expectedArgs.NewValue, actualArgs.NewValue);
+
+ Assert.Equal(expectedArgs.NewValue, variables.InternalVariables[expectedArgs.VariableType]);
+ }
+
+ [Fact]
+ public void should_correctly_raise_remove_event_on_removing_variables()
+ {
+ var expectedArgs = new VariableEventArgs(1, 10, default);
+ VariableEventArgs actualArgs = null;
+
+ var variables = new DefaultKeyedVariables(new Dictionary { {1, 10} });
+ variables.OnRemoved += (sender, args) => actualArgs = args;
+
+ variables.Remove(expectedArgs.VariableType);
+
+ Assert.NotNull(actualArgs);
+ Assert.Equal(expectedArgs.VariableType, actualArgs.VariableType);
+ Assert.Equal(expectedArgs.OldValue, actualArgs.OldValue);
+ Assert.Equal(expectedArgs.NewValue, actualArgs.NewValue);
+
+ Assert.False(variables.InternalVariables.ContainsKey(expectedArgs.VariableType));
+ }
+
+ [Fact]
+ public void should_do_insert_on_key_update_if_key_doesnt_exist()
+ {
+ var expectedAddArgs = new VariableEventArgs(1, default, 10);
+ var expectedChangeArgs = new VariableEventArgs(1, 10, 100);
+ VariableEventArgs actualAddArgs = null;
+ VariableEventArgs actualChangedArgs = null;
+
+ var variables = new DefaultKeyedVariables();
+ variables.OnAdded += (sender, args) => actualAddArgs = args;
+ variables.OnChanged += (sender, args) => actualChangedArgs = args;
+
+ variables[expectedAddArgs.VariableType] = expectedAddArgs.NewValue;
+ variables[expectedChangeArgs.VariableType] = expectedChangeArgs.NewValue;
+
+ Assert.NotNull(actualAddArgs);
+ Assert.Equal(expectedAddArgs.VariableType, actualAddArgs.VariableType);
+ Assert.Equal(expectedAddArgs.OldValue, actualAddArgs.OldValue);
+ Assert.Equal(expectedAddArgs.NewValue, actualAddArgs.NewValue);
+
+ Assert.NotNull(actualChangedArgs);
+ Assert.Equal(expectedChangeArgs.VariableType, actualChangedArgs.VariableType);
+ Assert.Equal(expectedChangeArgs.OldValue, actualChangedArgs.OldValue);
+ Assert.Equal(expectedChangeArgs.NewValue, actualChangedArgs.NewValue);
+
+ Assert.Equal(expectedChangeArgs.NewValue, variables.InternalVariables[expectedChangeArgs.VariableType]);
+ }
+}
\ No newline at end of file
diff --git a/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj b/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj
new file mode 100644
index 0000000..14075f4
--- /dev/null
+++ b/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj
@@ -0,0 +1,28 @@
+
+
+
+ net6.0
+ enable
+
+ false
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/src/OpenRpg.UnitTests/Scaling/CurveExtensionTests.cs b/src/OpenRpg.UnitTests/Scaling/CurveExtensionTests.cs
new file mode 100644
index 0000000..7ea1dd1
--- /dev/null
+++ b/src/OpenRpg.UnitTests/Scaling/CurveExtensionTests.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using OpenRpg.CurveFunctions;
+using OpenRpg.CurveFunctions.Extensions;
+using Xunit;
+
+namespace OpenRpg.UnitTests.Scaling;
+
+public class CurveExtensionTests
+{
+ public static IEnumerable