From 79d25286bdf49d7e5fb0880532db743d3bb4109d Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Fri, 6 Nov 2015 00:38:08 +0000 Subject: [PATCH 1/2] Cache MetamethodAttributes used in LuaClrObjectValue. This allows us to speed up LuaRuntime.PushCustomClrObject when pushing an object multiple times since we can do this costly reflection on construction on the object and retain it thereafter. Calling code that uses LuaTransparentClrObject benefits since we can cache this information for the proxy type. It can also benefit calling code that is able to reuse a LuaCustomClrObject instance across multiple Lua calls. --- Eluant/LuaClrObjectValue.cs | 15 ++++++++++++++- Eluant/LuaCustomClrObject.cs | 12 +++++++++++- Eluant/LuaOpaqueClrObject.cs | 10 +++++++++- Eluant/LuaRuntime.cs | 9 ++++----- Eluant/LuaTransparentClrObject.cs | 11 ++++++++++- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/Eluant/LuaClrObjectValue.cs b/Eluant/LuaClrObjectValue.cs index d8e4995..1498468 100644 --- a/Eluant/LuaClrObjectValue.cs +++ b/Eluant/LuaClrObjectValue.cs @@ -1,10 +1,12 @@ // // LuaClrObjectValue.cs // -// Author: +// Authors: // Chris Howie +// Tom Roostan // // Copyright (c) 2013 Chris Howie +// Copyright (c) 2015 Tom Roostan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,6 +27,8 @@ // THE SOFTWARE. using System; +using System.Linq; +using Eluant.ObjectBinding; namespace Eluant { @@ -54,6 +58,15 @@ public override string ToString() internal abstract object BackingCustomObject { get; } + internal abstract MetamethodAttribute[] BackingCustomObjectMetamethods { get; } + + static internal MetamethodAttribute[] Metamethods(Type backingCustomObjectType) + { + return backingCustomObjectType.GetInterfaces() + .SelectMany(iface => iface.GetCustomAttributes(typeof(MetamethodAttribute), false).Cast()) + .ToArray(); + } + internal override object ToClrType(Type type) { if (type == null) { throw new ArgumentNullException("type"); } diff --git a/Eluant/LuaCustomClrObject.cs b/Eluant/LuaCustomClrObject.cs index 76d0cb0..18dda5b 100644 --- a/Eluant/LuaCustomClrObject.cs +++ b/Eluant/LuaCustomClrObject.cs @@ -1,10 +1,12 @@ // // LuaCustomClrObject.cs // -// Author: +// Authors: // Chris Howie +// Tom Roostan // // Copyright (c) 2013 Chris Howie +// Copyright (c) 2015 Tom Roostan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,6 +27,7 @@ // THE SOFTWARE. using System; +using Eluant.ObjectBinding; namespace Eluant { @@ -51,6 +54,13 @@ internal override object BackingCustomObject { get { return ClrObject; } } + + private MetamethodAttribute[] metamethods; + + internal override MetamethodAttribute[] BackingCustomObjectMetamethods + { + get { return metamethods ?? (metamethods = Metamethods(BackingCustomObject.GetType())); } + } } } diff --git a/Eluant/LuaOpaqueClrObject.cs b/Eluant/LuaOpaqueClrObject.cs index 98ec940..1531f16 100644 --- a/Eluant/LuaOpaqueClrObject.cs +++ b/Eluant/LuaOpaqueClrObject.cs @@ -1,10 +1,12 @@ // // LuaOpaqueClrObject.cs // -// Author: +// Authors: // Chris Howie +// Tom Roostan // // Copyright (c) 2013 Chris Howie +// Copyright (c) 2015 Tom Roostan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,6 +27,7 @@ // THE SOFTWARE. using System; +using Eluant.ObjectBinding; namespace Eluant { @@ -51,6 +54,11 @@ internal override object BackingCustomObject { get { return null; } } + + internal override MetamethodAttribute[] BackingCustomObjectMetamethods + { + get { return null; } + } } } diff --git a/Eluant/LuaRuntime.cs b/Eluant/LuaRuntime.cs index 1b6d219..adeda17 100644 --- a/Eluant/LuaRuntime.cs +++ b/Eluant/LuaRuntime.cs @@ -1,10 +1,12 @@ // // LuaRuntime.cs // -// Author: +// Authors: // Chris Howie +// Tom Roostan // // Copyright (c) 2013 Chris Howie +// Copyright (c) 2015 Tom Roostan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -776,10 +778,7 @@ internal void PushCustomClrObject(LuaClrObjectValue obj) LuaApi.lua_settable(LuaState, -3); // For all others, we use MetamethodAttribute on the interface to make this code less repetitive. - var metamethods = obj.BackingCustomObject.GetType().GetInterfaces() - .SelectMany(iface => iface.GetCustomAttributes(typeof(MetamethodAttribute), false).Cast()); - - foreach (var metamethod in metamethods) { + foreach (var metamethod in obj.BackingCustomObjectMetamethods) { LuaApi.lua_pushstring(LuaState, metamethod.MethodName); Push(metamethodCallbacks[metamethod.MethodName]); LuaApi.lua_settable(LuaState, -3); diff --git a/Eluant/LuaTransparentClrObject.cs b/Eluant/LuaTransparentClrObject.cs index 592884b..42b6daa 100644 --- a/Eluant/LuaTransparentClrObject.cs +++ b/Eluant/LuaTransparentClrObject.cs @@ -1,10 +1,12 @@ // // LuaTransparentClrObject.cs // -// Author: +// Authors: // Chris Howie +// Tom Roostan // // Copyright (c) 2013 Chris Howie +// Copyright (c) 2015 Tom Roostan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -71,8 +73,15 @@ internal override object BackingCustomObject get { return proxy; } } + internal override MetamethodAttribute[] BackingCustomObjectMetamethods + { + get { return TransparentClrObjectProxy.Metamethods; } + } + private class TransparentClrObjectProxy : ILuaTableBinding, ILuaEqualityBinding { + public static readonly MetamethodAttribute[] Metamethods = LuaClrObjectValue.Metamethods(typeof(TransparentClrObjectProxy)); + private LuaTransparentClrObject clrObject; public TransparentClrObjectProxy(LuaTransparentClrObject obj) From 46d53a85ad5fcbcd052329f6bbddc367b34145e6 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Fri, 6 Nov 2015 21:49:25 +0000 Subject: [PATCH 2/2] Add a missing GC.SuppressFinalize call in LuaReference. This missing call meant even if the caller took care to dispose a LuaReference it was still being finalized. Adding this call prevents this needless finalization from taking place. --- Eluant/LuaReference.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Eluant/LuaReference.cs b/Eluant/LuaReference.cs index b5088c6..1a16d50 100644 --- a/Eluant/LuaReference.cs +++ b/Eluant/LuaReference.cs @@ -1,10 +1,12 @@ // // LuaReference.cs // -// Author: +// Authors: // Chris Howie +// Tom Roostan // // Copyright (c) 2013 Chris Howie +// Copyright (c) 2015 Tom Roostan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -50,6 +52,7 @@ internal LuaReference(LuaRuntime runtime, int reference) public sealed override void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing)