From fb6c335f0f180239ce860ba027e94c80573c201f Mon Sep 17 00:00:00 2001 From: Cintique Date: Tue, 31 May 2022 14:54:09 +1000 Subject: [PATCH 1/4] Add `LuaUserData.CreateUserDataOfType`. Converts a Lua value to a desired CLR type and wraps it in a userdata to avoid automatic conversions. Example: a Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything. Wrapping the value in a userdata preserves the original type during conversions. --- .../LuaCs/Lua/LuaClasses/LuaUserData.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs index 184dd852b..75671711d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs @@ -223,5 +223,19 @@ namespace Barotrauma var descriptor = (StandardUserDataDescriptor)IUUD; descriptor.RemoveMember(memberName); } + + /// + /// Converts a Lua value to a desired CLR type and wraps it in a userdata to avoid automatic conversions. + /// Example: a Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets + /// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything. + /// Wrapping the value in a userdata preserves the original type during conversions. + /// + /// Lua value to conert and wrap in a userdata. + /// The CLR type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters. Lua scripts can obtain Types from descriptors. + /// A userdata that wraps the Lua value converted to an object of the desired type. + public static DynValue CreateUserDataOfType(DynValue scriptObject, Type desiredType) + { + return UserData.Create(scriptObject.ToObject(desiredType)); + } } } \ No newline at end of file From ebcbcae46d8ea322788a7e5581eb71a8d65a2183 Mon Sep 17 00:00:00 2001 From: Cintique Date: Tue, 31 May 2022 14:59:17 +1000 Subject: [PATCH 2/4] Typo --- .../SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs index 75671711d..960003023 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs @@ -230,7 +230,7 @@ namespace Barotrauma /// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything. /// Wrapping the value in a userdata preserves the original type during conversions. /// - /// Lua value to conert and wrap in a userdata. + /// Lua value to convert and wrap in a userdata. /// The CLR type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters. Lua scripts can obtain Types from descriptors. /// A userdata that wraps the Lua value converted to an object of the desired type. public static DynValue CreateUserDataOfType(DynValue scriptObject, Type desiredType) From 62c0dc058042f755f4b1ea3ea18a74d7d2860818 Mon Sep 17 00:00:00 2001 From: Cintique Date: Wed, 1 Jun 2022 19:46:40 +1000 Subject: [PATCH 3/4] Better doc --- .../SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs index 960003023..615fb6d58 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs @@ -225,7 +225,7 @@ namespace Barotrauma } /// - /// Converts a Lua value to a desired CLR type and wraps it in a userdata to avoid automatic conversions. + /// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata. /// Example: a Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets /// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything. /// Wrapping the value in a userdata preserves the original type during conversions. From c39bf9f8002964808aaf8ea2d6550d3087042d27 Mon Sep 17 00:00:00 2001 From: Cintique Date: Thu, 2 Jun 2022 21:34:34 +1000 Subject: [PATCH 4/4] Allow wrapping unregistered types. `LuaUserData.CreateUserDataFromType` will instantiate a default `StandardUserDataDescriptor` to allow wrapping unregistered types. Whoops! --- .../LuaCs/Lua/LuaClasses/LuaUserData.cs | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs index 615fb6d58..ee8071ecb 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaClasses/LuaUserData.cs @@ -225,17 +225,35 @@ namespace Barotrauma } /// - /// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata. - /// Example: a Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets - /// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything. - /// Wrapping the value in a userdata preserves the original type during conversions. + /// See . /// /// Lua value to convert and wrap in a userdata. - /// The CLR type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters. Lua scripts can obtain Types from descriptors. - /// A userdata that wraps the Lua value converted to an object of the desired type. - public static DynValue CreateUserDataOfType(DynValue scriptObject, Type desiredType) + /// Descriptor of the type of the object to convert the Lua value to. Uses MoonSharp ScriptToClr converters. + /// A userdata that wraps the Lua value converted to an object of the desired type as described by . + public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor) { - return UserData.Create(scriptObject.ToObject(desiredType)); + return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor); + } + + /// + /// Converts a Lua value to a CLR object of a desired type and wraps it in a userdata. + /// If the type is not registered, then a new will be created and used. + /// The goal of this method is to allow Lua scripts to create userdata to wrap certain data without having to register types. + /// Wrapping the value in a userdata preserves the original type during script-to-CLR conversions. + /// A Lua script needs to pass a List`1 to a CLR method expecting System.Object, MoonSharp gets + /// in the way by converting the List`1 to a MoonSharp.Interpreter.Table and breaking everything. + /// Registering the List`1 type can break other scripts relying on default converters, so instead + /// it is better to manually wrap the List`1 object into a userdata. + /// + /// + /// Lua value to convert and wrap in a userdata. + /// Type describing the CLR type of the object to convert the Lua value to. + /// A userdata that wraps the Lua value converted to an object of the desired type. + public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType) + { + IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true); + descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default); + return CreateUserDataFromDescriptor(scriptObject, descriptor); } } } \ No newline at end of file