世界上没有好做的软件,觉得好做,只是你的系统简单而已,而不是哪个行业简单,特别像我们PCB制造企业务逻辑的很复杂的,仅仅靠决策树中的每个节点布置决策逻辑是不能满足要求的,所以我们在制作PCB规则引擎必须再向更高一层次考虑,让规则管理灵活度更高,控制力度更大的决策逻辑组件。当然一个好的规则引擎对脚本语言的支持是必不可少的,如何选择脚本语言是规则引擎选型非常重要一环,需要考虑,用户对脚本的易学,易用,脚本的性能,脚本语言与.net语言深度交互能力,

写了一个工具专用于对JS进行测试,语法支持,性能,交互性进行测试.

一.基本语法测试

1. 检测流程是否存在

var ppeflow =new Array('开料','钻孔','沉铜','板镀','干膜','图形电镀','退膜','蚀刻','退锡','阻焊','字符','喷锡','铣板','测试','终检');
if (ppeflow.exists ("开料"))
{
console.alert('存在');
}
else
{
console.alert('不存在');
}
/*
判断数组中是否存在
*/
Array.prototype.exists = function (val) {
for (var i = 0; i < this.length; i++) {
if (this[i] == val) {
return true;
}
}
return false;
}

2 检测流程顺序

//查找制定元素在数组中的索引值
Array.prototype.indexVf=function(arr){
for(var i=0;i<this.length;i++){
if(this[i]==arr){
return i;

}
}
var ppeflow =new Array('开料','钻孔','沉铜','板镀','干膜','图形电镀','退膜','蚀刻','退锡','阻焊','字符','喷锡','铣板','测试','终检');
var index1 = ppeflow.indexVf('字符');
var index2 = ppeflow.indexVf('喷锡');
if (index1< index2)
{
console.alert('字符在喷锡前');
}
else
{
console.alert('字符在喷锡后');
}

3 判断孔径比值

var holesize = 0.2;
var thick = 2.5;
//判断孔径比是否大于12:1
var scale = thick / holesize;
if (scale > 12)
{
console.alert('孔径比值大于12');
}
else
{
console.alert('孔径比值小于或等于12');
}

4 判断客户代码等于T001

var pdctno = 'at00101ca0'; //客户代码在生产型号中间2到5位
pdctno = pdctno.toUpperCase(); //转为大写
var custcode = pdctno.substr(1,4);
if (custcode == 'T001')
{
console.alert('客户代码等于T001');
}
else
{
console.alert('客户代码不等于T001');
}

5 求钻孔表总孔数

var drlTable = [
{'HoleType':'PTH','HoleSize':3.175,'HoleCount':5,'DisplayOrd':0},
{'HoleType':'PTH','HoleSize':0.2,'HoleCount':15,'DisplayOrd':1},
{'HoleType':'PTH','HoleSize':0.3,'HoleCount':52,'DisplayOrd':2},
{'HoleType':'PTH','HoleSize':1.0,'HoleCount':44,'DisplayOrd':3},
{'HoleType':'PTH','HoleSize':2.0,'HoleCount':11,'DisplayOrd':4},
{'HoleType':'PTH','HoleSize':3.5,'HoleCount':20,'DisplayOrd':5},
{'HoleType':'PTH','HoleSize':4.0,'HoleCount':18,'DisplayOrd':6}
];
var HoleCount = 0;
for(var i in drlTable)
{
HoleCount += drlTable[i].HoleCount ;
}
console.alert('总孔数:' + HoleCount) ;

6 板厚喷锡板尺寸判断

 /*
判断数组中是否存在
*/
Array.prototype.exists = function (val) {
for (var i = 0; i < this.length; i++) {
if (this[i] == val) {
return true;
}
}
return false;
}
var thick = 0.4;
var surface = '喷锡';
var pnlwidth = 18;
var pnlheight = 24;
//判断当板厚<=0.5mm,表面处理为喷锡时,PNL尺寸不能大于16X18
if (thick < 0.5 && ['喷锡','有铅喷锡','无铅喷锡'].exists(surface) )
{
if (pnlwidth > 16 || pnlheight > 18)
{
console.alert('板厚<=0.5mm,表面处理为喷锡时,PNL尺寸不能大于16X18');
}
}
else
{
console.alert('PNL尺寸符合要求');
}

小结:通过实际PCB工程基本检测规则对JS语法验证,选用JS语言作为PCB工程客户端进行规则维护还不错哦!JS语法友好,易学,易用。

二.性能测试

1.JS循环1亿次  耗时839毫秒

var sum = 0;
for (var i=0; i<100000000; i++)
{
sum ++;
}

2.C#外循环1000次,JS内循环10W次 合计1亿次  耗时3222毫秒

var sum = 0;
for (var i=0; i<100000; i++)
{
sum ++;
}

3.JS调函数循环1亿次  耗时8416毫秒

var sum = 0;
for (var i=0; i<100000000; i++)
{
var rndNum = Math.ceil(Math.random() * 10);
sum += sumsxi(rndNum,i);
}
function sumsxi(a,b)
{
return a + b;
}

4.C#外循环1000次, JS调用函数内循环10W次 合计1亿次  耗时17305毫秒

var sum = 0;
for (var i=0; i<100000; i++)
{
var rndNum = Math.ceil(Math.random() * 10);
sum += sumsxi(rndNum,i);
}
function sumsxi(a,b)
{
return a + b;
}

小结:通过以上测试:脚本语言能达到这个速度水平非常棒了,我们来看看这个速度是否能满足实际要求呢,

通常执行一次JS V8引擎实例化一次就好了(即在C#中执行),第一次将,列表数据,对象数据,C#函数,JS函数装载进去后,接着规则引擎主要耗时将在执行脚本上面了,比如:一个规则数结构最多按100个节点,应该足够了,然后每个节点存在JS可执行代码1000行,考虑到实际更复杂,将1000行代码复杂度乘以10倍,那么这里按1W行的代码量计算;100个节点乘以1W行代码量,就是100W行代码量,实测耗时:100毫秒。这个速度顶呱呱的.

但实际应用中还待验证(比如多用并发,更复杂的业务逻辑超耗时,大量数据(10M数据量)进入JS规则引擎参与到数据引用与计算).

三.交互性测试(JS内置对象返回)

把业务逻辑用JS脚本写,并用JS V8引擎执行脚本, 并将计算结果返回给C#

测试:JS脚本中的内置对象,如:单个值,对象,数组 类型,进行业务逻辑处理后并将对象变量返回给C#

1.JS内置单值

例1:计算孔径比

//计算孔径比值
var holesize = 0.2;
var thick = 2.5;
var scale = thick / holesize;
scale;

例2:通过表面处理ID号找到对应的表面处理名称

var arr =[ ['喷锡','A01'],['沉金','A02'],['OSP','A03'],['镀金','A04'],['沉银','A05'],['沉锡','A06']] ;
var SurfaceCode = 'A03'; //表面处理ID号
var SurfaceName = ''; //通过ID号找到对应的表面处理名称
for(var i in arr)
{
if (techno == arr[i][1])
{
SurfaceName = arr[i][0];
}
}
console.log(SurfaceName)
SurfaceName

2.JS内置对象

JS对象返回给C#类型转为:字典Dictionary<string,Object>类型

例3:将JS中的钻孔对象返回给C#

var HoleMod = { 'HoleType':'PTH','HoleSize':0.2,'DisplayOrd':1};
HoleMod.HoleCount = 22;
HoleMod

3.JS内置数组

JS 数组返回给C#类型转为:Object[]类型

例4:将JS中的钻孔表数组返回给C#

var drlTable = [
{'HoleType':'PTH','HoleSize':3.175,'HoleCount':5,'DisplayOrd':0},
{'HoleType':'PTH','HoleSize':0.2,'HoleCount':15,'DisplayOrd':1},
{'HoleType':'PTH','HoleSize':0.3,'HoleCount':52,'DisplayOrd':2},
{'HoleType':'PTH','HoleSize':1.0,'HoleCount':44,'DisplayOrd':3},
{'HoleType':'PTH','HoleSize':2.0,'HoleCount':11,'DisplayOrd':4},
{'HoleType':'PTH','HoleSize':3.5,'HoleCount':20,'DisplayOrd':5},
{'HoleType':'PTH','HoleSize':4.0,'HoleCount':18,'DisplayOrd':6}
];
drlTable;

例5:将JS中的表面处理数组返回给C#

var arr = ['OSP','沉金','喷锡'];
arr[6] = '沉锡';
arr;

4.JS内置函数

例6:在JS中写函数并在JS中调用应,   此函数不能返回给C#

//计算孔径比JS函数
function HoleSizeThickSclae(HoleSize,Thick)
{
return Thick/HoleSize;
} var holesize = 0.2;
var thick = 2.5;
HoleSizeThickSclae(holesize,thick);

四.交互性测试(C#传参与返回)

把业务逻辑用JS脚本写,用JS V8引擎执行脚本, 并将计算结果返回给C#

测试:将C#中的对象变量传给JS脚本,如:单个值,对象,数组,字典 等类型,JS脚本接受此类型数据后进行业务逻辑处理,处理完成后,再将对象变量返回给C#.

1.C#传入单值

C#传入数据:

            string str1 = "样板";
int num1 = ;

JS接受数据并处理,返回单个值

//原始C# 单个值输出
console.log(num1);
console.log(str1);
console.log('=================');
//更改C# 单个值
num1 += 10
str1 = '钻孔' + num1.toString();
//更改后C#对象值输出
console.log(num1);
console.log(str1);
console.log('=================');
//返回给C#
str1;

2.C#传入对象

C#传入数据:

            ppeflow ppeflow = new ppeflow ();
ppeflow.Num = ;
ppeflow.TechName = "开料";

JS接受数据并处理,返回对象

//原始C#对象输出
console.log(ppeflow.Num);
console.log(ppeflow.TechName);
//更改C#对象值
ppeflow.Num = 2
ppeflow.TechName = '钻孔';
//更改后C#对象值输出
console.log(ppeflow.Num);
console.log(ppeflow.TechName);
//返回给C#
ppeflow;

3.C#传入数组

C#传入数据:

            List<ppeflow> ppeflowList = new List<ppeflow>()
{
new ppeflow(){ Num = , TechName = "开料"},
new ppeflow(){ Num = , TechName = "钻孔"},
new ppeflow(){ Num = , TechName = "沉铜"},
new ppeflow(){ Num = , TechName = "板镀"},
new ppeflow(){ Num = , TechName = "干膜"},
new ppeflow(){ Num = , TechName = "图镀"},
new ppeflow(){ Num = , TechName = "退膜"},
new ppeflow(){ Num = , TechName = "蚀刻"},
};

JS接受数据并处理,返回数组

ppeflowList[0].TechName = 'ECN';  //更改0号数组值
ppeflowList[11] = { "Num":9,"TechName":"FQC"} //通过JS增加对象 给到11号数组
ppeflowList[12] = ppeflowList[1] //将C# 1号数组 赋值给12号数组
ppeflowList[12] .TechName = '包装' //修改12号数组值
for (var i in ppeflowList)
{
console.log(ppeflowList[i].TechName) //查看数组内容
}
ppeflowList; //返回给C#数据

JS处理后的数组返回给C#的数据变化关系

4.C#传入字典

C#传入数据:

            Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("", "开料");
dic.Add("", "钻孔");
dic.Add("", "干膜");

JS接受数据并处理,返回字典

dic[''] = '流程指示'; //修改C#字典值
dic[''] = 'FQC'; //增加字典值
dic; //返回给C#

5.C#传入函数

C#传入数据:

   calc calc = new calc();

    public class calc
{
public int sum(int a,int b)
{
return a + b;
}
}

JS调用C#函数,并返回结果

var aa = 18;
var bb = 2000;
var cc = calc.sum(aa,bb); //调用C#函数加算计算
console.log(cc);
cc;

五.JS扩展

1.扩展函数console 给JS使用

C#写函数部分

    public class console
{
public event EventHandler logHandler;
/// <summary>
/// 打印log
/// </summary>
/// <param name="msg"></param>
public void log(object msg)
{
if (logHandler != null)
logHandler(msg, null);
}
/// <summary>
/// 打印到控制台
/// </summary>
/// <param name="msg"></param>
public void print(string msg)
{
Console.WriteLine(msg);
}
/// <summary>
/// 弹窗提示
/// </summary>
/// <param name="msg"></param>
public void alert(string msg)
{
MessageBox.Show(msg, "JavaScript提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// 输入窗
/// </summary>
/// <param name="msg">输入框信息</param>
/// <param name="defVal">默认值</param>
/// <returns></returns>
public string prompt(string msg, string defVal = "")
{
return Interaction.InputBox(msg, "JavaScript输入", defVal);
}
/// <summary>
/// 确认Yes或No窗口
/// </summary>
/// <param name="msg">提示框信息</param>
/// <returns></returns>
public bool confirm(string msg)
{
DialogResult result = MessageBox.Show(msg, "JavaScript确认", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
return result == DialogResult.Yes;
}
}

JS调用C#函数

for (var i=0;i<10;i++){
console.log('log输出' +i);
}
var cc = 'pcbren 致力于PCB工程自动化研究';
console.alert(cc);
var tt = console.prompt('请输入:pcbren ','test');
while (tt !='pcbren')// 输入pcbren 否则死循环
{
tt = console.prompt('请输入:pcbren ','test');
}

JS调用C#函数测试界面

2.扩展函数JSON给JS使用

C#写函数部分

    public class JSON
{
/// <summary>
/// 对象转Json字符串
/// </summary>
/// <param name="Object"></param>
/// <returns></returns>
public string stringify(object Object)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(Object);
}
/// <summary>
/// Json字符串转对象
/// </summary>
/// <param name="StirngJSON"></param>
/// <returns></returns>
public object parse(string StirngJSON)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject(StirngJSON);
}
}

JS调用C#函数

var holeMod = {'HoleType':'PTH','HoleSize':3.175,'HoleCount':5,'DisplayOrd':0};
var StrJSON = JSON.stringify(holeMod) ;//转换过程: JS对象==>C#字典==》C#字符串==》JS字符串
console.log(StrJSON) ; var Mod = JSON.parse(StrJSON);//转换过程:JS字符串==》C#字符串==>C# JObject对象
console.log(Mod.ToString()) ; Mod;

JS调用C#函数测试界面

3.json数据交换与转换

我们将C#对象数据传递给JS V8引擎,JS脚本可以直接调用C#对象中的属性,如果从C#传入对象Json文本如何处理呢

3.1 C#Json字符串传入JS V8后通过JS内置eval 方法转为对象

C#代码部份

string strJSON = "{'Num':1,'TechName':'开料'}";

JS转对象部份

console.log(strJSON);                      //JSON传入JSON字符串
var obj = eval('(' + strJSON + ')'); //将JSON字符串转为JS对象
console.log(obj.Num);
console.log(obj.TechName);

3.2 C#Json字符串内嵌JS V8 变量为对象如 var = {'加投率:' 1.05};

JS代码部份

var objinput = {'Num':1,'TechName':'开料'};   //这代码码由C#在执行JS 之前内嵌在其中,
//对于用户看不见此行代码,但可以调用此对象 for(var i in objinput) {
console.log(objinput[i]);
}

PCB 规则引擎之脚本语言JavaScript应用评测的更多相关文章

  1. PCB 围绕CAM自动化,打造PCB规则引擎

    AutoCAM自动化平台,前端管理订单,而后端执行任务,前端UIl界面有板厚,铜厚,板材,表面处理,层数等信息,而这些信息并不是后端最终所需要的信息后.拿钻孔补偿来说,后端需要的是钻孔补偿值,但前端并 ...

  2. PCB 规则引擎之JSON对象查看器

    在PCB规则引擎开发中,JavaScript V8引擎是处理业务逻辑的, 当然业务逻辑需要数据支撑才行,  即需有将数据推进入到V8引擎.目前这边数据传输到JavaScript V8引擎以C# Mod ...

  3. 客户端脚本语言javascript

    2015.11.27  客户端脚本语言javascript. (叫这个名字的原因.想要攀高枝,希望变得和他一样通用.关于名字之间的关系类似于雷锋和雷峰塔,巴基斯坦和卡巴斯基,苏格拉底跟格拉苏蒂的关系一 ...

  4. PCB 规则引擎之编辑器(语法着色,错误提示,代码格式化)

    对于一个规则引擎中的脚本代码编辑器是非常关键的,因为UI控件直接使用对象是规则维护者,关系到用户体验,在选用脚本编辑器的功能时除了满足代码的编辑的基本编辑要求外,功能还需要包含;语法着色,错误提示,代 ...

  5. JavaScript 网页脚本语言 由浅入深 (随笔)

    1)基础 学习目的: 1. 客户端表单验证 2. 页面动态效果 3. jQuery的基础 什么是JavaScript? 一种描述性语言,也是一种基于对象和事件驱动的,并具有安全性能的脚本语言 java ...

  6. 脚本、脚本语言、shell脚本

    脚本是批处理文件的延伸,是一种纯文本保存的程序,一般来说的计算机脚本程序是确定的一系列控制计算机进行运算操作动作的组合,在其中可以实现一定的逻辑分支等.脚本程序相对一般程序开发来说比较接近自然语言,可 ...

  7. 用L脚本语言实现&quot;L脚本语言控制台&quot;

    下载Windows平台解释引擎 L脚本语言中能够将随意字符串当做一行L脚本语言程序来运行.通过循环接收用户输入,就是一个控制台IDE了 #scp #scp没有控制台IDE?我们自己用scp来实现一个 ...

  8. 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  9. 9月12日JavaScript脚本语言

    JS脚本语言 JS脚本语言全称JavaScript,是网页里面使用的脚本语言,也是一门非常强大的语言. 一.基础语法 1.注释语法 单行注释:// 多行注释:/**/ 2.输出语法 ①alert(信息 ...

随机推荐

  1. 基于APE物理引擎的管线容积率计算方法

    容积率一般应用在房地产开发中,是指用地范围内地上总建筑面积与项目总用地面积的比值,这个参数是衡量建设用地使用强度的一项非常重要的指标.在其他行业,容积率的计算也非常重要,如产品利用率.管道使用率等等. ...

  2. PS切图基本操作

    PS切图基本操作 2016-05-11 20:56:46|  分类: PhotoShop|字号 订阅     下载LOFTER我的照片书  |     1首先在“文件”中打开一张图片.   2点击“移 ...

  3. Vue.js 计算属性(computed)

    Vue.js 计算属性(computed) 如果在模板中使用一些复杂的表达式,会让模板显得过于繁重,且后期难以维护.对此,vue.js 提供了计算属性(computed),你可以把这些复杂的表达式写到 ...

  4. mybatis中resultMap引发的吐血bug

    简单的讲: 问题背景:如果在写mybatis中的resultMap时,不下心将resultMapde id写成映射接口的名字,会发生什么? 结论:单元测试进度条卡住但不报错, Tomcat运行不报错, ...

  5. 洛谷——P1413 坚果保龄球

    P1413 坚果保龄球 题目描述 PVZ这款游戏中,有一种坚果保龄球.zombie从地图右侧不断出现,向左走,玩家需要从左侧滚动坚果来碾死他们. 我们可以认为地图是一个行数为6,列数为60的棋盘.zo ...

  6. 微信小程序支付全问题解决

    这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档搞一发. * 注作者使用的PHP,不过支付流程都是这样 开发前必读 主要流程 小程序前端发送求参请求 接受请求封装 "统一下单 ...

  7. 【转】精选十二款餐饮、快递、票务行业微信小程序源码demo推荐

    微信小程序的初衷是为了线下实体业服务的,必须有实体相结合才能显示小程序的魅力.个人认为微信小程序对于餐饮业和快递业这样业务比较单一的行业比较有市场,故整理推荐12款餐饮业和快递业微信小程序源码demo ...

  8. open random

    open文件操作 f = open('文件路径',mode='rwab+',encoding='utf-8') # content = f.read(3) # 读出来的都是字符 # f.seek(3) ...

  9. better-scroll & scroll

    scroll better-scroll https://github.com/ustbhuangyi/better-scroll/blob/master/README.md#getting-star ...

  10. poj 1364 查分约束

    #include<stdio.h> #include<iostream> #include<stack> #include<string.h> usin ...