Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System; using System.Collections.Generic; using System.ComponentModel;
- using System.Windows.Forms; using System.Windows.Forms.Design; using System.Drawing.Design;
- using System.Reflection; namespace Fire {
- //TODO: Threading
- //##################################################################################################
- public abstract class PropsAttrBase: Attribute {
- string names; public string Names { get { return names; } set { names = value; } }
- public PropsAttrBase(string names) {
- this.names = names; }}
- //##################################################################################################
- [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct, AllowMultiple=false, Inherited=true)]
- public class PropsAttribute: PropsAttrBase {
- public PropsAttribute(string names): base(names) {}
- //##################################################################################################
- public static void ClearPropDescs() { init(propDescs); }
- public static PropertyDescriptorCollection GetProps(Type type) {
- return new PropertyDescriptorCollection(GetDescs(type)); }
- private static readonly PropertyDescriptor[] emptyPropDescs = TYPE<PropertyDescriptor>.EmptyArray;
- private static readonly Dictionary<Type, PropertyDescriptor[]> propDescs = create();
- private static Dictionary<Type, PropertyDescriptor[]> create() {
- return init(new Dictionary<Type, PropertyDescriptor[]>()); }
- private static Dictionary<Type, PropertyDescriptor[]> init(Dictionary<Type, PropertyDescriptor[]> it) {
- it.Clear(); it[typeof(string)] = emptyPropDescs; return it; }
- private static string[] stdnlist = new string[] { "..", "." };
- public static PropertyDescriptor[] GetDescs(Type type) {
- if(type == null || type.IsPrimitive) return emptyPropDescs;
- PropertyDescriptor[] props;
- if(!propDescs.TryGetValue(type, out props)) {
- string names = null;
- PropsAttrBase attr = type.GetAttribute<PropsAttribute>(false);
- if(attr == null) attr = type.GetAttribute<PropsAttrBase>(false);
- if(attr != null) names = attr.Names;
- if(names != null && names.Length == 0) {
- props = emptyPropDescs;
- propDescs[type] = props;
- return props; }
- string[] nlist = names != null ? names.SplitList() : stdnlist;
- List<PropertyDescriptor> list = new List<PropertyDescriptor>(nlist.Length);
- Dictionary<string, int> dict = new Dictionary<string, int>();
- PropertyDescriptor pd;
- foreach(string name in nlist) {
- if(name == "..") {
- // base properties
- foreach(PropertyDescriptor desc in GetDescs(type.BaseType))
- if(!dict.ContainsKey(desc.Name)) { dict.Add(desc.Name, list.Count); list.Add(desc); }
- } else if(name == "." || name == "...") {
- // new properties
- foreach(PropertyInfo pi in type.GetProperties(BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.Instance)) {
- if(!pi.CanRead) continue;
- BrowsableAttribute ba = pi.GetAttribute<BrowsableAttribute>();
- if(ba != null && ba.Browsable == false) continue;
- try { pd = TypeDescriptor.CreateProperty(type, pi.Name, pi.PropertyType);
- } catch { pd = new NonexistentProperty(type, pi.Name); }
- if(dict.ContainsKey(pd.Name)) list[dict[pd.Name]] = pd;
- else { dict.Add(pd.Name, list.Count); list.Add(pd); }}
- } else {
- // selected property
- string pname = name;
- bool remove = name[0] == '-';
- if(remove) pname = name.Substring(1);
- try {
- PropertyInfo pi = type.GetProperty(pname, BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.FlattenHierarchy);
- if(pi == null) pi = type.GetProperty(pname, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.FlattenHierarchy);
- pd = TypeDescriptor.CreateProperty(type, pname, pi.PropertyType);
- } catch { if(remove) continue; pd = new NonexistentProperty(type, pname); }
- pname = pd.Name;
- if(dict.ContainsKey(pname)) {
- int idx = dict[pname];
- if(!remove) list[idx] = pd;
- else {
- list.RemoveAt(idx);
- dict.Remove(pname);
- FireList<string> keys = new FireList<string>();
- foreach(string key in dict.Keys) {
- int val = dict[key];
- if(val > idx) keys.Add(key); }
- foreach(string key in keys)
- dict[key] = dict[key]-1; }
- } else if(!remove) { dict.Add(pname, list.Count); list.Add(pd); }}}
- props = list.Count > 0 ? list.ToArray() : emptyPropDescs;
- propDescs[type] = props; }
- return props; }
- //##################################################################################################
- public class NonexistentProperty: PropertyDescriptor {
- protected Type type, propType;
- public NonexistentProperty(Type type, string name, Type propType, Attribute[] attrs) : base(name, attrs) { this.type = type; this.propType = propType; }
- public NonexistentProperty(Type type, string name) : this(type, name, typeof(string), TYPE<Attribute>.EmptyArray) { }
- public override object GetValue(object component) { return Name + " does not exist"; }
- public override Type ComponentType { get { return type; } }
- public override Type PropertyType { get { return propType; } }
- public override bool CanResetValue(object component) { return false; }
- public override bool IsReadOnly { get { return true; } }
- public override bool ShouldSerializeValue(object component) { return false; }
- public override void ResetValue(object component) { }
- public override void SetValue(object component, object value) {}
- }}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement