Last active
August 29, 2015 14:05
-
-
Save 31/9d1225e1c7433747f5e9 to your computer and use it in GitHub Desktop.
Unity: Static-checked message broadcasting component extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
using UnityEngine; | |
public static class ComponentExtensions | |
{ | |
public static void BroadcastTypedMessage<T>( | |
this Component c, | |
Expression<Func<T, Action>> method, | |
SendMessageOptions options = SendMessageOptions.DontRequireReceiver) | |
{ | |
string msgName = MethodCallName(method.Body); | |
//Debug.Log(string.Format("Broadcasting to {0}: method {1}, no param", c, msgName)); | |
c.BroadcastMessage(msgName, options); | |
} | |
public static void BroadcastTypedMessage<T, TParam>( | |
this Component c, | |
Expression<Func<T, Action<TParam>>> method, | |
TParam parameter, | |
SendMessageOptions options = SendMessageOptions.DontRequireReceiver) | |
{ | |
string msgName = MethodCallName(method.Body); | |
//Debug.Log(string.Format("Broadcasting to {0}: method {1}, param {2}", c, msgName, parameter)); | |
c.BroadcastMessage(msgName, parameter, options); | |
} | |
private static string MethodCallName(Expression e) | |
{ | |
var unary = (UnaryExpression)e; | |
var operand = (MethodCallExpression)unary.Operand; | |
var constant = (ConstantExpression)operand.Arguments[2]; | |
var methodInfo = (MethodInfo)constant.Value; | |
return methodInfo.Name; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
public class SampleComponent : MonoBehaviour | |
{ | |
public void FooNoParams() | |
{ | |
// Do something. | |
} | |
public void FooParam(bool bar) | |
{ | |
// Do something. | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Somewhere in a component, where this game object and all child game objects should have a message passed: | |
this.BroadcastTypedMessage( | |
(SampleComponent c) => c.FooNoParams); | |
this.BroadcastTypedMessage( | |
(SampleComponent c) => c.FooParam, | |
true); | |
// The compiler can figure out the generic types necessary and extracts the message's name from the given MethodInfo. | |
// The generic types are strict enough that you can't even pass in the wrong type of parameter! This is a whole lot safer for refactoring. | |
// Because this is static typed, intellisense also works perfectly. | |
// I'm not sure if all expression trees given will be the same. It might need to be generalized for more exotic usage. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment