.NET平台的轻量级脚本引擎:NanoScript

日期: 2009-11-26 作者:Kim 来源:TechTarget中国 英文

  在过去的几天中,我一直在思考将.NET的部分应用程序脚本化这种可能性。
  
  虽然我查看了现有的解决方案,但是最终,在基于内置.NET编译器的基础上,我以一种非常简单的方式实现了这种功能。

  Nanoscript 就是我工作的成果。

  它允许我实现下面的功能:

  • 编写能够从应用程序调用的脚本函数。

  • 在脚本内部定义新类使其能在脚本内部能够实例化并使用。

  • 定义能够在脚本内部和外部使用的全局变量。

  • 为脚本上下文导出静态程序员函数并从脚本中调用它们。

  我已经为该方案添加了两个简单的示例应用程序。第一个示例是基于命令行的小型应用程序。这些仅是做一些基本的测试。使你可以对整个方案有个更好的了解。第二个示例是一个基于窗口的应用程序,用来画一个曲线:

基于窗口的应用程序

基于窗口的应用程序2

基于窗口的应用程序3

  我的脚本引擎使用起来非常简单,因为我不需要比现在更多的功能。基本上它仅仅用于编译生成的一个CS文件并生一个包含该类的程序集,该程序集封装了所有的脚本函数。NanoScript 不会使用自己的应用程序域。生成的代码在当前的应用程序域中将会执行。NanoScript不能执行外壳CS文件。它仅仅是一个简单的类库。我的目的是将其实现为一个简单的脚本游戏成为可能。如果使用谷歌搜索,你将会找到带有更多更能的优秀解决方案。

  使用代码

  使用Nanoscript非常简单。仅仅需要添加一个NanoScript.dll程序集合的引用并在代码中加入命名空间NanoScript即可。该示例程序使用下面的方法来编译代码,该代码被存储在一个文本框里面:

以下是引用片段:
  private void compileAndRunToolStripMenuItem_Click(object sender, EventArgs e)
  {
  isCodeCompiled = false;
  // create a new scripting context
  script = new ScriptEngine();
  // reference the required assemblies
  script.References(“System.Drawing.dll”);
  script.References(“System.Windows.Forms.dll”);
  // make namespaces visible
  script.Using(“System”);
  script.Using(“System.Drawing”);
  script.Using(“System.Windows”);
  script.Using(“System.Windows.Forms”);
  // export the functions DrawSprite and DrawSprites to the scripting context
  script.SetMemberFunction( this, “DrawSprite”);
  script.SetMemberFunction( this, “DrawSpriteS”);
  // set the code stored in textBox1
  script.SetCode(this.textBox1.Text);
  try
  {
  // try to compile
  script.Compile();
  }
  catch (NanoScript.ScriptEngine.ScriptingContextException ex)
  {  // present the compiling errors in a MessageBox
  StringBuilder b = new StringBuilder();
  List cc = ex.errors;
  b.AppendLine(“There were errors:”);
  foreach (ScriptEngine.ScriptingContextException.CompileError err in cc)
  {
  b.AppendLine(“Error ” + err.errNumber + ” at line ” +
  err.line + ” col ” + err.column +
  ” : “” + err.text+””” );
  b.AppendLine(“code: ” + err.codeSnippet);
  b.AppendLine();
  }
  MessageBox.Show(b.ToString(),”Compiling Error(s)”);
  return;
  }
  isCodeCompiled = true;
  }
  The functions DrawSprite and DrawSpriteS look like this:
  public void DrawSprite(String name, double posx, double posy)
  {
  if (name == “sprite1”)
  {
  g_mgnd.DrawImage(sprite1, new Point((int)posx, (int)posy));
  }
  }
  public void DrawSpriteS(String name, double posx, double posy, double w, double h)
  {
  if (name == “sprite1”)
   {
  g_mgnd.DrawImage(sprite1, (float)posx, (float)posy, (float)w, (float)h);
  }
  }

 
  现在,我们可以在我们的应用程序中编写脚本来实现绘画。我添加了7个示例函数来呈现不同的利萨如曲线。选择示例1到7填充适当代码到代码文本框中。

  点击“编译并运行”编译脚本,并在应用程序的主循环中运行它。该应用程序在脚本上下文中调用“main”函数并每秒执行50次。

以下是引用片段:
  private void MainFunc()
  {
  while(true)
  {
  if (isCodeCompiled)
  {
  g_mgnd.FillRectangle(Brushes.Black, mgndBounds);
  script.Execute(“main”);
  UpdatePicBox();
  }
  Thread.Sleep(20);
  }
  }

 
  当然,这仅仅是展示如何使用脚本的一个简单示例。我仅仅是想创建一个可视化的示例来展示如何以一种非常简单的方式使用脚本。它展示在应用程序中如何定义函数并在脚本中使用它。理论上,对于使用脚本引擎实现你想要的功能没有限制。我的下一步将集成该引擎到我的呈现器中,添加这些功能使其在不用重新编译的情况下添加新的类型。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

作者

Kim
Kim

相关推荐