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