Implemented static Achievments class, implemented propper backend api, merged AchievmentManagerConfig and AchievmentCollection

This commit is contained in:
LubieKakao1212 2023-01-20 20:27:39 +01:00
parent 36840271af
commit d0b4734572
12 changed files with 209 additions and 76 deletions

View File

@ -18,7 +18,7 @@ namespace NEG.Utils.Achievments
public const string DefaultAchivmentsConfigLabel = "Achivments"; public const string DefaultAchivmentsConfigLabel = "Achivments";
private AchievmentManager manager = new AchievmentManager(); private AchievmentManager manager = new AchievmentManager();
private IAchivmentStorage storage; private IAchievmentBackend backend;
public static Builder FromDefaultConfig() public static Builder FromDefaultConfig()
{ {
@ -48,19 +48,7 @@ namespace NEG.Utils.Achievments
return builder; return builder;
} }
public Builder WithLabeledDefinitions(string label) public Builder WithDefinitionsFrom(AchievmentManagerConfig collection)
{
var handle = Addressables.LoadAssetsAsync<AchivmentDefinitionCollection>((IEnumerable)new string[] { label }, delegate { }, Addressables.MergeMode.Union, false);
var achivmentCollections = handle.WaitForCompletion();
foreach (var achivmentCollection in achivmentCollections)
WithDefinitionsFrom(achivmentCollection);
return this;
}
public Builder WithDefinitionsFrom(AchivmentDefinitionCollection collection)
{ {
foreach (var def in collection.Achivments) foreach (var def in collection.Achivments)
{ {
@ -70,14 +58,26 @@ namespace NEG.Utils.Achievments
return this; return this;
} }
public Builder LoadedFrom(IAchivmentStorage storageIn) public Builder WithLabeledBackend(string label)
{ {
if (storage != null) var backendConfigHandle = Addressables.LoadAssetAsync<IAchievmentBackendConfig>(label);
{
throw new ApplicationException("Cannot Load achivment data from multiple storage instances"); var backendConfig = backendConfigHandle.WaitForCompletion();
WithBackend(backendConfig.ConstructBackend());
Addressables.Release(backendConfigHandle);
return this;
} }
this.storage = storageIn; public Builder WithBackend(IAchievmentBackend backendIn)
{
if (backend != null)
{
throw new ApplicationException("There can only be one Achievment Backend at a time");
}
this.backend = backendIn;
return this; return this;
} }
@ -90,11 +90,13 @@ namespace NEG.Utils.Achievments
public AchievmentManager Build() public AchievmentManager Build()
{ {
//TODO if (backend != null)
/*if (storage != null)
{ {
manager.LoadFrom(storage); manager.InitBackend(backend);
}*/ }else
{
Debug.LogWarning("No AchievmentBackend selected. Is this intended?");
}
return manager; return manager;
} }
} }
@ -127,15 +129,27 @@ namespace NEG.Utils.Achievments
} }
} }
/*private void LoadFrom(IAchivmentStorage achivmentStorage) /// <summary>
/// Initializes a backend syncing achievments data with it and redistering it as a callback reciever
/// </summary>
/// <remarks>Resets all achievments data</remarks>
private void InitBackend(IAchievmentBackend achievmentBackend)
{ {
foreach (var entry in definitionCache) foreach (var definition in definitionCache.Values)
{ {
var storedProgress = achivmentStorage.GetStoredAchivmentProgress(entry.Key); var storedProgress = achievmentBackend.GetStoredAchivment(definition);
dataCache[entry.Value].ProgressLeft = storedProgress; if (storedProgress != null)
{
dataCache[definition] = storedProgress;
}
else
{
dataCache[definition] = definition.Construct();
}
}
AddCallbackReciever(achievmentBackend);
} }
}*/
public void AddCallbackRecievers(IEnumerable<IAchievmentCallbackReciever> initialCallbacks) public void AddCallbackRecievers(IEnumerable<IAchievmentCallbackReciever> initialCallbacks)
{ {

View File

@ -1,3 +1,4 @@
using NEG.Utils.Achievments.AchievmentTypes;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -7,14 +8,12 @@ namespace NEG.Utils.Achievments
[CreateAssetMenu(menuName = "Achivments/BaseConfig")] [CreateAssetMenu(menuName = "Achivments/BaseConfig")]
public class AchievmentManagerConfig : ScriptableObject, IAchivmentManagerConfig public class AchievmentManagerConfig : ScriptableObject, IAchivmentManagerConfig
{ {
public const string DefaultAchivmentsCollectionLabel = "Achivments";
[field: SerializeField] [field: SerializeField]
public string AchivmentCollectionAssetLabel { get; private set; } = DefaultAchivmentsCollectionLabel; public List<AchievmentDefinition> Achivments { get; private set; } = new List<AchievmentDefinition>();
public void Apply(AchievmentManager.Builder builder) public void Apply(AchievmentManager.Builder builder)
{ {
builder.WithLabeledDefinitions(AchivmentCollectionAssetLabel); builder.WithDefinitionsFrom(this);
} }
public void ApplyLast(AchievmentManager.Builder builder) public void ApplyLast(AchievmentManager.Builder builder)

View File

@ -1,3 +1,5 @@
using NEG.Utils.Achievments.AchievmentTypes;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -12,11 +14,138 @@ namespace NEG.Utils.Achievments
{ {
if (instance == null) if (instance == null)
{ {
instance = instance = AchievmentManager.Builder.FromDefaultConfig()
.WithLabeledBackend(BackendLabel)
.Build();
}
return instance;
} }
} }
internal static string BackendLabel
{
get => backendLabel;
set
{
if (backendLabel != null)
{
throw new ApplicationException("Multiple AchievmentBackends enabled, this is not allowed");
} }
backendLabel = value;
}
}
private static string backendLabel;
private static AchievmentManager instance; private static AchievmentManager instance;
#region Achievment Manipulation (Sets, Gets)
/// <summary>
/// Returns if an achivment at a given id is completed
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <seealso cref="AchievmentManager.IsCompleted(string)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id</remarks>
public static bool IsCompleted(string id)
{
return instance.IsCompleted(id);
}
#region Toggle
/// <summary>
/// Sets a <see cref="ToggleAchievmentData"/> as completed. <br/>
/// </summary>
/// <seealso cref="ToggleAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.SetToggleAchivment(string)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static bool SetToggleAchivment(string id)
{
return instance.SetToggleAchivment(id);
}
/// <summary>
/// Gets a completion state from a <see cref="ToggleAchievmentData"/>.<br/>
/// </summary>
/// <seealso cref="ToggleAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.GetToggleState(string)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static bool GetToggleState(string id)
{
return instance.GetToggleState(id);
}
#endregion
#region Int
/// <summary>
/// Sets progress of a given <see cref="IntAchievmentData"/> to <paramref name="progress"/> <br/>
/// </summary>
/// <seealso cref="IntAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.SetIntProgress(string, int)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static bool SetIntProgress(string id, int progress)
{
return instance.SetIntProgress(id, progress);
}
/// <summary>
/// Changes progress of a given <see cref="IntAchievmentData"/> by <paramref name="delta"/><br/>
/// </summary>
/// <seealso cref="IntAchievmentDefinition"/>\
/// <seealso cref="AchievmentManager.ChangeIntProgress(string, int)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static bool ChangeIntProgress(string id, int delta)
{
return instance.ChangeIntProgress(id, delta);
}
/// <summary>
/// Gets current progress from a <see cref="IntAchievmentData"/>.<br/>
/// </summary>
/// <seealso cref="ToggleAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.GetIntProgress(string)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static int GetIntProgress(string id)
{
return instance.GetIntProgress(id);
}
#endregion
#region Float
/// <summary>
/// Sets progress of a given <see cref="FloatAchievmentData"/> to <paramref name="progress"/><br/>
/// </summary>
/// <seealso cref="FloatAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.SetFloatProgress(string, float)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static bool SetFloatProgress(string id, float progress)
{
return instance.SetFloatProgress(id, progress);
}
/// <summary>
/// Changes progress of a given <see cref="FloatAchievmentData"/> by <paramref name="delta"/><br/>
/// </summary>
/// <seealso cref="FloatAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.ChangeFloatProgress(string, float)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static bool ChangeFloatProgress(string id, float delta)
{
return instance.ChangeFloatProgress(id, delta);
}
/// <summary>
/// Gets current progress from a <see cref="FloatAchievmentData"/>.<br/>
/// </summary>
/// <seealso cref="FloatAchievmentDefinition"/>
/// <seealso cref="AchievmentManager.GetFloatProgress(string)"/>
/// <remarks>throws an <see cref="AchievmentException"/> if there is no achievment under id or an <see cref="AchievmentTypeException"/> if achievment under id is of a different type</remarks>
public static float GetFloatProgress(string id)
{
return instance.GetFloatProgress(id);
}
#endregion
#endregion
} }
} }

View File

@ -9,7 +9,6 @@ namespace NEG.Utils.Achievments
[CreateAssetMenu(menuName = "Achivments/Collection")] [CreateAssetMenu(menuName = "Achivments/Collection")]
public class AchivmentDefinitionCollection : ScriptableObject public class AchivmentDefinitionCollection : ScriptableObject
{ {
[field: SerializeField]
public List<AchievmentDefinition> Achivments { get; private set; } = new List<AchievmentDefinition>();
} }
} }

View File

@ -0,0 +1,26 @@
using NEG.Utils.Achievments.AchievmentTypes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace NEG.Utils.Achievments
{
/// <summary>
/// Used to construct <see cref="IAchievmentBackend"/> instance
/// </summary>
public interface IAchievmentBackendConfig
{
/// <returns>Constructed backend</returns>
public IAchievmentBackend ConstructBackend();
}
public interface IAchievmentBackend : IAchievmentCallbackReciever
{
/// <summary>
/// Constructs an AchievmentData for given <paramref name="definition"/>
/// </summary>
/// <remarks>May return null if there is no stored data for this achievment</remarks>
public AchievmentData GetStoredAchivment(AchievmentDefinition definition);
}
}

View File

@ -1,11 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace NEG.Utils.Achievments
{
public interface IAchivmentStorage
{
public int GetStoredAchivmentProgress(string id);
}
}

View File

@ -1,5 +1,5 @@
Static Achievments class Static Achievments class
Implement Storage again Implement Storage again API (done)
Fix typos Fix typos
Merge AchievmentCollection with AchievmentManagerConfig Merge AchievmentCollection with AchievmentManagerConfig (done)
Static backend constructors Static backend constructors

View File

@ -12,7 +12,7 @@ namespace NEG.Utils.Achievments.Tests
public class ConfigTests public class ConfigTests
{ {
public const string AchievmentsLabel = "TestAchivments"; public const string AchievmentsLabel = "TestAchievments";
public const string AchievmentIdToggle = "TOGGLE"; public const string AchievmentIdToggle = "TOGGLE";
public const string AchievmentIdInt = "INT"; public const string AchievmentIdInt = "INT";

View File

@ -1,18 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ef37a873be859d042bda22dee624e429, type: 3}
m_Name: AchivmentCollection
m_EditorClassIdentifier:
<Achivments>k__BackingField:
- {fileID: 11400000, guid: 7734df2e5d4033346aac56f0a2b2a836, type: 2}
- {fileID: 11400000, guid: c704b1ea2247ad540842a9caff628211, type: 2}
- {fileID: 11400000, guid: c71840de74e747e45afc82ecf8922dcd, type: 2}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 4d95138fe57571c4299aa325a378e4ea
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -12,4 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 88120b6e616164f489387a6a32a25dee, type: 3} m_Script: {fileID: 11500000, guid: 88120b6e616164f489387a6a32a25dee, type: 3}
m_Name: BaseConfig m_Name: BaseConfig
m_EditorClassIdentifier: m_EditorClassIdentifier:
<AchivmentCollectionAssetLabel>k__BackingField: TestAchivments <Achivments>k__BackingField:
- {fileID: 11400000, guid: 7734df2e5d4033346aac56f0a2b2a836, type: 2}
- {fileID: 11400000, guid: c704b1ea2247ad540842a9caff628211, type: 2}
- {fileID: 11400000, guid: c71840de74e747e45afc82ecf8922dcd, type: 2}