乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 125|回复: 9

ResultBuffer简化类

[复制链接]

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-1-4 14:31:00 | 显示全部楼层 |阅读模式
经常要做些选择集的过滤器,然而.Net的过滤器写起来真的很繁琐
所以。。。
ResultList类,原创是TonyT,:)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Autodesk..DatabaseServices;
  5. using Autodesk.AutoCAD.Runtime;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Geometry;
  8. namespace TlsCad.Collections
  9. {
  10.     ///
  11.     /// TypedValue Collection
  12.     ///
  13.     public class ResultList : List, IFormattable
  14.     {
  15.         public ResultList(){ }
  16.         public ResultList(IEnumerable values) : base(values)
  17.         { }
  18.         public ResultList(ResultBuffer rb) : base(rb.AsArray())
  19.         { }
  20.         #region Add
  21.         public void Add(int typeCode, object obj)
  22.         {
  23.             base.Add(new TypedValue(typeCode, obj));
  24.         }
  25.         public void Add(LispDataType type, object obj)
  26.         {
  27.             base.Add(new TypedValue((int)type, obj));
  28.         }
  29.         public void Add(DxfCode type, object obj)
  30.         {
  31.             base.Add(new TypedValue((int)type, obj));
  32.         }
  33.         #endregion
  34.         #region Convert
  35.         public static implicit operator TypedValue[](ResultList rlst)
  36.         {
  37.             return rlst.ToArray();
  38.         }
  39.         public static implicit operator ResultBuffer(ResultList rlst)
  40.         {
  41.             return new ResultBuffer(rlst.ToArray());
  42.         }
  43.         public static implicit operator SelectionFilter(ResultList rlst)
  44.         {
  45.             return new SelectionFilter(rlst.ToArray());
  46.         }
  47.         #endregion
  48.         #region IFormattable 成员
  49.         public override string ToString()
  50.         {
  51.             var rb = new ResultBuffer(ToArray());
  52.             return rb.ToString();
  53.         }
  54.         string IFormattable.ToString(string format, IFormatProvider formatProvider)
  55.         {
  56.             var rb = new ResultBuffer(ToArray());
  57.             return rb.ToString(format, formatProvider);
  58.         }
  59.         #endregion
  60.     }
  61. }
ResultTree类,原创飞狐
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Runtime;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.Geometry;
  9. using System.Collections;
  10. namespace TlsCad.Collections
  11. {
  12.    
  13.     public enum ResultTreeType
  14.     {
  15.         Node,
  16.         List,
  17.         DottedPair,
  18.         RelationalOperator,
  19.         LogicalOperator,
  20.     }
  21.    
  22.     ///
  23.     /// TypedValue Tree
  24.     ///
  25.     public class ResultTree : IEnumerable, IFormattable
  26.     {
  27.         ResultTreeType _treeType;
  28.         ResultTree _owner;
  29.         TypedValue _typedValue;
  30.         List _lst = new List();
  31.         static readonly List _relationalOperatorNames =
  32.             new List { "not", "and", "or", "xor" };
  33.         #region Properties
  34.         public ResultTree this[int index]
  35.         {
  36.             get
  37.             {
  38.                 if (_lst.Count == 0)
  39.                 {
  40.                     if(index == 0)
  41.                     {
  42.                         return this;
  43.                     }
  44.                 }
  45.                 else
  46.                 {
  47.                     if (index >= 0 && index ()
  48.         {
  49.             return (T)_typedValue.Value;
  50.         }
  51.         #endregion
  52.         #region Constructor
  53.         public ResultTree()
  54.         {
  55.             _treeType = ResultTreeType.Node;
  56.         }
  57.         public ResultTree(TypedValue value)
  58.             :this()
  59.         {
  60.             _typedValue = value;
  61.         }
  62.         public ResultTree(int typeCode, object obj)
  63.             : this(new TypedValue(typeCode, obj))
  64.         { }
  65.         public ResultTree(LispDataType type, object obj)
  66.             : this(new TypedValue((int)type, obj))
  67.         { }
  68.         public ResultTree(DxfCode type, object obj)
  69.             : this(new TypedValue((int)type, obj))
  70.         { }        public ResultTree(string operatorContext)
  71.         {
  72.             operatorContext = operatorContext.ToLower();
  73.             _treeType =
  74.                 _relationalOperatorNames.Contains(operatorContext) ?
  75.                 ResultTreeType.RelationalOperator : ResultTreeType.LogicalOperator;
  76.             _typedValue = new TypedValue(-4, operatorContext);
  77.         }
  78.         public ResultTree(ResultTreeType type)
  79.         {
  80.             _treeType = type;
  81.         }
  82.         private enum ResultNodeType
  83.         {
  84.             Node,
  85.             ListBegin,
  86.             ListEnd,
  87.             DottedPairEnd,
  88.             LogicalOperator,
  89.             RelationalOperatorBegin,
  90.             RelationalOperatorEnd,
  91.         }
  92.         private ResultNodeType GetNodeType(TypedValue tvalue, out ResultTree rt)
  93.         {
  94.             short typeCode = tvalue.TypeCode;
  95.             object value = tvalue.Value;
  96.             rt = null;
  97.             
  98.             if (typeCode == -4)
  99.             {
  100.                 string s = ((string)value).ToLower();
  101.                 if(s[0] == '' && _relationalOperatorNames.Contains(s.Substring(0, s.Length - 1)))
  102.                 {
  103.                     return ResultNodeType.RelationalOperatorEnd;
  104.                 }
  105.                 else
  106.                 {
  107.                     rt = new ResultTree(s);
  108.                     return ResultNodeType.LogicalOperator;
  109.                 }
  110.             }
  111.             else if(typeCode == (short)LispDataType.ListBegin)
  112.             {
  113.                 rt = new ResultTree(ResultTreeType.List);
  114.                 return ResultNodeType.ListBegin;
  115.             }
  116.             else if(typeCode == (short)LispDataType.ListEnd)
  117.             {
  118.                 return ResultNodeType.ListEnd;
  119.             }
  120.             else if(typeCode == (short)LispDataType.DottedPair)
  121.             {
  122.                 return ResultNodeType.DottedPairEnd;
  123.             }
  124.             else
  125.             {
  126.                 rt = new ResultTree(tvalue);
  127.                 return ResultNodeType.Node;
  128.             }
  129.         }
  130.         public ResultTree(ResultBuffer rb)
  131.         {
  132.             ResultTree rt = this;
  133.             foreach (TypedValue tv in rb)
  134.             {
  135.                 ResultTree trt;
  136.                 switch (GetNodeType(tv, out trt))
  137.                 {
  138.                     case ResultNodeType.LogicalOperator:
  139.                     case ResultNodeType.RelationalOperatorBegin:
  140.                     case ResultNodeType.ListBegin:
  141.                         rt = rt.Add(trt);
  142.                         break;
  143.                     case ResultNodeType.DottedPairEnd:
  144.                         rt._treeType = ResultTreeType.DottedPair;
  145.                         rt = rt._owner;
  146.                         break;
  147.                     case ResultNodeType.RelationalOperatorEnd:
  148.                     case ResultNodeType.ListEnd:
  149.                         rt = rt._owner;
  150.                         break;
  151.                     default:
  152.                         rt.Add(trt);
  153.                         if (rt._treeType == ResultTreeType.RelationalOperator)
  154.                             rt = rt._owner;
  155.                         break;
  156.                 }
  157.             }
  158.             if (_lst.Count == 1)
  159.             {
  160.                 rt = _lst[0];
  161.                 _lst.Remove(rt);
  162.                 _lst.AddRange(rt);
  163.                 _treeType = rt._treeType;
  164.                 _typedValue = rt._typedValue;
  165.             }
  166.         }
  167.         #endregion
  168.         #region Set
  169.         public void Set(int typeCode, object obj)
  170.         {
  171.             _typedValue = new TypedValue(typeCode, obj);
  172.         }
  173.         public void Set(LispDataType type, object obj)
  174.         {
  175.             _typedValue = new TypedValue((int)type, obj);
  176.         }
  177.         public void Set(DxfCode type, object obj)
  178.         {
  179.             _typedValue = new TypedValue((int)type, obj);
  180.         }        public void Set(int typeCode)
  181.         {
  182.             _typedValue = new TypedValue(typeCode);
  183.         }
  184.         public void Set(LispDataType type)
  185.         {
  186.             _typedValue = new TypedValue((int)type);
  187.         }
  188.         public void Set(DxfCode type)
  189.         {
  190.             _typedValue = new TypedValue((int)type);
  191.         }
  192.         #endregion
  193.         #region Add
  194.         public ResultTree Add(TypedValue value)
  195.         {
  196.             return Add(new ResultTree(value));
  197.         }
  198.         public ResultTree Add(int typeCode, object obj)
  199.         {
  200.             return Add(new ResultTree(typeCode, obj));
  201.         }
  202.         public ResultTree Add(LispDataType type, object obj)
  203.         {
  204.             return Add(new ResultTree(type, obj));
  205.         }
  206.         public ResultTree Add(DxfCode type, object obj)
  207.         {
  208.             return Add(new ResultTree(type, obj));
  209.         }
  210.         public ResultTree Add(ResultTree rt)
  211.         {
  212.             rt._owner = this;
  213.             _lst.Add(rt);
  214.             return rt;
  215.         }
  216.         #region Add LispData
  217.         public ResultTree Add(short value)
  218.         {
  219.             return Add(new ResultTree(LispDataType.Int16, value));
  220.         }
  221.         public ResultTree Add(int value)
  222.         {
  223.             return Add(new ResultTree(LispDataType.Int32, value));
  224.         }
  225.         public ResultTree Add(double value)
  226.         {
  227.             return Add(new ResultTree(LispDataType.Double, value));
  228.         }
  229.         public ResultTree Add(string value)
  230.         {
  231.             return Add(new ResultTree(LispDataType.Text, value));
  232.         }
  233.         public ResultTree Add(Point2d value)
  234.         {
  235.             return Add(new ResultTree(LispDataType.Point2d, value));
  236.         }
  237.         public ResultTree Add(Point3d value)
  238.         {
  239.             return Add(new ResultTree(LispDataType.Point3d, value));
  240.         }
  241.         public ResultTree Add(ObjectId value)
  242.         {
  243.             return Add(new ResultTree(LispDataType.ObjectId, value));
  244.         }
  245.         public ResultTree Add(SelectionSet value)
  246.         {
  247.             return Add(new ResultTree(LispDataType.SelectionSet, value));
  248.         }
  249.         //public void Add(ResultType type, params object[] values)
  250.         //{
  251.         //    ResultTree rt = new ResultTree(type);
  252.         //    foreach (object value in values)
  253.         //    {
  254.         //        if (value is short)
  255.         //        {
  256.         //            rt.Add((short)value);
  257.         //        }
  258.         //        else if (value is int)
  259.         //        {
  260.         //            rt.Add((int)value);
  261.         //        }
  262.         //        else if (value is double)
  263.         //        {
  264.         //            rt.Add((double)value);
  265.         //        }
  266.         //        else if (value is string)
  267.         //        {
  268.         //            rt.Add((string)value);
  269.         //        }
  270.         //        else if (value is Point2d)
  271.         //        {
  272.         //            rt.Add((Point2d)value);
  273.         //        }
  274.         //        else if (value is Point3d)
  275.         //        {
  276.         //            rt.Add((Point3d)value);
  277.         //        }
  278.         //        else if (value is ObjectId)
  279.         //        {
  280.         //            rt.Add((ObjectId)value);
  281.         //        }
  282.         //        else if (value is SelectionSet)
  283.         //        {
  284.         //            rt.Add((SelectionSet)value);
  285.         //        }
  286.         //    }
  287.         //}
  288.         #endregion
  289.         #endregion
  290.         #region Convert
  291.         private void GetValues(List values)
  292.         {
  293.             switch (_treeType)
  294.             {
  295.                 case  ResultTreeType.Node:
  296.                     if (_lst.Count == 0)
  297.                     {
  298.                         values.Add(_typedValue);
  299.                     }
  300.                     else
  301.                     {
  302.                         _lst.ForEach(rtree => rtree.GetValues(values));
  303.                     }
  304.                     break;
  305.                 case ResultTreeType.List:
  306.                     values.Add(new TypedValue((int)LispDataType.ListBegin));
  307.                     _lst.ForEach(rtree => rtree.GetValues(values));
  308.                     values.Add(new TypedValue((int)LispDataType.ListEnd));
  309.                     break;
  310.                 case ResultTreeType.DottedPair:
  311.                     values.Add(new TypedValue((int)LispDataType.ListBegin));
  312.                     _lst.ForEach(rtree => rtree.GetValues(values));
  313.                     values.Add(new TypedValue((int)LispDataType.DottedPair));
  314.                     break;
  315.                 case ResultTreeType.LogicalOperator:
  316.                     values.Add(_typedValue);
  317.                     _lst.ForEach(rtree => rtree.GetValues(values));
  318.                     break;
  319.                 case ResultTreeType.RelationalOperator:
  320.                     values.Add(new TypedValue(-4, " rtree.GetValues(values));
  321.                     values.Add(new TypedValue(-4, _typedValue.Value + ">"));
  322.                     break;
  323.             }
  324.         }
  325.         public TypedValue[] ToArray()
  326.         {
  327.             List values = new List();
  328.             GetValues(values);
  329.             return values.ToArray();
  330.         }
  331.         public static implicit operator SelectionFilter(ResultTree rtree)
  332.         {
  333.             return new SelectionFilter(rtree.ToArray());
  334.         }
  335.         public static implicit operator ResultBuffer(ResultTree rtree)
  336.         {
  337.             return new ResultBuffer(rtree.ToArray());
  338.         }
  339.         #endregion
  340.         #region RelationalOperator
  341.         private void MakeRelationalOperator(string operatorContext, ResultTree res)
  342.         {
  343.             if (_treeType == ResultTreeType.RelationalOperator && _typedValue.Value.ToString() == operatorContext)
  344.             {
  345.                 res._lst.AddRange(_lst);
  346.             }
  347.             else
  348.             {
  349.                 res.Add(this);
  350.             }
  351.         }
  352.         public static ResultTree operator !(ResultTree rt1)
  353.         {
  354.             ResultTree rt = new ResultTree("not") { rt1 };
  355.             return rt;
  356.         }
  357.         public static ResultTree operator &(ResultTree rt1, ResultTree rt2)
  358.         {
  359.             ResultTree rt = new ResultTree("and");
  360.             rt1.MakeRelationalOperator("and", rt);
  361.             rt2.MakeRelationalOperator("and", rt);
  362.             return rt;
  363.         }
  364.         public static ResultTree operator |(ResultTree rt1, ResultTree rt2)
  365.         {
  366.             ResultTree rt = new ResultTree("or");
  367.             rt1.MakeRelationalOperator("or", rt);
  368.             rt2.MakeRelationalOperator("or", rt);
  369.             return rt;
  370.         }
  371.         public static ResultTree operator ^(ResultTree rt1, ResultTree rt2)
  372.         {
  373.             return
  374.                 new ResultTree("xor")
  375.                 {
  376.                     rt1,
  377.                     rt2
  378.                 };
  379.         }
  380.         #endregion
  381.         
  382.         #region IFormattable 成员
  383.         public override string ToString()
  384.         {
  385.             var rb = new ResultBuffer(ToArray());
  386.             return rb.ToString();
  387.         }
  388.         string IFormattable.ToString(string format, IFormatProvider formatProvider)
  389.         {
  390.             var rb = new ResultBuffer(ToArray());
  391.             return rb.ToString(format, formatProvider);
  392.         }
  393.         #endregion
  394.         #region IEnumerable 成员
  395.         #region IEnumerable 成员
  396.         IEnumerator IEnumerable.GetEnumerator()
  397.         {
  398.             return _lst.GetEnumerator();
  399.         }
  400.         #endregion
  401.         IEnumerator IEnumerable.GetEnumerator()
  402.         {
  403.             return _lst.GetEnumerator();
  404.         }
  405.         #endregion
  406.     }
  407. }

扩展方法
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using TlsCad.Collections;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. namespace TlsCad.ExtendMethods
  8. {
  9.     public static class ResultBufferEx
  10.     {
  11.         public static ResultList ToList(this ResultBuffer rb)
  12.         {
  13.             return new ResultList(rb);
  14.         }
  15.         public static ResultTree ToTree(this ResultBuffer rb)
  16.         {
  17.             return new ResultTree(rb);
  18.         }
  19.     }
  20. }

示例代码
  1.         [CommandMethod("t9")]
  2.         public static void Test9()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptSelectionResult res1 =
  8.                 ed.SelectAll(
  9.                     new ResultTree
  10.                     {
  11.                         new ResultTree(">,>,*")
  12.                         {
  13.                             {10, new Point3d()}
  14.                         },
  15.                         new ResultTree(",>,*"},
  16.                         {10, new Point3d()},
  17.                         {-4, ""},
  18.                             {-4, ""},
  19.                         {-4, "or>"}
  20.                     });        }
  21.         [CommandMethod("t10")]
  22.         public static void Test10()
  23.         {
  24.             Document doc = Application.DocumentManager.MdiActiveDocument;
  25.             Database db = doc.Database;
  26.             Editor ed = doc.Editor;
  27.             PromptEntityResult res = ed.GetEntity("Select a Entity:");
  28.             using (DBTransaction tr = new DBTransaction())
  29.             {
  30.                 tr.OpenRegAppTable(OpenMode.ForWrite);
  31.                 tr.RegApp("MyApp");
  32.                 Entity ent = tr.GetObject(res.ObjectId, OpenMode.ForWrite) as Entity;
  33.                 ent.XData =
  34.                     new ResultList
  35.                     {
  36.                         {1001, "MyApp"},
  37.                         {1000, "This is a Test"},
  38.                         {DxfCode.ExtendedDataInteger16, 12}
  39.                     };
  40.             }
  41.         }
  42.         [CommandMethod("t11")]
  43.         public static void Test11()
  44.         {
  45.             Document doc = Application.DocumentManager.MdiActiveDocument;
  46.             Database db = doc.Database;
  47.             Editor ed = doc.Editor;
  48.             PromptEntityResult res1 = ed.GetEntity("\nSelect a Entity:");
  49.             InvokeArx.CmdEcho = false;
  50.             InvokeArx.Command(
  51.                 false,
  52.                 new ResultTree
  53.                 {
  54.                     "break",
  55.                     new ResultTree(ResultType.List)
  56.                     {
  57.                         res1.ObjectId,
  58.                         res1.PickedPoint
  59.                     },
  60.                     res1.PickedPoint
  61.                 });
  62.             InvokeArx.CmdEcho = true;
  63.         }
  64.         [LispFunction("lsptest1")]
  65.         public static ResultBuffer LTest1(ResultBuffer rb)
  66.         {
  67.             ResultTree rtree =
  68.                 new ResultTree(ResultType.List)
  69.                 {
  70.                     1,
  71.                     new ResultTree(ResultType.DottedPair)
  72.                     {
  73.                         10,
  74.                         new Point3d(10, 10, 0)
  75.                     }
  76.                 };
  77.             return rtree;
  78.         }
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-1-4 14:33:00 | 显示全部楼层
不过,简化写法必须在VS2008及以上版本才支持
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-1-4 21:24:00 | 显示全部楼层
ResultTree的操作符重载版本(一楼代码已更改),这样写挺好玩的,:)
测试代码复制代码返回:
((-4,)(-4,and>)(-4,)(-4,or>))
回复

使用道具 举报

7

主题

55

帖子

5

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
83
发表于 2010-1-4 21:36:00 | 显示全部楼层
个人觉得还是太麻烦。实际可能少用到。我就没有这样用过。
回复

使用道具 举报

17

主题

69

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
137
发表于 2010-1-4 21:37:00 | 显示全部楼层
顶我们的狐老大,哈哈!
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-7-9 15:53:00 | 显示全部楼层

更新版本,增加与ResultBuffer的互相转换,增强Lisp相关操作
简化选择集中逻辑表达式的写法(见示例)

LispFunction的相关示例
  1.         [LispFunction("mylisp1")]
  2.         public object lsptest11(ResultBuffer rb)
  3.         {
  4.             ResultTree rt = rb.ToTree();
  5.             switch (rt.TreeType)
  6.             {
  7.                 case ResultTreeType.Node:
  8.                     switch (rt.LispDataType)
  9.                     {
  10.                         case LispDataType.Point2d:
  11.                             Point2d pt2d = rt.GetValue();
  12.                             rt.Set(LispDataType.Point2d, new Point2d(10, pt2d.Y));
  13.                             break;
  14.                         case LispDataType.Point3d:
  15.                             Point3d pt3d = rt.GetValue();
  16.                             rt.Set(LispDataType.Point3d, new Point3d(10, pt3d.Y, pt3d.Z));
  17.                             break;
  18.                     }
  19.                     break;
  20.                 case ResultTreeType.List:
  21.                 case ResultTreeType.DottedPair:
  22.                     rt[0].Set(LispDataType.Int16, 10);
  23.                     return (ResultBuffer)rt;
  24.             }
  25.             return rt.TypedValue;
  26.         }

效果:复制代码
回复

使用道具 举报

18

主题

177

帖子

7

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
249
发表于 2010-7-13 22:01:00 | 显示全部楼层
好。
回复

使用道具 举报

0

主题

1

帖子

1

银币

初来乍到

Rank: 1

铜币
1
发表于 2010-8-24 17:32:00 | 显示全部楼层
必须留言 .... 好东西呀
回复

使用道具 举报

3

主题

18

帖子

3

银币

初来乍到

Rank: 1

铜币
30
发表于 2010-10-2 15:35:00 | 显示全部楼层
好东西,学习中
回复

使用道具 举报

13

主题

84

帖子

6

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
136
发表于 2011-1-24 10:01:00 | 显示全部楼层
lisp传递参数的ResultBuffer,有时表被当成点对,如何解决?
//Lisp:第二个参数是四个整数
(TTT "AAA" (list 10 20 30 40) 12.36)
//.NET:把(list 10 20 30 40)当成点对,得到一个Point3D(20,30,40),显然不对
Public Sub TTT(ByVal rbArgs As ResultBuffer)
     'rbArgs
End Sub
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-15 13:01 , Processed in 0.449292 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表