Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache metamethods, finalize references #7

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Eluant/LuaClrObjectValue.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// LuaClrObjectValue.cs
//
// Author:
// Authors:
// Chris Howie <[email protected]>
// Tom Roostan <[email protected]>
//
// 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
Expand All @@ -25,6 +27,8 @@
// THE SOFTWARE.

using System;
using System.Linq;
using Eluant.ObjectBinding;

namespace Eluant
{
Expand Down Expand Up @@ -54,6 +58,15 @@ public override string ToString()

internal abstract object BackingCustomObject { get; }

internal abstract MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime);

static internal MetamethodAttribute[] Metamethods(Type backingCustomObjectType)
{
return backingCustomObjectType.GetInterfaces()
.SelectMany(iface => iface.GetCustomAttributes(typeof(MetamethodAttribute), false).Cast<MetamethodAttribute>())
.ToArray();
}

internal override object ToClrType(Type type)
{
if (type == null) { throw new ArgumentNullException("type"); }
Expand Down
12 changes: 11 additions & 1 deletion Eluant/LuaCustomClrObject.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// LuaCustomClrObject.cs
//
// Author:
// Authors:
// Chris Howie <[email protected]>
// Tom Roostan <[email protected]>
//
// 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
Expand All @@ -25,6 +27,7 @@
// THE SOFTWARE.

using System;
using Eluant.ObjectBinding;

namespace Eluant
{
Expand All @@ -51,6 +54,13 @@ internal override object BackingCustomObject
{
get { return ClrObject; }
}

private MetamethodAttribute[] metamethods;

internal override MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime)
{
return metamethods ?? (metamethods = runtime.CachedMetamethods(BackingCustomObject.GetType()));
}
}
}

10 changes: 9 additions & 1 deletion Eluant/LuaOpaqueClrObject.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// LuaOpaqueClrObject.cs
//
// Author:
// Authors:
// Chris Howie <[email protected]>
// Tom Roostan <[email protected]>
//
// 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
Expand All @@ -25,6 +27,7 @@
// THE SOFTWARE.

using System;
using Eluant.ObjectBinding;

namespace Eluant
{
Expand All @@ -51,6 +54,11 @@ internal override object BackingCustomObject
{
get { return null; }
}

internal override MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime)
{
return null;
}
}
}

5 changes: 4 additions & 1 deletion Eluant/LuaReference.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// LuaReference.cs
//
// Author:
// Authors:
// Chris Howie <[email protected]>
// Tom Roostan <[email protected]>
//
// 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
Expand Down Expand Up @@ -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)
Expand Down
23 changes: 18 additions & 5 deletions Eluant/LuaRuntime.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// LuaRuntime.cs
//
// Author:
// Authors:
// Chris Howie <[email protected]>
// Tom Roostan <[email protected]>
//
// 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
Expand Down Expand Up @@ -76,6 +78,7 @@ protected GCHandle SelfHandle
private const string OPAQUECLROBJECT_METATABLE = "eluant_opaqueclrobject";

private Dictionary<string, LuaFunction> metamethodCallbacks = new Dictionary<string, LuaFunction>();
private Dictionary<Type, MetamethodAttribute[]> metamethodAttributes = new Dictionary<Type, MetamethodAttribute[]>();

private LuaFunction createManagedCallWrapper;

Expand Down Expand Up @@ -762,10 +765,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<MetamethodAttribute>());

foreach (var metamethod in metamethods) {
foreach (var metamethod in obj.BackingCustomObjectMetamethods(this)) {
LuaApi.lua_pushstring(LuaState, metamethod.MethodName);
Push(metamethodCallbacks[metamethod.MethodName]);
LuaApi.lua_settable(LuaState, -3);
Expand All @@ -778,6 +778,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 => {
Expand Down
11 changes: 10 additions & 1 deletion Eluant/LuaTransparentClrObject.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// LuaTransparentClrObject.cs
//
// Author:
// Authors:
// Chris Howie <[email protected]>
// Tom Roostan <[email protected]>
//
// 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
Expand Down Expand Up @@ -71,8 +73,15 @@ internal override object BackingCustomObject
get { return proxy; }
}

internal override MetamethodAttribute[] BackingCustomObjectMetamethods(LuaRuntime runtime)
{
return TransparentClrObjectProxy.Metamethods;
}

private class TransparentClrObjectProxy : ILuaTableBinding, ILuaEqualityBinding
{
public static readonly MetamethodAttribute[] Metamethods = LuaClrObjectValue.Metamethods(typeof(TransparentClrObjectProxy));

private LuaTransparentClrObject clrObject;

public TransparentClrObjectProxy(LuaTransparentClrObject obj)
Expand Down