Skip to content

Commit fef102f

Browse files
authored
Merge pull request #91 from tgiachi/develop
feat(scripting-lua): marshal dictionary and list returns to Lua tables
2 parents eb4c0dd + fa50894 commit fef102f

2 files changed

Lines changed: 80 additions & 1 deletion

File tree

src/SquidStd.Scripting.Lua/Services/LuaScriptEngineService.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections;
12
using System.Collections.Concurrent;
23
using System.Diagnostics;
34
using System.Diagnostics.CodeAnalysis;
@@ -697,7 +698,50 @@ private void AttachLuaEventBridge()
697698
};
698699

699700
private DynValue ConvertToLua(object? value)
700-
=> value == null ? DynValue.Nil : DynValue.FromObject(LuaScript, value);
701+
{
702+
switch (value)
703+
{
704+
case null:
705+
return DynValue.Nil;
706+
707+
case DynValue dynValue:
708+
return dynValue;
709+
710+
case string:
711+
return DynValue.FromObject(LuaScript, value);
712+
713+
case IDictionary dictionary:
714+
{
715+
var table = new Table(LuaScript);
716+
717+
foreach (DictionaryEntry entry in dictionary)
718+
{
719+
table[ConvertKey(entry.Key)] = ConvertToLua(entry.Value);
720+
}
721+
722+
return DynValue.NewTable(table);
723+
}
724+
725+
case IEnumerable enumerable:
726+
{
727+
var table = new Table(LuaScript);
728+
var index = 1;
729+
730+
foreach (var item in enumerable)
731+
{
732+
table[index++] = ConvertToLua(item);
733+
}
734+
735+
return DynValue.NewTable(table);
736+
}
737+
738+
default:
739+
return DynValue.FromObject(LuaScript, value);
740+
}
741+
}
742+
743+
private static object ConvertKey(object key)
744+
=> key is string text ? text : Convert.ToString(key, CultureInfo.InvariantCulture) ?? string.Empty;
701745

702746
/// <summary>
703747
/// Creates a Lua callback that invokes the constructor matching the number of arguments passed from Lua.

tests/SquidStd.Tests/Scripting/Lua/LuaScriptEngineServiceTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,41 @@ public void AddManualModuleFunction_RegistersActionAndTypedFunction()
5959
Assert.Equal(12d, result.Data);
6060
}
6161

62+
[Fact]
63+
public void ModuleFunctionReturningDictionary_MarshalsToLuaTable()
64+
{
65+
using var temp = new TempDirectory();
66+
using var container = new Container();
67+
using var engine = CreateEngine(temp, container);
68+
69+
engine.AddManualModuleFunction<double, Dictionary<string, object>>(
70+
"itemModule",
71+
"get",
72+
id => new() { ["id"] = id, ["name"] = "Dagger", ["amount"] = 3d }
73+
);
74+
75+
Assert.Equal(5d, engine.ExecuteFunction("item_module.get(5).id").Data);
76+
Assert.Equal("Dagger", engine.ExecuteFunction("item_module.get(5).name").Data);
77+
Assert.Equal(3d, engine.ExecuteFunction("item_module.get(5).amount").Data);
78+
}
79+
80+
[Fact]
81+
public void ModuleFunctionReturningList_MarshalsToLuaArrayTable()
82+
{
83+
using var temp = new TempDirectory();
84+
using var container = new Container();
85+
using var engine = CreateEngine(temp, container);
86+
87+
engine.AddManualModuleFunction<double, List<object>>(
88+
"itemModule",
89+
"contents",
90+
_ => [1073741824d, 1073741825d, 1073741826d]
91+
);
92+
93+
Assert.Equal(3d, engine.ExecuteFunction("#item_module.contents(1)").Data);
94+
Assert.Equal(1073741825d, engine.ExecuteFunction("item_module.contents(1)[2]").Data);
95+
}
96+
6297
[Fact]
6398
public void AddSearchDirectory_AllowsRequireFromAdditionalDirectory()
6499
{

0 commit comments

Comments
 (0)