init
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using RPGCoreCommon.Helpers;
|
||||
using RPGCoreCommon.Helpers.CustomTypes;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace RPGCoreCommon.DynamicValues
|
||||
{
|
||||
[Serializable]
|
||||
public class DynamicValue
|
||||
{
|
||||
// User defined formula or text with markers
|
||||
[SerializeField] internal string _serializedFormula;
|
||||
[SerializeField] internal SerializableDictionary<string, SerializableType> _serializedTypes = new();
|
||||
[SerializeField] internal SerializableDictionary<string, Object> _serializedSources = new();
|
||||
|
||||
private bool _isParsed;
|
||||
private string _formulaFormat;
|
||||
private MarkerParser[] _markers;
|
||||
|
||||
private void Parse()
|
||||
{
|
||||
if (Application.isPlaying && _isParsed) return;
|
||||
|
||||
_isParsed = true;
|
||||
|
||||
var matches = new Regex("{[a-zA-z0-9-\\.]*}").Matches(_serializedFormula);
|
||||
_markers = new MarkerParser[matches.Count];
|
||||
_formulaFormat = _serializedFormula;
|
||||
|
||||
for (var i = matches.Count-1; i >= 0; i--)
|
||||
{
|
||||
_markers[i] = new MarkerParser(matches[i].Value);
|
||||
_markers[i].sourceType = GetSourceType(_markers[i].sourceMarker);
|
||||
_formulaFormat = _formulaFormat.Remove(matches[i].Index, matches[i].Length).Insert(matches[i].Index, $"{{{i}}}");
|
||||
}
|
||||
}
|
||||
|
||||
private Type GetSourceType(string sourceMarker)
|
||||
{
|
||||
if (_serializedTypes.TryGetValue(sourceMarker, out var type)) return type;
|
||||
if (_serializedSources.TryGetValue(sourceMarker, out var obj)) return obj.GetType();
|
||||
return null;
|
||||
}
|
||||
|
||||
private object GetSource(string sourceMarker, DynamicValueSourceContext sourceContext = null)
|
||||
{
|
||||
if (_serializedSources.TryGetValue(sourceMarker, out var s1)) return s1;
|
||||
if (sourceContext != null && sourceContext.TryGetSource(sourceMarker, out var s2)) return s2;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveDynamicTypes()
|
||||
{
|
||||
_serializedTypes.Clear();
|
||||
}
|
||||
|
||||
public void SetDynamicTypes(Dictionary<string, Type> types)
|
||||
{
|
||||
RemoveDynamicTypes();
|
||||
types.DictForEach(SetDynamicType);
|
||||
}
|
||||
|
||||
public void SetDynamicType(string name, Type type)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Debug.LogError($"method '{nameof(SetDynamicType)}' is only available in editor. Dynamic types should not be changed runtime!");
|
||||
return;
|
||||
}
|
||||
|
||||
_serializedTypes[name] = new SerializableType(type);
|
||||
}
|
||||
|
||||
public MarkerParser[] GetMarkers()
|
||||
{
|
||||
Parse();
|
||||
return _markers.ToArray();
|
||||
}
|
||||
|
||||
public string GetString(DynamicValueSourceContext sourceContext = null)
|
||||
{
|
||||
Parse();
|
||||
var values = _markers
|
||||
.Select(marker => marker.GetValue(GetSource(marker.sourceMarker, sourceContext)))
|
||||
.ToArray<object>();
|
||||
return string.Format(_formulaFormat, values);
|
||||
}
|
||||
|
||||
public int GetValue(DynamicValueSourceContext sourceContext = null)
|
||||
{
|
||||
Parse();
|
||||
ExpressionEvaluator.Evaluate(GetString(sourceContext), out int value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user