Files
2026-04-25 23:37:10 +02:00

100 lines
3.4 KiB
C#

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;
}
}
}