HandlerTypeInfo GetTypeHandlerInfo (object cmdTarget)
{
HandlerTypeInfo typeInfo = (HandlerTypeInfo) handlerInfo [cmdTarget.GetType ()];
if (typeInfo != null) return typeInfo;
Type type = cmdTarget.GetType ();
typeInfo = new HandlerTypeInfo ();
List<CommandHandlerInfo> handlers = new List<CommandHandlerInfo> ();
List<CommandUpdaterInfo> updaters = new List<CommandUpdaterInfo> ();
Type curType = type;
while (curType != null && curType.Assembly != typeof(Gtk.Widget).Assembly && curType.Assembly != typeof(object).Assembly) {
MethodInfo[] methods = curType.GetMethods (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
foreach (MethodInfo method in methods) {
ICommandUpdateHandler customHandlerChain = null;
ICommandArrayUpdateHandler customArrayHandlerChain = null;
ICommandTargetHandler customTargetHandlerChain = null;
ICommandArrayTargetHandler customArrayTargetHandlerChain = null;
List<CommandHandlerInfo> methodHandlers = new List<CommandHandlerInfo> ();
foreach (object attr in method.GetCustomAttributes (true)) {
if (attr is CommandHandlerAttribute)
methodHandlers.Add (new CommandHandlerInfo (method, (CommandHandlerAttribute) attr));
else if (attr is CommandUpdateHandlerAttribute)
AddUpdater (updaters, method, (CommandUpdateHandlerAttribute) attr);
else {
customHandlerChain = ChainHandler (customHandlerChain, attr);
customArrayHandlerChain = ChainHandler (customArrayHandlerChain, attr);
customTargetHandlerChain = ChainHandler (customTargetHandlerChain, attr);
customArrayTargetHandlerChain = ChainHandler (customArrayTargetHandlerChain, attr);
}
}
foreach (object attr in type.GetCustomAttributes (true)) {
customHandlerChain = ChainHandler (customHandlerChain, attr);
customArrayHandlerChain = ChainHandler (customArrayHandlerChain, attr);
customTargetHandlerChain = ChainHandler (customTargetHandlerChain, attr);
customArrayTargetHandlerChain = ChainHandler (customArrayTargetHandlerChain, attr);
}
if (methodHandlers.Count > 0) {
if (customHandlerChain != null || customArrayHandlerChain != null) {
// There are custom handlers. Create update handlers for all commands
// that the method handles so the custom update handlers can be chained
foreach (CommandHandlerInfo ci in methodHandlers) {
CommandUpdaterInfo c = AddUpdateHandler (updaters, ci.CommandId);
c.AddCustomHandlers (customHandlerChain, customArrayHandlerChain);
}
}
if (customTargetHandlerChain != null || customArrayTargetHandlerChain != null) {
foreach (CommandHandlerInfo ci in methodHandlers)
ci.AddCustomHandlers (customTargetHandlerChain, customArrayTargetHandlerChain);
}
}
handlers.AddRange (methodHandlers);
}
curType = curType.BaseType;
}
if (handlers.Count > 0)
typeInfo.CommandHandlers = handlers.ToArray ();
if (updaters.Count > 0)
typeInfo.CommandUpdaters = updaters.ToArray ();
handlerInfo [type] = typeInfo;
return typeInfo;
}