zoukankan      html  css  js  c++  java
  • Visual Studio DSL 入门 11为状态机设计器添加规则

       上一节我们在设计器的显示方面进行了完善,在这一节,我们将深入状态机设计器的一些逻辑细节,给我们的设计器添加逻辑规则.为生成代码做好准备.
       在开始之前,我们先看一下Transition的几个属性之间的关系: 
         1.编辑Event,Condition,Action属性时,Label属性能够自动计算显示,计算逻辑为Event [Condition] / Action 
         2.当修改属性Label时,Event,Condition,Action的值也能够对应自动更新.  
       我们使用Vs.net Dsl的规则来实现:
         1.在Dsl项目下新增CustomCode文件夹来存放我们的自定义的代码,这是Dsl开发中的通用做法,Dsl再强大也不可能不一点代码不用写就能够使满足需求,一般情况下,无论是在开发Dsl还是在使用Dsl时,都需要结合生成的代码和自定义代码.在CustomCode文件夹下面新建文件夹Validation,用于存放手写的自定义验证类.
         2.在Validation文件夹下面添加类TransitionLabelRule.
         3.修改TransitionLabelRule继承于ChangeRule,并使用RuleOn属性标签标识此规则应用到域关系Transition上面.

    隐藏行号 复制代码
    1. using Microsoft.VisualStudio.Modeling;
      
    2. 
      
    3. namespace Company.LanguageSm
      
    4. {
      
    5.     [RuleOn(typeof(Transition))]
      
    6.     public sealed class TransitionLabelRule : ChangeRule
      
    7. {
      
    8.     }
      
    9. }
      
    10. 
      

           4.在规则类里面,我们需要实现ChangeRule唯一的一个方法ElementPropertyChanged(ElementPropertyChangedEventArgs e),从这个方法我们可以看出,当Transition的一些属性发生变化时就会触发这个规则,参数类型ElementPropertyChangedEventArgs,这个参数包含当前的模型元素ModelElement,编辑的属性DomainProperty,原值OldValue,新值NewValue,我们只需要判断当前的属性,如果是以上的Event,Condition,Action,Lable时,修改后就计算其余的属性.
       

    隐藏行号 复制代码
    1. public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e)
      
    2.         {
      
    3.             Transition t = e.ModelElement as Transition;
      
    4. 
      
    5.             // Compute Label when Event changes
      
    6. if (e.DomainProperty.Id == Transition.EventDomainPropertyId)
      
    7.                 t.Label = ComputeSummary(e.NewValue as string, t.Condition, t.Action);
      
    8. 
      
    9.             // Compute Label when Condition changes
      
    10. else if (e.DomainProperty.Id == Transition.ConditionDomainPropertyId)
      
    11.                 t.Label = ComputeSummary(t.Event, e.NewValue as string, t.Action);
      
    12. 
      
    13.             // Compute Label when Action changes
      
    14. else if (e.DomainProperty.Id == Transition.ActionDomainPropertyId)
      
    15.                 t.Label = ComputeSummary(t.Event, t.Condition, e.NewValue as string);
      
    16. 
      
    17.             // Compute Event, Condition, Action when Label changes
      
    18. else if (e.DomainProperty.Id == Transition.LabelDomainPropertyId)
      
    19.                 ComputeProperties(e.NewValue as string, t);
      
    20. 
      
    21.         }
      

       ComputeSummary是我们的辅助方法,通过Event,Condition,Action三个值来计算Lable的值,ComputeProperties方法是由Lable的值来分别匹配出另外三个属性的值.最后可以直接对域类的属性进入赋值. 这两个辅助方法就不在这里列出来了,在下载代码里可以看到.(在这里其实是默认提交,整个规则事件就在一个事务中).
            5.重新运行项目,会发现,写的规则没有起作用,修改Transition的属性时,也没有跳到TransitionLabelRule的断点里面来,这是怎么回事呢?这其实是和Vs.net dsl 的规则机制有关,我们还需要对这个Rule进行一下注册, 在CustomCode下面添加LanguageSmDomainModel(GeneratedCode下面的DomainModel.tt生成的类)的一个partial类,在这里类的GetCustomDomainModelTypes方法里,添加我们的自定义的Rule的集合,这样 vs.net在加载时,就会自动加载这个Rule,并添加到Rule集合中.
       

    隐藏行号 复制代码
    1. namespace Company.LanguageSm
      
    2. {
      
    3.     public partial class LanguageSmDomainModel
      
    4. {
      
    5.         protected override Type[] GetCustomDomainModelTypes()
      
    6.         {
      
    7.             return new Type[]{typeof(TransitionLabelRule),};
      
    8.         }
      
    9.     }
      
    10. }
      

           6.生成转换所有模板,我们来测试一下我们的规则:
     ~7OF3)~R2I0MRM~5]Q1P_C2


    代码下载

    参考资源
          1. Visual Stuido DSL 工具特定领域开发指南
          2. DSL Tools Lab     http://code.msdn.microsoft.com/DSLToolsLab  系列教程  [本系列的入门案例的主要参考]

    作者:孤独侠客似水流年
    出处:http://lonely7345.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    【BZOJ 4631】4631: 踩气球 (线段树)
    【BZOJ 4148】 4148: [AMPPZ2014]Pillars (乱搞)
    【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)
    【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)
    【BZOJ 4103】 4103: [Thu Summer Camp 2015]异或运算 (可持久化Trie)
    【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)
    【BZOJ 3997】 3997: [TJOI2015]组合数学 (DP| 最小链覆盖=最大点独立集)
    【BZOJ 3727】 3727: PA2014 Final Zadanie (递推)
    【BZOJ 3442】 3442: 学习小组 (最大费用流)
    【BZOJ 3218】 3218: a + b Problem(最小割+可持久化线段树)
  • 原文地址:https://www.cnblogs.com/lonely7345/p/1678702.html
Copyright © 2011-2022 走看看