From 2c0ef03b2665c0623d7c64f18449b2770c1cdfad Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Tue, 29 Dec 2015 00:17:01 +0000 Subject: [PATCH] Cache metamethods in each LuaRuntime. This reflection is expensive, so by allowing it to be cached against each runtime we can remove most of the cost. Since each runtime is likely to only deal with a handful of custom objects, it shouldn't be an issue for memory usage. --- Eluant/LuaClrObjectValue.cs | 2 +- Eluant/LuaCustomClrObject.cs | 4 ++-- Eluant/LuaOpaqueClrObject.cs | 4 ++-- Eluant/LuaRuntime.cs | 16 +++++++++++++++- Eluant/LuaTransparentClrObject.cs | 4 ++-- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Eluant/LuaClrObjectValue.cs b/Eluant/LuaClrObjectValue.cs index 1498468..be45862 100644 --- a/Eluant/LuaClrObjectValue.cs +++ b/Eluant/LuaClrObjectValue.cs @@ -58,7 +58,7 @@ public override string ToString() internal abstract object BackingCustomObject { get; } - internal abstract MetamethodAttribute[] BackingCustomObjectMetamethods { get; } + internal abstract MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime); static internal MetamethodAttribute[] Metamethods(Type backingCustomObjectType) { diff --git a/Eluant/LuaCustomClrObject.cs b/Eluant/LuaCustomClrObject.cs index 18dda5b..946cffc 100644 --- a/Eluant/LuaCustomClrObject.cs +++ b/Eluant/LuaCustomClrObject.cs @@ -57,9 +57,9 @@ internal override object BackingCustomObject private MetamethodAttribute[] metamethods; - internal override MetamethodAttribute[] BackingCustomObjectMetamethods + internal override MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime) { - get { return metamethods ?? (metamethods = Metamethods(BackingCustomObject.GetType())); } + return metamethods ?? (metamethods = runtime.CachedMetamethods(BackingCustomObject.GetType())); } } } diff --git a/Eluant/LuaOpaqueClrObject.cs b/Eluant/LuaOpaqueClrObject.cs index 1531f16..b6ebd45 100644 --- a/Eluant/LuaOpaqueClrObject.cs +++ b/Eluant/LuaOpaqueClrObject.cs @@ -55,9 +55,9 @@ internal override object BackingCustomObject get { return null; } } - internal override MetamethodAttribute[] BackingCustomObjectMetamethods + internal override MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime) { - get { return null; } + return null; } } } diff --git a/Eluant/LuaRuntime.cs b/Eluant/LuaRuntime.cs index adeda17..e885e7d 100644 --- a/Eluant/LuaRuntime.cs +++ b/Eluant/LuaRuntime.cs @@ -78,6 +78,7 @@ protected GCHandle SelfHandle private const string OPAQUECLROBJECT_METATABLE = "eluant_opaqueclrobject"; private Dictionary metamethodCallbacks = new Dictionary(); + private Dictionary metamethodAttributes = new Dictionary(); private LuaFunction createManagedCallWrapper; @@ -778,7 +779,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. - foreach (var metamethod in obj.BackingCustomObjectMetamethods) { + foreach (var metamethod in obj.BackingCustomObjectMetamethods(this)) { LuaApi.lua_pushstring(LuaState, metamethod.MethodName); Push(metamethodCallbacks[metamethod.MethodName]); LuaApi.lua_settable(LuaState, -3); @@ -791,6 +792,19 @@ internal void PushCustomClrObject(LuaClrObjectValue obj) } } + internal MetamethodAttribute[] CachedMetamethods(Type backingCustomObjectType) + { + MetamethodAttribute[] metamethods; + if (metamethodAttributes.TryGetValue(backingCustomObjectType, out metamethods)) { + return metamethods; + } + + metamethods = LuaClrObjectValue.Metamethods(backingCustomObjectType); + metamethodAttributes.Add(backingCustomObjectType, metamethods); + + return metamethods; + } + private int NewindexCallback(IntPtr state) { return LuaToClrBoundary(state, toDispose => { diff --git a/Eluant/LuaTransparentClrObject.cs b/Eluant/LuaTransparentClrObject.cs index 42b6daa..936136e 100644 --- a/Eluant/LuaTransparentClrObject.cs +++ b/Eluant/LuaTransparentClrObject.cs @@ -73,9 +73,9 @@ internal override object BackingCustomObject get { return proxy; } } - internal override MetamethodAttribute[] BackingCustomObjectMetamethods + internal override MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime) { - get { return TransparentClrObjectProxy.Metamethods; } + return TransparentClrObjectProxy.Metamethods; } private class TransparentClrObjectProxy : ILuaTableBinding, ILuaEqualityBinding