Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 98 additions & 28 deletions DistantWorlds2.ModLoader.Core/GameDataDefinitionPatching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,18 @@ public static void PatchDynamicDefinition(Type type, object def, YamlSequenceNod
if (!pass)
continue;

ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
ConcurrentDictionary<object, Func<object>> compileCache = new();

try {
ProcessObjectUpdate(type, def, item,
(key, expr) => compileCache.GetOrAdd((key,expr), _ => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
ModLoader.ModManager.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
Console.Error.WriteLine($"Failed to parse {type.Name} @ {item.Start}");
break;
}

Console.WriteLine($"Updated {type.Name} where {whereStr}");

Expand Down Expand Up @@ -735,6 +745,8 @@ int ConvertToInt(object id)

var def = PrepopulateTyped(Activator.CreateInstance<T>());

if (def is null) throw new NotImplementedException();

if (idLookupReq.Value is YamlScalarNode idLookupVarNode)
{
var idLookupVar = idLookupVarNode.Value;
Expand All @@ -748,17 +760,19 @@ int ConvertToInt(object id)
Dsl["collection"] = null;
Dsl["def"] = def;

try
{
ConcurrentDictionary<object, Func<object>> compileCache = new();

try {
ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
(key, expr) => compileCache.GetOrAdd((key,expr), _ => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
ModLoader.ModManager.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
Console.Error.WriteLine($"Failed to parse {type.Name} @ {item.Start}");
break;
}

defs.Add(def);
break;
}
Expand Down Expand Up @@ -827,8 +841,18 @@ int ConvertToInt(object id)
Dsl["collection"] = null;
Dsl["def"] = def;

ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
ConcurrentDictionary<object, Func<object>> compileCache = new();

try {
ProcessObjectUpdate(type, def, item,
(key, expr) => compileCache.GetOrAdd((key,expr), _ => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
ModLoader.ModManager.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
Console.Error.WriteLine($"Failed to parse {type.Name} @ {item.Start}");
break;
}

Console.WriteLine($"Updated {type.Name} {id}");
break;
Expand Down Expand Up @@ -859,6 +883,14 @@ int ConvertToInt(object id)
break;
}


if (!defs.Any()) {
Console.Error.WriteLine($"There don't appear to be any {type.Name} @ {whereNode.Start}");
break;
}

Func<object>? whereFn = null;

foreach (var def in defs)
{
var idObj = GetId(def);
Expand All @@ -869,11 +901,10 @@ int ConvertToInt(object id)
Dsl["collection"] = null;
Dsl["value"] = idVal;
Dsl["def"] = def;

Func<object> whereFn;

try
{
whereFn = Dsl.Parse(whereStr).Compile(true);
whereFn ??= Dsl.Parse(whereStr).Compile(true);
}
catch
{
Expand All @@ -896,8 +927,18 @@ int ConvertToInt(object id)
if (!pass)
continue;

ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
ConcurrentDictionary<object, Func<object>> compileCache = new();

try {
ProcessObjectUpdate(type, def, item,
(key, expr) => compileCache.GetOrAdd((key,expr), _ => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
ModLoader.ModManager.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
Console.Error.WriteLine($"Failed to parse {type.Name} @ {item.Start}");
break;
}

Console.WriteLine($"Updated {type.Name} {idVal}");
}
Expand Down Expand Up @@ -1193,6 +1234,8 @@ int ConvertToInt(object id)

var def = PrepopulateTyped(Activator.CreateInstance<T>());

if (def is null) throw new NotImplementedException();

if (idLookupReq.Value is YamlScalarNode idLookupVarNode)
{
var idLookupVar = idLookupVarNode.Value;
Expand All @@ -1206,10 +1249,12 @@ int ConvertToInt(object id)
Dsl["collection"] = null;
Dsl["def"] = def;

ConcurrentDictionary<object, Func<object>> compileCache = new();

try
{
ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
(key, expr) => compileCache.GetOrAdd((key,expr), k => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
Expand Down Expand Up @@ -1298,8 +1343,18 @@ int ConvertToInt(object id)
Dsl["collection"] = null;
Dsl["def"] = def;

ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
ConcurrentDictionary<object, Func<object>> compileCache = new();

try {
ProcessObjectUpdate(type, def, item,
(key, expr) => compileCache.GetOrAdd((key,expr), _ => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
ModLoader.ModManager.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
Console.Error.WriteLine($"Failed to parse {type.Name} @ {item.Start}");
break;
}

Console.WriteLine($"Updated {type.Name} {id}");

Expand All @@ -1326,18 +1381,28 @@ int ConvertToInt(object id)
Console.Error.WriteLine($"Can't parse update-all where clause @ {whereNode.Start}");
break;
}

if (!defs.Any()) {
Console.Error.WriteLine($"There don't appear to be any {type.Name} @ {whereNode.Start}");
break;
}

Func<object>? whereFn = null;

foreach (var def in defs)
{
var idObj = GetId(def);

var idVal = ((IConvertible)idObj).ToDouble(NumberFormatInfo.InvariantInfo);

Dsl["item"] = null;
Dsl["value"] = null;
Dsl["collection"] = null;
Dsl["value"] = idVal;
Dsl["def"] = def;

Func<object> whereFn;

try
{
whereFn = Dsl.Parse(whereStr).Compile(true);
whereFn ??= Dsl.Parse(whereStr).Compile(true);
}
catch
{
Expand All @@ -1357,15 +1422,21 @@ int ConvertToInt(object id)
break;
}

var idObj = GetId(def);

var idVal = ((IConvertible)idObj).ToDouble(NumberFormatInfo.InvariantInfo);

if (!pass)
continue;

ProcessObjectUpdate(type, def, item,
(_, expr) => Dsl.Parse(expr).Compile(true));
ConcurrentDictionary<object, Func<object>> compileCache = new();

try {
ProcessObjectUpdate(type, def, item,
(key, expr) => compileCache.GetOrAdd((key,expr), _ => Dsl.Parse(expr).Compile(true)));
}
catch (Exception ex)
{
ModLoader.ModManager.OnUnhandledException(ExceptionDispatchInfo.Capture(ex));
Console.Error.WriteLine($"Failed to parse {type.Name} @ {item.Start}");
break;
}

Console.WriteLine($"Updated {type.Name} {idVal}");
}
Expand Down Expand Up @@ -1695,7 +1766,6 @@ private static void ParseCollectionUpdate(Type collectionType, ref IList collect

if (keyStr[0] == '(' && keyStr[keyStr.Length - 1] == ')')
{
// no state, always cache
try
{
for (var i = 0; i < collection.Count; i++)
Expand All @@ -1707,7 +1777,7 @@ private static void ParseCollectionUpdate(Type collectionType, ref IList collect
object result;
try
{
result = compileFn("", keyStr.Substring(1, keyStr.Length - 2))();
result = compileFn(collection, keyStr.Substring(1, keyStr.Length - 2))();
}
catch
{
Expand Down Expand Up @@ -1762,7 +1832,7 @@ or TypeCode.Decimal
IConvertible newValue = valStr;
try {
Dsl["value"] = initValue;
var fn = compileFn("", valStr);
var fn = compileFn(collection, valStr);
newValue = (IConvertible)fn();
}
catch (Exception ex) {
Expand Down
13 changes: 6 additions & 7 deletions DistantWorlds2.ModLoader.Core/MmVariableDslBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ public object? this[string symbol]
private static ConcurrentDictionary<string, object> StaticVariableSource
=> ModLoader.ModManager.SharedVariables;


public override Expression? ResolveGlobalSymbol(string symbol)
public override object? ResolveGlobalSymbol(string symbol)
{
var expr = base.ResolveGlobalSymbol(symbol);
return expr ?? (
StaticVariableSource.TryGetValue(symbol, out var obj)
? Expression.Constant(obj, obj.GetType())
: expr
var obj = base.ResolveGlobalSymbol(symbol);
return obj ?? (
StaticVariableSource.TryGetValue(symbol, out obj)
? obj
: null
);
}
}
Loading