Skip to content

Commit

Permalink
Add lazy loading for skill level info
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaioru committed Nov 15, 2023
1 parent c435e31 commit 9903a10
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
using System.Collections.Frozen;
using Duey.Abstractions;
using Edelstein.Common.Utilities.Templates;
using Edelstein.Protocol.Gameplay.Models.Characters.Skills.Templates;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Gameplay.Models.Characters.Skills.Templates;

public class SkillTemplate : ISkillTemplate
{
public int ID { get; }

public ISkillTemplateLevel? this[int level] => Levels.TryGetValue(level, out var result) ? result : null;
public ISkillTemplateLevel? this[int level] => Levels.Retrieve(level).Result;

public short MaxLevel { get; }

Expand All @@ -24,7 +26,7 @@ public class SkillTemplate : ISkillTemplate

public ICollection<int> PsdSkill { get; }
public IDictionary<int, int> ReqSkill { get; }
public IDictionary<int, ISkillTemplateLevel> Levels { get; }
public ITemplateCollection<ISkillTemplateLevel> Levels { get; }

public SkillTemplate(int id, IDataNode node)
{
Expand Down Expand Up @@ -76,22 +78,29 @@ public SkillTemplate(int id, IDataNode node)
if (maxLevelStr != null)
maxLevel = Convert.ToInt32(maxLevelStr);

Levels = Enumerable
Levels = new TemplateCollectionProvider<ISkillTemplateLevel>(Enumerable
.Range(1, maxLevel + (IsCombatOrders ? 2 : 0))
.ToFrozenDictionary(
i => i,
i => (ISkillTemplateLevel)new SkillTemplateLevelCommon(i, common.Cache())
);
i => (ITemplateProvider<ISkillTemplateLevel>)new TemplateProviderLazy<ISkillTemplateLevel>(
i,
() => new SkillTemplateLevelCommon(i, common.Cache())
)
));
MaxLevel = (short)maxLevel;
}
else
{
var level = node.ResolvePath("level");

Levels = level?.Children.ToFrozenDictionary(
c => Convert.ToInt32(c.Name),
c => (ISkillTemplateLevel)new SkillTemplateLevel(Convert.ToInt32(c.Name), c.Cache())
) ?? FrozenDictionary<int, ISkillTemplateLevel>.Empty;
Levels = new TemplateCollectionProvider<ISkillTemplateLevel>(
level?.Children.ToFrozenDictionary(
c => Convert.ToInt32(c.Name),
c => (ITemplateProvider<ISkillTemplateLevel>)new TemplateProviderEager<ISkillTemplateLevel>(
Convert.ToInt32(c.Name),
new SkillTemplateLevel(Convert.ToInt32(c.Name), c.Cache()))
) ?? FrozenDictionary<int, ITemplateProvider<ISkillTemplateLevel>>.Empty
);
MaxLevel = (short)(Levels?.Count ?? 0);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Edelstein.Common.Gameplay.Models.Characters.Skills.Templates;

public class SkillTemplateLevel : ISkillTemplateLevel
{
public int ID => Level;

public int Level { get; }

public short HP { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace Edelstein.Common.Gameplay.Models.Characters.Skills.Templates;

public class SkillTemplateLevelCommon : ISkillTemplateLevel
{
public int ID => Level;

public int Level { get; }

public short HP { get; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.Immutable;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Utilities.Templates;

public class TemplateCollection<TTemplate>(
IReadOnlyDictionary<int, TTemplate> templates
) :
ITemplateCollection<TTemplate>
where TTemplate : ITemplate
{
public int Count => templates.Count;

public Task<TTemplate?> Retrieve(int key)
=> Task.FromResult(templates.TryGetValue(key, out var result) ? result : default);

public Task<ICollection<TTemplate>> RetrieveAll()
=> Task.FromResult<ICollection<TTemplate>>(templates.Values.ToImmutableArray());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Frozen;
using System.Collections.Immutable;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Utilities.Templates;

public class TemplateCollectionProvider<TTemplate>(
IReadOnlyDictionary<int, ITemplateProvider<TTemplate>> providers
) :
ITemplateCollection<TTemplate>
where TTemplate : ITemplate
{
public int Count => providers.Count;

public async Task<TTemplate?> Retrieve(int key)
=> providers.TryGetValue(key, out var provider) ? await provider.Provide() : default;

public async Task<ICollection<TTemplate>> RetrieveAll()
=> await Task.WhenAll(providers.Values.Select(p => p.Provide()));
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@

namespace Edelstein.Common.Utilities.Templates;

public class TemplateManager<TTemplate> : ITemplateManager<TTemplate> where TTemplate : ITemplate
public class TemplateManager<TTemplate> :
ITemplateManager<TTemplate>
where TTemplate : ITemplate
{
private readonly IDictionary<int, ITemplateProvider<TTemplate>> _providers;
private readonly IDictionary<int, ITemplateProvider<TTemplate>> _providers = new Dictionary<int, ITemplateProvider<TTemplate>>();
private FrozenDictionary<int, ITemplateProvider<TTemplate>>? _providersFrozen;

public TemplateManager() => _providers = new Dictionary<int, ITemplateProvider<TTemplate>>();

public int Count => (_providersFrozen ?? _providers).Count;

public async Task<TTemplate?> Retrieve(int key) =>
(_providersFrozen ?? _providers).TryGetValue(key, out var provider) ? await provider.Provide() : default;

public Task<ITemplateProvider<TTemplate>> Insert(ITemplateProvider<TTemplate> entry) =>
Task.FromResult((_providersFrozen ?? _providers)[entry.ID] = entry);

public async Task<ICollection<TTemplate>> RetrieveAll() =>
await Task.WhenAll((_providersFrozen ?? _providers).Values.Select(p => p.Provide()));

public Task<ITemplateProvider<TTemplate>> Insert(ITemplateProvider<TTemplate> entry) =>
Task.FromResult((_providersFrozen ?? _providers)[entry.ID] = entry);

public void Freeze()
{
_providersFrozen = _providers.ToFrozenDictionary();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ public interface ISkillTemplate : ITemplate

ICollection<int> PsdSkill { get; }
IDictionary<int, int> ReqSkill { get; }
IDictionary<int, ISkillTemplateLevel> Levels { get; }
ITemplateCollection<ISkillTemplateLevel> Levels { get; }
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Edelstein.Protocol.Utilities.Spatial;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Protocol.Gameplay.Models.Characters.Skills.Templates;

public interface ISkillTemplateLevel
public interface ISkillTemplateLevel : ITemplate
{
int Level { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

<ItemGroup>
<Folder Include="Pipelines"/>
<Folder Include="Templates"/>
<Folder Include="Tickers"/>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Edelstein.Protocol.Utilities.Repositories.Methods;

namespace Edelstein.Protocol.Utilities.Templates;

public interface ITemplateCollection<TTemplate> :
IRepositoryMethodRetrieve<int, TTemplate>,
IRepositoryMethodRetrieveAll<int, TTemplate>
where TTemplate : ITemplate
{
int Count { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
namespace Edelstein.Protocol.Utilities.Templates;

public interface ITemplateManager<TTemplate> :
IRepositoryMethodRetrieve<int, TTemplate>,
IRepositoryMethodRetrieveAll<int, TTemplate>,
ITemplateCollection<TTemplate>,
IRepositoryMethodInsert<int, ITemplateProvider<TTemplate>>,
IRepositoryMethodFreeze
where TTemplate : ITemplate
{
int Count { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Edelstein.Protocol.Utilities.Templates;

public interface ITemplateProvider<TTemplate> : IIdentifiable<int> where TTemplate : ITemplate
public interface ITemplateProvider<TTemplate> :
IIdentifiable<int>
where TTemplate : ITemplate
{
Task<TTemplate> Provide();
}

0 comments on commit 9903a10

Please sign in to comment.