2007-06-26 06:01:52 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* /
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Drawing ;
using System.Text ;
using System.Reflection ;
#endregion
namespace CodeImp.DoomBuilder.Controls
{
2008-01-05 18:11:29 +00:00
/// <summary>
/// This binds a method to an action.
/// </summary>
2007-06-26 06:01:52 +00:00
[AttributeUsage(AttributeTargets.Method, Inherited=true, AllowMultiple=true)]
2007-10-24 17:25:03 +00:00
public class ActionAttribute : Attribute
2007-06-26 06:01:52 +00:00
{
#region = = = = = = = = = = = = = = = = = = Variables
// The action to bind to
private string action ;
2008-01-02 21:49:43 +00:00
private bool baseaction ;
2007-06-26 06:01:52 +00:00
#endregion
2008-01-02 21:49:43 +00:00
#region = = = = = = = = = = = = = = = = = = Properties
2008-01-05 18:11:29 +00:00
/// <summary>
/// Set to true to indicate this is a core Doom Builder action when used within a plugin.
/// </summary>
2008-01-02 21:49:43 +00:00
public bool BaseAction { get { return baseaction ; } set { baseaction = value ; } }
#endregion
2007-06-26 06:01:52 +00:00
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
2008-01-05 18:11:29 +00:00
/// <summary>
/// This binds a method to an action.
/// </summary>
/// <param name="action">The action name as defined in Actions.cfg resource.</param>
2007-06-26 06:01:52 +00:00
public ActionAttribute ( string action )
{
// Initialize
this . action = action ;
2008-01-02 21:49:43 +00:00
this . baseaction = false ;
2007-06-26 06:01:52 +00:00
}
#endregion
2008-01-02 21:49:43 +00:00
#region = = = = = = = = = = = = = = = = = = Methods
// This makes the proper name
public string GetFullActionName ( Assembly asm )
{
string asmname ;
if ( baseaction )
asmname = General . ThisAssembly . GetName ( ) . Name . ToLowerInvariant ( ) ;
else
asmname = asm . GetName ( ) . Name . ToLowerInvariant ( ) ;
return asmname + "_" + action ;
}
#endregion
2007-06-26 06:01:52 +00:00
#region = = = = = = = = = = = = = = = = = = Static Methods
2008-01-02 21:49:43 +00:00
// This makes the proper name
public string GetFullActionName ( Assembly asm , bool baseaction , string actionname )
{
string asmname ;
if ( baseaction )
asmname = General . ThisAssembly . GetName ( ) . Name . ToLowerInvariant ( ) ;
else
asmname = asm . GetName ( ) . Name . ToLowerInvariant ( ) ;
return asmname + "_" + actionname ;
}
2007-06-26 06:01:52 +00:00
// This binds all methods marked with this attribute
2008-01-02 21:49:43 +00:00
internal static void BindMethods ( Type type )
2007-06-26 06:01:52 +00:00
{
// Bind static methods
BindMethods ( null , type ) ;
}
// This binds all methods marked with this attribute
2008-01-02 21:49:43 +00:00
internal static void BindMethods ( object obj )
2007-06-26 06:01:52 +00:00
{
// Bind instance methods
BindMethods ( obj , obj . GetType ( ) ) ;
}
// This binds all methods marked with this attribute
private static void BindMethods ( object obj , Type type )
{
MethodInfo [ ] methods ;
ActionAttribute [ ] attrs ;
ActionDelegate del ;
2008-01-02 21:49:43 +00:00
string actionname ;
2007-10-04 18:16:05 +00:00
if ( obj = = null )
General . WriteLogLine ( "Binding static action methods for class " + type . Name + "..." ) ;
else
General . WriteLogLine ( "Binding action methods for " + type . Name + " object..." ) ;
2007-06-26 06:01:52 +00:00
// Go for all methods on obj
2008-01-02 21:49:43 +00:00
methods = type . GetMethods ( BindingFlags . Instance | BindingFlags . NonPublic | BindingFlags . Public | BindingFlags . Static ) ;
2007-06-26 06:01:52 +00:00
foreach ( MethodInfo m in methods )
{
// Check if the method has this attribute
attrs = ( ActionAttribute [ ] ) m . GetCustomAttributes ( typeof ( ActionAttribute ) , true ) ;
// Go for all attributes
foreach ( ActionAttribute a in attrs )
{
// Create a delegate for this method
del = ( ActionDelegate ) Delegate . CreateDelegate ( typeof ( ActionDelegate ) , obj , m ) ;
2008-01-02 21:49:43 +00:00
// Make proper name
actionname = a . GetFullActionName ( type . Assembly ) ;
2007-06-26 06:01:52 +00:00
// Bind method to action
2008-01-02 21:49:43 +00:00
if ( General . Actions . Exists ( actionname ) )
General . Actions [ actionname ] . Bind ( del ) ;
2007-11-10 19:24:52 +00:00
else
2008-01-02 21:49:43 +00:00
throw new ArgumentException ( "Could not bind " + m . ReflectedType . Name + "." + m . Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions." ) ;
2007-06-26 06:01:52 +00:00
}
}
}
2008-01-02 21:49:43 +00:00
// This binds a delegate manually
internal static void BindDelegate ( Assembly asm , ActionDelegate d , ActionAttribute a )
{
string actionname ;
// Make proper name
actionname = a . GetFullActionName ( asm ) ;
// Bind delegate to action
if ( General . Actions . Exists ( actionname ) )
General . Actions [ actionname ] . Bind ( d ) ;
else
2008-01-06 20:56:48 +00:00
General . WriteLogLine ( "WARNING: Could not bind delegate for " + d . Method . Name + " to action \"" + a . action + "\" (" + actionname + "), that action does not exist! Refer to, or edit Actions.cfg for all available application actions." ) ;
2008-01-02 21:49:43 +00:00
}
2007-06-26 06:01:52 +00:00
// This unbinds all methods marked with this attribute
2008-01-02 21:49:43 +00:00
internal static void UnbindMethods ( Type type )
2007-06-26 06:01:52 +00:00
{
// Unbind static methods
UnbindMethods ( null , type ) ;
}
// This unbinds all methods marked with this attribute
2008-01-02 21:49:43 +00:00
internal static void UnbindMethods ( object obj )
2007-06-26 06:01:52 +00:00
{
// Unbind instance methods
UnbindMethods ( obj , obj . GetType ( ) ) ;
}
// This unbinds all methods marked with this attribute
private static void UnbindMethods ( object obj , Type type )
{
MethodInfo [ ] methods ;
ActionAttribute [ ] attrs ;
ActionDelegate del ;
2008-01-02 21:49:43 +00:00
string actionname ;
2007-06-26 06:01:52 +00:00
2007-10-04 18:16:05 +00:00
if ( obj = = null )
General . WriteLogLine ( "Unbinding static action methods for class " + type . Name + "..." ) ;
else
General . WriteLogLine ( "Unbinding action methods for " + type . Name + " object..." ) ;
2007-06-26 06:01:52 +00:00
// Go for all methods on obj
methods = type . GetMethods ( ) ;
foreach ( MethodInfo m in methods )
{
// Check if the method has this attribute
attrs = ( ActionAttribute [ ] ) m . GetCustomAttributes ( typeof ( ActionAttribute ) , true ) ;
// Go for all attributes
foreach ( ActionAttribute a in attrs )
{
// Create a delegate for this method
del = ( ActionDelegate ) Delegate . CreateDelegate ( typeof ( ActionDelegate ) , obj , m ) ;
2008-01-02 21:49:43 +00:00
// Make proper name
actionname = a . GetFullActionName ( type . Assembly ) ;
2007-06-26 06:01:52 +00:00
// Unbind method from action
2008-01-02 21:49:43 +00:00
General . Actions [ actionname ] . Unbind ( del ) ;
2007-06-26 06:01:52 +00:00
}
}
}
2008-01-02 21:49:43 +00:00
// This unbinds a delegate manually
internal static void UnbindDelegate ( Assembly asm , ActionDelegate d , ActionAttribute a )
{
string actionname ;
// Make proper name
actionname = a . GetFullActionName ( asm ) ;
// Unbind delegate to action
General . Actions [ actionname ] . Unbind ( d ) ;
}
2007-06-26 06:01:52 +00:00
#endregion
}
}